Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ const ComponentPropertiesPanelInner: FC = () => {
};

export const ComponentPropertiesPanel = React.memo(ComponentPropertiesPanelInner);

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export interface ITabPaneProps
export interface IPropertiesTabsComponentProps extends IConfigurableFormComponent {
tabs: ITabPaneProps[];
size?: SizeType;
defaultActiveKey?: string;
tabType?: 'line' | 'card';
hidden?: boolean;
customVisibility?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { filterDynamicComponents } from './utils';
import { IPropertiesTabsComponentProps } from './models';
import { useFormStateOrUndefined, useFormActionsOrUndefined } from '@/providers/form';
import { useShaFormDataUpdate } from '@/providers/form/providers/shaFormProvider';
import { useFormDesignerActiveSettingsTabKey, useFormDesigner } from '@/providers/formDesigner';

interface SearchableTabsProps {
model: IPropertiesTabsComponentProps;
Expand All @@ -16,12 +17,16 @@ interface SearchableTabsProps {
const SearchableTabs: React.FC<SearchableTabsProps> = ({ model }) => {
const { tabs } = model;
const [searchQuery, setSearchQuery] = useState('');
const [activeTabKey, setActiveTabKey] = useState('1');
const searchRefs = useRef(new Map());
const { styles } = useStyles();

const formState = useFormStateOrUndefined();
const formActions = useFormActionsOrUndefined();
const formDesigner = useFormDesigner();
const persistedActiveTabKey = useFormDesignerActiveSettingsTabKey();

// Use persisted tab key if available, otherwise default to first tab
const activeTabKey = persistedActiveTabKey ?? '1';
Comment thread
czwe-01 marked this conversation as resolved.

useShaFormDataUpdate();

Expand Down Expand Up @@ -69,9 +74,9 @@ const SearchableTabs: React.FC<SearchableTabsProps> = ({ model }) => {
}
}, [activeTabKey]);

const handleTabChange = useCallback((newActiveKey: string): void => {
setActiveTabKey(newActiveKey);
}, [setActiveTabKey]);
const handleTabChange = (newActiveKey: string): void => {
formDesigner.setActiveSettingsTabKey(newActiveKey);
};

// Focus search input when search query changes and we have matching results
useEffect(() => {
Expand Down Expand Up @@ -164,19 +169,17 @@ const SearchableTabs: React.FC<SearchableTabsProps> = ({ model }) => {
Array.isArray(tab.components) ? tab.components.length > 0 : !!tab.components,
);
if (firstVisibleTab && firstVisibleTab.key !== activeTabKey) {
setActiveTabKey(firstVisibleTab.key);
formDesigner.setActiveSettingsTabKey(firstVisibleTab.key);
}
}
}, [searchQuery, newFilteredTabs, activeTabKey]);
}, [searchQuery, newFilteredTabs, activeTabKey, formDesigner]);

// Ensure we have a valid active tab key
useEffect(() => {
if (newFilteredTabs.length > 0 && !newFilteredTabs.find((tab) => tab.key === activeTabKey)) {
setActiveTabKey(newFilteredTabs[0].key);
formDesigner.setActiveSettingsTabKey(newFilteredTabs[0].key);
}
}, [newFilteredTabs, activeTabKey]);

const tabPlacement = model.position === 'left' ? 'start' : model.position === 'right' ? 'end' : model.position;
}, [newFilteredTabs, activeTabKey, formDesigner]);

const localTabs = useMemo(() => (
<Tabs
Expand All @@ -185,11 +188,11 @@ const SearchableTabs: React.FC<SearchableTabsProps> = ({ model }) => {
onChange={handleTabChange}
size={model.size}
type={model.tabType || 'card'}
tabPlacement={tabPlacement || 'top'}
tabPosition={model.position || 'top'}
items={newFilteredTabs}
className={styles.content}
/>
), [activeTabKey, handleTabChange, model.size, model.tabType, newFilteredTabs, styles.content, tabPlacement]);
), [activeTabKey, handleTabChange, model.size, model.tabType, newFilteredTabs, styles.content, model.position]);

return (
<>
Expand Down
2 changes: 2 additions & 0 deletions shesha-reactjs/src/providers/formDesigner/contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export type FormDesignerState = {
isDebug: boolean;
readOnly: boolean;
formMode: FormMode;
activeSettingsTabKey: string | undefined;

settingsPanelRef: MutableRefObject<HTMLDivElement | undefined>;
};
Expand Down Expand Up @@ -118,6 +119,7 @@ export type FormDesignerActions = {

setReadOnly: (value: boolean) => void;
setFormMode: (value: FormMode) => void;
setActiveSettingsTabKey: (key: string) => void;

getCachedComponentEditor: (type: string, evaluator: () => ISettingsFormFactory) => ISettingsFormFactory;

Expand Down
6 changes: 6 additions & 0 deletions shesha-reactjs/src/providers/formDesigner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ const useFormDesignerUndoRedo = (): IUndoable => {
};
};

const useFormDesignerActiveSettingsTabKey = (): string | undefined => {
useFormDesignerSubscription('settings-tab');
return useFormDesigner().activeSettingsTabKey;
};

export {
FormDesignerProvider,
useFormDesignerOrUndefined,
Expand All @@ -147,4 +152,5 @@ export {
useFormDesignerFormMode,
useFormDesignerUndoRedo,
useFormDesignerIsModified,
useFormDesignerActiveSettingsTabKey,
};
9 changes: 9 additions & 0 deletions shesha-reactjs/src/providers/formDesigner/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export class FormDesignerInstance implements IFormDesignerInstance {

formMode: FormMode;

activeSettingsTabKey: string | undefined;

get state(): FormDesignerFormState {
return this.undoableState.getState();
}
Expand All @@ -98,6 +100,7 @@ export class FormDesignerInstance implements IFormDesignerInstance {
this.isDragging = false;
this.hasDragged = false;
this.isDataModified = false;
this.activeSettingsTabKey = undefined;
this.subscriptions = new Map<FormDesignerSubscriptionType, Set<FormDesignerSubscription>>();

// eslint-disable-next-line no-console
Expand Down Expand Up @@ -718,6 +721,12 @@ export class FormDesignerInstance implements IFormDesignerInstance {
this.notifySubscribers(['mode']);
};

setActiveSettingsTabKey = (key: string): void => {
if (this.activeSettingsTabKey === key) return;
this.activeSettingsTabKey = key;
this.notifySubscribers(['settings-tab']);
};

componentEditors: IComponentSettingsEditorsCache = {};

getCachedComponentEditor = (type: string, evaluator: () => ISettingsFormFactory): ISettingsFormFactory => {
Expand Down
2 changes: 1 addition & 1 deletion shesha-reactjs/src/providers/formDesigner/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type IComponentSettingsEditorsCache = Record<string, ISettingsFormFactory
export type RerenderTrigger = () => void;

export type FormDesignerSubscription = (designer: IFormDesignerInstance) => void;
export type FormDesignerSubscriptionType = 'markup' | 'selection' | 'readonly' | 'mode' | 'debug' | 'history' | 'data-modified';
export type FormDesignerSubscriptionType = 'markup' | 'selection' | 'readonly' | 'mode' | 'debug' | 'history' | 'data-modified' | 'settings-tab';

export interface AddComponentPayloadBase {
index: number;
Expand Down
Loading