@ouidesigner/oui-ion
v4.0.5
Published
Angular/Ionic renderer for OuIB JSON pages.
Readme
oui-ion
oui-ion is an Angular/Ionic renderer for OuIB JSON pages.
It receives a UIPage, parses its uiData, finds a parser for each node's type, and dynamically creates Ionic/Angular components. A JSON page definition such as a Column with Text and OButton children becomes a real Angular/Ionic view at runtime.
Mental Model
The render flow is:
- The host app imports
OUIIonModule.forChild(config)or registersprovideOUIIon(config). OUIIonis created with app config, service bridges, and parser registrations.- A page is selected through navigation, resolved by code, or passed to a modal.
OUIDisplayComponentpasses the page intoOUIIonPageRender.OUIIonPageRenderloads related service pages, parsespage.uiData, createsUIPageState, and creates anOUIDefaultClickListener.- The root node is rendered by
<app-ion-oui>. IonOUIcallsOUIIon.buildComponent(data).OUIIonfinds the parser matchingdata.type.- The parser dynamically creates the Angular component.
- Child components repeat the same process recursively.
Public API
The public surface is exported from src/public-api.ts.
Important exports:
OUIIonModuleandprovideOUIIonfor Angular setup.OUIIonas the main runtime/facade.OUIIonServiceas the bridge to HTTP, navigation, alerts, loading, media, and platform services.OUIIonPageRenderfor rendering aUIPage.OUIDisplayComponentas the route/modal wrapper around the renderer.OUIIonParserandOUIAbstractIonParserfor custom parser implementations.OUIDefaultClickListenerand helper utilities for OuIB runtime behavior.PinUtil/ pin helpers frompin-utils.
Angular Setup
Use the module API in Angular module based apps:
import { OUIIonModule } from '@ouidesigner/oui-ion';
@NgModule({
imports: [
OUIIonModule.forChild({
serverUrl: 'https://example.com',
appId: 'app-id',
appSecret: 'app-secret',
appPackage: 'com.example.app',
pinCrypto: {
reference: environment.ouiPinCryptoReference,
keySize: environment.ouiPinCryptoKeySize,
specialsChars: environment.ouiPinCryptoSpecials,
},
userData: {
id: 'user-id',
name: 'User Name',
},
platform: 'md',
pageViewRoute: '/mini-pages',
}),
],
})
export class FeatureModule {}Use the provider API in standalone apps:
import { provideOUIIon } from '@ouidesigner/oui-ion';
export const appConfig = {
providers: [
provideOUIIon({
serverUrl: 'https://example.com',
appId: 'app-id',
appSecret: 'app-secret',
appPackage: 'com.example.app',
pinCrypto: {
reference: environment.ouiPinCryptoReference,
keySize: environment.ouiPinCryptoKeySize,
specialsChars: environment.ouiPinCryptoSpecials,
},
userData: {
id: 'user-id',
name: 'User Name',
},
platform: 'ios',
}),
],
};OUIIonModule also registers a child route with path: ':page' and renders it through OUIDisplayComponent.
PIN Crypto Configuration
pinCrypto is required when mini-app scripts use __secure__(...) or when tightened auth encrypts API endpoint segments. Keep those values in the consuming host app configuration or environment files. Do not hardcode host PIN crypto material in @ouidesigner/oui-ion.
provideOUIIon({
serverUrl: environment.ouibServerUrl,
appId: environment.ouibAppId,
appSecret: environment.ouibAppSecret,
appPackage: environment.appPackage,
pinCrypto: {
reference: environment.ouiPinCryptoReference,
keySize: environment.ouiPinCryptoKeySize,
specialsChars: environment.ouiPinCryptoSpecials,
},
});Core Runtime
OUIIon in src/lib/o-ui.ts owns the runtime state:
- parser registration and lookup
- page and service page loading
- page cache
- app info and user config
- MEvento global functions
- navigation and modal bridge
- API calls
- asset URL resolution
- theme variables
- simulation flag
Rendering depends on data.type. If no parser is registered for a type, that node renders nothing.
Page Rendering
OUIDisplayComponent is a thin wrapper. For normal route navigation it reads the selected page and nav params from oui.exchange. For modal rendering, the page and params are passed directly through component inputs.
OUIIonPageRender does the actual page bootstrapping:
- calls
oui.loadService(page.code)so nested templates/fragments can resolve service pages - parses
page.uiData - creates
UIPageState,StateHolder,OGlobalFormState, and output state - creates the page click handler
- runs
__init__when the JSON has the structured__view__format - renders either
uiData.__view__or the whole parsed JSON tree
Structured pages look like this:
{
__init__: 'SOME_MEVENTO_SETUP()',
__view__: {
type: 'Column',
children: [],
},
}Plain pages can render the JSON root directly:
{
type: 'Root',
child: {
type: 'Text',
value: 'Hello',
},
}Parser System
Every renderable node is handled by an OUIIonParser.
export interface OUIIonParser {
type: string;
componentType: Type<OUIIonElement>;
parse(
data: { [k: string]: any },
ouiHost: IonOUIDirective,
clickHandler?: OUIDefaultClickListener,
options?: any,
): OUIIonElement;
export(element: OUIIonElement): { [k: string]: any };
}Most parsers extend OUIAbstractIonParser, which:
- clears the host
ViewContainerRef - creates the parser's Angular component
- assigns
data,clickHandler,mode, and layout constraint options
The built-in parser catalog lives in src/lib/parsers/default-parsers.ts.
Common parser families:
- page shell and layout:
Root,SingleChildScrollView,Container,Padding,SizedView,Stack,Positioned - text and media:
Text,DynamicText,Image,Icon,QrCode - flex layout:
Row,Column,Expanded,Flexible,WrapView - buttons:
OButton,TextButton,ElevatedButton,OutlinedButton - forms:
Form,TextField,DateTime,Switch,Slider,Checkbox,Dropdown,Selector,FilePicker - data and control views:
FutureView,ListView,GridView,Stated,Controller,Interval,VisibilityControl,DelayedView - composition:
Template
Dynamic Values
Helpers in src/lib/helpers.ts resolve dynamic string values used by many parsers:
- normal strings are passed through translation
- strings beginning with
%are treated as translation keys - strings wrapped in
${...}are executed by the current MEvento VM
Example:
{
type: 'Text',
value: '${USER.name}',
}MEvento Integration
OUIIon registers runtime functions into MEvento during initialization. These include storage helpers, logging, map/list helpers, encoding utilities, date/time helpers, math/string helpers, navigation, modal behavior, API execution, asset resolution, and secure PIN helpers.
OUIDefaultClickListener is the main bridge between page actions, MEvento execution, API calls, form state, navigation, and the current UIPageState.
Because OuIB page JSON can include MEvento expressions and scripts, page definitions are not only static UI data; they can also execute behavior.
Service Bridge
OUIIonService wraps platform and app services used by the runtime:
httpGet()andhttpPost()with OuIB common headers- alerts, toasts, loading indicators, and confirmations
- navigation and back behavior
- modal dismissal
- camera/image picking
- barcode scanning
- date formatting
Common request headers include SDK version, user id/name, app id/secret, app package, and language.
Page Loading
OUIIon loads pages through the consumer API:
- app services list:
GET /api/v1/c/apps/{appId}/services - single service/page by code:
GET /api/v1/c/apps/{appId}/services/{code} - pages belonging to a service:
GET /api/v1/c/apps/{appId}/{code}/pages
The runtime keeps a cached page list and per-service page caches. page(code) resolves from cache first and falls back to _loadPage(code).
Hosts can provide a custom UIPageResolver when page resolution needs to come from another source.
Preview And Simulation
simulation is a runtime flag used for mock/no-backend flows. It is not a preview/draft switch. When simulation is enabled, parts of the runtime skip real backend calls and some components use simulation data.
To preview unreleased pages, the host app and backend must expose draft or build selection through the consumer API contract, for example with a query/header such as preview=true or build=74. oui-ion can forward query params through OUIIonService.httpGet, but it does not call admin-only metadata endpoints by default.
Adding A Parser
To add a new node type:
- Create a standalone component implementing
OUIIonElement. - Create a parser implementing
OUIIonParseror extendingOUIAbstractIonParser. - Set the parser
typeto the JSON node type. - Add the parser to
defaultParsersor pass it throughOUIIonOptions.parsers.
Example:
export class MyWidgetParser extends OUIAbstractIonParser {
type = 'MyWidget';
componentType = MyWidgetComponent;
}JSON:
{
type: 'MyWidget',
value: 'Hello',
}Development
Run commands from the workspace root (D:\COMMON\ouib-angular-lab).
GitLab registry: publish and install guides live in the workspace docs/registry-setup.md and docs/consuming-packages.md.
Build once:
npx ng build oui-ionBuild on changes:
npx ng build oui-ion --watchRun unit tests:
npx ng test oui-ionRun the package scripts from the library folder if needed:
npm run build:lib
npm run build:dev
npm testNotes And Risks
OUIConfigis static/global runtime state; avoid creating multiple conflicting runtime configs in the same app shell.- Parser lookup is string based. A typo in
data.typesilently produces no UI. uiDatacan execute MEvento code. Treat loaded pages as trusted app content.- Several runtime paths currently log to the console unconditionally.
simulationshould not be reused for previewing draft pages because it changes backend behavior.
