Code Monkey home page Code Monkey logo

ui5-cap-event-app's Introduction

ui5-cap-event-app

REUSE status

Showcase of two UI5 user interfaces, one built with freestyle SAPUI5 (or rather OpenUI5), the other using SAP Fiori elements, with a CAP backend, using OData V4 with Draft mode.

Description

This app uses simple attendee registration and administration for events as an example scenario for demonstrating the data handling and overall setup. The app consists of three parts: an end-user UI implemented in freestyle SAPUI5, a metadata-driven administrator UI generated with Fiori elements and a Node.js-based CAP backend. While the code implements a complete end-to-end full-stack app, it is kept as simple as possible and the main focus is on freestyle SAPUI5 code making use of OData V4 as well as of "Draft" functionality to persist non-final datasets.

Further details about how the functionality is implemented can be found in the documentation.

Requirements

  • Node.js (latest LTS version which supports npm workspaces)
  • SAP CAP CLI (do npm install -g @sap/cds-dk)
  • sqlite3 (only needed separately on Windows, commandline tools zip need to be downloaded, extracted, and directory added to the PATH)

Download and Installation

  1. Clone the project.

    git clone https://github.com/SAP-samples/ui5-cap-event-app
    cd ui5-cap-event-app
  2. Use npm to install the dependencies.

    npm i

Running the Project

Execute the following command to run the project locally for development (start the CDS server running the admin UI and form UI embedded):

npm start

As also shown in the terminal after executing this command, the CDS server is running on http://localhost:4004/.

For the form UI, you can use user name [email protected] with password 123. For the admin UI, use [email protected] and password 123.

Building the Project

Execute the following command to build the project and get one integrated app that can be deployed (build the form UI, admin UI, and CDS server):

npm run build

Prerequisite: npm run build runs cds build in the CDS server package which requires @sap/cds-dk. Please ensure to install @sap/cds-dk globally via:

npm i -g @sap/cds-dk

After building the individual packages, the build results will be copied to the central dist folder. The resulting package inside the dist folder consists of the CDS server hosting the form UI and the admin UI as well as a sandbox Fiori launchpad to start the individual UIs.

To start the generated package, just run npm install and npm start inside the dist folder. This installs the dependencies and starts the CDS server hosting the UIs. Now the sandbox Fiori launchpad can be opened on http://localhost:4004/.

Debugging the Project

We have prepared two ways of debugging the Node.js part of the app easily:

Debugging with VSCode

The launch configuration "debug server in vscode" is part of the project and can be used to run the CAP server in debug mode and debug directly in VSCode (e.g. set breakpoints).

Note: the UI parts are not started by this launch configuration. To debug the interaction of server and UI, the form UI or admin UI has to be started separately with npm run start:ui-form or npm run start:ui-admin.

Limitations

The local database uses in-memory mode. Data will be re-initialized after each restart.

The sample does not cover deployment of the app, where additional considerations e.g. regarding database and authentication are needed.

How to obtain support

The sample code is provided as-is. No support is provided.

References

Other projects demonstrating similar use-cases:

License

Copyright (c) 2020-2023 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the LICENSE file.

ui5-cap-event-app's People

Contributors

akudev avatar btbernard avatar d023604 avatar joaquinrecio avatar petermuessig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ui5-cap-event-app's Issues

TS Types for different UI5 versions (Question)

Hi all,

I noticed some differences in the TS types for other UI5 versions. Can we generate the types for other versions as well?

One more thing, I noticed that the names of the controllers also contain "Controller" at the end while this is not added in the controllername defined in the view. Does the framework excludes "Controller" when connecting the view to the controller?

Thank you in advance!

Kr, Wouter

Typescript Feedback (JSONModel && Promisification)

Hi All,

First thank you very much for the typescript branch. I am really super excited about the progress made here. I think the overall developments in this direction will be a giantic step for the UI5 development generally. After developing a year with typescript I really don't want to go back - It is fantastic that my day-to-day framework now makes that step too..

