Frontend. User Exits¶
General information¶
User Exits (UE) are TypeScript, programming code that is executed when a specific event occurs.
User Exits are used when it is necessary to perform some non-standard actions beyond the system's capabilities. For example, if an insertion operation requires sending a special notification containing authentication data for further authorization in a third-party system.
The complete list of User Exits can be found in the types module in src/declareUe.ts
. This is an autogenerated file. It is updated after each npm ci
or npm run dev command
.
User Exits descriptions
Dynamic loading of User Exits¶
You can add User Exits to the running Universe application.
Step 1. Create file with customization who exports User Exits config. The file extension is recommended .ts, but you can also use .js. There are no requirements for the file name and file location. Example:
export const CustomAttributeOnDataCard: UniverseUE.IUeMeta['RenderAttributeOnDataCard'] = { // UniverseUE - global namespace, IUeMeta - an interface describing all available UES, where the keys are their types.
moduleId: '', // ID UE (human-readable or uuid)
active: true, // flag indicating that the UE is active and will be applied
system: false,
resolver: () => true, // a function that determines whether to call the UE for execution or not. In the case of a Render , the attribute has the following type: type Resolver = (attribute: IMetaAbstractAttribute, model: AbstractModel) => boolean;, where IMetaAbstractAttribute is type from the product SDK, AbstractModel - type from the common SDK
meta: {} // additional parameters. For example displayName: () => string define the label attribute on the record card
component: Component // UE realisation (react component).
};
Step 2. Create an index file combining the customization of the project/direction. It should export by default a list of extension points. See UE type in @universe-platform/user-exit inside the package (IUeModuleBase). Example:
import {CustomAttributeOnDataCard} from '...';
export default {
userExits: [
{
type: 'RenderAttributeOnDataCard', // A string defined by the type UniverseUE.UeTypes (this is one of the interface keys UniverseUE.IUeMeta).
...CustomAttributeOnDataCard
},
...
]
}
Step 3. Add a list of paths to the file(s) with customizations to the file customer.json: field EXTERNAL_MODULES.
Step 4. As a result, when the application is loaded, the contents of these UES are added to ueModuleManager.
When running the application via Docker, you can define the path to the directory with the UE list on the host machine via the FRONTEND_UE environment variable. This directory will be installed in the CUX directory (root directory for nginx FE), i.e. the paths to the files must start with `CUX` in EXTERNAL_MODULES.
docker-compose.yml example:
// docker-compose.yml
...
volumes:
- ${FRONTEND_UE:-/dev/null}:/usr/share/nginx/html/CUX
...
customer.json example:
// customer.json
...
"EXTERNAL_MODULES": [
"/CUX/index.es.js"
],
...
Create your own User Exits¶
User exits should be created as modules. At the same time, some externals in the window object will be available in them.
Below are recommendations for working with dynamic UE. Recommendations are based on record card customization.
Step 1. Create a new project. Set devDependencies (currently globally available React, Mobx, '@universe-platform/uikit' and '@universe-platform/sdk'). React, Mobx, '@universe-platform/uikit' they will be installed together with the SDK, you do not need to specify them.
npm i @universe-platform/ui-cli @universe-platform/sdk --save-dev
Step 2. The source files must be located in src. You definitely need an index.ts, in which we return user exits.
import {Component} from './Component';
export default {
userExits: [{
moduleId: 'testUE',
type: 'DataCardMenuItem',
active: true,
system: false,
resolver: () => true,
meta: {},
component: Component
}]
}
Step 3. When creating a component, import packages via import. By means of assembly, they will be replaced by const n = window.React, s = window["@unidata/uikit"].Button, i = window.Universe.i18n
src/Component.tsx example:
import * as React from 'react';
import {Button} from '@unidata/uikit';
import {i18n} from '@universe-platform/sdk';
export class Component extends React.Component<any> {
get dataRecord () {
return this.props.dataCardStore.dataRecordStore.getDataEntity();
}
get metaRecord () {
return this.props.dataCardStore.metaRecordStore.getMetaEntity();
}
handleDelete = (wipe: boolean) => {
return this.props.dataCardStore.handleDelete(wipe);
};
override render () {
return (
<Button>
{i18n.t('some new delete button')}
</Button>
);
}
}
Step 4. Next, you need to add the tsconfig file.json with the following content:
{
"extends": "./node_modules/@universe-platform/ui-cli/vite/tsconfig.json",
"include": ["src"]
}
Step 5. To build, add the script to package.json. The resulting file will be in the dist directory. It will be possible to put it in the CUX directory from the previous section.
{
...
"scripts": {
...
"build": "npx tsc && npx vite build --config node_modules/@universe-platform/ui-cli/vite/vite.external.config.ts"
...
}
...
}