You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Create your own application

Copy the template

There is currently no automated template or maven artifact template that automatically creates a new application.
For this reason, the easiest way is to copy the pattern app `demoApp` under `apps`.


Then make the following adjustments.

1. At least customize ** Name **, ** Version ** and ** Description ** in the file `packages.json`:  "name" :  "@ odlux / demo-app",

     Note: Use hyphenated letter instead of uppercase letter. demoApp becomes a demo-app.

2. Check the file `webpack.config.js` to see if all backend paths are configured (see Customizing the local environment)

3. Adapt the name of the module in the Webpack-config (demoApp). This is followed by the path to the entry file (`. / plugin.tsx`).
```js
entry: {
demoApp: ["./plugin.tsx"]
},
```
    Note: Do not use bindings or special characters.

4. Optionally, you can specify in the same entry what the entry file for this module/app should be called. Default is `plugin.tsx`.

5. In the file `index.html` the module to be loaded (` demoApp`) has to be exchanged, against its own module:
```js
// run the application
require(["app","demoApp"], function (app) {
app("./app.tsx")
});
```

   Note: The name of this module has been set in step 3.


Customize the configuration of the app

The new app is configured within the entry file (default: `plugin.tsx`).

Here the unique name, the icon, the title of the menu item, etc. are defined.


1. Select icon from the library `fontawesome 5`.
```ts
import { faAddressBook } from '@fortawesome/free-solid-svg-icons';
```


2. Adjust the registration of the app in the entry file.

The unique name is used by the framework to differentiate the apps. The icon is used for navigation and the title bar. The root component is the very first component of this app. The menu entry is optional to display a name for this app in the navigation.
```js
applicationManager.registerApplication({
name: "demoApp", // eindeutiger Name der App
icon: faAddressBook, // Icon der App
rootComponent: FinalApp, // Wurzelkomponente der App
menuEntry: "Demo App" // Menu Eintrag
});
```


3. If this application contains its own action handler, it must also be configured. The creation of Action Handlers is considered more closely in a Seperate Sever.
```js
applicationManager.registerApplication({
// ...
rootActionHandler: demoAppRootHandler,
});
```


4. If this application is to provide its own components for other apps, these must also be configured. The key is the name with which the component can be accessed later, as well as the value of the component to be exported.
```js
applicationManager.registerApplication({
// ...
exportedComponents: { counter: Counter },
});
```


5. Optionally specify a path under which the app should be reached. If this is not specified, the name is used as the path.
```js
applicationManager.registerApplication({
// ...
path: "demoApp",
});
```


Here, e.g. URL parameters that are to be passed to the app.
```js
applicationManager.registerApplication({
// ...
path: "demoApp/:param1",
});
```


6. Depending on whether the app should receive one or more URL parameters, these should be specified as generic TypeParameters for the `RouteComponentProps` of the` AppProps`.
```ts

// Example without parameters
type AppProps = RouteComponentProps & Connect;


// Example with a parameter
type AppProps = RouteComponentProps<{ param1: number }> & Connect;
```


7. If sub-routes within the app are to be used, they must be specified within the root component. Otherwise you can start directly with the programming of the main view.
```ts
const App = (props: AppProps) => (
<Switch>
<Route exact path={ `${ props.match.path }/authors` }
component={AuthorsList} />
<Route path={ `${ props.match.path }/authors/:authorId` }
component={EditAuthor } />
<Redirect to={ `${ props.match.path }/authors` } />
</Switch>
);
```


8. In any case, connect the app to the router using `withRouter`.
```ts
const FinalApp = withRouter(connect()(App));
```

Creating the data models or services

All data models to be used within this app are created within the `models` folder or in a subfolder in this folder. Example: `Author` for presenting authors.
```ts
/**
* Represents an author.
*/
export interface IAuthor {
/**
* Defines the unique id of the autor.
*/
id: number;

/**
* Defines the first name of this author.
*/
firstName: string;

/**
* Defines the last name of this author.
*/
lastName: string;
}
```


All services that this app should use are located in the folder `services` or a subfolder in it. In the current version, services are created as ** singleton **. To do this, the implementation file exports a single instance as `default`.
```ts
class AuthorService {
// ...
}
// return as a singleton
export const authorService = new AuthorService();
export default authorService;
```

Create / customize your own action handler

Each application can define a `root state` that represents all states specific to that app. This should be defined as an interface with the name consisting of I ** AppName ** StoreState. For the `demoApp` this would be called` IDemoAppStoreState`.
```ts
export interface IDemoAppStoreState {
listAuthors: IListAuthors;
editAuthor: IEditAuthor;
}
```


It makes sense to create this ** StoreState ** within the file with the root action handler. The name of this file should be put together as follows ** appName ** RootHandler.ts in the directory `handlers`.
For `demoApp` this would be` demoAppRootHandler.ts`.


In order to be able to effectively access the overall application state with TypeScript type security, it is necessary within this file to extend the application state of the app as follows.
```ts
declare module '../../../../framework/src/store/applicationStore' {
interface IApplicationStoreState {
demoApp: IDemoAppStoreState
}
}
```


If the app is composed of several action handlers, these must be connected with the `combineActionHandler` function of the framework before exporting.
```ts
const actionHandlers = {
listAuthors: listAuthorsHandler,
editAuthor: editAuthorHandler,
};

export const demoAppRootHandler = combineActionHandler <IDemoAppStoreState>(actionHandlers);
export default demoAppRootHandler;
```


Libraries

The O-D-L-UX framework distinguishes between libraries that are mapped to a single app. These can not be shared with other apps and must be installed separately in each app.
As a result, they are also included in the bundle of each app.

As well as libraries shared between all apps. These do not have to be installed in every app and they only exist once in the bundle of the framework.


Add a shared library

Examples of shared libraries are `react`,` react-dom`, `jQuery` or` lodash`. This library is first added to the dependencies of the parent `package.json` file (in the root directory of O-D-L-UX) in the` dependencies` section.
```json
"dependencies": {
"@types/react": "16.4.14",
"@types/react-dom": "16.0.8",
"@types/react-router-dom": "4.3.1",
"@material-ui/core": "3.1.1",
"@material-ui/icons": "3.0.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
"react": "16.5.2",
"react-dom": "16.5.2",
"react-router-dom": "4.3.1",
"@fortawesome/react-fontawesome": "0.1.3",
"@fortawesome/fontawesome-svg-core": "1.2.4",
"@fortawesome/free-solid-svg-icons": "5.3.1",
"jsonwebtoken": "8.3.0",
"@types/jsonwebtoken": "7.2.8"
},
```


Afterwards, the dependencies required for the framework and / or the app are taken over into the `package.json` file of the framework or the app in the section` peerDependencies`, which are each required by the shared dependencies.
```json
"peerDependencies": {
"@types/react": "16.4.14",
"@types/react-dom": "16.0.8",
"@types/react-router-dom": "4.3.1",
"@material-ui/core": "3.1.1",
"@material-ui/icons": "3.0.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
"react": "16.5.2",
"react-dom": "16.5.2",
"react-router-dom": "4.3.1"
}
```


After configuring ** ALL ** required apps and the framework with the new dependency, the command: `lerna bootstrap` is run to download the dependencies and provide them to the apps and the framework.

Add an exclusive library

If an app should use a library, but not share it with the other apps, this dependency is only included in the app's `package.json` file in the` dependencies` section.
```json
"dependencies": {
"object-assign": "3.2.1"
}
```

Also in this case `lerna bootstrap` should be executed in the root directory of O-D-L-UX.


Own Libraries

You can develop your own libraries in a separate project folder below the `lib` folder.


  • No labels