feat: 관리자 페이지 레이아웃 통일 및 JSX 구문 수정

- admin/screenMng, dataflow 페이지에 tableMng 레퍼런스 레이아웃 적용
- admin/standards 페이지 JSX 괄호 문제 수정
- 전체 관리자 페이지 UI 일관성 향상
- bg-gray-50 배경, container 구조, 통일된 제목 스타일 적용
This commit is contained in:
leeheejin
2025-09-24 18:07:36 +09:00
parent 3c839a56bf
commit 1a60177fe4
62 changed files with 1173 additions and 677 deletions

View File

@@ -22,7 +22,7 @@ interface SingleTableWithStickyProps {
renderCheckboxCell: (row: any, index: number) => React.ReactNode;
formatCellValue: (value: any, format?: string, columnName?: string) => string;
getColumnWidth: (column: ColumnConfig) => number;
joinColumnMapping: Record<string, string>; // 조인 컬럼 매핑 추가
containerWidth?: string; // 컨테이너 너비 설정
}
export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
@@ -40,13 +40,28 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
renderCheckboxCell,
formatCellValue,
getColumnWidth,
joinColumnMapping,
containerWidth,
}) => {
const checkboxConfig = tableConfig.checkbox || {};
return (
<div className="relative h-full w-full overflow-auto">
<Table className="w-full">
<div
className="relative h-full overflow-auto"
style={{
width: "100%",
maxWidth: "100%",
boxSizing: "border-box",
}}
>
<Table
className="w-full"
style={{
width: "100%",
maxWidth: "100%",
tableLayout: "fixed",
boxSizing: "border-box",
}}
>
<TableHeader className={tableConfig.stickyHeader ? "sticky top-0 z-20 bg-white" : ""}>
<TableRow>
{visibleColumns.map((column, colIndex) => {
@@ -66,7 +81,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
return (
<TableHead
key={`sticky-header-${colIndex}-${column.columnName}`}
key={column.columnName}
className={cn(
column.columnName === "__checkbox__"
? "h-10 border-b px-4 py-2 text-center align-middle"
@@ -83,6 +98,9 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
width: getColumnWidth(column),
minWidth: getColumnWidth(column),
maxWidth: getColumnWidth(column),
boxSizing: "border-box",
overflow: "hidden",
textOverflow: "ellipsis",
// sticky 위치 설정
...(column.fixed === "left" && { left: leftFixedWidth }),
...(column.fixed === "right" && { right: rightFixedWidth }),
@@ -92,7 +110,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
<div className="flex items-center gap-2">
{column.columnName === "__checkbox__" ? (
checkboxConfig.selectAll && (
<Checkbox checked={isAllSelected} onCheckedChange={handleSelectAll} aria-label="전체 선택" />
<Checkbox checked={isAllSelected} onCheckedChange={handleSelectAll} aria-label="전체 선택" style={{ zIndex: 1 }} />
)
) : (
<>
@@ -131,7 +149,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
) : (
data.map((row, index) => (
<TableRow
key={`sticky-row-${index}`}
key={`row-${index}`}
className={cn(
"h-10 cursor-pointer border-b leading-none",
tableConfig.tableStyle?.hoverEffect && "hover:bg-gray-50",
@@ -157,7 +175,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
return (
<TableCell
key={`sticky-cell-${index}-${colIndex}-${column.columnName}`}
key={`cell-${column.columnName}`}
className={cn(
"h-10 px-4 py-2 align-middle text-sm whitespace-nowrap",
`text-${column.align}`,
@@ -169,6 +187,11 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
minHeight: "40px",
height: "40px",
verticalAlign: "middle",
width: getColumnWidth(column),
boxSizing: "border-box",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
// sticky 위치 설정
...(column.fixed === "left" && { left: leftFixedWidth }),
...(column.fixed === "right" && { right: rightFixedWidth }),
@@ -176,25 +199,7 @@ export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
>
{column.columnName === "__checkbox__"
? renderCheckboxCell(row, index)
: (() => {
// 🎯 매핑된 컬럼명으로 데이터 찾기 (기본 테이블과 동일한 로직)
const mappedColumnName = joinColumnMapping[column.columnName] || column.columnName;
// 조인 컬럼 매핑 정보 로깅
if (column.columnName !== mappedColumnName && index === 0) {
console.log(`🔗 Sticky 조인 컬럼 매핑: ${column.columnName}${mappedColumnName}`);
}
const cellValue = row[mappedColumnName];
if (index === 0) {
// 첫 번째 행만 로그 출력 (디버깅용)
console.log(
`🔍 Sticky 셀 데이터 [${column.columnName}${mappedColumnName}]:`,
cellValue,
);
}
return formatCellValue(cellValue, column.format, column.columnName) || "\u00A0";
})()}
: formatCellValue(row[column.columnName], column.format, column.columnName) || "\u00A0"}
</TableCell>
);
})}

View File

@@ -33,7 +33,13 @@ export const TableListConfigPanel: React.FC<TableListConfigPanelProps> = ({
tableColumns,
}) => {
console.log("🔍 TableListConfigPanel props:", {
config: config?.selectedTable,
config,
configType: typeof config,
configSelectedTable: config?.selectedTable,
configPagination: config?.pagination,
paginationEnabled: config?.pagination?.enabled,
paginationPageSize: config?.pagination?.pageSize,
configKeys: typeof config === 'object' ? Object.keys(config || {}) : 'not object',
screenTableName,
tableColumns: tableColumns?.length,
tableColumnsSample: tableColumns?.[0],
@@ -210,13 +216,25 @@ export const TableListConfigPanel: React.FC<TableListConfigPanelProps> = ({
};
const handleNestedChange = (parentKey: keyof TableListConfig, childKey: string, value: any) => {
console.log("🔧 TableListConfigPanel handleNestedChange:", {
parentKey,
childKey,
value,
parentValue: config[parentKey],
hasOnChange: !!onChange,
onChangeType: typeof onChange,
});
const parentValue = config[parentKey] as any;
onChange({
const newConfig = {
[parentKey]: {
...parentValue,
[childKey]: value,
},
});
};
console.log("📤 TableListConfigPanel onChange 호출:", newConfig);
onChange(newConfig);
};
// 컬럼 추가

View File

@@ -13,9 +13,27 @@ export class TableListRenderer extends AutoRegisteringComponentRenderer {
static componentDefinition = TableListDefinition;
render(): React.ReactElement {
return <TableListComponent {...this.props} renderer={this} />;
return <TableListComponent
{...this.props}
renderer={this}
onConfigChange={this.handleConfigChange}
/>;
}
// 설정 변경 핸들러
protected handleConfigChange = (config: any) => {
console.log("📥 TableListRenderer에서 설정 변경 받음:", config);
// 상위 컴포넌트의 onConfigChange 호출 (화면 설계자에게 알림)
if (this.props.onConfigChange) {
this.props.onConfigChange(config);
} else {
console.log("⚠️ 상위 컴포넌트에서 onConfigChange가 전달되지 않음");
}
this.updateComponent({ config });
};
/**
* 컴포넌트별 특화 메서드들
*/