### Composable Appsetup Example Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0401_appsetup.adoc This snippet demonstrates the basic structure of a composable appsetup in TypeScript. It shows how components can define their own setup logic. ```tsx import React from 'react'; import { A12AppSetup, A12Component } from '@mgm/a12-client'; // Define a simple A12 Component with its setup interface MyComponentProps { message: string; } const MyComponent: A12Component = { name: 'MyComponent', setup: ({ registerReducer, registerSaga, registerDataHandler }) => { // Example setup logic for the component registerReducer('myReducer', (state = 0, action) => { if (action.type === 'INCREMENT') { return state + 1; } return state; }); registerSaga('mySaga', function*() { // Saga logic here }); registerDataHandler('myDataHandler', async () => { // Data handler logic here return { data: 'some data' }; }); return { // Component specific props message: 'Hello from MyComponent!' }; }, render: ({ message }) => (
{message}
) }; // App setup using the composable API const appSetup: A12AppSetup = { components: [ MyComponent // Other components can be added here ] }; export default appSetup; ``` -------------------------------- ### Initialize Example Models Source: https://github.com/mgm-tp/a12-client/blob/main/devapp/README.md Initializes the example models for the A12 Client Devapp. ```shell npm run init ``` -------------------------------- ### Example Variant Selection Mapper and UI Setup Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0412_heterogeneity.adoc This TypeScript code demonstrates the setup of a variant selection mapper and its integration with a React component for rendering a type selection UI. It's used for tailoring heterogeneity functionality to project-specific needs. ```typescript import React from "react"; import { HeterogeneousScene, Model, View } from "@mgm/client.core"; import { ProductOverviewModel } from "@mgm/client.core.models"; import { OverviewCRUDView } from "@mgm/client.core.views"; import { ProductModel, BrandModel } from "@mgm/client.core.models"; import { RelationshipFormEngineView } from "@mgm/client.core.views"; // Setup a Scene using the Overview Model `Product-overview` and the view `OverviewCRUD`. const overviewScene = new HeterogeneousScene({ model: new Model({ graph: ProductOverviewModel, }), view: new View({ component: OverviewCRUDView, }), }); // Setup a Scene using the Form Models `Product` and `Brand` (constrained to the respective type) and the view `RelationshipFormEngine`. const relationshipScene = new HeterogeneousScene({ model: new Model({ graph: [ ProductModel.withConstraint({ type: "Product" }), BrandModel.withConstraint({ type: "Brand" }), ], }), view: new View({ component: RelationshipFormEngineView, }), }); ``` -------------------------------- ### Start Development Application Source: https://github.com/mgm-tp/a12-client/blob/main/README.md Starts the development application, which showcases client library features. Navigate to the 'devapp' directory first. ```sh cd devapp pnpm start ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/mgm-tp/a12-client/blob/main/README.md Installs all project dependencies using pnpm. This command should be run in the repository root. ```sh pnpm install ``` -------------------------------- ### Run the Devapp (Default Mock Profile) Source: https://github.com/mgm-tp/a12-client/blob/main/devapp/README.md Starts the A12 Client Devapp using the default 'mock' profile. In this profile, no backend is started, and data is mocked. ```shell npm start ``` -------------------------------- ### createA12ApplicationSetup Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Initializes the A12 application setup, returning the store, initial actions, and the main application component. ```APIDOC ## createA12ApplicationSetup ### Description Creates and configures the A12 application, providing access to the Redux store, initial actions, and the root component. ### Signature createA12ApplicationSetup(appConfig: A12ApplicationConfig): { store: Store; initialActions: () => Promise; Component: JSX.Element; } ### Parameters - **appConfig** (A12ApplicationConfig) - Configuration object for the application. ### Returns An object containing the application store, a function to dispatch initial actions, and the main application component. ``` -------------------------------- ### addReduxSetupAction Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Adds setup actions to be executed during the Redux store setup. These actions can be used for initializing Redux-related configurations. ```APIDOC ## addReduxSetupAction ### Description Adds setup actions to be executed during the Redux store setup. These actions can be used for initializing Redux-related configurations. ### Method Not applicable (function signature) ### Endpoint Not applicable (function signature) ### Parameters - **...setupActions** (NonNullable) - Required - A variable number of Redux setup action functions. ### Request Example Not applicable (function signature) ### Response Not applicable (function signature) #### Success Response (200) Not applicable (function signature) #### Response Example Not applicable (function signature) ``` -------------------------------- ### Install A12 Client Application Model Migration Tool Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1100_migration.adoc Install the migration tool globally using npm. This command ensures the tool is available system-wide for use. ```bash npm install -g @com.mgmtp.a12.client/client-application-model-migration ``` -------------------------------- ### createApplicationSetup Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Initializes and creates the application setup based on the provided configuration. This function is the primary entry point for configuring the client application. ```APIDOC ## createApplicationSetup ### Description Creates the application setup based on the provided configuration. ### Signature export function createApplicationSetup(input: Config): ApplicationSetup; ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **input** (Config) - Required - The configuration object for setting up the application. ### Request Example ```json { "example": "config object" } ``` ### Response #### Success Response (200) * **ApplicationSetup** - The created application setup object. ### Response Example ```json { "example": "application setup object" } ``` ``` -------------------------------- ### Example of a simple ModelLoader implementation Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0403_model_loading.adoc This snippet provides an example implementation of a custom ModelLoader. It shows how to define a loader that can fetch models. ```tsx import { Model, ModelLoader } from "@mgm/a12-client"; export class SimpleModelLoader implements ModelLoader { async loadModel(modelId: string): Promise { // Simulate fetching a model from a source console.log(`Loading model with id: ${modelId}`); // In a real scenario, you would fetch the model data here // For example, from an API or a local store if (modelId === "example-model") { return { id: modelId, // ... other model properties } as Model; } return undefined; } } ``` -------------------------------- ### Install A12 Client Core Package Source: https://github.com/mgm-tp/a12-client/blob/main/README.md Installs the latest client core package using npm. Ensure peer dependencies are provided. ```sh npm install @com.mgmtp.a12.client/client-core ``` -------------------------------- ### Install Dependencies Source: https://github.com/mgm-tp/a12-client/blob/main/devapp/README.md Installs project dependencies using npm. The legacy-peer-deps flag is necessary to resolve compatibility issues. ```shell npm install --legacy-peer-deps ``` -------------------------------- ### Install A12 Client Codemod with pnpm Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1101_2025.06-ext4.adoc Install the codemod globally using pnpm. This is the first step to migrate deep import paths. ```bash pnpm install -g @com.mgmtp.a12.client/client-codemod ``` -------------------------------- ### Registering DataHandlers Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0306_data_loading.adoc Example of registering DataHandlers in application setup. The order of registration is important for DataProviders and DataLoaders, while DataEditors are always evaluated first. ```tsx const dataHandlers: DataHandler[] = [ new DocumentDataEditor(), new DataLoader(), new DataProvider() /* ... */ ] ``` -------------------------------- ### Application Setup Configuration Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Defines the configuration options for setting up an application. This includes various triggers, middleware, reducers, and model loading configurations. ```typescript export interface ApplicationSetup { readonly applicationResetTriggers?: { readonly resetRequested: ActionCreator[]; readonly resetConfirmed: AnyAction_2; readonly reset: ActionCreator[]; }; composeEnhancer?: ComposeEnhancer; readonly customSagaMiddleware?: SagaMiddleware; customSagas?: (() => SagaIterator)[]; dataHandlers?: DataHandler[]; readonly dataReducers?: ActivityReducers.DataReducer[]; dispatchSaga?(descriptors: ApplicationSaga.Descriptor[]): SagaIterator; readonly locale?: Locale; model: ApplicationModel; modelLoader: ModelLoader; overridePlatformSagas?: ApplicationSaga.Descriptor[]; preComputeNewDocuments?: boolean; readonly reducerMap?: ReducerMap; readonly rootReducer?: (defaultReducer: Reducer) => Reducer; setupActions?: AnyAction_2[]; } export function createApplicationSetup(input: Config): ApplicationSetup; ``` -------------------------------- ### Scene Match Condition Example Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0305_application_model.adoc This JSON snippet demonstrates the structure of match conditions used to select a scene based on activity descriptor properties. It includes examples of 'mustEqual' and 'isSet' criteria. ```json { "matchCondition": [ { "key": "model", "mustEqual": "Offer" }, { "key": "instance", "isSet": false } ] } ``` -------------------------------- ### Run the Devapp (Mock Profile Explicitly) Source: https://github.com/mgm-tp/a12-client/blob/main/devapp/README.md Starts the A12 Client Devapp explicitly with the 'mock' profile, ensuring no backend server is used. ```shell npm run start:mock ``` -------------------------------- ### ApplicationActions.startMainActivityRequested Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Action creator to request the start of the main activity. This is typically used to initiate the primary user interface flow. ```APIDOC ## ApplicationActions.startMainActivityRequested ### Description Action creator to request the start of the main activity. This is typically used to initiate the primary user interface flow. ### Method Not applicable (action creator) ### Endpoint Not applicable (action creator) ### Parameters - **payload** (ApplicationActions.StartMainActivityRequestedPayload) - Required - Payload containing initial activity details, potentially including an action. - **action** (AnyAction) - Optional - An associated action. ### Request Example Not applicable (action creator) ### Response Not applicable (action creator) #### Success Response (200) Not applicable (action creator) #### Response Example Not applicable (action creator) ``` -------------------------------- ### Customize MasterDetail Widget with ClientWidgetMapContext Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1102_2025.06-ext2.adoc This example demonstrates the recommended approach for customizing widgets by using ClientWidgetMapContext. ```typescript import { useContext } from "react"; import { ClientWidgetMapContext } from "@com.mgmtp.a12.client/client-core/lib/core/ClientWidgetMap.js"; export function CustomResizableMasterDetailLayout( props: FrameViews.MasterDetailLayoutProps ) { const DefaultClientWidgetMap = useContext(ClientWidgetMapContext); const customWidgetMap = { ...DefaultClientWidgetMap, MasterDetail: CustomMasterDetail }; return ( ); } ``` -------------------------------- ### Run A12 Client Application Model Migration Tool with npx Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1100_migration.adoc Perform the migration directly using npx without global installation. This is an alternative to the npm install command. The -b flag creates backups if models are not under version control. Use -h for help. ```bash npx @com.mgmtp.a12.client/client-application-model-migration -b ``` -------------------------------- ### Run the Devapp (Platform Profile) Source: https://github.com/mgm-tp/a12-client/blob/main/devapp/README.md Starts the A12 Client Devapp with the 'platform' profile, which includes a simple A12 backend server running on localhost:9090 with in-memory database. ```shell npm run start:platform ``` -------------------------------- ### Setup Adapter Module for Multiple Application Models Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0407_modularization.adoc Demonstrates how to set up the Adapter Module to handle multiple Application Models. This is useful when your model graph contains several models that need to be loaded and made available. ```tsx import { Client, AbstractModule } from "@a12/client"; import { AdapterModule } from "@a12/client/adapter"; // Placeholder for ApplicationModel type when using AdapterModule // type ApplicationModel = any; const client = new Client({ modules: [ new AdapterModule(), // ... other modules ], // When using AdapterModule, specifying applicationModel here is obsolete // but still required by the type signature. applicationModel: null as any, }); ``` -------------------------------- ### addInitialAction Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Adds initial actions to be executed when the application store is set up. These actions can perform setup tasks or dispatch initial data. ```APIDOC ## addInitialAction ### Description Adds initial actions to be executed when the application store is set up. These actions can perform setup tasks or dispatch initial data. ### Method Not applicable (function signature) ### Endpoint Not applicable (function signature) ### Parameters - **...actions** (readonly ((store: Store) => Promise | void)[]) - Required - A variable number of functions that take the store and perform an action. ### Request Example Not applicable (function signature) ### Response Not applicable (function signature) #### Success Response (200) Not applicable (function signature) #### Response Example Not applicable (function signature) ``` -------------------------------- ### DocServiceFactory Singleton Get Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Gets the singleton instance of DocServiceFactory. ```typescript export function get(): DocServiceFactory; ``` -------------------------------- ### Example DataProvider Implementation Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0306_data_loading.adoc This DataProvider handles loading documents from an API. It checks if the operation is 'load' and if the data holder instance is defined. It fetches documents using getDocumentById and dispatches an action to set the data. ```tsx const DocumentsDataProvider: DataProvider = { name: "DocumentsDataProvider", canHandle({ dataHolder, operation }) { switch (operation) { case "load": return dataHolder.descriptor.instance !== undefined; case "save": case "delete": return false; default: throw new Error(`No support for ${operation}.`); } }, *provideData({ activityId, dataHolders, operation, details }) { switch (operation) { case "load": const documents = yield all( dataHolders.map(({ descriptor }) => // getDocumentById fetches data from a external source and returns a promise call(getDocumentById, `/documents/${descriptor.instance}`) )); yield put(ActivityActions.setData({ activityId, data: documents })); break; case "save": case "delete": default: throw new Error(`No support for ${operation}.`); } } }; ``` -------------------------------- ### Module Menu Entry Configuration Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0305_application_model.adoc Defines a menu entry for a module, including its name, localized label, and the initial activity to start. ```json { "menu": { "name": "offer", "label": { "en": "Offer" }, "initialActivity": { "descriptor": { "model": "Offer_v3" } } } } ``` -------------------------------- ### Basic Scene Change Directives Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0305_application_model.adoc Example of directives to clear a region and add a view when a scene is entered. This is a common pattern for initializing UI components. ```json { "onEnter": [ { "type": "REGION_CLEAR", "region": ["CONTENT"] }, { "type": "VIEW_ADD", "region": ["CONTENT"], "name": "OverviewCRUD" } ], "onExit": [] } ``` -------------------------------- ### Simple Server Connector Configuration Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0403_model_loading.adoc This example demonstrates providing a custom server connector implementation using the ConnectorLocator API. It can be used to modify authentication filters or provide a custom server connector. ```tsx import { ConnectorLocator } from "@mgm/a12-client/server/connector"; const locator: ConnectorLocator = { getConnector: () => { // Provide your custom server connector here return { // ... connector implementation }; }, }; export default locator; ``` -------------------------------- ### Custom Layout Implementation Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0404_layouts.adoc Define a custom layout by returning it from a custom LayoutProvider. This example shows how to reference it in the Application Model. ```tsx import { ApplicationModel, LayoutProvider, ViewComponent, } from "@mgm/a12-client-core"; const customLayoutProvider: LayoutProvider = { getLayout(name: string): ViewComponent | undefined { if (name === "custom") { return () => (

Custom Layout

); } return undefined; }, }; const appModel = new ApplicationModel({ layoutProvider: customLayoutProvider, }); appModel.addView("myView", { layout: "custom" }); ``` -------------------------------- ### Custom Progress Indicator Predicate Example Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1103_2025.06.adoc Demonstrates how to create a custom progress indicator provider using a predicate function to determine the loading state based on the first data holder's content. ```tsx import type { Activity } from "@com.mgmtp.a12.client/client-core/lib/core/activity"; import { FrameFactories } from "@com.mgmtp.a12.client/client-core/lib/core/frame"; function isFirstDataHolderEmpty(a: Activity): boolean { return a.dataHolders.at(0)?.data === undefined; } FrameFactories.createProgressComponentProvider([isFirstDataHolderEmpty]) ``` -------------------------------- ### Example Usage of waitForStateChange Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0414_asynchronous-flows-with-redux-saga.adoc Illustrates how to use the waitForStateChange saga within another saga by passing a selector to wait for a desired state change and retrieve a return value. ```tsx const returnValue = yield call(StoreSagas.waitForStateChange, mySelector(myArguments)) ``` -------------------------------- ### Implement Custom Extension Point Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0407_modularization.adoc Example of implementing a custom extension point 'getModuleSpecificRenderer' in a module. This allows for rendering module-specific components. ```tsx class MyAbstractModule extends AbstractModule { // ... getModuleSpecificRenderer(): Renderer | undefined { return undefined; } } class MyModuleExtensions { static getRenderer(module: MyAbstractModule): Renderer | undefined { return module.getModuleSpecificRenderer(); } } interface Renderer { render(): React.ReactNode; } // Example usage: // const renderer = MyModuleExtensions.getRenderer(myModule); // if (renderer) { // return renderer.render(); // } ``` -------------------------------- ### Importing Types and Components Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md This snippet demonstrates the various imports used in the client-core package, including types for actions, UI components, and utility functions. Ensure these dependencies are correctly installed. ```typescript import type { Action } from 'typescript-fsa'; import type { Action as Action_2 } from 'redux'; import type { ActionContentboxProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/contentbox/main/action-contentbox/action-contentbox.api.js'; import { ActionCreator } from 'typescript-fsa'; import type { AnyAction } from 'typescript-fsa'; import { AnyAction as AnyAction_2 } from 'redux'; import type { ApplicationFrameProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/layout/application-frame/main/application-frame.api.js'; import type { ApplicationHeaderProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/application-header/main/application-header.api.js'; import { AsyncActionCreators } from 'typescript-fsa'; import type { ButtonGroupProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/button-group/main/button-group.api.js'; import type { ButtonProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/button/main/button.api.js'; import { ComponentType } from 'react'; import type { Container } from '@com.mgmtp.a12.widgets/widgets-core/lib/common/main/base-props.js'; import type { ContentBoxProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/contentbox/main/template/contentbox.tpl.api.js'; import { Context } from 'react'; import type { CSSProperties } from 'react'; import type { Dispatch } from 'redux'; import type { DocumentModel } from '@com.mgmtp.a12.kernel/kernel-md-facade/lib/main/js/api.js'; import { flow } from 'fp-ts/lib/function.js'; import type { FlyoutMenuProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/menu/main/flyout-menu.api.js'; import type { Header } from '@com.mgmtp.a12.base/base-model-api/lib/main/header/index.js'; import type { HeaderTriggerProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/button/main/header-trigger/header-trigger.api.js'; import type { IconProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/icon/main/icon.api.js'; import type { IGeneratedCodeAccessor } from '@com.mgmtp.a12.kernel/kernel-md-facade/lib/main/js/api.js'; import { JSX } from 'react/jsx-runtime'; import { JSX as JSX_2 } from 'react'; import type { LabelProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/input/base/template/base.tpl.api.js'; import type { LayoutGridProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/layout/layout-grid/main/layout-grid.api.js'; import type { ListItemProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/list/main/list.api.js'; import type { ListProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/list/main/list.api.js'; import { Locale } from '@com.mgmtp.a12.utils/utils-localization/lib/main/localization/Locale.js'; import type { Locale as Locale_2 } from '@com.mgmtp.a12.utils/utils-localization/lib/main/index.js'; import type { Localizable } from '@com.mgmtp.a12.utils/utils-localization/lib/main/localization/Localizable.js'; import type { Localizable as Localizable_2 } from '@com.mgmtp.a12.utils/utils-localization/lib/main/index.js'; import type { LocalizedModelText } from '@com.mgmtp.a12.utils/utils-localization/lib/main/localization/LocalizedModelText.js'; import type { Localizer } from '@com.mgmtp.a12.utils/utils-localization/lib/main/localization/Localizer.js'; import type { MasterDetailProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/layout/master-detail/main/master-detail.api.js'; import { MemoExoticComponent } from 'react'; import type { Middleware } from 'redux'; import type { MiddlewareAPI } from 'redux'; import type { ModalNotificationProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/modal-notification/main/modal-notification.api.js'; import type { ModalOverlayProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/modal-overlay/main/modal-overlay.api.js'; import { Model as Model_2 } from '@com.mgmtp.a12.base/base-model-api/lib/main/model/index.js'; import type { ModelGraph } from '@com.mgmtp.a12.dataservices/dataservices-access/lib/Relationship/ModelGraph.js'; import type { PopUpMenuProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/pop-up-menu/main/pop-up-menu.api.js'; import type { ProgressIndicatorProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/progress-indicator/main/progress-indicator.api.js'; import type { PropsWithChildren } from 'react'; import type { ReactElement } from 'react'; import type { ReactNode } from 'react'; import type { Reducer } from 'redux'; import type { RefObject } from 'react'; import type { SagaGenerator } from 'typed-redux-saga'; import type { SagaIterator } from 'redux-saga'; import type { SagaMiddleware } from 'redux-saga'; import type { SelectProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/input/select/main/select.api.js'; import type { SizeDetectorProps } from '@com.mgmtp.a12.widgets/widgets-core/lib/layout/size-detector/main/size-detector.api.js'; ``` -------------------------------- ### Example Usage of acquireActivityLock Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0414_asynchronous-flows-with-redux-saga.adoc Demonstrates how to use the acquireActivityLock saga and subsequently release the acquired lock. It includes a check for a undefined lockId to handle cases where the activity is deleted during the locking process. ```tsx const lockId = yield call(ActivitySagas.acquireActivityLock, activityId, owner, details); if (lockId === undefined){ // activity with activityId is not in the store anymore, so it makes sense to stop here.. return "failed"; } // Statements while having the lock // When you are done, unlock the activity with the lockId yield put(ActivityActions.unlock({activityId: activityId, lockId: lockId})); ``` -------------------------------- ### Sample DataReducer Implementation Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0307_data_reducers.adoc An example of a DataReducer that reacts to a specific action to update a particular DataHolder. It ensures the action payload contains an activity identifier. ```tsx include::assets/typescript/features/data-reducer.ts[tags="dataReducerAPI"] ``` -------------------------------- ### Module Registry Provider Instance Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Provides access to the singleton instance of the ModuleRegistry and a utility to get a view provider. ```typescript export namespace ModuleRegistryProvider { export function getInstance(): ModuleRegistry; export function getViewProvider(state: object, fallback: View.Provider): View.Provider; } ``` -------------------------------- ### Example of a custom model loading saga Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0403_model_loading.adoc This snippet illustrates a custom model loading saga. It demonstrates how to handle model loading independently of the default Client loading mechanism. ```tsx import { call, put, takeEvery } from "redux-saga/effects"; import { ModelActions } from "@mgm/a12-client"; // Assume CustomModelService is a service that handles custom model loading import { CustomModelService } from "./custom-model-service"; function* handleCustomModelLoading(action: ReturnType) { try { const models = yield call(CustomModelService.loadModels, action.payload.modelIds); yield put(ModelActions.setModels(models)); } catch (error) { yield put(ModelActions.modelLoadingFailed(error)); } } export function* customModelLoadingSaga() { yield takeEvery(ModelActions.loadCustomModel.type, handleCustomModelLoading); } ``` -------------------------------- ### Client Extensions Example Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0401_appsetup.adoc This snippet illustrates how to register client extensions with the A12 Client API. These extensions can provide additional features or modify component behavior. ```tsx import React from 'react'; import { A12AppSetup, A12Component, A12ClientExtension } from '@mgm/a12-client'; // Define a custom client extension const myClientExtension: A12ClientExtension = { name: 'MyClientExtension', setup: ({ registerFeature }) => { registerFeature('customFeature', () => { console.log('Custom feature activated!'); return { data: 'feature data' }; }); } }; // Define a component that uses the client extension interface AnotherComponentProps { featureData?: any; } const AnotherComponent: A12Component = { name: 'AnotherComponent', setup: ({ useFeature }) => { const customFeatureData = useFeature('customFeature'); return { featureData: customFeatureData }; }, render: ({ featureData }) => (

Another Component

Feature Data: {JSON.stringify(featureData)}

) }; // App setup including the client extension and component const appSetupWithExtensions: A12AppSetup = { components: [ AnotherComponent ], clientExtensions: [ myClientExtension ] }; export default appSetupWithExtensions; ``` -------------------------------- ### Custom Root Reducer Example Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0402_root_reducer.adoc Define a custom root reducer to handle specific actions and fall back to the default reducer for others. This is useful for updating top-level Client state slices. ```typescript import { Action, DefaultRootReducer, RootReducer } from "@a12/core"; const customRootReducer: RootReducer = (state, action) => { switch (action.type) { case "CUSTOM_ACTION": // Handle custom action return { ...state, customData: action.payload }; default: // Delegate to the default root reducer for other actions return DefaultRootReducer(state, action); } }; export default customRootReducer; ``` -------------------------------- ### Test Action Creator Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0801_write-tests.adoc Tests an action creator to verify it returns the correct action object. This example focuses on a specific content tag within a larger file. ```tsx import { describe, it, expect } from "@jest/globals"; import { createMultipleDataHolders } from "./actions"; describe("createMultipleDataHolders", () => { it("should return the correct action", () => { const data = { id: 1, name: "Test Data", }; const expectedAction = { type: "CREATE_MULTIPLE_DATA_HOLDERS", payload: { data: [ { id: 1, name: "Test Data", } ], }, }; expect(createMultipleDataHolders([data])).toEqual(expectedAction); }); }); ``` -------------------------------- ### Custom Progress Indicator with UI Settings Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1103_2025.06.adoc Example of customizing the Progress Indicator component by setting UI settings as properties. This involves creating a custom component and potentially a custom widget for the indicator. ```tsx import type { JSX } from "react"; import { ViewViews } from "@com.mgmtp.a12.client/client-core/lib/core/view"; import type { ProgressIndicatorProps } from "@com.mgmtp.a12.widgets/widgets-core/lib/progress-indicator/main/progress-indicator.api"; import { ProgressIndicator } from "@com.mgmtp.a12.widgets/widgets-core/lib/progress-indicator/main/progress-indicator.view"; // somewhere in your render tree function CustomProgressIndicator(): JSX.Element { return ( ); } // customizing the actual indicator widget function CustomWidget(props: ProgressIndicatorProps): JSX.Element { const customFastAppear = true; const customDelay = 100; return ; } ``` -------------------------------- ### Migrating canHandleAsync to canHandle (No Saga Effects) Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1102_2025.06-ext2.adoc Example of refactoring logic from canHandleAsync to canHandle when no saga effects are used. This demonstrates accessing activity data directly from the config. ```typescript *canHandleAsync(config: DataProvider.CanHandleConfig): SagaGenerator { const instance = yield* select( ActivitySelectors.activityPropById( config.activityId, activity => activity.descriptor.instance ) ); return instance !== undefined; } ``` ```typescript canHandle(config: DataProvider.CanHandleConfig): boolean { const { activityId, activities } = config; const activity = activities[activityId]; return activity?.descriptor.instance !== undefined; } ``` -------------------------------- ### Activity with Multiple DataHolders Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0303_activity.adoc An example of an activity object initialized with three DataHolders, each managing different types of data (document, candidate, link). ```tsx const activity = { id: "223", descriptor: { model: "Product", instance: "DomainProduct/15" }, dataHolders: [ { descriptor: { model: "Product", instance: "DomainProduct/15"}, data: {}, dirty: "false", loadingState: "missing", savingState: "not_saved" }, { descriptor: { type: "candidate", instance: "1" }, data: { /*...*/ }, dirty: "false", loadingState: "loaded", savingState: "not_saved" }, { descriptor: { type: "link", instance: "1" }, data: { /*...*/ }, dirty: "false", loadingState: "loaded", savingState: "not_saved" } ] }; ``` -------------------------------- ### Real-world Selector Example with Empty Array Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0903_performance.adoc This selector might return a new empty array on each call if the condition is not met, leading to performance issues. Consider memoization or returning stable empty arrays. ```ts import { createSelector } from "@reduxjs/toolkit"; interface State { items: string[]; } // Selector that might return a new empty array export const itemsSelector = createSelector( (state: State) => state.items, (items) => items.length > 0 ? items : [] // Returns a new empty array if items is empty ); ``` -------------------------------- ### Register Deep Linking Sagas Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0410_deep-linking.adoc Register the deep linking extension by passing its sagas to the application setup. This activates the encoding of the last started activity into the URL. ```typescript import { DeepLinkingFactories } from "@a12/deep-linking"; import { ApplicationFactories } from "@a12/application"; const sagas = DeepLinkingFactories.createSagas({ // Configuration object }); const setup = ApplicationFactories.createApplicationSetup({ customSagas: sagas }); ``` -------------------------------- ### Adding New DataHolders with a Reducer Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0307_data_reducers.adoc This example demonstrates how to add new DataHolders based on an action payload. It can be a performance gain over multiple dispatched actions for adding multiple data holders. ```tsx function addDataHolders(action: Action, dataHolders: Activity.DataHolder[]) { // based on the action payload, create new DHs here const newDataHolders = [] // add them to the existing ones return [ ...dataHolders, ...newDataHolders ] } const customTriggerReducer: ActivityReducers.DataReducer = { reduce(dataHolders, action) { return customTriggerAction.match(action) ? addDataHolders(action, dataHolders) : dataHolders; } } ``` -------------------------------- ### Document Runtime Service Factory Singleton Get Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Gets the singleton instance of DocumentRuntimeServiceFactory. ```typescript export function get(): DocumentRuntimeServiceFactory; ``` -------------------------------- ### Create HTTP Model Loader Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0403_model_loading.adoc Use the createHttpModelLoader factory function to get a model loader for HTTP Model Loading. Configure the base path and model processors when calling the function. Defaults to the root path if no base path is provided. ```tsx const modelLoader = createHttpModelLoader({ basePath: "/models/", modelProcessors: [] }); ``` -------------------------------- ### Run A12 Client Application Model Migration Tool Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1100_migration.adoc Execute the migration tool to process application model files. Specify the path to your files. The -b flag creates backups if models are not under version control. Use -h for help. ```bash client-application-model-migration -b ``` -------------------------------- ### ValidationConfig.get Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Gets the current ValidationConfig instance. ```APIDOC ## ValidationConfig.get ### Description Gets the current ValidationConfig instance. ### Method N/A (Function Signature) ### Returns - ValidationConfig - The current validation configuration. ``` -------------------------------- ### Get Document Service Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Retrieves the DocumentService. ```typescript getDocumentService: () => DocumentService; ``` -------------------------------- ### ValidatorProviderFactory.get Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Gets the current validator provider factory instance. ```APIDOC ## ValidatorProviderFactory.get ### Description Gets the current validator provider factory instance. ### Method (Not specified, likely a static method call) ### Parameters (None) ### Response #### Success Response - **ValidatorProviderFactory** - The current factory instance. ### Request Example (Not applicable for static method) ### Response Example (Not applicable for static method) ``` -------------------------------- ### Configure Dashboard Layout and Add Views Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0305_application_model.adoc Sets up a dashboard layout with specific rows and columns, then adds various views to the region. The 'CONTENT' region is the default if not specified. ```json { "sceneChange": { "onEnter": [ { "type": "REGION_CLEAR", "layout": { "name": "Dashboard", "settings": { "rows": [ { "columns": [ { "width": { "sm": 3, "md": 4, "lg": 9 } }, { "width": { "sm": 1, "md": 2, "lg": 3 }, "rows": [ { "columns": [ { "width": { "sm": 4, "md": 6, "lg": 12 } } ] }, { "columns": [ { "width": { "sm": 4, "md": 6, "lg": 12 } } ] } ] } ] }, { "columns": [ { "width": { "sm": 4, "md": 2, "lg": 4 } }, { "width": { "sm": 4, "md": 4, "lg": 8 } } ] } ] } } }, { "type": "VIEW_ADD", "name": "DashboardIntroTile" }, { "type": "VIEW_ADD", "name": "DashboardCalendarTile" }, { "type": "VIEW_ADD", "name": "DashboardNotesTile" }, { "type": "VIEW_ADD", "name": "DashboardTasksTile" }, { "type": "VIEW_ADD", "name": "OverviewCRUD", "models": [ { "modelType": "overview", "name": "CRUD-overview" } ] } ] } } ``` -------------------------------- ### Get Document Model Search Service Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Retrieves the DocumentModelSearchService for a given DocumentModel. ```typescript getDocumentModelSearchService: (dm: DocumentModel) => DocumentModelSearchService; ``` -------------------------------- ### getDocumentPathForRepeatableGroup Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Gets the document path for a repeatable group within a specific data context. ```APIDOC ## getDocumentPathForRepeatableGroup ### Description Determines the document path for an entry within a repeatable group, given the model path of the group and the data context. ### Parameters #### Request Body - **modelPath** (ModelPath) - Required - The model path of the repeatable group. - **dataContext** (EntityInstancePath) - Required - The data context for the instance. ``` -------------------------------- ### Customize MasterDetail Widget with widgetMap (Deprecated) Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1102_2025.06-ext2.adoc This example shows the deprecated method of customizing the MasterDetail widget using the widgetMap property. ```typescript const customWidgetMap: FrameViews.MasterDetailLayoutProps["widgetMap"] = { masterDetail: CustomMasterDetail }; export function CustomResizableMasterDetailLayout( props: FrameViews.MasterDetailLayoutProps ) { return ; } ``` -------------------------------- ### Build the Devapp Source: https://github.com/mgm-tp/a12-client/blob/main/devapp/README.md Builds the A12 Client Devapp. The output is placed in the dist folder and can be served as a static page. ```shell npm run build ``` -------------------------------- ### Module Registration Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0407_modularization.adoc Demonstrates how to register a module with the ModuleRegistry, either before or after bootstrapping the Client Application. Avoid removing modules at runtime if possible, as it can lead to errors if active views are present. ```typescript import { ApplicationSetup } from "./applicationSetup"; import { myModule } from "./myModule"; // Register module before bootstrapping ApplicationSetup.getModuleRegistry().registerModule(myModule); // Or register after bootstrapping // ApplicationSetup.getModuleRegistry().registerModule(myModule); ``` -------------------------------- ### ActivityActions.create Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Creates a new activity with the provided descriptor and optional initial data. ```APIDOC ## ActivityActions.create ### Description Creates a new activity based on a descriptor. This action can optionally take an initial activity ID, data, initiating activity ID, loading state, and slices. ### Method ActionCreator ### Parameters #### Request Body - **input** (CreatePayload) - Required - The payload for creating an activity. - **activityDescriptor** (Activity.Descriptor) - Required - Describes the activity to be created. - **activityId** (string) - Optional - The ID for the new activity. - **data** (object) - Optional - Initial data for the activity. - **initiatingActivityId** (string) - Optional - The ID of the activity that initiated this creation. - **loadingState** (Activity.LoadingState) - Optional - The initial loading state of the activity. - **slices** (Activity.DataHolder["slices"]) - Optional - Initial slices for the activity's data holders. ### Response Returns an Action of type PushPayload. ``` -------------------------------- ### ApplicationSelectors.busy Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Returns a selector that can be used to get the current busy status of the application. This is useful for displaying loading indicators or disabling UI elements. ```APIDOC ## ApplicationSelectors.busy ### Description Returns a selector that can be used to get the current busy status of the application. This is useful for displaying loading indicators or disabling UI elements. ### Method Selector ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters None ### Request Example ```typescript // Example usage in a React component using reselect or similar const selectBusyStatus = createSelector(ApplicationSelectors.busy(), (isBusy) => isBusy); // In your component: const busy = selectBusyStatus(state); ``` ### Response #### Success Response Selector #### Response Example Returns a selector function that, when called with the application state, returns a boolean indicating if the application is busy. ``` -------------------------------- ### Usage of ModelProcessor API Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0403_model_loading.adoc This snippet demonstrates how to use the ModelProcessor API for post-processing loaded models. It shows an example of a custom ModelProcessor implementation. ```tsx import { ModelProcessor } from "@mgm/a12-client"; export const uiModelProcessor: ModelProcessor = { process: (model) => { // Custom processing logic for UiModel console.log("Processing UI model:", model); return model; }, }; ``` -------------------------------- ### Custom Logging Strategy Implementation Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/1103_2025.06.adoc Shows how to set a custom logging strategy using the utils-logging library. Includes a method to reset to the default strategy. ```tsx import { Settings } from "@com.mgmtp.a12.utils/utils-logging/lib/Settings"; Settings.LogStrategy = new MyCustomStrategy(); // to restore the default Settings.resetLogStrategy(); ``` -------------------------------- ### ApplicationSaga.watchDispatchSaga Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Starts watching for dispatched actions to be handled by registered sagas. It takes an array of saga descriptors, each defining how to handle specific actions. ```APIDOC ## ApplicationSaga.watchDispatchSaga ### Description Starts watching for dispatched actions to be handled by registered sagas. It takes an array of saga descriptors, each defining how to handle specific actions. ### Method SagaIterator ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **sagas** (ApplicationSaga.Descriptor[]) - An array of saga descriptors to register for action handling. ### Request Example ```typescript // Example usage within a saga watchDispatchSaga([ { canHandle: (ad, action) => action.type === 'MY_ACTION', handle: function* (action) { // ... saga logic ... } } ]); ``` ### Response #### Success Response SagaIterator #### Response Example None explicitly defined, returns a SagaIterator. ``` -------------------------------- ### Context and Constants Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Exposes context for layout providers and constants for locale resource keys. ```APIDOC ## Context and Constants ### `LayoutProvidersContext` Context for `ProvidersProps` used by layout providers. ### `LOCALE_RESOURCE_KEYS` Constants for locale resource keys, including application title, dashboard title, and error messages. ### `LOCALE_SELECT_RESOURCE_KEYS` Constants for locale selection resource keys, such as label and locale. ``` -------------------------------- ### Run Project Tests Source: https://github.com/mgm-tp/a12-client/blob/main/README.md Executes the project's test suite. This command is used for verifying the functionality of the codebase. ```sh pnpm test ``` -------------------------------- ### Lens Type Definition Source: https://github.com/mgm-tp/a12-client/blob/main/core/client-core.api.md Defines a Lens, a functional programming concept for accessing and updating parts of a data structure. It provides `get` and `set` operations. ```typescript // @public export type Lens = { get(s: S): A; set(a: A): (s: S) => S; }; ``` -------------------------------- ### Compile Project Source: https://github.com/mgm-tp/a12-client/blob/main/README.md Compiles the project. This command can be executed in the repository root or individual sub-project folders. ```sh pnpm compile ``` -------------------------------- ### Specific Selector for Optimized Re-renders Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0903_performance.adoc This example demonstrates a component subscribing only to the 'lock' property of the activity state. This prevents re-renders when other properties of the activity change. ```tsx import React from "react"; import { useSelector } from "react-redux"; interface Activity { id: string; name: string; lock: boolean; } interface State { activity: Activity; } const ViewComponent: React.FC = () => { // Selecting only the 'lock' property const lock = useSelector((state: State) => state.activity.lock); return (
{lock ? "Locked" : "Unlocked"}
); }; export default ViewComponent; ``` -------------------------------- ### initializeDataComponent Source: https://github.com/mgm-tp/a12-client/blob/main/data/client-data.api.md Initializes the data component with provided documents and links. ```APIDOC ## initializeDataComponent ### Description Initializes the data component, setting up its initial state with provided documents, optional links, and an entry point. ### Parameters #### Request Body - **docs** (DgDocument[]) - Required - An array of documents to initialize with. - **links** (DgLinkInternal[]) - Optional - An array of internal links to associate. - **entryPoint** (string) - Optional - The entry point for the data component. ``` -------------------------------- ### Unsafe DataReducer Implementation (Do Not Use) Source: https://github.com/mgm-tp/a12-client/blob/main/documentation/src/0307_data_reducers.adoc An example of an unsafe DataReducer that unconditionally modifies the state regardless of the action. This pattern should be avoided to prevent unwanted state changes. ```tsx // this reducer always changes the state, regardless of the action! DO NOT COPY THIS! const doNotUseThisReducer: ActivityReducers.DataReducer = { reduce(dataHolders, action) { return dataHolders?.map(dh => TodoActions.addTodo.match(action) ? handleAddTodo(action)(dh) : dh); } } ```