Regarding typescript the most "urgent" open point was mentioned in PR #5.
There are however two more open points, which I'd like to address, which might be a big help for application developers. Both can be easily implemented by customers, so are therefore no blockers at all, but imo would be great inside the core product / framework.
I am not sure if that is the right place (probably more the typescript or the openui5 repo?), but still I want to give you short feedback also regarding the sample, as maybe (if this here should be a best practice typescript application) you might add sth. of the examples below inside your code.

Open up JSONModel

Typescript and JSON-Model is a small "no-no" when using the "normal API". Using setProperty("long/long/1/path/without/typing", some_unknown_value) inside typescript is very sad.
In out project we have build a sub-class of the JSON Model, which:

  1. Publishes JSONModel.oData with a fixed type (template based)
  2. Allows full read-access on the type. Writing is only allowed using functions
  3. Automatically triggers a JSONModel.checkUpdate after a write function is called ("easy workaround" vs. doing deep change detection using proxies, or getter / setters, which are reducing the performance.)

For that however both "oData" && checkUpdate should be opened and made public (we are working with "any" atm, to workaround that restriction).

Example-Code: State

export class DetailControllerState {
    busy: boolean;
    public setBusy(bBusy: boolean) {
        this.busy = bBusy;
    }
}
export type DetailControllerStateRO = { +readonly [P in keyof DetailControllerState]: DetailControllerState[P] };

and Usage inside a controller..
grafik

Using that "State" approach you can mostly avoid using formatter by using "getters" instead (ofc not "perfect", as the change detection is not working here, but still nice). Example of a state method:

    get getAmountOfData(): string {
        return this.data.filter((e) => e.type=== ENUM_DATA.MY_TYPE && e.change_indicator !== "D").length.toString();
    } 

JSONModel:

export default class GenericJSONModel<T> extends JSONModel {
    public _setData(oData: T, bMerge?: boolean): void {
        this.setData(oData, bMerge);
        this._observeFunctions();
    }

    private _observeFunctions() {
        Object.getOwnPropertyNames(Object.getPrototypeOf(this.oData)).forEach((sAttr) => {
            const sVal = allData[sAttr];
            if ( typeof sVal === "function" ) {
                const funcBefore: Function = sVal;
                const funcApply = this._checkUpdate.bind(this);
                allData[sAttr] = function(...args: any[]) {
                    const ret = funcBefore.apply(this,args);
                    funcApply();
                    return ret;
                };
            }
        });
    }
}

Promisification

Using transpiler / babel we can finally use await/async - but the scope of it is somewhat limited without the use of promise based APIs. UI5 still has a lot of places where callback based APIs are published. As ofc breaking changes are not really possible, i'd suggest the creation of some reusable classes build on top of the existing APIs.
I want to give you two short examples of our current project, where we have build promisified versions of the ODataModel handler and the MessageBox method.

  1. MessageBox Handling example, asking the user if he wants to leave the current page without saving
    protected async _confirmNavBack() {
        if(!this._isDirty()) { return true; }
        const answer = await AsyncMessageBoxDef.confirm(this.getText("confirmCancelMsg"), {
            title: this.getText("confirmCancelTitle"),
        });
        return answer === Action.OK;
    }

    protected async _onNavBack() {
        const allowNavBack = await this._confirmNavBack();
        if ( allowNavBack === false ) { return; }
        this.getRouter().navTo("Master");
    }
  1. ODataModel handler read call, including static typings (using templates)
        try {
            const headData = await this._oModel.read(sNormalizedPath);
           //access all elements, headData is statically typed using DTOs etc..
            if (headData.status === "2") {
                return;
            }
        } catch (e) {
            return;
        }

Regards,
Timo

Changing name of "create" button in fiori elements app

Hi,
First of all it's a wonderful app to learn SAP CAP, I have created the fiori elements app using wizard and consuming SAP CAP LOCAL SERVICE and i see two simple issues here.

  1. When we click "create" to create new record and the new screen open to enter the data, but in the footer I see the button name "create", If I have to rename this button to "Save" I don't see there is any possibility to change the name?
  2. After clicking on the "create" button and when data is saved, There is no button to go on main page where table is coming, Is there any possibility to somehow add a "back" button which takes me to main page?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.