laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
500 lines (499 loc) • 19.7 kB
JavaScript
"use client";
import { jsxs as c, jsx as l } from "react/jsx-runtime";
import { useState as d, useEffect as re, useCallback as S, useMemo as Y, useRef as Le } from "react";
import { useReactTable as Pe, flexRender as _ } from "../../../../node_modules/@tanstack/react-table/build/lib/index.js";
import { useVirtualizer as $e } from "../../../../node_modules/@tanstack/react-virtual/dist/esm/index.js";
import { TableSkeleton as Ae } from "../../table-skeleton.js";
import { TruncatedText as x } from "./truncated-text.js";
import { useDataCrossTable as He } from "./data-cross-table-context.js";
import { cn as V } from "../../../../lib/utils.js";
import { Button as k } from "../../button.js";
import { Icon as q } from "../../icon.js";
import { Popover as Be, PopoverTrigger as Fe, PopoverContent as Oe } from "../../popover.js";
import { getSortedRowModel as We, getCoreRowModel as Ue } from "../../../../node_modules/@tanstack/table-core/build/lib/index.js";
import { Table as ie, TableHeader as ae, TableRow as G, TableHead as ce, TableBody as Xe, TableCell as Ye } from "../../table.js";
function ct({
crossTableData: E,
filterable: v = !1,
loading: de = !1,
emptyComponent: ue,
className: j,
notFoundMessage: fe = "Nessun risultato trovato.",
cornerHeaderFrom: I = "Da",
cornerHeaderTo: K = "A",
minWidthCell: M = 160,
editable: me = !1,
editMode: pe = !1,
onEditModeChange: L,
onSelectedRow: J,
selectedRow: w,
rowSortAsc: he = !0
}) {
const [ge, xe] = d([]), f = E.headerTop, u = E.headerLeft, p = E.data, [b, P] = d(
w?.id ?? null
), [$, A] = d(he), y = He(), [ve, _e] = d(me && pe), [we, be] = d({}), [ye, Ce] = d({}), C = y?.editMode ?? ve, Q = y?.editedCells ?? we, H = y?.setEditedCells ?? be, B = y?.toDefaultCells ?? ye, F = y?.setToDefaultCells ?? Ce;
re(() => {
L && L(!!C);
}, [C, L]), re(() => {
w?.id && P(w.id);
}, [w]);
const [s, Ne] = d(null), [Se, h] = d(!1), [z, T] = d(null), Ve = S(
(t) => {
t && s && T(s.value), h(t);
},
[s]
), ke = S(() => {
s && z !== null ? (H((t) => ({
...t,
[s.cellKey]: {
value: z,
cell: s.cellData
}
})), B[s.cellKey] && F((t) => {
const e = { ...t };
return delete e[s.cellKey], e;
}), setTimeout(() => {
h(!1);
}, 300)) : h(!1);
}, [s, z, B]), ze = S(() => {
s && (T(s.originalValue), H((t) => {
const e = { ...t };
return e[s.cellKey] && delete e[s.cellKey], e;
}), F((t) => {
const e = { ...t };
return e[s.cellKey] && delete e[s.cellKey], e;
})), h(!1);
}, [s]), Te = S(() => {
s && (H((t) => {
const e = { ...t };
return e[s.cellKey] && delete e[s.cellKey], e;
}), F((t) => ({
...t,
[s.cellKey]: {
value: s.originalValue,
cell: s.cellData
}
}))), h(!1);
}, [s]), Re = S(
(t) => {
T(t.target.value);
},
[]
), De = (t) => t && typeof t == "object" && "value" in t ? t.value : t, g = Y(() => {
if (!b || !u.find((o) => o.id === b)) return f;
const e = u.findIndex(
(o) => o.id === b
);
if (e === -1) return f;
const n = f.map((o, i) => {
const r = p[e]?.[i] ?? null, a = De(r);
return { header: o, value: a };
});
return n.sort((o, i) => {
if (typeof o.value == "number" && typeof i.value == "number")
return $ ? o.value - i.value : i.value - o.value;
const r = String(o.value ?? ""), a = String(i.value ?? "");
return $ ? r.localeCompare(a) : a.localeCompare(r);
}), n.map((o) => o.header);
}, [f, u, p, b, $]), Ee = Y(() => {
const t = [
{
id: "cross-header",
header: () => /* @__PURE__ */ c("div", { className: "relative", children: [
/* @__PURE__ */ l("div", { className: "absolute top-0 left-2 text-xs", children: I }),
/* @__PURE__ */ l("div", { className: "absolute right-2 bottom-0 text-xs", children: K })
] }),
accessorFn: (e) => e.item,
cell: (e) => {
const n = e.getValue();
if (!v)
return /* @__PURE__ */ l(x, { text: n.label, className: "w-full" });
const o = b === n.id;
return /* @__PURE__ */ l(
k,
{
variant: "ghost",
size: "sm",
iconLeft: "ArrowLeftRight",
className: "text-right",
onClick: () => {
v && (o ? A((i) => !i) : (P(u[e.row.index].id), A(!0), J && J(u[e.row.index])));
},
children: /* @__PURE__ */ l(x, { text: n.label })
}
);
}
}
];
return g.forEach((e) => {
t.push({
id: e.id,
accessorFn: (n) => n[e.id],
header: ({ column: n }) => v ? /* @__PURE__ */ l(
k,
{
variant: "ghost",
size: "sm",
iconLeft: "ArrowUpDown",
onClick: v ? () => n.toggleSorting(n.getIsSorted() === "asc") : void 0,
children: /* @__PURE__ */ l(
x,
{
text: e.label,
className: "w-full max-w-full min-w-0"
}
)
}
) : /* @__PURE__ */ l(
x,
{
text: e.label,
className: "w-full max-w-full min-w-0 text-center font-medium"
}
),
sortingFn: (n, o, i) => {
let r = n.getValue(i), a = o.getValue(i);
return r == null && a == null ? 0 : r == null ? 1 : a == null ? -1 : (r && typeof r == "object" && "value" in r && (r = r.value), a && typeof a == "object" && "value" in a && (a = a.value), typeof r == "number" && typeof a == "number" ? r - a : String(r).localeCompare(String(a)));
},
cell: (n) => {
const o = n.getValue();
return o ? o.render ? o.render(o.fromId, o.toId, o.id) : /* @__PURE__ */ l("div", { className: "flex h-full w-full min-w-0 items-center justify-center", children: /* @__PURE__ */ l(x, { text: String(o?.value ?? "") }) }) : null;
}
});
}), t;
}, [
g,
I,
K,
w,
v,
P,
A
]), je = Y(() => u.map((t, e) => {
const n = { item: t };
return g.forEach((o) => {
const i = f.findIndex((r) => r.id === o.id);
n[o.id] = i !== -1 ? p[e]?.[i] ?? null : null;
}), n;
}), [u, g, p, f]), R = Pe({
data: je,
columns: Ee,
state: { sorting: ge },
onSortingChange: xe,
getCoreRowModel: Ue(),
getSortedRowModel: We()
}), Z = Le(null), ee = $e({
count: R.getRowModel().rows.length,
getScrollElement: () => Z.current,
estimateSize: () => 40,
overscan: 5,
measureElement: typeof window < "u" ? (t) => t.getBoundingClientRect().height : void 0
});
if (de)
return /* @__PURE__ */ l(
Ae,
{
headerRow: g.map((t) => t.label),
rowCount: u.length || 5,
columnCount: g.length || 5,
className: j,
cornerHeaderFrom: I,
cornerHeaderTo: K
}
);
const te = (t) => {
const e = t.column.id === "cross-header", n = e, o = ["bg-d-secondary"];
e || o.push("border-r"), e && o.push("sticky left-0"), o.push("sticky top-0 z-20"), n ? o.push("z-40") : e && o.push("z-30");
let i = "none";
return e && (i = "inset -1px 0 0 0 var(--d-border), 0 1px 0 0 var(--d-border)"), {
className: o.join(" "),
style: { boxShadow: i, width: `${M}px` }
};
};
return !p || p.length === 0 ? /* @__PURE__ */ c(
"div",
{
className: V(
"flex h-full w-full flex-col overflow-auto",
j ?? ""
),
children: [
/* @__PURE__ */ l(ie, { className: "relative w-full table-fixed border-collapse", children: /* @__PURE__ */ l(
ae,
{
className: "bg-d-secondary sticky top-0 z-20 w-full",
style: { boxShadow: "0 1px 0 0 var(--d-border)" },
children: (R.getHeaderGroups() ?? []).map((t) => /* @__PURE__ */ l(
G,
{
className: "bg-d-secondary sticky top-0 z-20",
children: t.headers.map((e) => {
const n = te(e);
return /* @__PURE__ */ l(
ce,
{
className: n.className,
style: n.style,
children: e.isPlaceholder ? null : _(
e.column.columnDef.header,
e.getContext()
)
},
e.id
);
})
},
t.id
))
}
) }),
/* @__PURE__ */ l("div", { className: "sticky top-0 left-0 flex flex-1", children: ue || fe })
]
}
) : /* @__PURE__ */ c("div", { className: `${V("w-[900px]", j || "")}`, children: [
/* @__PURE__ */ l(
"div",
{
ref: Z,
className: "border-d-border h-fit max-h-full min-h-0 overflow-auto rounded-md border",
children: /* @__PURE__ */ c(ie, { className: "relative w-full table-fixed border-collapse", children: [
/* @__PURE__ */ l(
ae,
{
className: "bg-d-secondary sticky top-0 z-20 w-full",
style: { boxShadow: "0 1px 0 0 var(--d-border)" },
children: R.getHeaderGroups().map((t) => /* @__PURE__ */ l(
G,
{
className: "bg-d-secondary sticky top-0 z-20",
children: t.headers.map((e) => {
const n = te(e);
return /* @__PURE__ */ l(
ce,
{
className: n.className,
style: n.style,
children: e.isPlaceholder ? null : _(
e.column.columnDef.header,
e.getContext()
)
},
e.id
);
})
},
t.id
))
}
),
/* @__PURE__ */ l(
Xe,
{
style: {
height: `${ee.getTotalSize()}px`,
position: "relative",
width: "100%"
},
children: ee.getVirtualItems().map((t) => {
const e = R.getRowModel().rows[t.index];
return /* @__PURE__ */ l(
G,
{
"data-index": t.index,
style: {
position: "absolute",
top: 0,
left: 0,
transform: `translateY(${t.start}px)`,
width: "100%",
height: `${t.size}px`,
display: "flex"
},
children: e.getVisibleCells().map((n, o) => {
const i = o === 0, r = n.getValue(), a = i ? "var(--d-secondary)" : r?.bgColor || "transparent", N = r.editable ?? !0;
return /* @__PURE__ */ l(
Ye,
{
onClick: (m) => {
!N || !C || (m.stopPropagation(), m.preventDefault());
},
className: V(
"border-d-border text-center",
i ? "sticky left-0 z-10" : "border-r",
N && C && "cursor-pointer"
),
style: {
boxShadow: i ? "inset -1px 0 0 0 var(--d-border)" : "none",
backgroundColor: a,
color: r?.textColor || "inherit",
minWidth: `${M}px`,
flex: `1 0 ${M}px`,
display: "flex",
alignItems: "center",
justifyContent: "center"
},
children: i || !C || !r ? (
// Rendering normale per la prima colonna o quando non siamo in modalità edit
_(
n.column.columnDef.cell,
n.getContext()
)
) : (
// Rendering con cella modificabile
(() => {
const m = `${e.index}-${n.column.id}`, D = m in Q ? Q[m].value : r.value || "", Ie = D !== r.value, le = m in B;
return /* @__PURE__ */ l(
"div",
{
className: "flex w-full cursor-pointer items-center justify-center",
onClick: (Ke) => {
const O = Ke.currentTarget.getBoundingClientRect(), oe = 400, ne = 164, W = 8;
let U = O.left + window.scrollX, X = O.bottom + 5;
const se = window.innerWidth, Me = window.innerHeight;
U + oe > se - W && (U = se - oe - W), X + ne > Me - W && (X = O.bottom - ne - 5), Ne({
cellKey: m,
value: D,
originalValue: r.value || "",
cellData: r,
position: { top: X, left: U }
}), T(D), h(!0);
},
children: /* @__PURE__ */ c("div", { className: "relative flex h-full max-h-full w-full max-w-full items-center justify-center gap-1", children: [
Ie && !le && /* @__PURE__ */ l(
"div",
{
className: "bg-d-primary absolute -top-1.5 -left-1.5 rounded p-1",
title: "Valore modificato"
}
),
le && /* @__PURE__ */ l(
"div",
{
className: "bg-d-destructive absolute -top-1.5 -left-1.5 rounded p-1",
title: "Ripristino richiesto"
}
),
/* @__PURE__ */ l("div", { className: "flex min-w-0 flex-1", children: /* @__PURE__ */ l(
"div",
{
className: V(
"h-full min-h-full w-full min-w-full truncate text-center",
N ? "text-d-muted-foreground" : "text-d-muted"
),
children: /* @__PURE__ */ l(
x,
{
text: D,
className: "w-full"
}
)
}
) }),
/* @__PURE__ */ l(
q,
{
name: N ? "Pencil" : "PencilOff",
size: "sm",
className: V(
"h-3 w-3",
N ? "text-d-muted-foreground" : "text-d-muted"
)
}
)
] })
}
);
})()
)
},
n.id
);
})
},
e.id
);
})
}
)
] })
}
),
/* @__PURE__ */ c(Be, { open: Se, onOpenChange: Ve, children: [
/* @__PURE__ */ l(Fe, { asChild: !0, children: /* @__PURE__ */ l("div", { style: { display: "none" } }) }),
/* @__PURE__ */ l(
Oe,
{
className: "w-[400px] p-4",
sideOffset: 5,
style: {
position: "absolute",
top: s?.position?.top ?? 0,
left: s?.position?.left ?? 0,
zIndex: 50
},
children: /* @__PURE__ */ c("div", { className: "space-y-4", children: [
/* @__PURE__ */ c("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ l("div", { className: "font-medium", children: "Modifica valore" }),
s && s.value !== s.originalValue && /* @__PURE__ */ l("div", { className: "text-d-muted-foreground text-xs", children: "Valore modificato" })
] }),
/* @__PURE__ */ l(
"input",
{
type: "text",
className: "bg-d-secondary w-full rounded border p-2",
value: z || "",
onChange: Re,
autoFocus: !0
}
),
/* @__PURE__ */ c("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ c(
k,
{
variant: "destructive",
size: "sm",
onClick: Te,
className: "text-xs",
title: "Ripristina il valore originale e segna la cella come da ripristinare",
children: [
/* @__PURE__ */ l(q, { name: "RotateCcw", className: "mr-1 h-3 w-3" }),
"Ripristina"
]
}
),
/* @__PURE__ */ c("div", { className: "flex space-x-2", children: [
/* @__PURE__ */ l(
k,
{
variant: "ghost",
size: "sm",
onClick: ze,
className: "text-xs",
title: "Annulla le modifiche correnti e chiudi",
children: "Annulla"
}
),
/* @__PURE__ */ c(
k,
{
size: "sm",
onClick: ke,
className: "text-xs",
title: "Conferma le modifiche e salva",
children: [
/* @__PURE__ */ l(q, { name: "Check", className: "mr-1 h-3 w-3" }),
"Conferma"
]
}
)
] })
] })
] })
}
)
] })
] });
}
export {
ct as DataCrossTable
};