Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions shesha-reactjs/src/designer-components/wizard/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { componentsTreeToFlatStructure, executeScriptSync, useAvailableConstantsData } from '@/providers/form/utils';
import { getStepDescritpion, getWizardStep } from './utils';
import { IConfigurableActionConfiguration } from '@/interfaces/configurableAction';
import { IConfigurableFormComponent, isConfigurableFormComponent, useForm, useSheshaApplication } from '@/providers';
import { IConfigurableFormComponent, isConfigurableFormComponent, useForm, useSheshaApplication, ShaForm } from '@/providers';
import { IWizardComponentProps, IWizardStepProps } from './models';
import { useConfigurableAction } from '@/providers/configurableActionsDispatcher';
import { useEffect, useMemo, useState } from 'react';
Expand Down Expand Up @@ -66,6 +66,8 @@ export const useWizard = (model: Omit<IWizardComponentProps, 'size'>): IWizardCo
return getDefaultStepIndex(defaultActiveStep);
});

const { componentRelations, allComponents } = ShaForm.useMarkup();

const visibleSteps = useDeepCompareMemo(
() =>
tabs
Expand All @@ -74,8 +76,29 @@ export const useWizard = (model: Omit<IWizardComponentProps, 'size'>): IWizardCo
const isVisibleByCondition = executeBooleanExpression(customVisibility, true);

return !((!granted || !isVisibleByCondition) && formMode !== 'designer');
})
.map((step) => {
// Get footer id - use existing or generate fallback
const footerId = step.stepFooter?.id ?? (step.hasCustomFooter ? `${step.id}_footer` : undefined);

if (step.hasCustomFooter && footerId) {
const footerComponentIds = componentRelations[footerId] || [];
const footerComponents = footerComponentIds
.map((id) => allComponents[id])
.filter(isConfigurableFormComponent);

return {
...step,
stepFooter: {
...step.stepFooter,
id: footerId,
components: footerComponents,
},
};
}
return step;
}),
[tabs, formMode],
[tabs, formMode, componentRelations, allComponents],
);

const currentStep = visibleSteps[current];
Expand Down
35 changes: 32 additions & 3 deletions shesha-reactjs/src/designer-components/wizard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@ const TabsComponent: IToolboxComponent<Omit<IWizardComponentProps, 'size'>> = {
...step,
showBackButton: step?.showBackButton ?? true,
showDoneButton: step?.showDoneButton ?? true,
hasCustomFooter: step?.hasCustomFooter ?? false,
stepFooter: step?.stepFooter ?? {
id: `${step.id}_footer`,
components: [],
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
})) ?? [],
}),
customContainerNames: ['steps'],
migrator: (m) =>
m
.add<IWizardComponentPropsV0>(0, (prev) => {
Expand Down Expand Up @@ -93,13 +99,36 @@ const TabsComponent: IToolboxComponent<Omit<IWizardComponentProps, 'size'>> = {
.add<IWizardComponentProps>(5, (prev) => ({ ...migrateFormApi.properties(prev) }))
.add<IWizardComponentProps>(6, (prev) => removeComponents(prev))
.add<IWizardComponentProps>(7, (prev) => ({ ...migratePrevStyles({ ...prev, primaryTextColor: '#fff' }, defaultStyles()), overflow: true }))
.add<IWizardComponentProps>(8, (prev) => ({ ...prev, stepWidth: '200px' })),
.add<IWizardComponentProps>(8, (prev) => ({ ...prev, stepWidth: '200px' }))
.add<IWizardComponentProps>(9, (prev) => ({
...prev,
steps: prev.steps?.map((step) => ({
...step,
hasCustomFooter: step.hasCustomFooter ?? false,
stepFooter: step?.stepFooter ?? {
id: `${step.id}_footer`,
components: [],
},
})) ?? [],
})),
settingsFormMarkup: getSettings,
validateSettings: (model) => validateConfigurableComponentSettings(getSettings, model),

customContainerNames: ['steps'],
getContainers: (model) => {
return model.steps.map<IFormComponentContainer>((t) => ({ id: t.id }));
const containers: IFormComponentContainer[] = [];
model.steps.forEach((step) => {
containers.push({ id: step.id, parentId: model.id });
});

// Add step footer containers
const footerContainers = model.steps
.filter((s) => s.hasCustomFooter)
.map((s) => ({
id: s.stepFooter?.id ?? `${s.id}_footer`,
parentId: model.id,
}));

return [...containers, ...footerContainers];
},
};

Expand Down
15 changes: 15 additions & 0 deletions shesha-reactjs/src/designer-components/wizard/itemSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,25 @@ export const getItemSettings = (fbf: FormBuilderFactory): IConfigurableFormCompo
validate: {},
jsSetting: true,
})
.addSettingsInput({
inputType: 'switch',
id: nanoid(),
propertyName: 'hasCustomFooter',
label: 'Custom Footer',
labelAlign: 'right',
parentId: commonTabId,
hidden: false,
validate: {},
jsSetting: true,
})
.addCollapsiblePanel({
id: nanoid(),
propertyName: 'nextButtonCollapsiblePanel',
label: 'Next Button',
labelAlign: 'right',
parentId: commonTabId,
ghost: true,
hidden: { _code: 'return getSettingValue(data?.hasCustomFooter) === true;', _mode: 'code', _value: false },
collapsible: 'header',
content: {
id: nextButtonContentId,
Expand Down Expand Up @@ -222,6 +234,7 @@ export const getItemSettings = (fbf: FormBuilderFactory): IConfigurableFormCompo
labelAlign: 'right',
parentId: commonTabId,
ghost: true,
hidden: { _code: 'return getSettingValue(data?.hasCustomFooter) === true;', _mode: 'code', _value: false },
collapsible: 'header',
content: {
id: backButtonContentId,
Expand Down Expand Up @@ -289,6 +302,7 @@ export const getItemSettings = (fbf: FormBuilderFactory): IConfigurableFormCompo
labelAlign: 'right',
parentId: commonTabId,
ghost: true,
hidden: { _code: 'return getSettingValue(data?.hasCustomFooter) === true;', _mode: 'code', _value: false },
collapsible: 'header',
content: {
id: doneButtonContentId,
Expand Down Expand Up @@ -358,6 +372,7 @@ export const getItemSettings = (fbf: FormBuilderFactory): IConfigurableFormCompo
labelAlign: 'right',
parentId: commonTabId,
ghost: true,
hidden: { _code: 'return getSettingValue(data?.hasCustomFooter) === true;', _mode: 'code', _value: false },
collapsible: 'header',
content: {
id: cancelButtonContentId,
Expand Down
17 changes: 12 additions & 5 deletions shesha-reactjs/src/designer-components/wizard/models.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { IConfigurableFormComponent, IStyleType } from '@/interfaces';
import { IConfigurableActionConfiguration } from '@/interfaces/configurableAction';
import { FormInstance, StepProps } from 'antd';
import { FormInstance, StepsProps } from 'antd';

export interface IStepFooterContainer {
id: string;
components?: IConfigurableFormComponent[];
}

export interface IWizardStepProps extends IStyleType {
id: string;
Expand All @@ -10,7 +15,7 @@ export interface IWizardStepProps extends IStyleType {
subTitle: string;
description: string;
allowCancel?: boolean;
status?: StepProps['status'];
status?: StepsProps['status'];

label?: string;
name?: string;
Expand All @@ -28,6 +33,7 @@ export interface IWizardStepProps extends IStyleType {

showBackButton?: boolean;
showDoneButton?: boolean;
hasCustomFooter?: boolean;

cancelButtonActionConfiguration?: IConfigurableActionConfiguration;
nextButtonActionConfiguration?: IConfigurableActionConfiguration;
Expand All @@ -39,6 +45,7 @@ export interface IWizardStepProps extends IStyleType {
permissions?: string[];
components?: IConfigurableFormComponent[];
childItems?: IWizardStepProps[];
stepFooter?: IStepFooterContainer;

onBeforeRenderActionConfiguration?: IConfigurableActionConfiguration;

Expand All @@ -61,11 +68,11 @@ export interface IWizardSequence {
pending?: string;
}

export interface IStepProps extends StepProps {
content?: JSX.Element;
export interface IStepProps extends StepsProps {
bodyContent?: JSX.Element;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

export interface IWizardComponentProps extends Omit<IConfigurableFormComponent, 'size'>, Pick<StepProps, 'status'>, Omit<IStyleType, 'size'> {
export interface IWizardComponentProps extends Omit<IConfigurableFormComponent, 'size'>, Pick<StepsProps, 'status'>, Omit<IStyleType, 'size'> {
steps: IWizardStepProps[];
wizardType?: 'default' | 'navigation';
form?: FormInstance<any>;
Expand Down
Loading