160 lines
4.8 KiB
TypeScript
160 lines
4.8 KiB
TypeScript
|
|
import { ComponentData } from "@/types/screen";
|
||
|
|
import { FlowVisibilityConfig } from "@/types/control-management";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 선택된 컴포넌트들이 모두 버튼인지 확인
|
||
|
|
*/
|
||
|
|
export function areAllButtons(components: ComponentData[]): boolean {
|
||
|
|
return components.every((comp) => {
|
||
|
|
return (
|
||
|
|
comp.type === "button" ||
|
||
|
|
(comp.type === "component" && ["button-primary", "button-secondary"].includes((comp as any).componentType))
|
||
|
|
);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 선택된 버튼들 중 플로우 제어가 활성화된 버튼 찾기
|
||
|
|
*/
|
||
|
|
export function getFlowEnabledButtons(components: ComponentData[]): ComponentData[] {
|
||
|
|
return components.filter((comp) => {
|
||
|
|
const flowConfig = (comp as any).webTypeConfig?.flowVisibilityConfig as FlowVisibilityConfig | undefined;
|
||
|
|
return flowConfig?.enabled;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 고유한 그룹 ID 생성
|
||
|
|
*/
|
||
|
|
export function generateGroupId(): string {
|
||
|
|
return `flow-group-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 버튼들을 그룹으로 묶기
|
||
|
|
*/
|
||
|
|
export function groupButtons(
|
||
|
|
buttons: ComponentData[],
|
||
|
|
groupId: string,
|
||
|
|
groupSettings?: {
|
||
|
|
direction?: "horizontal" | "vertical";
|
||
|
|
gap?: number;
|
||
|
|
align?: "start" | "center" | "end" | "space-between" | "space-around";
|
||
|
|
}
|
||
|
|
): ComponentData[] {
|
||
|
|
return buttons.map((button) => {
|
||
|
|
const currentConfig = (button as any).webTypeConfig?.flowVisibilityConfig as FlowVisibilityConfig | undefined;
|
||
|
|
|
||
|
|
// 플로우 제어가 비활성화되어 있으면 먼저 활성화
|
||
|
|
const updatedConfig: FlowVisibilityConfig = {
|
||
|
|
enabled: currentConfig?.enabled ?? true,
|
||
|
|
targetFlowComponentId: currentConfig?.targetFlowComponentId || "",
|
||
|
|
targetFlowId: currentConfig?.targetFlowId,
|
||
|
|
targetFlowName: currentConfig?.targetFlowName,
|
||
|
|
mode: currentConfig?.mode || "whitelist",
|
||
|
|
visibleSteps: currentConfig?.visibleSteps || [],
|
||
|
|
hiddenSteps: currentConfig?.hiddenSteps || [],
|
||
|
|
layoutBehavior: "auto-compact", // 그룹화 시 자동으로 auto-compact 모드
|
||
|
|
groupId,
|
||
|
|
groupDirection: groupSettings?.direction || currentConfig?.groupDirection || "horizontal",
|
||
|
|
groupGap: groupSettings?.gap ?? currentConfig?.groupGap ?? 8,
|
||
|
|
groupAlign: groupSettings?.align || currentConfig?.groupAlign || "start",
|
||
|
|
};
|
||
|
|
|
||
|
|
return {
|
||
|
|
...button,
|
||
|
|
webTypeConfig: {
|
||
|
|
...(button as any).webTypeConfig,
|
||
|
|
flowVisibilityConfig: updatedConfig,
|
||
|
|
},
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 버튼 그룹 해제
|
||
|
|
*/
|
||
|
|
export function ungroupButtons(buttons: ComponentData[]): ComponentData[] {
|
||
|
|
return buttons.map((button) => {
|
||
|
|
const currentConfig = (button as any).webTypeConfig?.flowVisibilityConfig as FlowVisibilityConfig | undefined;
|
||
|
|
|
||
|
|
if (!currentConfig) return button;
|
||
|
|
|
||
|
|
const updatedConfig: FlowVisibilityConfig = {
|
||
|
|
...currentConfig,
|
||
|
|
layoutBehavior: "preserve-position", // 그룹 해제 시 preserve-position 모드로
|
||
|
|
groupId: undefined,
|
||
|
|
groupDirection: undefined,
|
||
|
|
groupGap: undefined,
|
||
|
|
groupAlign: undefined,
|
||
|
|
};
|
||
|
|
|
||
|
|
return {
|
||
|
|
...button,
|
||
|
|
webTypeConfig: {
|
||
|
|
...(button as any).webTypeConfig,
|
||
|
|
flowVisibilityConfig: updatedConfig,
|
||
|
|
},
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 화면의 모든 버튼 그룹 찾기
|
||
|
|
*/
|
||
|
|
export function findAllButtonGroups(components: ComponentData[]): Record<string, ComponentData[]> {
|
||
|
|
const groups: Record<string, ComponentData[]> = {};
|
||
|
|
|
||
|
|
components.forEach((comp) => {
|
||
|
|
const isButton =
|
||
|
|
comp.type === "button" ||
|
||
|
|
(comp.type === "component" && ["button-primary", "button-secondary"].includes((comp as any).componentType));
|
||
|
|
|
||
|
|
if (isButton) {
|
||
|
|
const flowConfig = (comp as any).webTypeConfig?.flowVisibilityConfig as FlowVisibilityConfig | undefined;
|
||
|
|
|
||
|
|
if (flowConfig?.enabled && flowConfig.layoutBehavior === "auto-compact" && flowConfig.groupId) {
|
||
|
|
if (!groups[flowConfig.groupId]) {
|
||
|
|
groups[flowConfig.groupId] = [];
|
||
|
|
}
|
||
|
|
groups[flowConfig.groupId].push(comp);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return groups;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 그룹 정보 추출
|
||
|
|
*/
|
||
|
|
export interface ButtonGroupInfo {
|
||
|
|
groupId: string;
|
||
|
|
buttonCount: number;
|
||
|
|
buttons: ComponentData[];
|
||
|
|
direction: "horizontal" | "vertical";
|
||
|
|
gap: number;
|
||
|
|
align: "start" | "center" | "end" | "space-between" | "space-around";
|
||
|
|
targetFlowName?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function getButtonGroupInfo(groupId: string, buttons: ComponentData[]): ButtonGroupInfo | null {
|
||
|
|
if (buttons.length === 0) return null;
|
||
|
|
|
||
|
|
const firstButton = buttons[0];
|
||
|
|
const flowConfig = (firstButton as any).webTypeConfig?.flowVisibilityConfig as FlowVisibilityConfig | undefined;
|
||
|
|
|
||
|
|
if (!flowConfig) return null;
|
||
|
|
|
||
|
|
return {
|
||
|
|
groupId,
|
||
|
|
buttonCount: buttons.length,
|
||
|
|
buttons,
|
||
|
|
direction: flowConfig.groupDirection || "horizontal",
|
||
|
|
gap: flowConfig.groupGap ?? 8,
|
||
|
|
align: flowConfig.groupAlign || "start",
|
||
|
|
targetFlowName: flowConfig.targetFlowName,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|