밑꺽쇠 수정했음!
This commit is contained in:
parent
e6bb366ec7
commit
62a82b3bcf
|
|
@ -16,6 +16,7 @@ import {
|
|||
PivotAreaType,
|
||||
AggregationType,
|
||||
FieldDataType,
|
||||
DateGroupInterval,
|
||||
} from "./types";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
|
@ -202,6 +203,28 @@ const AreaDropZone: React.FC<AreaDropZoneProps> = ({
|
|||
</Select>
|
||||
)}
|
||||
|
||||
{/* 행/열 영역에서 날짜 타입일 때 그룹화 옵션 */}
|
||||
{(area === "row" || area === "column") && field.dataType === "date" && (
|
||||
<Select
|
||||
value={field.groupInterval || "__none__"}
|
||||
onValueChange={(v) => onUpdateField(idx, {
|
||||
groupInterval: v === "__none__" ? undefined : v as DateGroupInterval
|
||||
})}
|
||||
>
|
||||
<SelectTrigger className="h-6 w-16 text-xs">
|
||||
<SelectValue placeholder="그룹" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="__none__">없음</SelectItem>
|
||||
<SelectItem value="year">년</SelectItem>
|
||||
<SelectItem value="quarter">분기</SelectItem>
|
||||
<SelectItem value="month">월</SelectItem>
|
||||
<SelectItem value="week">주</SelectItem>
|
||||
<SelectItem value="day">일</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
|
|
@ -295,7 +318,8 @@ export const PivotGridConfigPanel: React.FC<PivotGridConfigPanelProps> = ({
|
|||
const mappedColumns: ColumnInfo[] = columnList.map((c: any) => ({
|
||||
column_name: c.columnName || c.column_name,
|
||||
data_type: c.dataType || c.data_type || "text",
|
||||
column_comment: c.columnLabel || c.column_label || c.columnName || c.column_name,
|
||||
// 라벨 우선순위: displayName > comment > columnLabel > columnName
|
||||
column_comment: c.displayName || c.comment || c.columnLabel || c.column_label || c.columnName || c.column_name,
|
||||
}));
|
||||
setColumns(mappedColumns);
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ import {
|
|||
FilterX,
|
||||
LayoutGrid,
|
||||
Trash2,
|
||||
Calendar,
|
||||
Check,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
|
|
@ -132,6 +134,16 @@ const SortableFieldChip: React.FC<FieldChipProps> = ({
|
|||
// 필터 적용 여부 확인
|
||||
const hasFilter = field.filterValues && field.filterValues.length > 0;
|
||||
const filterCount = field.filterValues?.length || 0;
|
||||
|
||||
// 그룹화 상태 확인
|
||||
const hasGrouping = field.groupInterval && field.dataType === "date";
|
||||
const groupLabels: Record<string, string> = {
|
||||
year: "연도",
|
||||
quarter: "분기",
|
||||
month: "월",
|
||||
week: "주",
|
||||
day: "일",
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -169,6 +181,12 @@ const SortableFieldChip: React.FC<FieldChipProps> = ({
|
|||
<span className={cn("font-medium", hasFilter && "text-primary")}>
|
||||
{field.caption}
|
||||
</span>
|
||||
{/* 그룹화 적용 표시 */}
|
||||
{hasGrouping && (
|
||||
<span className="bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300 text-[10px] px-1 rounded">
|
||||
{groupLabels[field.groupInterval!]}
|
||||
</span>
|
||||
)}
|
||||
{/* 필터 적용 개수 배지 */}
|
||||
{hasFilter && (
|
||||
<span className="bg-primary text-primary-foreground text-[10px] px-1 rounded">
|
||||
|
|
@ -224,6 +242,59 @@ const SortableFieldChip: React.FC<FieldChipProps> = ({
|
|||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
{/* 날짜 그룹화 옵션 (행/열 영역의 날짜 타입 필드만) */}
|
||||
{(field.area === "row" || field.area === "column") &&
|
||||
field.dataType === "date" && (
|
||||
<>
|
||||
<div className="px-2 py-1.5 text-xs font-semibold text-muted-foreground flex items-center gap-1">
|
||||
<Calendar className="h-3 w-3" />
|
||||
날짜 그룹화
|
||||
</div>
|
||||
<DropdownMenuItem
|
||||
onClick={() => onSettingsChange?.({ ...field, groupInterval: undefined })}
|
||||
className="pl-6"
|
||||
>
|
||||
{!field.groupInterval && <Check className="h-3 w-3 mr-2" />}
|
||||
<span className={!field.groupInterval ? "font-medium" : ""}>그룹화 없음</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => onSettingsChange?.({ ...field, groupInterval: "year" })}
|
||||
className="pl-6"
|
||||
>
|
||||
{field.groupInterval === "year" && <Check className="h-3 w-3 mr-2" />}
|
||||
<span className={field.groupInterval === "year" ? "font-medium" : ""}>연도별</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => onSettingsChange?.({ ...field, groupInterval: "quarter" })}
|
||||
className="pl-6"
|
||||
>
|
||||
{field.groupInterval === "quarter" && <Check className="h-3 w-3 mr-2" />}
|
||||
<span className={field.groupInterval === "quarter" ? "font-medium" : ""}>분기별</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => onSettingsChange?.({ ...field, groupInterval: "month" })}
|
||||
className="pl-6"
|
||||
>
|
||||
{field.groupInterval === "month" && <Check className="h-3 w-3 mr-2" />}
|
||||
<span className={field.groupInterval === "month" ? "font-medium" : ""}>월별</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => onSettingsChange?.({ ...field, groupInterval: "week" })}
|
||||
className="pl-6"
|
||||
>
|
||||
{field.groupInterval === "week" && <Check className="h-3 w-3 mr-2" />}
|
||||
<span className={field.groupInterval === "week" ? "font-medium" : ""}>주별</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => onSettingsChange?.({ ...field, groupInterval: "day" })}
|
||||
className="pl-6"
|
||||
>
|
||||
{field.groupInterval === "day" && <Check className="h-3 w-3 mr-2" />}
|
||||
<span className={field.groupInterval === "day" ? "font-medium" : ""}>일별</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
onSettingsChange?.({
|
||||
|
|
|
|||
|
|
@ -304,6 +304,7 @@ export interface PivotHeaderNode {
|
|||
level: number; // 깊이
|
||||
children?: PivotHeaderNode[]; // 자식 노드
|
||||
isExpanded: boolean; // 확장 상태
|
||||
hasChildren: boolean; // 자식 존재 가능 여부 (다음 레벨 필드 있음)
|
||||
path: string[]; // 경로 (드릴다운용)
|
||||
subtotal?: PivotCellValue[]; // 소계
|
||||
span?: number; // colspan/rowspan
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ function buildHeaderTree(
|
|||
caption: key,
|
||||
level: 0,
|
||||
isExpanded: expandedPaths.has(pathKey),
|
||||
hasChildren: remainingFields.length > 0, // 다음 레벨 필드가 있으면 자식 있음
|
||||
path: path,
|
||||
span: 1,
|
||||
};
|
||||
|
|
@ -195,6 +196,7 @@ function buildChildNodes(
|
|||
caption: key,
|
||||
level: level,
|
||||
isExpanded: expandedPaths.has(pathKey),
|
||||
hasChildren: remainingFields.length > 0, // 다음 레벨 필드가 있으면 자식 있음
|
||||
path: path,
|
||||
span: 1,
|
||||
};
|
||||
|
|
@ -238,7 +240,7 @@ function flattenRows(nodes: PivotHeaderNode[]): PivotFlatRow[] {
|
|||
level: node.level,
|
||||
caption: node.caption,
|
||||
isExpanded: node.isExpanded,
|
||||
hasChildren: !!(node.children && node.children.length > 0),
|
||||
hasChildren: node.hasChildren, // 노드에서 직접 가져옴 (다음 레벨 필드 존재 여부 기준)
|
||||
});
|
||||
|
||||
if (node.isExpanded && node.children) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue