All files / blong-browser/src/model/component subjectObjectNew.ts

55.76% Statements 29/52
100% Branches 2/2
100% Functions 1/1
55.76% Lines 29/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 531x 4x 4x 4x 4x 4x 4x                                               1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
import type {
    ICardConfig,
    IEnrichedSchema,
    IHandlerProxy,
    IResolvedModelSpec,
} from '@feasibleone/blong';
import type {LayoutConfig} from '../../hooks/useLayout.js';

export async function subjectObjectNew(model: IResolvedModelSpec, blong: IHandlerProxy<unknown>) {
    const {objectTitle, browser, methods, subject, object} = model;

    return async () => ({
        title: `Create ${objectTitle}`,
        permission: browser.permission.add,
        icon: 'pi pi-plus',
        component: async () => {
            const [schemaOverride, {Editor}] = await Promise.all([
                blong.handler.subjectObjectSchema<IEnrichedSchema>({subject, object}, {}),
                import('../../components/Editor/Editor.js'),
            ]);

            const schema = blong.lib.merge({}, model.schema, schemaOverride);
            // Hoisted outside NewPage so the object reference is stable across renders —
            // an inline object literal would create a new identity on every render and
            // trigger the Form's value-sync effect (useEffect([value, reset])) on every
            // dirty-state transition, calling reset({}) and wiping the user's input.
            const defaultValue: Record<string, unknown> = {};
            // Hoisted outside NewPage so the object reference is stable across renders —
            // an inline object literal would create a new identity on every render and
            // trigger the Editor's tab-title effect every time, causing an infinite loop.
            const title = {new: `Create ${objectTitle}`, edit: `Edit ${objectTitle}`};
            function NewPage(props: Record<string, unknown>) {
                return Editor({
                    schema,
                    cards: model.cards as Record<string, ICardConfig>,
                    layout: 'edit',
                    layouts: model.layouts as Record<string, LayoutConfig>,
                    loadAction: methods.get,
                    createAction: methods.add,
                    saveAction: methods.edit,
                    value: defaultValue,
                    mode: 'new',
                    editable: false,
                    title,
                    ...props,
                });
            }
 
            return NewPage as unknown as React.ComponentType;
        },
    });
}