260710_1
This commit is contained in:
@@ -100,6 +100,20 @@
|
||||
background: var(--color-paper);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--text-caption);
|
||||
border: 1px solid transparent;
|
||||
cursor: default;
|
||||
transition:
|
||||
background-color var(--transition-base),
|
||||
color var(--transition-base),
|
||||
cursor var(--transition-base);
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step.is-enabled {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step.is-enabled:hover {
|
||||
background: var(--color-paper-hover, var(--color-paper));
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step.is-active {
|
||||
@@ -107,6 +121,28 @@
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step.state-complete {
|
||||
border-color: var(--color-success);
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step.state-in_progress {
|
||||
border-color: var(--color-warning);
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step.state-stale {
|
||||
border-color: var(--color-muted);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.ui-workflow-layout__step.state-failed {
|
||||
border-color: var(--color-danger);
|
||||
}
|
||||
|
||||
.ui-workflow-layout__body {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
import "./ui_template_workflow_layout.css";
|
||||
|
||||
export interface WorkflowStage {
|
||||
stage_no: number;
|
||||
stage_key: string;
|
||||
state: string;
|
||||
}
|
||||
|
||||
export interface WorkflowLayoutOptions {
|
||||
title: string;
|
||||
steps: string[];
|
||||
activeStep: number;
|
||||
leftPanel: HTMLElement;
|
||||
mainContent: HTMLElement;
|
||||
stages?: WorkflowStage[];
|
||||
routes?: string[];
|
||||
onStepClick?: (stepIndex: number, route: string) => void;
|
||||
onMenuToggle?: (isOpen: boolean) => void;
|
||||
onHeaderToggle?: (isVisible: boolean) => void;
|
||||
}
|
||||
@@ -16,15 +25,62 @@ export interface WorkflowLayoutHandle {
|
||||
setHeaderVisible: (isVisible: boolean) => void;
|
||||
}
|
||||
|
||||
function createStepBar(steps: readonly string[], activeStep: number): HTMLElement {
|
||||
function createStepBar(
|
||||
steps: readonly string[],
|
||||
activeStep: number,
|
||||
options?: {
|
||||
stages?: WorkflowStage[];
|
||||
routes?: string[];
|
||||
onStepClick?: (stepIndex: number, route: string) => void;
|
||||
},
|
||||
): HTMLElement {
|
||||
const bar = document.createElement("div");
|
||||
bar.className = "ui-workflow-layout__steps";
|
||||
steps.forEach((step, index) => {
|
||||
const item = document.createElement("span");
|
||||
item.className = "ui-workflow-layout__step";
|
||||
if (index === activeStep) item.classList.add("is-active");
|
||||
item.textContent = step;
|
||||
bar.append(item);
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "ui-workflow-layout__step";
|
||||
if (index === activeStep) button.classList.add("is-active");
|
||||
button.textContent = step;
|
||||
|
||||
// DB state 기반 활성화 로직
|
||||
let enabled = false;
|
||||
if (options?.stages && options.stages.length > 0) {
|
||||
enabled = index === 0 || options.stages[index - 1]?.state === "COMPLETE";
|
||||
} else {
|
||||
enabled = index <= activeStep;
|
||||
}
|
||||
|
||||
button.disabled = !enabled;
|
||||
if (enabled) {
|
||||
button.classList.add("is-enabled");
|
||||
}
|
||||
|
||||
// state 기반 스타일링
|
||||
if (options?.stages && options.stages[index]) {
|
||||
const state = options.stages[index].state;
|
||||
button.classList.add(`state-${state.toLowerCase()}`);
|
||||
if (state === "STALE") {
|
||||
button.title = "Stale (하위 단계 변경으로 무효화됨)";
|
||||
} else if (state === "FAILED") {
|
||||
button.title = "Failed (실패)";
|
||||
} else if (state === "COMPLETE") {
|
||||
button.title = "Complete (완료)";
|
||||
} else if (state === "IN_PROGRESS") {
|
||||
button.title = "In Progress (진행 중)";
|
||||
} else {
|
||||
button.title = "Not Started (미실행)";
|
||||
}
|
||||
}
|
||||
|
||||
// 클릭 이벤트
|
||||
if (enabled && options?.routes && options?.routes[index]) {
|
||||
button.addEventListener("click", () => {
|
||||
options.onStepClick?.(index, options.routes![index]);
|
||||
});
|
||||
}
|
||||
|
||||
bar.append(button);
|
||||
});
|
||||
return bar;
|
||||
}
|
||||
@@ -47,7 +103,14 @@ export function createWorkflowLayout(options: WorkflowLayoutOptions): WorkflowLa
|
||||
const title = document.createElement("h2");
|
||||
title.className = "ui-workflow-layout__title";
|
||||
title.textContent = options.title;
|
||||
titleWrap.append(title, createStepBar(options.steps, options.activeStep));
|
||||
titleWrap.append(
|
||||
title,
|
||||
createStepBar(options.steps, options.activeStep, {
|
||||
stages: options.stages,
|
||||
routes: options.routes,
|
||||
onStepClick: options.onStepClick,
|
||||
}),
|
||||
);
|
||||
|
||||
const headerHideButton = document.createElement("button");
|
||||
headerHideButton.type = "button";
|
||||
|
||||
Reference in New Issue
Block a user