import { List } from "immutable"; import { BasicFun, DispatchParsedType, DispatchSpecificationDeserializationResult, DispatchFormsParserState, PredicateValue, simpleUpdater, Sum, Unit, ValueOrErrors, Template, unit, DispatchOnChange, DispatchInjectablesTypes, DispatchInfiniteStreamSources, DispatchEnumOptionsSources, DispatchEntityApis, DispatchTableApiSources, DispatchLookupSources, FormRefEditApiHandlers, FormRefCreateApiHandlers, Guid, BasicUpdater, Updater, Renderer, DispatcherContext, CommonAbstractRendererReadonlyContext, CommonAbstractRendererState, CommonAbstractRendererForeignMutationsExpected, PreprocessedSpecContext, } from "../../../../../main"; import { DispatchCreateFormLauncherState } from "./domains/kind/create/state"; import { DispatchEditFormLauncherApi, DispatchEditFormLauncherState, } from "./domains/kind/edit/state"; import { DispatchPassthroughFormLauncherState } from "./domains/kind/passthrough/state"; export type DispatcherContextWithApiSources< T extends DispatchInjectablesTypes, Flags, CustomPresentationContext, ExtraContext, > = Omit< DispatcherContext, "defaultState" > & BaseApiSources & { defaultState: ( t: DispatchParsedType, renderer: Renderer, ) => ValueOrErrors; }; export type BaseLauncherRef = { name: string; apiSources: T; }; export type LauncherRefWithEntityApis = T & { entityApis: DispatchEntityApis; }; export type BaseApiSources = { infiniteStreamSources: DispatchInfiniteStreamSources; enumOptionsSources: DispatchEnumOptionsSources; tableApiSources?: DispatchTableApiSources; lookupSources?: DispatchLookupSources; }; export type EntityLauncherRefConfig = | { source: "entity"; value: Sum, "not initialized">; } | { source: "api"; getGlobalConfig?: () => Promise; }; export type PassthroughLauncherRef = { kind: "passthrough"; entity: Sum, "not initialized">; config: Sum, "not initialized">; onEntityChange: DispatchOnChange; } & BaseLauncherRef; export type EditLauncherRef = { kind: "edit"; entityId: Guid; apiHandlers?: FormRefEditApiHandlers; config: EntityLauncherRefConfig; } & BaseLauncherRef>; export type CreateLauncherRef = { kind: "create"; apiHandlers?: FormRefCreateApiHandlers; config: EntityLauncherRefConfig; } & BaseLauncherRef>; export type LauncherRef = | PassthroughLauncherRef | EditLauncherRef | CreateLauncherRef; export type DispatchFormRunnerStatus< T extends DispatchInjectablesTypes, Flags, CustomPresentationContext, ExtraContext, > = | { kind: "not initialized" } | { kind: "loading" } | { kind: "loaded"; Form: Template< CommonAbstractRendererReadonlyContext< DispatchParsedType, PredicateValue, CustomPresentationContext, ExtraContext > & CommonAbstractRendererState, CommonAbstractRendererState, CommonAbstractRendererForeignMutationsExpected >; } | { kind: "error"; errors: List }; export type DispatchFormRunnerContext< T extends DispatchInjectablesTypes, Flags, CustomPresentationContext = Unit, ExtraContext = Unit, > = { extraContext: ExtraContext; globallyDisabled: boolean; globallyReadOnly: boolean; launcherRef: LauncherRef; showFormParsingErrors: BasicFun< DispatchSpecificationDeserializationResult< T, Flags, CustomPresentationContext, ExtraContext >, JSX.Element >; remoteEntityVersionIdentifier: string; loadingComponent?: JSX.Element; errorComponent?: JSX.Element; preprocessedSpecContext?: PreprocessedSpecContext; usePreprocessor: boolean; } & DispatchFormsParserState; export type DispatchFormRunnerState< T extends DispatchInjectablesTypes, Flags, CustomPresentationContext, ExtraContext, > = { innerFormState: | { kind: "create"; state: DispatchCreateFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext >; } | { kind: "edit"; state: DispatchEditFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext >; } | { kind: "passthrough"; state: DispatchPassthroughFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext >; }; }; export const DispatchFormRunnerState = < T extends DispatchInjectablesTypes, Flags, CustomPresentationContext, ExtraContext, >() => ({ Default: { create: (): DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > => ({ innerFormState: { kind: "create", state: DispatchCreateFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext >().Default(), }, }), edit: (): DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > => ({ innerFormState: { kind: "edit", state: DispatchEditFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext >().Default(), }, }), passthrough: (): DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > => ({ innerFormState: { kind: "passthrough", state: DispatchPassthroughFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext >().Default(), }, }), }, Updaters: { Core: { ...simpleUpdater< DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > >()("innerFormState"), }, Template: { create: ( upd: BasicUpdater< DispatchCreateFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext > >, ): Updater< DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > > => DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext >().Updaters.Core.innerFormState((v) => v.kind === "create" ? { ...v, state: upd(v.state) } : v, ), edit: ( upd: BasicUpdater< DispatchEditFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext > >, ): Updater< DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > > => DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext >().Updaters.Core.innerFormState((v) => v.kind === "edit" ? { ...v, state: upd(v.state) } : v, ), passthrough: ( upd: BasicUpdater< DispatchPassthroughFormLauncherState< T, Flags, CustomPresentationContext, ExtraContext > >, ): Updater< DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > > => DispatchFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext >().Updaters.Core.innerFormState((v) => v.kind === "passthrough" ? { ...v, state: upd(v.state) } : v, ), }, }, }); export type DispatchFormRunnerForeignMutationsExpected = Unit; export type DispatchCommonFormRunnerState< T extends DispatchInjectablesTypes, Flags, CustomPresentationContext, ExtraContext, > = { status: DispatchFormRunnerStatus< T, Flags, CustomPresentationContext, ExtraContext >; formState: CommonAbstractRendererState; formName: string; }; export const DispatchCommonFormRunnerState = < T extends DispatchInjectablesTypes, Flags, CustomPresentationContext, ExtraContext, >() => { return { Default: (): DispatchCommonFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > => ({ status: { kind: "not initialized" }, formState: CommonAbstractRendererState.Default(), formName: "", }), Updaters: { ...simpleUpdater< DispatchCommonFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > >()("status"), ...simpleUpdater< DispatchCommonFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > >()("formState"), ...simpleUpdater< DispatchCommonFormRunnerState< T, Flags, CustomPresentationContext, ExtraContext > >()("formName"), }, }; };