Show wizard like form only when adding entries, otherwise a different form

Hey Guys,

We are trying to implement a wizard like form for creating documents. We want the form to only be used for creating new entries. When viewing or editing existing entries, another form should be used.

For that, we have created two form models.
One with multiple screens to act like a wizard form (wizard-form for creating).
And another form model which contains all the details on one screen (details-form for viewing/editing).

In the app-model, we are using one scene for the wizard-form (“ItemFormWizard”). Its match conditions contain, besides the model, the “instance” key which must equal __NEW__.
The scene used for the details-form (“ItemForm”) has similar match conditions, the only difference is “instance” is just set to “isSet: true”.
The scene for the wizard-form is defined before the details-form scene, since its match conditions are more specific.

import { ApplicationModel } from "@com.mgmtp.a12.client/client-core/lib/core/model";

export const itemAppModel: ApplicationModel = {
    header: {
        id: "item-appmodel",
        modelType: "application",
        modelVersion: "5.0.0",
        locales: [
            {
                code: "en"
            }
        ]
    },
    content: {
        modules: [
            {
                name: "ItemModule",
                menu: {
                    name: "Item",
                    label: [
                        {
                            locale: "en",
                            text: "Item"
                        },
                        {
                            locale: "de",
                            text: "Item"
                        }
                    ],
                    initialActivity: {
                        descriptor: {
                            model: "Item-document"
                        }
                    }
                },
                flows: [
                    {
                        name: "ItemFlow",
                        scenes: [
                            {
                                name: "ItemOverview",
                                description: "Overview of Items",
                                matchConditions: [
                                    {
                                        key: "model",
                                        mustEqual: "Item-document"
                                    },
                                    {
                                        key: "instance",
                                        isSet: false
                                    },
                                    {
                                        key: "processDefinitionKey",
                                        isSet: false
                                    }
                                ],
                                sceneChange: {
                                    onEnter: [
                                        {
                                            type: "REGION_CLEAR",
                                            layout: {
                                                name: "MasterDetail"
                                            }
                                        },
                                        {
                                            type: "VIEW_ADD",
                                            name: "ItemOverviewEngine",
                                            models: [
                                                {
                                                    modelType: "overview",
                                                    name: "Item-overview"
                                                }
                                            ]
                                        }
                                    ]
                                }
                            },
                            {
                                name: "ItemFormWizard",
                                description: "Wizard form showing on Item",
                                matchConditions: [
                                    {
                                        key: "model",
                                        mustEqual: "Item-document"
                                    },
                                    {
                                        key: "instance",
                                        mustEqual: "__NEW__"
                                    },
                                    {
                                        key: "processDefinitionKey",
                                        isSet: false
                                    }
                                ],
                                sceneChange: {
                                    onEnter: [
                                        {
                                            type: "VIEW_ADD",
                                            name: "FormCRUD",
                                            constraints: {
                                                type: "MasterDetail"
                                            },
                                            models: [
                                                {
                                                    modelType: "form",
                                                    name: "Item-form-wizard",
                                                    documentModel: "Item-document"
                                                }
                                            ]
                                        }
                                    ]
                                }
                            },
                            {
                                name: "ItemForm",
                                description: "Form showing on Item",
                                matchConditions: [
                                    {
                                        key: "model",
                                        mustEqual: "Item-document"
                                    },
                                    {
                                        key: "instance",
                                        isSet: true
                                    },
                                    {
                                        key: "processDefinitionKey",
                                        isSet: false
                                    }
                                ],
                                sceneChange: {
                                    onEnter: [
                                        {
                                            type: "VIEW_ADD",
                                            name: "FormCRUD",
                                            constraints: {
                                                type: "MasterDetail"
                                            },
                                            models: [
                                                {
                                                    modelType: "form",
                                                    name: "Item-form",
                                                    documentModel: "Item-document"
                                                }
                                            ]
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                ]
            }
        ],
        region: {
            name: "APP",
            layout: {
                name: "ApplicationFrame"
            },
            subRegions: [
                {
                    name: "CONTENT",
                    layout: {
                        name: "MasterDetail"
                    }
                }
            ]
        },
        defaultRegion: ["CONTENT"]
    }
};

The problem is, when you are using the wizard-form after you already had the details-form opened at any point in time, after saving the newly created document at the last screen, the form crashes with following error:

Uncaught Error: Internal Error: Screen "/Screen 3" was not found!
    at Object.getCurrentScreen (utility-functions.js:56:15)
    at FormScreen (content-box-component.js:79:64)
    at renderWithHooks (react-dom.development.js:14985:18)
    at updateFunctionComponent (react-dom.development.js:17356:20)
    at beginWork (react-dom.development.js:19063:16)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:16)
    at invokeGuardedCallback (react-dom.development.js:4056:31)
    at beginWork$1 (react-dom.development.js:23959:7)
    at performUnitOfWork (react-dom.development.js:22771:12)

If you never open the details-form and create documents with the wizard-form it stays open with the created document. The activity descriptor matching the details-form is now active, but the wizard-form is still shown.

It seems that the activity descriptor of the form scene becomes out of sync with the actual state of what is being shown.
I’m trying to show in this gif, that after the SAVE_DONE action the activity descriptor changes from instance: __NEW__ to instance: Item-document/{id}, but the wizard-form is still open and not the details-form.

Also in the second run seen in the gif when the error happens, the same out of sync problem of the activity descriptor happens. With the only difference beeing the models which are loaded. There is one more model loaded, it is the details-form model.

Maybe is that the cause of the problem, so that in the first run, after saving the document, the wizard-form is still shown although the activity descriptor matches the details-form, but the details-form was not loaded and because of that he still shows the wizard-form?

And in the second run the details-form is loaded, because it was opened earlier and after saving the document, the activity descriptor changes, what leds to him trying to render the details-form, but he cannot find “/Screen 3”, because the screen is not in the model?

_Imgur: The magic of the Internet

Page reload resets the state in which the error occurs.

Has someone here experienced this problem or a similar before and can help us and is there any truth to our assumtions?

Hi @raffael-broad-linden,

I was able to reproduce your issue with the project template in version 202306.4.1 by slightly adapting the given models and app model (changed files: person-appmodel.json (4.8 KB) and Person-form-wizard.json (13.3 KB)).

So root cause for your problem seems to be that the loading of the form model and reset of screen location is not taken into account by the redux action flow which is triggered by CRUD::SAVE event. We will forward that information to the corresponding A12 Team for evaluating steps resulting from that findings.

For the moment you can simply workaround by adding a custom middleware that will prevent the activity data from reloading and instead will reload a completely new activity from the save result:

import {StoreFactories} from "@com.mgmtp.a12.client/client-core/lib/core/store";
import {ActivityActions, ActivitySelectors} from "@com.mgmtp.a12.client/client-core/lib/core/activity";
import {NEW_INSTANCE_IDENTIFIER} from "@com.mgmtp.a12.client/client-core/lib/core/application";

export const saveDoneInstanceBasedReload = StoreFactories.createMiddleware((api, next, action) => {
    if(ActivityActions.save.done.match(action)) {
        const activityId = action.payload.params.activityId;
        const activity = ActivitySelectors.activityById(activityId)(api.getState());
        if (activity?.descriptor.instance === NEW_INSTANCE_IDENTIFIER) {
            const newActivity = ActivityActions.create({activityDescriptor: {...activity?.descriptor, instance: action.payload.result.instance}, initiatingActivityId: activity?.initiatingActivityId});
            api.dispatch(ActivityActions.cancel({activityId, replacementActivity: newActivity.payload.activity}))
        }
    }
    return next(action)
});
// add to the appsetup

ApplicationFactories.createApplicationSetup(
  additionalMiddlewares: [
    //..
    saveDoneInstanceBasedReload,
    //..
  ],
  //...

Another solution, if the Detail View of the Master/Detail layout must not stay open, is to use “event_submit” instead of “CRUD::SAVE”.

Dear @raffael-broad-linden ,

was the response helpful and is the issue now solved or are there some additional questions? If it is solved, please, use the checkbox to mark the solution to your problem so that other users also know what helped to your case.

Denise from the Discourse team