first commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
"use client";
|
||||
import { ColumnDef, DataTableLayout } from "ikoncomponents";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { getAllWorkingDays } from "@/app/utils/api/workingDays";
|
||||
|
||||
interface WorkingDaysDetailsData {
|
||||
id: string;
|
||||
year: string;
|
||||
month: string;
|
||||
workingDays: string;
|
||||
}
|
||||
|
||||
function WorkingDaysDetailsTable() {
|
||||
const [workingDaysDetails, setWorkingDaysDetails] = useState<
|
||||
WorkingDaysDetailsData[]
|
||||
>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const fetchWorkingDaysDetailsData = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const workingDayData = await getAllWorkingDays();
|
||||
|
||||
let flatData: WorkingDaysDetailsData[] = [];
|
||||
if (workingDayData?.content) {
|
||||
workingDayData.content.forEach((item: any) => {
|
||||
if (item.workingDaysDetails) {
|
||||
Object.values(item.workingDaysDetails).forEach((yearObj: any) => {
|
||||
Object.values(yearObj).forEach((monthObj: any) => {
|
||||
flatData.push({
|
||||
id: `${monthObj.year}-${monthObj.month}`,
|
||||
year: monthObj.year,
|
||||
month: monthObj.month,
|
||||
workingDays: String(monthObj.workingDays),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setWorkingDaysDetails(flatData);
|
||||
} catch (error) {
|
||||
console.error("Error fetching WorkingDaysDetails data:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Headers must be plain strings: DataTableLayout's grouping resolver maps the
|
||||
// grouped header string back to its accessorKey, and only string headers expose
|
||||
// the drag handle. Function headers (e.g. a centered <div>) can't be grouped.
|
||||
const columns: ColumnDef<WorkingDaysDetailsData>[] = [
|
||||
{
|
||||
accessorKey: "year",
|
||||
header: "Year",
|
||||
},
|
||||
{
|
||||
accessorKey: "month",
|
||||
header: "Month",
|
||||
},
|
||||
{
|
||||
accessorKey: "workingDays",
|
||||
header: "Number of working days",
|
||||
},
|
||||
];
|
||||
|
||||
// DataTableLayout keeps its grouping state internal with no prop to seed it —
|
||||
// grouping is only triggered by dragging a column onto the grouping bar. To
|
||||
// default-group by year, once the table has mounted we synthesise that drop
|
||||
// (a "drop" event carrying columnHeader=Year) on the grouping drop zone once.
|
||||
const tableContainerRef = useRef<HTMLDivElement>(null);
|
||||
const groupedByYear = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchWorkingDaysDetailsData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading || groupedByYear.current) return;
|
||||
|
||||
const container = tableContainerRef.current;
|
||||
if (!container) return;
|
||||
|
||||
// This table is list-only, so hide DataTableLayout's built-in List/Grid
|
||||
// toggle (it has no prop to disable it). Hide the whole toggle group rather
|
||||
// than just the grid button so a lone list button isn't left dangling.
|
||||
const gridButton = container.querySelector<HTMLButtonElement>(
|
||||
'button[title="Grid View"]',
|
||||
);
|
||||
if (gridButton?.parentElement) {
|
||||
gridButton.parentElement.style.display = "none";
|
||||
}
|
||||
|
||||
const dropZone = container.querySelector<HTMLDivElement>(
|
||||
'div[class*="border-dashed"]',
|
||||
);
|
||||
if (!dropZone) return;
|
||||
|
||||
const dataTransfer = new DataTransfer();
|
||||
dataTransfer.setData("columnHeader", "Year");
|
||||
dropZone.dispatchEvent(
|
||||
new DragEvent("drop", { bubbles: true, cancelable: true, dataTransfer }),
|
||||
);
|
||||
groupedByYear.current = true;
|
||||
}, [isLoading]);
|
||||
|
||||
return (
|
||||
<div ref={tableContainerRef} className="p-6 space-y-6">
|
||||
<DataTableLayout
|
||||
columns={columns}
|
||||
data={workingDaysDetails}
|
||||
extraTools={{
|
||||
keyExtractor: (row: WorkingDaysDetailsData) => row.id,
|
||||
totalPages: 1,
|
||||
currentPage: 1,
|
||||
isLoading,
|
||||
onReload: fetchWorkingDaysDetailsData,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default WorkingDaysDetailsTable;
|
||||
Reference in New Issue
Block a user