Compare commits
No commits in common. "b242a858013e19e1bceed25d6c295e651eae864f" and "a6ad975ced25d16f043a9a8c428321f4bd3bb7c8" have entirely different histories.
b242a85801
...
a6ad975ced
|
|
@ -27,10 +27,6 @@ export default function ScreenViewPage() {
|
||||||
// 테이블에서 선택된 행 데이터 (버튼 액션에 전달)
|
// 테이블에서 선택된 행 데이터 (버튼 액션에 전달)
|
||||||
const [selectedRowsData, setSelectedRowsData] = useState<any[]>([]);
|
const [selectedRowsData, setSelectedRowsData] = useState<any[]>([]);
|
||||||
|
|
||||||
// 플로우에서 선택된 데이터 (버튼 액션에 전달)
|
|
||||||
const [flowSelectedData, setFlowSelectedData] = useState<any[]>([]);
|
|
||||||
const [flowSelectedStepId, setFlowSelectedStepId] = useState<number | null>(null);
|
|
||||||
|
|
||||||
// 테이블 새로고침을 위한 키 (값이 변경되면 테이블이 리렌더링됨)
|
// 테이블 새로고침을 위한 키 (값이 변경되면 테이블이 리렌더링됨)
|
||||||
const [tableRefreshKey, setTableRefreshKey] = useState(0);
|
const [tableRefreshKey, setTableRefreshKey] = useState(0);
|
||||||
|
|
||||||
|
|
@ -232,18 +228,6 @@ export default function ScreenViewPage() {
|
||||||
console.log("🔍 화면에서 선택된 행 데이터:", selectedData);
|
console.log("🔍 화면에서 선택된 행 데이터:", selectedData);
|
||||||
setSelectedRowsData(selectedData);
|
setSelectedRowsData(selectedData);
|
||||||
}}
|
}}
|
||||||
flowSelectedData={flowSelectedData}
|
|
||||||
flowSelectedStepId={flowSelectedStepId}
|
|
||||||
onFlowSelectedDataChange={(selectedData: any[], stepId: number | null) => {
|
|
||||||
console.log("🔍 [page.tsx] 플로우 선택된 데이터 받음:", {
|
|
||||||
dataCount: selectedData.length,
|
|
||||||
selectedData,
|
|
||||||
stepId,
|
|
||||||
});
|
|
||||||
setFlowSelectedData(selectedData);
|
|
||||||
setFlowSelectedStepId(stepId);
|
|
||||||
console.log("🔍 [page.tsx] 상태 업데이트 완료");
|
|
||||||
}}
|
|
||||||
refreshKey={tableRefreshKey}
|
refreshKey={tableRefreshKey}
|
||||||
onRefresh={() => {
|
onRefresh={() => {
|
||||||
console.log("🔄 테이블 새로고침 요청됨");
|
console.log("🔄 테이블 새로고침 요청됨");
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,6 @@ export const InteractiveScreenViewerDynamic: React.FC<InteractiveScreenViewerPro
|
||||||
// 테이블에서 선택된 행 데이터 (버튼 액션에 전달)
|
// 테이블에서 선택된 행 데이터 (버튼 액션에 전달)
|
||||||
const [selectedRowsData, setSelectedRowsData] = useState<any[]>([]);
|
const [selectedRowsData, setSelectedRowsData] = useState<any[]>([]);
|
||||||
|
|
||||||
// 플로우에서 선택된 데이터 (버튼 액션에 전달)
|
|
||||||
const [flowSelectedData, setFlowSelectedData] = useState<any[]>([]);
|
|
||||||
const [flowSelectedStepId, setFlowSelectedStepId] = useState<number | null>(null);
|
|
||||||
|
|
||||||
// 팝업 화면 상태
|
// 팝업 화면 상태
|
||||||
const [popupScreen, setPopupScreen] = useState<{
|
const [popupScreen, setPopupScreen] = useState<{
|
||||||
screenId: number;
|
screenId: number;
|
||||||
|
|
@ -198,13 +194,6 @@ export const InteractiveScreenViewerDynamic: React.FC<InteractiveScreenViewerPro
|
||||||
console.log("🔍 테이블에서 선택된 행 데이터:", selectedData);
|
console.log("🔍 테이블에서 선택된 행 데이터:", selectedData);
|
||||||
setSelectedRowsData(selectedData);
|
setSelectedRowsData(selectedData);
|
||||||
}}
|
}}
|
||||||
flowSelectedData={flowSelectedData}
|
|
||||||
flowSelectedStepId={flowSelectedStepId}
|
|
||||||
onFlowSelectedDataChange={(selectedData, stepId) => {
|
|
||||||
console.log("🔍 플로우에서 선택된 데이터:", { selectedData, stepId });
|
|
||||||
setFlowSelectedData(selectedData);
|
|
||||||
setFlowSelectedStepId(stepId);
|
|
||||||
}}
|
|
||||||
onRefresh={() => {
|
onRefresh={() => {
|
||||||
console.log("🔄 버튼에서 테이블 새로고침 요청됨");
|
console.log("🔄 버튼에서 테이블 새로고침 요청됨");
|
||||||
// 테이블 컴포넌트는 자체적으로 loadData 호출
|
// 테이블 컴포넌트는 자체적으로 loadData 호출
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,6 @@ interface OptimizedButtonProps {
|
||||||
formData?: Record<string, any>;
|
formData?: Record<string, any>;
|
||||||
companyCode?: string;
|
companyCode?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
selectedRows?: any[];
|
|
||||||
selectedRowsData?: any[];
|
|
||||||
flowSelectedData?: any[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -45,10 +41,6 @@ export const OptimizedButtonComponent: React.FC<OptimizedButtonProps> = ({
|
||||||
formData = {},
|
formData = {},
|
||||||
companyCode = "DEFAULT",
|
companyCode = "DEFAULT",
|
||||||
disabled = false,
|
disabled = false,
|
||||||
selectedRows = [],
|
|
||||||
selectedRowsData = [],
|
|
||||||
flowSelectedData = [],
|
|
||||||
flowSelectedStepId = null,
|
|
||||||
}) => {
|
}) => {
|
||||||
// 🔥 상태 관리
|
// 🔥 상태 관리
|
||||||
const [isExecuting, setIsExecuting] = useState(false);
|
const [isExecuting, setIsExecuting] = useState(false);
|
||||||
|
|
@ -87,8 +79,6 @@ export const OptimizedButtonComponent: React.FC<OptimizedButtonProps> = ({
|
||||||
formData,
|
formData,
|
||||||
selectedRows: selectedRows || [],
|
selectedRows: selectedRows || [],
|
||||||
selectedRowsData: selectedRowsData || [],
|
selectedRowsData: selectedRowsData || [],
|
||||||
flowSelectedData: flowSelectedData || [],
|
|
||||||
flowSelectedStepId: flowSelectedStepId,
|
|
||||||
controlDataSource: config?.dataflowConfig?.controlDataSource || "form",
|
controlDataSource: config?.dataflowConfig?.controlDataSource || "form",
|
||||||
buttonId: component.id,
|
buttonId: component.id,
|
||||||
componentData: component,
|
componentData: component,
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,6 @@ interface RealtimePreviewProps {
|
||||||
onDragEnd?: () => void;
|
onDragEnd?: () => void;
|
||||||
onGroupToggle?: (groupId: string) => void; // 그룹 접기/펼치기
|
onGroupToggle?: (groupId: string) => void; // 그룹 접기/펼치기
|
||||||
children?: React.ReactNode; // 그룹 내 자식 컴포넌트들
|
children?: React.ReactNode; // 그룹 내 자식 컴포넌트들
|
||||||
// 플로우 선택 데이터 전달용
|
|
||||||
onFlowSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 영역 레이아웃에 따른 아이콘 반환
|
// 영역 레이아웃에 따른 아이콘 반환
|
||||||
|
|
@ -220,7 +218,6 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
|
||||||
onDragEnd,
|
onDragEnd,
|
||||||
onGroupToggle,
|
onGroupToggle,
|
||||||
children,
|
children,
|
||||||
onFlowSelectedDataChange,
|
|
||||||
}) => {
|
}) => {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { type, id, position, size, style = {} } = component;
|
const { type, id, position, size, style = {} } = component;
|
||||||
|
|
@ -497,10 +494,7 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-auto w-full">
|
<div className="h-auto w-full">
|
||||||
<FlowWidget
|
<FlowWidget component={flowComponent as any} />
|
||||||
component={flowComponent as any}
|
|
||||||
onSelectedDataChange={onFlowSelectedDataChange}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})()}
|
})()}
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,6 @@ interface RealtimePreviewProps {
|
||||||
tableName?: string;
|
tableName?: string;
|
||||||
selectedRowsData?: any[];
|
selectedRowsData?: any[];
|
||||||
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
|
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
|
||||||
flowSelectedData?: any[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
onFlowSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
|
|
||||||
refreshKey?: number;
|
refreshKey?: number;
|
||||||
onRefresh?: () => void;
|
onRefresh?: () => void;
|
||||||
|
|
||||||
|
|
@ -96,9 +93,6 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
|
||||||
tableName,
|
tableName,
|
||||||
selectedRowsData,
|
selectedRowsData,
|
||||||
onSelectedRowsChange,
|
onSelectedRowsChange,
|
||||||
flowSelectedData,
|
|
||||||
flowSelectedStepId,
|
|
||||||
onFlowSelectedDataChange,
|
|
||||||
refreshKey,
|
refreshKey,
|
||||||
onRefresh,
|
onRefresh,
|
||||||
formData,
|
formData,
|
||||||
|
|
@ -294,9 +288,6 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
|
||||||
tableName={tableName}
|
tableName={tableName}
|
||||||
selectedRowsData={selectedRowsData}
|
selectedRowsData={selectedRowsData}
|
||||||
onSelectedRowsChange={onSelectedRowsChange}
|
onSelectedRowsChange={onSelectedRowsChange}
|
||||||
flowSelectedData={flowSelectedData}
|
|
||||||
flowSelectedStepId={flowSelectedStepId}
|
|
||||||
onFlowSelectedDataChange={onFlowSelectedDataChange}
|
|
||||||
refreshKey={refreshKey}
|
refreshKey={refreshKey}
|
||||||
onRefresh={onRefresh}
|
onRefresh={onRefresh}
|
||||||
formData={formData}
|
formData={formData}
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,9 @@ import {
|
||||||
interface FlowWidgetProps {
|
interface FlowWidgetProps {
|
||||||
component: FlowComponent;
|
component: FlowComponent;
|
||||||
onStepClick?: (stepId: number, stepName: string) => void;
|
onStepClick?: (stepId: number, stepName: string) => void;
|
||||||
onSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FlowWidget({ component, onStepClick, onSelectedDataChange }: FlowWidgetProps) {
|
export function FlowWidget({ component, onStepClick }: FlowWidgetProps) {
|
||||||
const [flowData, setFlowData] = useState<FlowDefinition | null>(null);
|
const [flowData, setFlowData] = useState<FlowDefinition | null>(null);
|
||||||
const [steps, setSteps] = useState<FlowStep[]>([]);
|
const [steps, setSteps] = useState<FlowStep[]>([]);
|
||||||
const [stepCounts, setStepCounts] = useState<Record<number, number>>({});
|
const [stepCounts, setStepCounts] = useState<Record<number, number>>({});
|
||||||
|
|
@ -157,8 +156,6 @@ export function FlowWidget({ component, onStepClick, onSelectedDataChange }: Flo
|
||||||
setStepData([]);
|
setStepData([]);
|
||||||
setStepDataColumns([]);
|
setStepDataColumns([]);
|
||||||
setSelectedRows(new Set());
|
setSelectedRows(new Set());
|
||||||
// 선택 초기화 전달
|
|
||||||
onSelectedDataChange?.([], null);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,8 +163,6 @@ export function FlowWidget({ component, onStepClick, onSelectedDataChange }: Flo
|
||||||
setSelectedStepId(stepId);
|
setSelectedStepId(stepId);
|
||||||
setStepDataLoading(true);
|
setStepDataLoading(true);
|
||||||
setSelectedRows(new Set());
|
setSelectedRows(new Set());
|
||||||
// 선택 초기화 전달
|
|
||||||
onSelectedDataChange?.([], stepId);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await getStepDataList(flowId!, stepId, 1, 100);
|
const response = await getStepDataList(flowId!, stepId, 1, 100);
|
||||||
|
|
@ -202,32 +197,15 @@ export function FlowWidget({ component, onStepClick, onSelectedDataChange }: Flo
|
||||||
newSelected.add(rowIndex);
|
newSelected.add(rowIndex);
|
||||||
}
|
}
|
||||||
setSelectedRows(newSelected);
|
setSelectedRows(newSelected);
|
||||||
|
|
||||||
// 선택된 데이터를 상위로 전달
|
|
||||||
const selectedData = Array.from(newSelected).map((index) => stepData[index]);
|
|
||||||
console.log("🌊 FlowWidget - 체크박스 토글, 상위로 전달:", {
|
|
||||||
rowIndex,
|
|
||||||
newSelectedSize: newSelected.size,
|
|
||||||
selectedData,
|
|
||||||
selectedStepId,
|
|
||||||
hasCallback: !!onSelectedDataChange,
|
|
||||||
});
|
|
||||||
onSelectedDataChange?.(selectedData, selectedStepId);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 전체 선택/해제
|
// 전체 선택/해제
|
||||||
const toggleAllRows = () => {
|
const toggleAllRows = () => {
|
||||||
let newSelected: Set<number>;
|
|
||||||
if (selectedRows.size === stepData.length) {
|
if (selectedRows.size === stepData.length) {
|
||||||
newSelected = new Set();
|
setSelectedRows(new Set());
|
||||||
} else {
|
} else {
|
||||||
newSelected = new Set(stepData.map((_, index) => index));
|
setSelectedRows(new Set(stepData.map((_, index) => index)));
|
||||||
}
|
}
|
||||||
setSelectedRows(newSelected);
|
|
||||||
|
|
||||||
// 선택된 데이터를 상위로 전달
|
|
||||||
const selectedData = Array.from(newSelected).map((index) => stepData[index]);
|
|
||||||
onSelectedDataChange?.(selectedData, selectedStepId);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 현재 단계에서 가능한 다음 단계들 찾기
|
// 현재 단계에서 가능한 다음 단계들 찾기
|
||||||
|
|
@ -286,8 +264,6 @@ export function FlowWidget({ component, onStepClick, onSelectedDataChange }: Flo
|
||||||
// 선택 초기화
|
// 선택 초기화
|
||||||
setSelectedNextStepId(null);
|
setSelectedNextStepId(null);
|
||||||
setSelectedRows(new Set());
|
setSelectedRows(new Set());
|
||||||
// 선택 초기화 전달
|
|
||||||
onSelectedDataChange?.([], selectedStepId);
|
|
||||||
|
|
||||||
// 데이터 새로고침
|
// 데이터 새로고침
|
||||||
await handleStepClick(selectedStepId, steps.find((s) => s.id === selectedStepId)?.stepName || "");
|
await handleStepClick(selectedStepId, steps.find((s) => s.id === selectedStepId)?.stepName || "");
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,6 @@ export interface ComponentRenderer {
|
||||||
selectedRows?: any[];
|
selectedRows?: any[];
|
||||||
selectedRowsData?: any[];
|
selectedRowsData?: any[];
|
||||||
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
|
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
|
||||||
// 플로우 선택된 데이터 정보 (플로우 위젯 선택 액션용)
|
|
||||||
flowSelectedData?: any[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
onFlowSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
|
|
||||||
// 테이블 새로고침 키
|
// 테이블 새로고침 키
|
||||||
refreshKey?: number;
|
refreshKey?: number;
|
||||||
// 편집 모드
|
// 편집 모드
|
||||||
|
|
@ -99,10 +95,6 @@ export interface DynamicComponentRendererProps {
|
||||||
selectedRows?: any[];
|
selectedRows?: any[];
|
||||||
selectedRowsData?: any[];
|
selectedRowsData?: any[];
|
||||||
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
|
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
|
||||||
// 플로우 선택된 데이터 정보 (플로우 위젯 선택 액션용)
|
|
||||||
flowSelectedData?: any[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
onFlowSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
|
|
||||||
// 테이블 새로고침 키
|
// 테이블 새로고침 키
|
||||||
refreshKey?: number;
|
refreshKey?: number;
|
||||||
// 편집 모드
|
// 편집 모드
|
||||||
|
|
@ -182,9 +174,6 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||||
selectedRows,
|
selectedRows,
|
||||||
selectedRowsData,
|
selectedRowsData,
|
||||||
onSelectedRowsChange,
|
onSelectedRowsChange,
|
||||||
flowSelectedData,
|
|
||||||
flowSelectedStepId,
|
|
||||||
onFlowSelectedDataChange,
|
|
||||||
refreshKey,
|
refreshKey,
|
||||||
onConfigChange,
|
onConfigChange,
|
||||||
isPreview,
|
isPreview,
|
||||||
|
|
@ -300,10 +289,6 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||||
selectedRows,
|
selectedRows,
|
||||||
selectedRowsData,
|
selectedRowsData,
|
||||||
onSelectedRowsChange,
|
onSelectedRowsChange,
|
||||||
// 플로우 선택된 데이터 정보 전달
|
|
||||||
flowSelectedData,
|
|
||||||
flowSelectedStepId,
|
|
||||||
onFlowSelectedDataChange,
|
|
||||||
// 설정 변경 핸들러 전달
|
// 설정 변경 핸들러 전달
|
||||||
onConfigChange,
|
onConfigChange,
|
||||||
refreshKey,
|
refreshKey,
|
||||||
|
|
@ -314,26 +299,16 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||||
};
|
};
|
||||||
|
|
||||||
// 렌더러가 클래스인지 함수인지 확인
|
// 렌더러가 클래스인지 함수인지 확인
|
||||||
console.log("🔍🔍 DynamicComponentRenderer - 렌더러 타입 확인:", {
|
|
||||||
componentType,
|
|
||||||
isFunction: typeof NewComponentRenderer === "function",
|
|
||||||
hasPrototype: !!NewComponentRenderer.prototype,
|
|
||||||
hasRenderMethod: !!NewComponentRenderer.prototype?.render,
|
|
||||||
rendererName: NewComponentRenderer.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
typeof NewComponentRenderer === "function" &&
|
typeof NewComponentRenderer === "function" &&
|
||||||
NewComponentRenderer.prototype &&
|
NewComponentRenderer.prototype &&
|
||||||
NewComponentRenderer.prototype.render
|
NewComponentRenderer.prototype.render
|
||||||
) {
|
) {
|
||||||
// 클래스 기반 렌더러 (AutoRegisteringComponentRenderer 상속)
|
// 클래스 기반 렌더러 (AutoRegisteringComponentRenderer 상속)
|
||||||
console.log("✅ 클래스 기반 렌더러로 렌더링:", componentType);
|
|
||||||
const rendererInstance = new NewComponentRenderer(rendererProps);
|
const rendererInstance = new NewComponentRenderer(rendererProps);
|
||||||
return rendererInstance.render();
|
return rendererInstance.render();
|
||||||
} else {
|
} else {
|
||||||
// 함수형 컴포넌트
|
// 함수형 컴포넌트
|
||||||
console.log("✅ 함수형 컴포넌트로 렌더링:", componentType);
|
|
||||||
return <NewComponentRenderer {...rendererProps} />;
|
return <NewComponentRenderer {...rendererProps} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -396,10 +371,6 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||||
selectedRows: props.selectedRows,
|
selectedRows: props.selectedRows,
|
||||||
selectedRowsData: props.selectedRowsData,
|
selectedRowsData: props.selectedRowsData,
|
||||||
onSelectedRowsChange: props.onSelectedRowsChange,
|
onSelectedRowsChange: props.onSelectedRowsChange,
|
||||||
// 플로우 선택된 데이터 정보 전달
|
|
||||||
flowSelectedData: props.flowSelectedData,
|
|
||||||
flowSelectedStepId: props.flowSelectedStepId,
|
|
||||||
onFlowSelectedDataChange: props.onFlowSelectedDataChange,
|
|
||||||
refreshKey: props.refreshKey,
|
refreshKey: props.refreshKey,
|
||||||
// DOM 안전한 props들
|
// DOM 안전한 props들
|
||||||
...safeLegacyProps,
|
...safeLegacyProps,
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,6 @@ export interface ButtonPrimaryComponentProps extends ComponentRendererProps {
|
||||||
// 테이블 선택된 행 정보 (다중 선택 액션용)
|
// 테이블 선택된 행 정보 (다중 선택 액션용)
|
||||||
selectedRows?: any[];
|
selectedRows?: any[];
|
||||||
selectedRowsData?: any[];
|
selectedRowsData?: any[];
|
||||||
|
|
||||||
// 플로우 선택된 데이터 정보 (플로우 위젯 선택 액션용)
|
|
||||||
flowSelectedData?: any[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -66,8 +62,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||||
onClose,
|
onClose,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
selectedRowsData,
|
selectedRowsData,
|
||||||
flowSelectedData,
|
|
||||||
flowSelectedStepId,
|
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
console.log("🔵 ButtonPrimaryComponent 렌더링, 받은 props:", {
|
console.log("🔵 ButtonPrimaryComponent 렌더링, 받은 props:", {
|
||||||
|
|
@ -75,10 +69,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||||
hasSelectedRowsData: !!selectedRowsData,
|
hasSelectedRowsData: !!selectedRowsData,
|
||||||
selectedRowsDataLength: selectedRowsData?.length,
|
selectedRowsDataLength: selectedRowsData?.length,
|
||||||
selectedRowsData,
|
selectedRowsData,
|
||||||
hasFlowSelectedData: !!flowSelectedData,
|
|
||||||
flowSelectedDataLength: flowSelectedData?.length,
|
|
||||||
flowSelectedData,
|
|
||||||
flowSelectedStepId,
|
|
||||||
tableName,
|
tableName,
|
||||||
screenId,
|
screenId,
|
||||||
});
|
});
|
||||||
|
|
@ -435,19 +425,12 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||||
// 테이블 선택된 행 정보 추가
|
// 테이블 선택된 행 정보 추가
|
||||||
selectedRows,
|
selectedRows,
|
||||||
selectedRowsData,
|
selectedRowsData,
|
||||||
// 플로우 선택된 데이터 정보 추가
|
|
||||||
flowSelectedData,
|
|
||||||
flowSelectedStepId,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("🔍 버튼 액션 실행 전 context 확인:", {
|
console.log("🔍 버튼 액션 실행 전 context 확인:", {
|
||||||
hasSelectedRowsData: !!selectedRowsData,
|
hasSelectedRowsData: !!selectedRowsData,
|
||||||
selectedRowsDataLength: selectedRowsData?.length,
|
selectedRowsDataLength: selectedRowsData?.length,
|
||||||
selectedRowsData,
|
selectedRowsData,
|
||||||
hasFlowSelectedData: !!flowSelectedData,
|
|
||||||
flowSelectedDataLength: flowSelectedData?.length,
|
|
||||||
flowSelectedData,
|
|
||||||
flowSelectedStepId,
|
|
||||||
tableName,
|
tableName,
|
||||||
screenId,
|
screenId,
|
||||||
formData,
|
formData,
|
||||||
|
|
@ -515,8 +498,6 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
||||||
selectedRows: _selectedRows,
|
selectedRows: _selectedRows,
|
||||||
selectedRowsData: _selectedRowsData,
|
selectedRowsData: _selectedRowsData,
|
||||||
onSelectedRowsChange: _onSelectedRowsChange,
|
onSelectedRowsChange: _onSelectedRowsChange,
|
||||||
flowSelectedData: _flowSelectedData, // 플로우 선택 데이터 필터링
|
|
||||||
flowSelectedStepId: _flowSelectedStepId, // 플로우 선택 스텝 ID 필터링
|
|
||||||
originalData: _originalData, // 부분 업데이트용 원본 데이터 필터링
|
originalData: _originalData, // 부분 업데이트용 원본 데이터 필터링
|
||||||
refreshKey: _refreshKey, // 필터링 추가
|
refreshKey: _refreshKey, // 필터링 추가
|
||||||
isInModal: _isInModal, // 필터링 추가
|
isInModal: _isInModal, // 필터링 추가
|
||||||
|
|
|
||||||
|
|
@ -4,41 +4,16 @@ import React from "react";
|
||||||
import { AutoRegisteringComponentRenderer } from "../../AutoRegisteringComponentRenderer";
|
import { AutoRegisteringComponentRenderer } from "../../AutoRegisteringComponentRenderer";
|
||||||
import { FlowWidgetDefinition } from "./index";
|
import { FlowWidgetDefinition } from "./index";
|
||||||
import { FlowWidget } from "@/components/screen/widgets/FlowWidget";
|
import { FlowWidget } from "@/components/screen/widgets/FlowWidget";
|
||||||
import { createComponentDefinition } from "../../utils/createComponentDefinition";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FlowWidget 렌더러
|
* FlowWidget 렌더러
|
||||||
* 자동 등록 시스템을 사용하여 컴포넌트를 레지스트리에 등록
|
* 자동 등록 시스템을 사용하여 컴포넌트를 레지스트리에 등록
|
||||||
*/
|
*/
|
||||||
export class FlowWidgetRenderer extends AutoRegisteringComponentRenderer {
|
export class FlowWidgetRenderer extends AutoRegisteringComponentRenderer {
|
||||||
// 먼저 Definition에 컴포넌트 설정
|
static componentDefinition = FlowWidgetDefinition;
|
||||||
static componentDefinition = (() => {
|
|
||||||
// FlowWidgetRenderer를 컴포넌트로 설정
|
|
||||||
const definition = { ...FlowWidgetDefinition, component: FlowWidgetRenderer };
|
|
||||||
// createComponentDefinition으로 검증 및 처리
|
|
||||||
return createComponentDefinition(definition as any);
|
|
||||||
})();
|
|
||||||
|
|
||||||
render(): React.ReactElement {
|
render(): React.ReactElement {
|
||||||
console.log("🎨🎨🎨 FlowWidgetRenderer - render 호출 시작 🎨🎨🎨");
|
return <FlowWidget component={this.props.component as any} />;
|
||||||
console.log("🎨 FlowWidgetRenderer - render 호출:", {
|
|
||||||
componentId: this.props.component.id,
|
|
||||||
hasOnFlowSelectedDataChange: !!this.props.onFlowSelectedDataChange,
|
|
||||||
onFlowSelectedDataChangeType: typeof this.props.onFlowSelectedDataChange,
|
|
||||||
allPropsKeys: Object.keys(this.props),
|
|
||||||
allPropsValues: this.props,
|
|
||||||
});
|
|
||||||
console.log("🎨🎨🎨 FlowWidget에 전달할 prop:", {
|
|
||||||
hasComponent: !!this.props.component,
|
|
||||||
hasOnSelectedDataChange: !!this.props.onFlowSelectedDataChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FlowWidget
|
|
||||||
component={this.props.component as any}
|
|
||||||
onSelectedDataChange={this.props.onFlowSelectedDataChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,22 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { createComponentDefinition } from "../../utils/createComponentDefinition";
|
||||||
import { ComponentCategory } from "@/types/component";
|
import { ComponentCategory } from "@/types/component";
|
||||||
|
import { FlowWidget } from "@/components/screen/widgets/FlowWidget";
|
||||||
import { FlowWidgetConfigPanel } from "@/components/screen/config-panels/FlowWidgetConfigPanel";
|
import { FlowWidgetConfigPanel } from "@/components/screen/config-panels/FlowWidgetConfigPanel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FlowWidget 컴포넌트 정의 (컴포넌트는 FlowWidgetRenderer에서 설정됨)
|
* FlowWidget 컴포넌트 정의
|
||||||
* 플로우 관리 시스템의 플로우를 화면에 표시
|
* 플로우 관리 시스템의 플로우를 화면에 표시
|
||||||
*/
|
*/
|
||||||
export const FlowWidgetDefinition = {
|
export const FlowWidgetDefinition = createComponentDefinition({
|
||||||
id: "flow-widget",
|
id: "flow-widget",
|
||||||
name: "플로우 위젯",
|
name: "플로우 위젯",
|
||||||
nameEng: "Flow Widget",
|
nameEng: "Flow Widget",
|
||||||
description: "플로우 관리 시스템의 플로우를 화면에 표시합니다",
|
description: "플로우 관리 시스템의 플로우를 화면에 표시합니다",
|
||||||
category: ComponentCategory.DISPLAY,
|
category: ComponentCategory.DISPLAY,
|
||||||
webType: "text" as const, // 기본 웹타입 (필수)
|
webType: "text", // 기본 웹타입 (필수)
|
||||||
component: null as any, // FlowWidgetRenderer에서 설정됩니다
|
component: FlowWidget,
|
||||||
defaultConfig: {
|
defaultConfig: {
|
||||||
flowId: undefined,
|
flowId: undefined,
|
||||||
flowName: undefined,
|
flowName: undefined,
|
||||||
|
|
@ -28,11 +30,11 @@ export const FlowWidgetDefinition = {
|
||||||
gridColumnSpan: "full", // 전체 너비 사용
|
gridColumnSpan: "full", // 전체 너비 사용
|
||||||
},
|
},
|
||||||
configPanel: FlowWidgetConfigPanel,
|
configPanel: FlowWidgetConfigPanel,
|
||||||
icon: "Workflow" as const,
|
icon: "Workflow",
|
||||||
tags: ["플로우", "워크플로우", "프로세스", "상태"],
|
tags: ["플로우", "워크플로우", "프로세스", "상태"],
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
author: "개발팀",
|
author: "개발팀",
|
||||||
documentation: "",
|
documentation: "",
|
||||||
} as const;
|
});
|
||||||
|
|
||||||
// 컴포넌트는 FlowWidgetRenderer에서 자동 등록됩니다
|
// 컴포넌트는 FlowWidgetRenderer에서 자동 등록됩니다
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,6 @@ export interface ButtonActionContext {
|
||||||
selectedRows?: any[];
|
selectedRows?: any[];
|
||||||
selectedRowsData?: any[];
|
selectedRowsData?: any[];
|
||||||
|
|
||||||
// 플로우 선택된 데이터 정보 (플로우 위젯 선택 액션용)
|
|
||||||
flowSelectedData?: any[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
|
|
||||||
// 제어 실행을 위한 추가 정보
|
// 제어 실행을 위한 추가 정보
|
||||||
buttonId?: string;
|
buttonId?: string;
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
|
@ -306,23 +302,12 @@ export class ButtonActionExecutor {
|
||||||
* 삭제 액션 처리
|
* 삭제 액션 처리
|
||||||
*/
|
*/
|
||||||
private static async handleDelete(config: ButtonActionConfig, context: ButtonActionContext): Promise<boolean> {
|
private static async handleDelete(config: ButtonActionConfig, context: ButtonActionContext): Promise<boolean> {
|
||||||
const { formData, tableName, screenId, selectedRowsData, flowSelectedData } = context;
|
const { formData, tableName, screenId, selectedRowsData } = context;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 플로우 선택 데이터 우선 사용
|
// 다중 선택된 행이 있는 경우 (테이블에서 체크박스로 선택)
|
||||||
let dataToDelete = flowSelectedData && flowSelectedData.length > 0 ? flowSelectedData : selectedRowsData;
|
if (selectedRowsData && selectedRowsData.length > 0) {
|
||||||
|
console.log(`다중 삭제 액션 실행: ${selectedRowsData.length}개 항목`, selectedRowsData);
|
||||||
console.log("🔍 handleDelete - 데이터 소스 확인:", {
|
|
||||||
hasFlowSelectedData: !!(flowSelectedData && flowSelectedData.length > 0),
|
|
||||||
flowSelectedDataLength: flowSelectedData?.length || 0,
|
|
||||||
hasSelectedRowsData: !!(selectedRowsData && selectedRowsData.length > 0),
|
|
||||||
selectedRowsDataLength: selectedRowsData?.length || 0,
|
|
||||||
dataToDeleteLength: dataToDelete?.length || 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 다중 선택된 데이터가 있는 경우
|
|
||||||
if (dataToDelete && dataToDelete.length > 0) {
|
|
||||||
console.log(`다중 삭제 액션 실행: ${dataToDelete.length}개 항목`, dataToDelete);
|
|
||||||
|
|
||||||
// 테이블의 기본키 조회
|
// 테이블의 기본키 조회
|
||||||
let primaryKeys: string[] = [];
|
let primaryKeys: string[] = [];
|
||||||
|
|
@ -339,7 +324,7 @@ export class ButtonActionExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 각 선택된 항목을 삭제
|
// 각 선택된 항목을 삭제
|
||||||
for (const rowData of dataToDelete) {
|
for (const rowData of selectedRowsData) {
|
||||||
let deleteId: any = null;
|
let deleteId: any = null;
|
||||||
|
|
||||||
// 1순위: 데이터베이스에서 조회한 기본키 사용
|
// 1순위: 데이터베이스에서 조회한 기본키 사용
|
||||||
|
|
@ -401,7 +386,7 @@ export class ButtonActionExecutor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`✅ 다중 삭제 성공: ${dataToDelete.length}개 항목`);
|
console.log(`✅ 다중 삭제 성공: ${selectedRowsData.length}개 항목`);
|
||||||
context.onRefresh?.(); // 테이블 새로고침
|
context.onRefresh?.(); // 테이블 새로고침
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -596,21 +581,10 @@ export class ButtonActionExecutor {
|
||||||
* 편집 액션 처리
|
* 편집 액션 처리
|
||||||
*/
|
*/
|
||||||
private static handleEdit(config: ButtonActionConfig, context: ButtonActionContext): boolean {
|
private static handleEdit(config: ButtonActionConfig, context: ButtonActionContext): boolean {
|
||||||
const { selectedRowsData, flowSelectedData } = context;
|
const { selectedRowsData } = context;
|
||||||
|
|
||||||
// 플로우 선택 데이터 우선 사용
|
// 선택된 행이 없는 경우
|
||||||
let dataToEdit = flowSelectedData && flowSelectedData.length > 0 ? flowSelectedData : selectedRowsData;
|
if (!selectedRowsData || selectedRowsData.length === 0) {
|
||||||
|
|
||||||
console.log("🔍 handleEdit - 데이터 소스 확인:", {
|
|
||||||
hasFlowSelectedData: !!(flowSelectedData && flowSelectedData.length > 0),
|
|
||||||
flowSelectedDataLength: flowSelectedData?.length || 0,
|
|
||||||
hasSelectedRowsData: !!(selectedRowsData && selectedRowsData.length > 0),
|
|
||||||
selectedRowsDataLength: selectedRowsData?.length || 0,
|
|
||||||
dataToEditLength: dataToEdit?.length || 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 선택된 데이터가 없는 경우
|
|
||||||
if (!dataToEdit || dataToEdit.length === 0) {
|
|
||||||
toast.error("수정할 항목을 선택해주세요.");
|
toast.error("수정할 항목을 선택해주세요.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -621,15 +595,15 @@ export class ButtonActionExecutor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`📝 편집 액션 실행: ${dataToEdit.length}개 항목`, {
|
console.log(`📝 편집 액션 실행: ${selectedRowsData.length}개 항목`, {
|
||||||
dataToEdit,
|
selectedRowsData,
|
||||||
targetScreenId: config.targetScreenId,
|
targetScreenId: config.targetScreenId,
|
||||||
editMode: config.editMode,
|
editMode: config.editMode,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (dataToEdit.length === 1) {
|
if (selectedRowsData.length === 1) {
|
||||||
// 단일 항목 편집
|
// 단일 항목 편집
|
||||||
const rowData = dataToEdit[0];
|
const rowData = selectedRowsData[0];
|
||||||
console.log("📝 단일 항목 편집:", rowData);
|
console.log("📝 단일 항목 편집:", rowData);
|
||||||
|
|
||||||
this.openEditForm(config, rowData, context);
|
this.openEditForm(config, rowData, context);
|
||||||
|
|
@ -736,8 +710,6 @@ export class ButtonActionExecutor {
|
||||||
formData: context.formData,
|
formData: context.formData,
|
||||||
selectedRows: context.selectedRows,
|
selectedRows: context.selectedRows,
|
||||||
selectedRowsData: context.selectedRowsData,
|
selectedRowsData: context.selectedRowsData,
|
||||||
flowSelectedData: context.flowSelectedData,
|
|
||||||
flowSelectedStepId: context.flowSelectedStepId,
|
|
||||||
config,
|
config,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -767,10 +739,7 @@ export class ButtonActionExecutor {
|
||||||
|
|
||||||
if (!controlDataSource) {
|
if (!controlDataSource) {
|
||||||
// 설정이 없으면 자동 판단
|
// 설정이 없으면 자동 판단
|
||||||
if (context.flowSelectedData && context.flowSelectedData.length > 0) {
|
if (context.selectedRowsData && context.selectedRowsData.length > 0) {
|
||||||
controlDataSource = "flow-selection";
|
|
||||||
console.log("🔄 자동 판단: flow-selection 모드 사용");
|
|
||||||
} else if (context.selectedRowsData && context.selectedRowsData.length > 0) {
|
|
||||||
controlDataSource = "table-selection";
|
controlDataSource = "table-selection";
|
||||||
console.log("🔄 자동 판단: table-selection 모드 사용");
|
console.log("🔄 자동 판단: table-selection 모드 사용");
|
||||||
} else if (context.formData && Object.keys(context.formData).length > 0) {
|
} else if (context.formData && Object.keys(context.formData).length > 0) {
|
||||||
|
|
@ -786,8 +755,6 @@ export class ButtonActionExecutor {
|
||||||
formData: context.formData || {},
|
formData: context.formData || {},
|
||||||
selectedRows: context.selectedRows || [],
|
selectedRows: context.selectedRows || [],
|
||||||
selectedRowsData: context.selectedRowsData || [],
|
selectedRowsData: context.selectedRowsData || [],
|
||||||
flowSelectedData: context.flowSelectedData || [],
|
|
||||||
flowSelectedStepId: context.flowSelectedStepId,
|
|
||||||
controlDataSource,
|
controlDataSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -812,20 +779,11 @@ export class ButtonActionExecutor {
|
||||||
// 노드 플로우 실행 API 호출 (API 클라이언트 사용)
|
// 노드 플로우 실행 API 호출 (API 클라이언트 사용)
|
||||||
const { executeNodeFlow } = await import("@/lib/api/nodeFlows");
|
const { executeNodeFlow } = await import("@/lib/api/nodeFlows");
|
||||||
|
|
||||||
// 데이터 소스 준비: 플로우 선택, 테이블 선택, 또는 폼 데이터
|
// 데이터 소스 준비: 선택된 행 또는 폼 데이터
|
||||||
let sourceData: any = null;
|
let sourceData: any = null;
|
||||||
let dataSourceType: string = "none";
|
let dataSourceType: string = "none";
|
||||||
|
|
||||||
if (context.flowSelectedData && context.flowSelectedData.length > 0) {
|
if (context.selectedRowsData && context.selectedRowsData.length > 0) {
|
||||||
// 플로우에서 선택된 데이터 사용
|
|
||||||
sourceData = context.flowSelectedData;
|
|
||||||
dataSourceType = "flow-selection";
|
|
||||||
console.log("🌊 플로우 선택 데이터 사용:", {
|
|
||||||
stepId: context.flowSelectedStepId,
|
|
||||||
dataCount: sourceData.length,
|
|
||||||
sourceData,
|
|
||||||
});
|
|
||||||
} else if (context.selectedRowsData && context.selectedRowsData.length > 0) {
|
|
||||||
// 테이블에서 선택된 행 데이터 사용
|
// 테이블에서 선택된 행 데이터 사용
|
||||||
sourceData = context.selectedRowsData;
|
sourceData = context.selectedRowsData;
|
||||||
dataSourceType = "table-selection";
|
dataSourceType = "table-selection";
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ export interface ButtonExecutionContext {
|
||||||
formData?: Record<string, any>;
|
formData?: Record<string, any>;
|
||||||
selectedRows?: any[];
|
selectedRows?: any[];
|
||||||
tableData?: any[];
|
tableData?: any[];
|
||||||
flowSelectedData?: any[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExecutionResult {
|
export interface ExecutionResult {
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ export interface ButtonDataflowConfig {
|
||||||
/**
|
/**
|
||||||
* 제어 데이터 소스 타입
|
* 제어 데이터 소스 타입
|
||||||
*/
|
*/
|
||||||
export type ControlDataSource = "form" | "table-selection" | "flow-selection" | "both";
|
export type ControlDataSource = "form" | "table-selection" | "both";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 직접 제어 설정
|
* 직접 제어 설정
|
||||||
|
|
@ -376,17 +376,13 @@ export interface ExtendedControlContext {
|
||||||
selectedRows?: unknown[];
|
selectedRows?: unknown[];
|
||||||
selectedRowsData?: Record<string, unknown>[];
|
selectedRowsData?: Record<string, unknown>[];
|
||||||
|
|
||||||
// 플로우 선택 데이터
|
|
||||||
flowSelectedData?: Record<string, unknown>[];
|
|
||||||
flowSelectedStepId?: number | null;
|
|
||||||
|
|
||||||
// 제어 데이터 소스 타입
|
// 제어 데이터 소스 타입
|
||||||
controlDataSource: ControlDataSource;
|
controlDataSource: ControlDataSource;
|
||||||
|
|
||||||
// 기타 컨텍스트
|
// 기타 컨텍스트
|
||||||
buttonId?: string;
|
buttonId: string;
|
||||||
componentData?: unknown;
|
componentData?: unknown;
|
||||||
timestamp?: string;
|
timestamp: string;
|
||||||
clickCount?: number;
|
clickCount?: number;
|
||||||
|
|
||||||
// 사용자 정보
|
// 사용자 정보
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue