refactor: 테이블 리스트 컴포넌트에서 검색 필터 UI 제거
- 테이블 상단 헤더 UI 전체 제거 (AdvancedSearchFilters 영역) - 테이블 옵션, 필터 설정, 그룹 설정 버튼 제거 - 전체 개수 표시 제거 - 검색 필터 로직은 모두 유지 (상태, 함수, localStorage) - 해당 기능은 TableSearchWidget 컴포넌트에서 제공 예정 변경 사유: - 검색 필터 기능을 독립적인 TableSearchWidget으로 분리 - 테이블 컴포넌트와 검색 필터 UI의 관심사 분리 - 재사용 가능한 검색 필터 컴포넌트 구조로 개선
This commit is contained in:
parent
df0929db60
commit
e06f21f63f
|
|
@ -1876,124 +1876,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||||
if (tableConfig.stickyHeader && !isDesignMode) {
|
if (tableConfig.stickyHeader && !isDesignMode) {
|
||||||
return (
|
return (
|
||||||
<div {...domProps}>
|
<div {...domProps}>
|
||||||
{tableConfig.filter?.enabled && (
|
{/* 필터 헤더는 TableSearchWidget으로 이동 */}
|
||||||
<div className="border-border border-b px-4 py-2 sm:px-6 sm:py-2">
|
|
||||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-start sm:gap-3">
|
|
||||||
<div className="flex-1">
|
|
||||||
<AdvancedSearchFilters
|
|
||||||
filters={activeFilters}
|
|
||||||
searchValues={searchValues}
|
|
||||||
onSearchValueChange={handleSearchValueChange}
|
|
||||||
onSearch={handleAdvancedSearch}
|
|
||||||
onClearFilters={handleClearAdvancedFilters}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
{/* 전체 개수 */}
|
|
||||||
<div className="hidden sm:block text-sm text-muted-foreground whitespace-nowrap">
|
|
||||||
전체 <span className="font-semibold text-foreground">{totalItems.toLocaleString()}</span>개
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setIsTableOptionsOpen(true)}
|
|
||||||
className="w-full flex-shrink-0 sm:mt-1 sm:w-auto"
|
|
||||||
>
|
|
||||||
<TableIcon className="mr-2 h-4 w-4" />
|
|
||||||
테이블 옵션
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setIsFilterSettingOpen(true)}
|
|
||||||
className="w-full flex-shrink-0 sm:mt-1 sm:w-auto"
|
|
||||||
>
|
|
||||||
<Settings className="mr-2 h-4 w-4" />
|
|
||||||
필터 설정
|
|
||||||
</Button>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
className="flex-shrink-0 w-full sm:w-auto sm:mt-1"
|
|
||||||
>
|
|
||||||
<Layers className="mr-2 h-4 w-4" />
|
|
||||||
그룹 설정
|
|
||||||
{groupByColumns.length > 0 && (
|
|
||||||
<span className="ml-2 rounded-full bg-primary px-2 py-0.5 text-[10px] font-semibold text-primary-foreground">
|
|
||||||
{groupByColumns.length}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-80 p-0" align="end">
|
|
||||||
<div className="space-y-3 p-4">
|
|
||||||
<div className="space-y-1">
|
|
||||||
<h4 className="text-sm font-semibold">그룹 설정</h4>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
데이터를 그룹화할 컬럼을 선택하세요
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 컬럼 목록 */}
|
|
||||||
<div className="max-h-[300px] space-y-2 overflow-y-auto">
|
|
||||||
{visibleColumns
|
|
||||||
.filter((col) => col.columnName !== "__checkbox__")
|
|
||||||
.map((col) => (
|
|
||||||
<div
|
|
||||||
key={col.columnName}
|
|
||||||
className="flex items-center gap-3 rounded p-2 hover:bg-muted/50"
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
id={`group-dropdown-${col.columnName}`}
|
|
||||||
checked={groupByColumns.includes(col.columnName)}
|
|
||||||
onCheckedChange={() => toggleGroupColumn(col.columnName)}
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
htmlFor={`group-dropdown-${col.columnName}`}
|
|
||||||
className="flex-1 cursor-pointer text-xs font-normal"
|
|
||||||
>
|
|
||||||
{columnLabels[col.columnName] || col.displayName || col.columnName}
|
|
||||||
</Label>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 선택된 그룹 안내 */}
|
|
||||||
{groupByColumns.length > 0 && (
|
|
||||||
<div className="rounded bg-muted/30 p-2 text-xs text-muted-foreground">
|
|
||||||
<span className="font-semibold text-foreground">
|
|
||||||
{groupByColumns.map((col) => columnLabels[col] || col).join(" → ")}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 초기화 버튼 */}
|
|
||||||
{groupByColumns.length > 0 && (
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
setGroupByColumns([]);
|
|
||||||
if (groupSettingKey) {
|
|
||||||
localStorage.removeItem(groupSettingKey);
|
|
||||||
}
|
|
||||||
toast.success("그룹 설정이 초기화되었습니다");
|
|
||||||
}}
|
|
||||||
className="w-full text-xs"
|
|
||||||
>
|
|
||||||
초기화
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 그룹 표시 배지 */}
|
{/* 그룹 표시 배지 */}
|
||||||
{groupByColumns.length > 0 && (
|
{groupByColumns.length > 0 && (
|
||||||
|
|
@ -2056,125 +1939,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div {...domProps}>
|
<div {...domProps}>
|
||||||
{/* 필터 */}
|
{/* 필터 헤더는 TableSearchWidget으로 이동 */}
|
||||||
{tableConfig.filter?.enabled && (
|
|
||||||
<div className="border-border flex-shrink-0 border-b px-4 py-3 sm:px-6 sm:py-4">
|
|
||||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:gap-4">
|
|
||||||
<div className="flex-1">
|
|
||||||
<AdvancedSearchFilters
|
|
||||||
filters={activeFilters}
|
|
||||||
searchValues={searchValues}
|
|
||||||
onSearchValueChange={handleSearchValueChange}
|
|
||||||
onSearch={handleAdvancedSearch}
|
|
||||||
onClearFilters={handleClearAdvancedFilters}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
{/* 전체 개수 */}
|
|
||||||
<div className="hidden sm:block text-sm text-muted-foreground whitespace-nowrap">
|
|
||||||
전체 <span className="font-semibold text-foreground">{totalItems.toLocaleString()}</span>개
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setIsTableOptionsOpen(true)}
|
|
||||||
className="w-full flex-shrink-0 sm:mt-1 sm:w-auto"
|
|
||||||
>
|
|
||||||
<TableIcon className="mr-2 h-4 w-4" />
|
|
||||||
테이블 옵션
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setIsFilterSettingOpen(true)}
|
|
||||||
className="w-full flex-shrink-0 sm:mt-1 sm:w-auto"
|
|
||||||
>
|
|
||||||
<Settings className="mr-2 h-4 w-4" />
|
|
||||||
필터 설정
|
|
||||||
</Button>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
className="flex-shrink-0 w-full sm:w-auto sm:mt-1"
|
|
||||||
>
|
|
||||||
<Layers className="mr-2 h-4 w-4" />
|
|
||||||
그룹 설정
|
|
||||||
{groupByColumns.length > 0 && (
|
|
||||||
<span className="ml-2 rounded-full bg-primary px-2 py-0.5 text-[10px] font-semibold text-primary-foreground">
|
|
||||||
{groupByColumns.length}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-80 p-0" align="end">
|
|
||||||
<div className="space-y-3 p-4">
|
|
||||||
<div className="space-y-1">
|
|
||||||
<h4 className="text-sm font-semibold">그룹 설정</h4>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
데이터를 그룹화할 컬럼을 선택하세요
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 컬럼 목록 */}
|
|
||||||
<div className="max-h-[300px] space-y-2 overflow-y-auto">
|
|
||||||
{visibleColumns
|
|
||||||
.filter((col) => col.columnName !== "__checkbox__")
|
|
||||||
.map((col) => (
|
|
||||||
<div
|
|
||||||
key={col.columnName}
|
|
||||||
className="flex items-center gap-3 rounded p-2 hover:bg-muted/50"
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
id={`group-dropdown-2-${col.columnName}`}
|
|
||||||
checked={groupByColumns.includes(col.columnName)}
|
|
||||||
onCheckedChange={() => toggleGroupColumn(col.columnName)}
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
htmlFor={`group-dropdown-2-${col.columnName}`}
|
|
||||||
className="flex-1 cursor-pointer text-xs font-normal"
|
|
||||||
>
|
|
||||||
{columnLabels[col.columnName] || col.displayName || col.columnName}
|
|
||||||
</Label>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 선택된 그룹 안내 */}
|
|
||||||
{groupByColumns.length > 0 && (
|
|
||||||
<div className="rounded bg-muted/30 p-2 text-xs text-muted-foreground">
|
|
||||||
<span className="font-semibold text-foreground">
|
|
||||||
{groupByColumns.map((col) => columnLabels[col] || col).join(" → ")}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 초기화 버튼 */}
|
|
||||||
{groupByColumns.length > 0 && (
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
setGroupByColumns([]);
|
|
||||||
if (groupSettingKey) {
|
|
||||||
localStorage.removeItem(groupSettingKey);
|
|
||||||
}
|
|
||||||
toast.success("그룹 설정이 초기화되었습니다");
|
|
||||||
}}
|
|
||||||
className="w-full text-xs"
|
|
||||||
>
|
|
||||||
초기화
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 그룹 표시 배지 */}
|
{/* 그룹 표시 배지 */}
|
||||||
{groupByColumns.length > 0 && (
|
{groupByColumns.length > 0 && (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue