버튼 수정과 그룹드롭다운, 품목복사기능, 연속입력기능추가
This commit is contained in:
@@ -35,6 +35,11 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { AdvancedSearchFilters } from "@/components/screen/filters/AdvancedSearchFilters";
|
||||
import { SingleTableWithSticky } from "./SingleTableWithSticky";
|
||||
@@ -274,7 +279,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
const [visibleFilterColumns, setVisibleFilterColumns] = useState<Set<string>>(new Set());
|
||||
|
||||
// 그룹 설정 관련 상태
|
||||
const [isGroupSettingOpen, setIsGroupSettingOpen] = useState(false);
|
||||
const [groupByColumns, setGroupByColumns] = useState<string[]>([]);
|
||||
const [collapsedGroups, setCollapsedGroups] = useState<Set<string>>(new Set());
|
||||
|
||||
@@ -1281,17 +1285,14 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
}));
|
||||
}, [visibleColumns, visibleFilterColumns, columnLabels]);
|
||||
|
||||
// 그룹 설정 저장
|
||||
const saveGroupSettings = useCallback(() => {
|
||||
// 그룹 설정 자동 저장 (localStorage)
|
||||
useEffect(() => {
|
||||
if (!groupSettingKey) return;
|
||||
|
||||
try {
|
||||
localStorage.setItem(groupSettingKey, JSON.stringify(groupByColumns));
|
||||
setIsGroupSettingOpen(false);
|
||||
toast.success("그룹 설정이 저장되었습니다");
|
||||
} catch (error) {
|
||||
console.error("그룹 설정 저장 실패:", error);
|
||||
toast.error("설정 저장에 실패했습니다");
|
||||
}
|
||||
}, [groupSettingKey, groupByColumns]);
|
||||
|
||||
@@ -1542,10 +1543,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
>
|
||||
<ChevronsRight className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||
</Button>
|
||||
|
||||
<span className="text-muted-foreground ml-2 text-[10px] sm:ml-4 sm:text-xs">
|
||||
전체 {totalItems.toLocaleString()}개
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* 우측 새로고침 버튼 */}
|
||||
@@ -1607,7 +1604,12 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
onClearFilters={handleClearAdvancedFilters}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<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"
|
||||
@@ -1626,15 +1628,84 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
필터 설정
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setIsGroupSettingOpen(true)}
|
||||
className="w-full flex-shrink-0 sm:mt-1 sm:w-auto"
|
||||
>
|
||||
<Layers 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>
|
||||
@@ -1714,7 +1785,12 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
onClearFilters={handleClearAdvancedFilters}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<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"
|
||||
@@ -1733,15 +1809,84 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
필터 설정
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setIsGroupSettingOpen(true)}
|
||||
className="w-full flex-shrink-0 sm:mt-1 sm:w-auto"
|
||||
>
|
||||
<Layers 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>
|
||||
@@ -2206,68 +2351,6 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* 그룹 설정 다이얼로그 */}
|
||||
<Dialog open={isGroupSettingOpen} onOpenChange={setIsGroupSettingOpen}>
|
||||
<DialogContent className="max-w-[95vw] sm:max-w-[500px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-base sm:text-lg">그룹 설정</DialogTitle>
|
||||
<DialogDescription className="text-xs sm:text-sm">
|
||||
데이터를 그룹화할 컬럼을 선택하세요. 여러 컬럼을 선택하면 계층적으로 그룹화됩니다.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-3 sm:space-y-4">
|
||||
{/* 컬럼 목록 */}
|
||||
<div className="max-h-[50vh] space-y-2 overflow-y-auto rounded border p-2">
|
||||
{visibleColumns
|
||||
.filter((col) => col.columnName !== "__checkbox__")
|
||||
.map((col) => (
|
||||
<div key={col.columnName} className="hover:bg-muted/50 flex items-center gap-3 rounded p-2">
|
||||
<Checkbox
|
||||
id={`group-${col.columnName}`}
|
||||
checked={groupByColumns.includes(col.columnName)}
|
||||
onCheckedChange={() => toggleGroupColumn(col.columnName)}
|
||||
/>
|
||||
<Label
|
||||
htmlFor={`group-${col.columnName}`}
|
||||
className="flex-1 cursor-pointer text-xs font-normal sm:text-sm"
|
||||
>
|
||||
{columnLabels[col.columnName] || col.displayName || col.columnName}
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 선택된 그룹 안내 */}
|
||||
<div className="text-muted-foreground bg-muted/30 rounded p-3 text-xs">
|
||||
{groupByColumns.length === 0 ? (
|
||||
<span>그룹화할 컬럼을 선택하세요</span>
|
||||
) : (
|
||||
<span>
|
||||
선택된 그룹:{" "}
|
||||
<span className="text-primary font-semibold">
|
||||
{groupByColumns.map((col) => columnLabels[col] || col).join(" → ")}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="gap-2 sm:gap-0">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setIsGroupSettingOpen(false)}
|
||||
className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
|
||||
>
|
||||
취소
|
||||
</Button>
|
||||
<Button onClick={saveGroupSettings} className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm">
|
||||
적용
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* 테이블 옵션 모달 */}
|
||||
<TableOptionsModal
|
||||
isOpen={isTableOptionsOpen}
|
||||
|
||||
Reference in New Issue
Block a user