feat: V2 컴포넌트 설정 스키마 정비 및 화면 복제 기능 개선
- 레거시 컴포넌트를 제거하고, V2/V2 컴포넌트 전용 Zod 스키마와 기본값 레지스트리를 통합 관리합니다. - V2 컴포넌트의 overrides 스키마를 정의하고, 관련된 설정 패널을 통합하였습니다. - 화면 복제 기능을 개선하여 DB 구조 개편 후의 효율적인 화면 관리를 지원하며, 버튼의 `targetScreenId` 매핑 버그를 수정하였습니다. - 프리뷰 모드에서 URL 파라미터의 company_code를 우선 사용하도록 변경하였습니다. - UnifiedRepeater 및 UnifiedSelect 컴포넌트를 추가하여 다양한 데이터 관리 기능을 지원합니다.
This commit is contained in:
@@ -1062,7 +1062,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
|
||||
// 부모 컴포넌트에 초기 컬럼 순서 전달
|
||||
if (onSelectedRowsChange && parsedOrder.length > 0) {
|
||||
|
||||
// 초기 데이터도 함께 전달 (컬럼 순서대로 재정렬)
|
||||
const initialData = data.map((row: any) => {
|
||||
const reordered: any = {};
|
||||
@@ -2630,21 +2629,26 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
// 카테고리 매핑된 값 처리
|
||||
if (value !== null && value !== undefined) {
|
||||
const valueStr = String(value);
|
||||
|
||||
|
||||
// 디버그 로그 (카테고리 값인 경우만)
|
||||
if (valueStr.startsWith("CATEGORY_")) {
|
||||
console.log("🔍 [엑셀다운로드] 카테고리 변환 시도:", {
|
||||
columnName: col.columnName,
|
||||
value: valueStr,
|
||||
hasMappings: !!categoryMappings[col.columnName],
|
||||
mappingsKeys: categoryMappings[col.columnName] ? Object.keys(categoryMappings[col.columnName]).slice(0, 5) : [],
|
||||
mappingsKeys: categoryMappings[col.columnName]
|
||||
? Object.keys(categoryMappings[col.columnName]).slice(0, 5)
|
||||
: [],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (categoryMappings[col.columnName]) {
|
||||
// 쉼표로 구분된 중복 값 처리
|
||||
if (valueStr.includes(",")) {
|
||||
const values = valueStr.split(",").map((v) => v.trim()).filter((v) => v);
|
||||
const values = valueStr
|
||||
.split(",")
|
||||
.map((v) => v.trim())
|
||||
.filter((v) => v);
|
||||
const labels = values.map((v) => {
|
||||
const mapping = categoryMappings[col.columnName][v];
|
||||
return mapping ? mapping.label : v;
|
||||
@@ -2657,7 +2661,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
return mapping.label;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -5778,7 +5782,9 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
}}
|
||||
className={cn(
|
||||
"hover:bg-primary/20 ml-1 rounded p-0.5 transition-colors",
|
||||
(headerFilters[column.columnName]?.size > 0 || headerLikeFilters[column.columnName]) && "text-primary bg-primary/10",
|
||||
(headerFilters[column.columnName]?.size > 0 ||
|
||||
headerLikeFilters[column.columnName]) &&
|
||||
"text-primary bg-primary/10",
|
||||
)}
|
||||
title="필터"
|
||||
>
|
||||
@@ -5795,7 +5801,8 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
<span className="text-xs font-medium">
|
||||
필터: {columnLabels[column.columnName] || column.displayName}
|
||||
</span>
|
||||
{(headerFilters[column.columnName]?.size > 0 || headerLikeFilters[column.columnName]) && (
|
||||
{(headerFilters[column.columnName]?.size > 0 ||
|
||||
headerLikeFilters[column.columnName]) && (
|
||||
<button
|
||||
onClick={() => {
|
||||
clearHeaderFilter(column.columnName);
|
||||
@@ -5813,7 +5820,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
</div>
|
||||
{/* LIKE 검색 입력 필드 */}
|
||||
<div className="relative">
|
||||
<Search className="text-muted-foreground absolute left-2 top-1/2 h-3 w-3 -translate-y-1/2" />
|
||||
<Search className="text-muted-foreground absolute top-1/2 left-2 h-3 w-3 -translate-y-1/2" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="검색어 입력 (포함)"
|
||||
@@ -5824,12 +5831,14 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
[column.columnName]: e.target.value,
|
||||
}));
|
||||
}}
|
||||
className="border-input bg-background placeholder:text-muted-foreground h-7 w-full rounded-md border pl-7 pr-2 text-xs focus:outline-none focus:ring-1 focus:ring-primary"
|
||||
className="border-input bg-background placeholder:text-muted-foreground focus:ring-primary h-7 w-full rounded-md border pr-2 pl-7 text-xs focus:ring-1 focus:outline-none"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
</div>
|
||||
{/* 구분선 */}
|
||||
<div className="text-muted-foreground border-t pt-2 text-[10px]">또는 값 선택:</div>
|
||||
<div className="text-muted-foreground border-t pt-2 text-[10px]">
|
||||
또는 값 선택:
|
||||
</div>
|
||||
<div className="max-h-40 space-y-1 overflow-y-auto">
|
||||
{columnUniqueValues[column.columnName]?.slice(0, 50).map((val) => {
|
||||
const isSelected = headerFilters[column.columnName]?.has(val);
|
||||
|
||||
Reference in New Issue
Block a user