검색 필터기능 수정사항

This commit is contained in:
kjs
2025-09-23 14:26:18 +09:00
parent e653effac0
commit da9985cd24
11 changed files with 1537 additions and 318 deletions

View File

@@ -41,11 +41,12 @@ import {
import { tableTypeApi } from "@/lib/api/screen";
import { commonCodeApi } from "@/lib/api/commonCode";
import { getCurrentUser, UserInfo } from "@/lib/api/client";
import { DataTableComponent, DataTableColumn, DataTableFilter, AttachedFileInfo } from "@/types/screen";
import { DataTableComponent, DataTableColumn, DataTableFilter } from "@/types/screen-legacy-backup";
import { cn } from "@/lib/utils";
import { downloadFile, getLinkedFiles, getFilePreviewUrl, getDirectFileUrl } from "@/lib/api/file";
import { toast } from "sonner";
import { FileUpload } from "@/components/screen/widgets/FileUpload";
import { AdvancedSearchFilters } from "./filters/AdvancedSearchFilters";
// 파일 데이터 타입 정의 (AttachedFileInfo와 호환)
interface FileInfo {
@@ -332,7 +333,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
// 검색 가능한 컬럼만 필터링
const visibleColumns = component.columns?.filter((col: DataTableColumn) => col.visible) || [];
const searchFilters = component.filters || [];
// 컬럼의 실제 웹 타입 정보 찾기
const getColumnWebType = useCallback(
@@ -525,6 +525,11 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
}
}, [component.tableName]);
// 실제 사용할 필터 (설정된 필터만 사용, 자동 생성 안함)
const searchFilters = useMemo(() => {
return component.filters || [];
}, [component.filters]);
// 초기 데이터 로드
useEffect(() => {
loadData(1, searchValues);
@@ -1480,115 +1485,7 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
}
};
// 검색 필터 렌더링
const renderSearchFilter = (filter: DataTableFilter) => {
const value = searchValues[filter.columnName] || "";
switch (filter.widgetType) {
case "text":
case "email":
case "tel":
return (
<Input
key={filter.columnName}
placeholder={`${filter.label} 검색...`}
value={value}
onChange={(e) => handleSearchValueChange(filter.columnName, e.target.value)}
onKeyPress={(e) => {
if (e.key === "Enter") {
handleSearch();
}
}}
/>
);
case "number":
case "decimal":
return (
<Input
key={filter.columnName}
type="number"
placeholder={`${filter.label} 입력...`}
value={value}
onChange={(e) => handleSearchValueChange(filter.columnName, e.target.value)}
onKeyPress={(e) => {
if (e.key === "Enter") {
handleSearch();
}
}}
/>
);
case "date":
return (
<Input
key={filter.columnName}
type="date"
value={value}
onChange={(e) => handleSearchValueChange(filter.columnName, e.target.value)}
/>
);
case "datetime":
return (
<Input
key={filter.columnName}
type="datetime-local"
value={value}
onChange={(e) => handleSearchValueChange(filter.columnName, e.target.value)}
/>
);
case "select":
// TODO: 선택 옵션은 추후 구현
return (
<Select
key={filter.columnName}
value={value}
onValueChange={(newValue) => handleSearchValueChange(filter.columnName, newValue)}
>
<SelectTrigger>
<SelectValue placeholder={`${filter.label} 선택...`} />
</SelectTrigger>
<SelectContent>
<SelectItem value=""></SelectItem>
{/* TODO: 동적 옵션 로드 */}
</SelectContent>
</Select>
);
case "code":
// 코드 타입은 텍스트 검색으로 처리 (코드명으로 검색 가능)
return (
<Input
key={filter.columnName}
placeholder={`${filter.label} 검색... (코드명 또는 코드값)`}
value={value}
onChange={(e) => handleSearchValueChange(filter.columnName, e.target.value)}
onKeyPress={(e) => {
if (e.key === "Enter") {
handleSearch();
}
}}
/>
);
default:
return (
<Input
key={filter.columnName}
placeholder={`${filter.label} 검색...`}
value={value}
onChange={(e) => handleSearchValueChange(filter.columnName, e.target.value)}
onKeyPress={(e) => {
if (e.key === "Enter") {
handleSearch();
}
}}
/>
);
}
};
// 기존 renderSearchFilter 함수는 AdvancedSearchFilters 컴포넌트로 대체됨
// 파일 다운로드
const handleDownloadFile = useCallback(async (fileInfo: FileInfo) => {
@@ -1847,31 +1744,22 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
</div>
</div>
{/* 검색 필터 */}
{searchFilters.length > 0 && (
{/* 검색 필터 - 항상 표시 (컬럼 정보 기반 자동 생성) */}
{tableColumns && tableColumns.length > 0 && (
<>
<Separator className="my-2" />
<div className="space-y-3">
<div className="text-muted-foreground flex items-center gap-2 text-sm">
<Search className="h-3 w-3" />
</div>
<div
className="grid gap-3"
style={{
gridTemplateColumns: searchFilters
.map((filter: DataTableFilter) => `${filter.gridColumns || 3}fr`)
.join(" "),
}}
>
{searchFilters.map((filter: DataTableFilter) => (
<div key={filter.columnName} className="space-y-1">
<label className="text-muted-foreground text-xs font-medium">{filter.label}</label>
{renderSearchFilter(filter)}
</div>
))}
</div>
</div>
<AdvancedSearchFilters
filters={searchFilters.length > 0 ? searchFilters : []}
searchValues={searchValues}
onSearchValueChange={handleSearchValueChange}
onSearch={handleSearch}
onClearFilters={() => {
setSearchValues({});
loadData(1, {});
}}
tableColumns={tableColumns}
tableName={component.tableName}
/>
</>
)}
</div>