uibee 3.1.2 → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/components/index.d.ts +59 -27
- package/dist/src/components/index.js +819 -336
- package/dist/style.css +283 -67
- package/package.json +1 -1
- package/src/components/index.ts +2 -17
- package/src/components/navbar/navbar.tsx +0 -5
- package/src/components/navbar/navbarDropdown.tsx +0 -2
- package/src/components/navbar/navbarItem.tsx +0 -2
- package/src/components/table/body.tsx +260 -153
- package/src/components/table/constants.ts +53 -0
- package/src/components/table/empty.tsx +31 -0
- package/src/components/table/format.ts +29 -22
- package/src/components/table/header.tsx +115 -70
- package/src/components/table/menu.tsx +43 -27
- package/src/components/table/pagination.tsx +162 -136
- package/src/components/table/skeleton.tsx +56 -0
- package/src/components/table/table.tsx +261 -34
- package/src/components/table/types.ts +94 -0
- package/src/components/table/utils.ts +12 -0
- package/src/components/toggle/theme.tsx +0 -3
- package/src/globals.css +11 -0
- package/src/utils/auth/callback.ts +0 -2
- package/src/utils/index.ts +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as useClickOutside } from "../../useClickOutside-Cmp-RsP3.js";
|
|
2
|
+
import { t as useClickOutside$1 } from "../../useClickOutside-Cmp-RsP3.js";
|
|
3
3
|
import { D as Facebook, Kt as Wikijs, N as Github, W as Linkedin, x as Discord } from "../../icons-lZYQ6Vlr.js";
|
|
4
|
-
import React, { createContext, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
|
-
import { AlertCircle, AlertTriangle, ArrowUpRight, Calendar, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, CircleAlert, CircleHelp, Clock, EllipsisVertical, ExternalLink, Eye, Globe, Info, LogIn, LogOut, Pencil, Search, TriangleAlert, User, X } from "lucide-react";
|
|
4
|
+
import React, { Suspense, createContext, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { AlertCircle, AlertTriangle, ArrowUpRight, Calendar, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, ChevronsUpDown, CircleAlert, CircleHelp, Clock, EllipsisVertical, ExternalLink, Eye, Globe, Info, LogIn, LogOut, Pencil, Search, TableIcon, TriangleAlert, User, X } from "lucide-react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import Markdown from "react-markdown";
|
|
8
8
|
import remarkGfm from "remark-gfm";
|
|
@@ -651,7 +651,7 @@ function Input(props) {
|
|
|
651
651
|
const [isOpen, setIsOpen] = useState(false);
|
|
652
652
|
const anchorName = `--input-${useId().replace(/:/g, "")}`;
|
|
653
653
|
const containerRef = useRef(null);
|
|
654
|
-
useClickOutside(containerRef, () => setIsOpen(false));
|
|
654
|
+
useClickOutside$1(containerRef, () => setIsOpen(false));
|
|
655
655
|
const isDateType = [
|
|
656
656
|
"date",
|
|
657
657
|
"datetime-local",
|
|
@@ -988,7 +988,7 @@ function Select({ label, name, value, onChange, options, error, className, disab
|
|
|
988
988
|
setSelectedOption(options.find((opt) => opt.value === value));
|
|
989
989
|
}, [value, options]);
|
|
990
990
|
const containerRef = useRef(null);
|
|
991
|
-
useClickOutside(containerRef, () => setIsOpen(false));
|
|
991
|
+
useClickOutside$1(containerRef, () => setIsOpen(false));
|
|
992
992
|
function handleSelect(option) {
|
|
993
993
|
if (disabled) return;
|
|
994
994
|
setSelectedOption(option);
|
|
@@ -1200,7 +1200,7 @@ function TagInput({ label, name, value = [], onChange, placeholder = "Add...", e
|
|
|
1200
1200
|
function MultiSelect({ label, name, options, value = [], onChange, placeholder = "Select…", error, className, disabled, required, info, description, textSize = "sm" }) {
|
|
1201
1201
|
const [open, setOpen] = useState(false);
|
|
1202
1202
|
const containerRef = useRef(null);
|
|
1203
|
-
useClickOutside(containerRef, () => setOpen(false));
|
|
1203
|
+
useClickOutside$1(containerRef, () => setOpen(false));
|
|
1204
1204
|
function toggleOption(optionValue) {
|
|
1205
1205
|
if (!onChange) return;
|
|
1206
1206
|
if (value.includes(optionValue)) onChange(value.filter((v) => v !== optionValue));
|
|
@@ -2705,138 +2705,387 @@ function Alert({ children, variant = "warning", className = "" }) {
|
|
|
2705
2705
|
});
|
|
2706
2706
|
}
|
|
2707
2707
|
//#endregion
|
|
2708
|
+
//#region src/components/table/constants.ts
|
|
2709
|
+
const HIGHLIGHT = {
|
|
2710
|
+
green: "bg-green-500/15 text-green-400 ring-1 ring-green-500/25",
|
|
2711
|
+
yellow: "bg-yellow-500/15 text-yellow-400 ring-1 ring-yellow-500/25",
|
|
2712
|
+
red: "bg-red-500/15 text-red-400 ring-1 ring-red-500/25",
|
|
2713
|
+
blue: "bg-blue-500/15 text-blue-400 ring-1 ring-blue-500/25",
|
|
2714
|
+
gray: "bg-gray-500/15 text-gray-400 ring-1 ring-gray-500/25",
|
|
2715
|
+
orange: "bg-orange-500/15 text-orange-400 ring-1 ring-orange-500/25",
|
|
2716
|
+
purple: "bg-purple-500/15 text-purple-400 ring-1 ring-purple-500/25"
|
|
2717
|
+
};
|
|
2718
|
+
const DENSITY_TH = {
|
|
2719
|
+
compact: "px-4 py-2",
|
|
2720
|
+
comfortable: "px-6 py-3",
|
|
2721
|
+
spacious: "px-8 py-4"
|
|
2722
|
+
};
|
|
2723
|
+
const DENSITY_TD = {
|
|
2724
|
+
compact: "px-4 py-1.5",
|
|
2725
|
+
comfortable: "px-6 py-3.5",
|
|
2726
|
+
spacious: "px-8 py-5"
|
|
2727
|
+
};
|
|
2728
|
+
const VARIANT_CONTAINER = {
|
|
2729
|
+
original: "bg-login-500/50 rounded-lg border border-login-600 shadow",
|
|
2730
|
+
modern: "bg-transparent"
|
|
2731
|
+
};
|
|
2732
|
+
const VARIANT_THEAD = {
|
|
2733
|
+
original: "bg-login-700",
|
|
2734
|
+
modern: "bg-transparent border-b border-login-500/40"
|
|
2735
|
+
};
|
|
2736
|
+
const VARIANT_THEAD_TH = {
|
|
2737
|
+
original: "text-login-200",
|
|
2738
|
+
modern: "text-login-300"
|
|
2739
|
+
};
|
|
2740
|
+
const VARIANT_TBODY = {
|
|
2741
|
+
original: "bg-login-500/50 divide-login-600",
|
|
2742
|
+
modern: "divide-login-600/15"
|
|
2743
|
+
};
|
|
2744
|
+
const VARIANT_ROW_HOVER = {
|
|
2745
|
+
original: "hover:bg-login-600/30",
|
|
2746
|
+
modern: "hover:bg-login-700/50"
|
|
2747
|
+
};
|
|
2748
|
+
const VARIANT_ROW_STRIPED = {
|
|
2749
|
+
original: "even:bg-login-600/40",
|
|
2750
|
+
modern: "even:bg-login-800/40"
|
|
2751
|
+
};
|
|
2752
|
+
//#endregion
|
|
2753
|
+
//#region src/components/table/header.tsx
|
|
2754
|
+
function formatLabel(key, label) {
|
|
2755
|
+
if (label) return label;
|
|
2756
|
+
if (key.length <= 2) return key.toUpperCase();
|
|
2757
|
+
return key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replaceAll("_", " ").replaceAll("-", " ").split(/\s+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
2758
|
+
}
|
|
2759
|
+
function Header({ columns, sort, onSort, hasMenu, hasSelect, hasExpand, allSelected, someSelected, onSelectAll, variant, density }) {
|
|
2760
|
+
function handleSort(key) {
|
|
2761
|
+
onSort({
|
|
2762
|
+
column: key,
|
|
2763
|
+
order: sort?.column === key && sort?.order === "asc" ? "desc" : "asc"
|
|
2764
|
+
});
|
|
2765
|
+
}
|
|
2766
|
+
return /* @__PURE__ */ jsx("thead", {
|
|
2767
|
+
className: `block w-full sticky top-0 z-10 ${VARIANT_THEAD[variant]}`,
|
|
2768
|
+
children: /* @__PURE__ */ jsxs("tr", {
|
|
2769
|
+
className: "flex w-full",
|
|
2770
|
+
children: [
|
|
2771
|
+
hasSelect && /* @__PURE__ */ jsx("th", {
|
|
2772
|
+
className: "flex items-center justify-center",
|
|
2773
|
+
style: {
|
|
2774
|
+
width: "3rem",
|
|
2775
|
+
minWidth: "3rem",
|
|
2776
|
+
flexShrink: 0
|
|
2777
|
+
},
|
|
2778
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
2779
|
+
type: "button",
|
|
2780
|
+
"aria-label": allSelected ? "Deselect all" : "Select all",
|
|
2781
|
+
onClick: onSelectAll,
|
|
2782
|
+
className: `
|
|
2783
|
+
h-4 w-4 rounded border flex items-center justify-center transition-colors cursor-pointer
|
|
2784
|
+
${allSelected || someSelected ? "bg-login border-login text-white" : "border-login-400 bg-transparent hover:border-login-200"}
|
|
2785
|
+
`,
|
|
2786
|
+
children: [someSelected && !allSelected && /* @__PURE__ */ jsx("span", { className: "block h-0.5 w-2 bg-white rounded-full" }), allSelected && /* @__PURE__ */ jsx("svg", {
|
|
2787
|
+
className: "h-3 w-3",
|
|
2788
|
+
viewBox: "0 0 12 12",
|
|
2789
|
+
fill: "none",
|
|
2790
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
2791
|
+
d: "M2 6l3 3 5-5",
|
|
2792
|
+
stroke: "currentColor",
|
|
2793
|
+
strokeWidth: "1.5",
|
|
2794
|
+
strokeLinecap: "round",
|
|
2795
|
+
strokeLinejoin: "round"
|
|
2796
|
+
})
|
|
2797
|
+
})]
|
|
2798
|
+
})
|
|
2799
|
+
}),
|
|
2800
|
+
columns.map((col) => {
|
|
2801
|
+
const sortable = col.sortable !== false;
|
|
2802
|
+
const isActive = sort?.column === col.key;
|
|
2803
|
+
const ariaSort = isActive ? sort.order === "asc" ? "ascending" : "descending" : "none";
|
|
2804
|
+
const alignClass = col.align === "right" ? "justify-end" : col.align === "center" ? "justify-center" : "";
|
|
2805
|
+
return /* @__PURE__ */ jsx("th", {
|
|
2806
|
+
"aria-sort": sortable ? ariaSort : void 0,
|
|
2807
|
+
style: col.width ? {
|
|
2808
|
+
width: col.width,
|
|
2809
|
+
flexShrink: 0
|
|
2810
|
+
} : void 0,
|
|
2811
|
+
className: `
|
|
2812
|
+
${col.width ? "" : "flex-1"}
|
|
2813
|
+
text-xs font-medium uppercase tracking-wider
|
|
2814
|
+
${DENSITY_TH[density]} ${VARIANT_THEAD_TH[variant]}
|
|
2815
|
+
`,
|
|
2816
|
+
children: sortable ? /* @__PURE__ */ jsxs("button", {
|
|
2817
|
+
type: "button",
|
|
2818
|
+
className: `group inline-flex items-center gap-1.5 w-full cursor-pointer ${alignClass}`,
|
|
2819
|
+
onClick: () => handleSort(col.key),
|
|
2820
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2821
|
+
className: "whitespace-nowrap",
|
|
2822
|
+
children: formatLabel(col.key, col.label)
|
|
2823
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
2824
|
+
className: "shrink-0 text-current",
|
|
2825
|
+
children: isActive ? sort.order === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-3.5 w-3.5 opacity-0 group-hover:opacity-35 transition-opacity" })
|
|
2826
|
+
})]
|
|
2827
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
2828
|
+
className: `flex w-full ${alignClass}`,
|
|
2829
|
+
children: formatLabel(col.key, col.label)
|
|
2830
|
+
})
|
|
2831
|
+
}, col.key);
|
|
2832
|
+
}),
|
|
2833
|
+
hasExpand && /* @__PURE__ */ jsx("th", {
|
|
2834
|
+
className: "flex items-center justify-center",
|
|
2835
|
+
style: {
|
|
2836
|
+
width: "2.5rem",
|
|
2837
|
+
minWidth: "2.5rem",
|
|
2838
|
+
flexShrink: 0
|
|
2839
|
+
},
|
|
2840
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
2841
|
+
className: `text-xs font-medium tracking-wider uppercase opacity-50 ${VARIANT_THEAD_TH[variant]}`,
|
|
2842
|
+
children: "+"
|
|
2843
|
+
})
|
|
2844
|
+
}),
|
|
2845
|
+
hasMenu && /* @__PURE__ */ jsx("th", {
|
|
2846
|
+
"aria-hidden": "true",
|
|
2847
|
+
style: {
|
|
2848
|
+
width: "3.5rem",
|
|
2849
|
+
minWidth: "3.5rem",
|
|
2850
|
+
flexShrink: 0
|
|
2851
|
+
}
|
|
2852
|
+
})
|
|
2853
|
+
]
|
|
2854
|
+
})
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2857
|
+
//#endregion
|
|
2858
|
+
//#region src/components/table/format.ts
|
|
2859
|
+
const nullableTimeKeys = /* @__PURE__ */ new Set([
|
|
2860
|
+
"date",
|
|
2861
|
+
"last_sent",
|
|
2862
|
+
"sent_at",
|
|
2863
|
+
"time"
|
|
2864
|
+
]);
|
|
2865
|
+
const RX_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
|
|
2866
|
+
const RX_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
2867
|
+
const RX_TIME = /^\d{2}:\d{2}(:\d{2})?$/;
|
|
2868
|
+
function formatValue(key, value) {
|
|
2869
|
+
if (value === null || value === void 0) return nullableTimeKeys.has(key) ? "Never" : "-";
|
|
2870
|
+
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
2871
|
+
if (typeof value === "number") {
|
|
2872
|
+
if (key.includes("capacity") && value === 0) return "Unlimited";
|
|
2873
|
+
return value;
|
|
2874
|
+
}
|
|
2875
|
+
if (typeof value === "string") {
|
|
2876
|
+
if (RX_DATETIME.test(value)) return new Date(value).toLocaleString("nb-NO", {
|
|
2877
|
+
timeZone: "Europe/Oslo",
|
|
2878
|
+
year: "numeric",
|
|
2879
|
+
month: "2-digit",
|
|
2880
|
+
day: "2-digit",
|
|
2881
|
+
hour: "2-digit",
|
|
2882
|
+
minute: "2-digit"
|
|
2883
|
+
});
|
|
2884
|
+
if (RX_DATE.test(value)) return new Date(value).toLocaleDateString("nb-NO", { timeZone: "Europe/Oslo" });
|
|
2885
|
+
if (RX_TIME.test(value)) return (/* @__PURE__ */ new Date(`1970-01-01T${value}`)).toLocaleTimeString("nb-NO", {
|
|
2886
|
+
timeZone: "Europe/Oslo",
|
|
2887
|
+
hour: "2-digit",
|
|
2888
|
+
minute: "2-digit"
|
|
2889
|
+
});
|
|
2890
|
+
return value;
|
|
2891
|
+
}
|
|
2892
|
+
if (Array.isArray(value)) return value.join(", ");
|
|
2893
|
+
return String(value);
|
|
2894
|
+
}
|
|
2895
|
+
//#endregion
|
|
2896
|
+
//#region src/components/table/utils.ts
|
|
2897
|
+
function resolveId(row, idKey, columns) {
|
|
2898
|
+
if (idKey && row[idKey] !== void 0) return String(row[idKey]);
|
|
2899
|
+
if (row["id"] !== void 0) return String(row["id"]);
|
|
2900
|
+
const firstKey = columns[0]?.key ?? Object.keys(row)[0];
|
|
2901
|
+
return String(row[firstKey] ?? "");
|
|
2902
|
+
}
|
|
2903
|
+
//#endregion
|
|
2708
2904
|
//#region src/components/table/menu.tsx
|
|
2709
|
-
const
|
|
2905
|
+
const MenuCtx = createContext({});
|
|
2710
2906
|
function Menu({ ref, children, anchor, onClose }) {
|
|
2907
|
+
useEffect(() => {
|
|
2908
|
+
function handleKey(e) {
|
|
2909
|
+
if (e.key === "Escape") onClose?.();
|
|
2910
|
+
}
|
|
2911
|
+
window.addEventListener("keydown", handleKey);
|
|
2912
|
+
return () => window.removeEventListener("keydown", handleKey);
|
|
2913
|
+
}, [onClose]);
|
|
2711
2914
|
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
2712
2915
|
ref,
|
|
2916
|
+
role: "menu",
|
|
2917
|
+
"aria-orientation": "vertical",
|
|
2713
2918
|
style: {
|
|
2714
2919
|
top: anchor.top,
|
|
2715
2920
|
right: anchor.right
|
|
2716
2921
|
},
|
|
2717
|
-
className: "fixed
|
|
2718
|
-
children: /* @__PURE__ */ jsx(
|
|
2922
|
+
className: "fixed z-[9999] w-44 overflow-hidden rounded-lg border border-login-500/60 bg-login-600 shadow-xl shadow-black/40",
|
|
2923
|
+
children: /* @__PURE__ */ jsx(MenuCtx.Provider, {
|
|
2719
2924
|
value: { onClose },
|
|
2720
2925
|
children
|
|
2721
2926
|
})
|
|
2722
2927
|
}), document.body);
|
|
2723
2928
|
}
|
|
2724
|
-
function MenuButton({ icon, text, hotKey, onClick, className }) {
|
|
2725
|
-
const { onClose } = useContext(
|
|
2929
|
+
function MenuButton({ icon, text, hotKey, onClick, className = "" }) {
|
|
2930
|
+
const { onClose } = useContext(MenuCtx);
|
|
2726
2931
|
useEffect(() => {
|
|
2727
2932
|
if (!hotKey) return;
|
|
2728
|
-
function
|
|
2933
|
+
function handleKey(e) {
|
|
2934
|
+
const tag = e.target.tagName;
|
|
2935
|
+
if (tag === "INPUT" || tag === "TEXTAREA") return;
|
|
2729
2936
|
if (e.key.toLowerCase() === hotKey.toLowerCase()) {
|
|
2730
2937
|
e.preventDefault();
|
|
2731
2938
|
onClick();
|
|
2732
2939
|
onClose?.();
|
|
2733
2940
|
}
|
|
2734
2941
|
}
|
|
2735
|
-
window.addEventListener("keydown",
|
|
2736
|
-
return () => window.removeEventListener("keydown",
|
|
2942
|
+
window.addEventListener("keydown", handleKey);
|
|
2943
|
+
return () => window.removeEventListener("keydown", handleKey);
|
|
2737
2944
|
}, [
|
|
2738
2945
|
hotKey,
|
|
2739
2946
|
onClick,
|
|
2740
2947
|
onClose
|
|
2741
2948
|
]);
|
|
2742
2949
|
return /* @__PURE__ */ jsxs("button", {
|
|
2950
|
+
role: "menuitem",
|
|
2743
2951
|
onClick: () => {
|
|
2744
2952
|
onClick();
|
|
2745
2953
|
onClose?.();
|
|
2746
2954
|
},
|
|
2747
|
-
className: `
|
|
2748
|
-
|
|
2955
|
+
className: `
|
|
2956
|
+
flex w-full items-center justify-between px-3 py-2 text-sm
|
|
2957
|
+
text-login-75 transition-colors duration-100
|
|
2958
|
+
hover:bg-login-500 focus:bg-login-500 focus:outline-none
|
|
2959
|
+
first:rounded-t-lg last:rounded-b-lg
|
|
2960
|
+
${className}
|
|
2749
2961
|
`,
|
|
2750
|
-
children: [/* @__PURE__ */ jsxs("
|
|
2751
|
-
className: "flex items-center",
|
|
2752
|
-
children: [
|
|
2753
|
-
|
|
2754
|
-
|
|
2962
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
2963
|
+
className: "flex items-center gap-2",
|
|
2964
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2965
|
+
className: "h-4 w-4 shrink-0 flex items-center justify-center",
|
|
2966
|
+
children: icon
|
|
2967
|
+
}), text]
|
|
2968
|
+
}), hotKey && /* @__PURE__ */ jsx("kbd", {
|
|
2969
|
+
className: "font-mono text-xs opacity-40",
|
|
2755
2970
|
children: hotKey
|
|
2756
2971
|
})]
|
|
2757
2972
|
});
|
|
2758
2973
|
}
|
|
2759
2974
|
//#endregion
|
|
2760
|
-
//#region src/components/table/
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
}
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
};
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2975
|
+
//#region src/components/table/body.tsx
|
|
2976
|
+
function useClickOutside(ref, cb, enabled) {
|
|
2977
|
+
useEffect(() => {
|
|
2978
|
+
if (!enabled) return;
|
|
2979
|
+
function handler(e) {
|
|
2980
|
+
if (ref.current && !ref.current.contains(e.target)) cb();
|
|
2981
|
+
}
|
|
2982
|
+
document.addEventListener("mousedown", handler);
|
|
2983
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
2984
|
+
}, [
|
|
2985
|
+
ref,
|
|
2986
|
+
cb,
|
|
2987
|
+
enabled
|
|
2988
|
+
]);
|
|
2989
|
+
}
|
|
2990
|
+
function resolveRedirectUrl(redirectPath, row, id) {
|
|
2991
|
+
if (!redirectPath) return null;
|
|
2992
|
+
const cfg = typeof redirectPath === "string" ? {
|
|
2993
|
+
path: redirectPath,
|
|
2994
|
+
key: void 0
|
|
2995
|
+
} : redirectPath;
|
|
2996
|
+
if (!cfg.path) return null;
|
|
2997
|
+
const rid = cfg.key ? String(row[cfg.key] ?? id) : id;
|
|
2998
|
+
return cfg.path.includes("?") ? `${cfg.path}${rid}` : `${cfg.path}/${rid}`;
|
|
2999
|
+
}
|
|
3000
|
+
function Cell({ col, row, density }) {
|
|
3001
|
+
const value = row[col.key];
|
|
3002
|
+
const shouldTruncate = col.truncate === true;
|
|
3003
|
+
const align = col.align ?? "left";
|
|
3004
|
+
const wrapperAlign = align === "right" ? "text-right" : align === "center" ? "text-center" : "";
|
|
3005
|
+
let content;
|
|
3006
|
+
if (col.render) content = col.render(value, row);
|
|
3007
|
+
else if (col.highlight) {
|
|
3008
|
+
const colorName = col.highlight[String(value)] ?? col.highlight["default"];
|
|
3009
|
+
const formatted = String(formatValue(col.key, value));
|
|
3010
|
+
if (colorName) content = /* @__PURE__ */ jsx("span", {
|
|
3011
|
+
className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${HIGHLIGHT[colorName]}`,
|
|
3012
|
+
children: formatted
|
|
3013
|
+
});
|
|
3014
|
+
else content = /* @__PURE__ */ jsx("span", {
|
|
3015
|
+
className: shouldTruncate ? "block truncate" : "whitespace-nowrap",
|
|
3016
|
+
children: formatted
|
|
3017
|
+
});
|
|
3018
|
+
} else {
|
|
3019
|
+
const formatted = formatValue(col.key, value);
|
|
3020
|
+
content = /* @__PURE__ */ jsx("span", {
|
|
3021
|
+
className: shouldTruncate ? "block truncate" : "whitespace-nowrap",
|
|
3022
|
+
children: formatted === null || formatted === void 0 ? "-" : String(formatted)
|
|
3023
|
+
});
|
|
2787
3024
|
}
|
|
2788
|
-
|
|
2789
|
-
|
|
3025
|
+
return /* @__PURE__ */ jsx("td", {
|
|
3026
|
+
style: col.width ? {
|
|
3027
|
+
width: col.width,
|
|
3028
|
+
flexShrink: 0
|
|
3029
|
+
} : void 0,
|
|
3030
|
+
className: `
|
|
3031
|
+
${col.width ? "" : "flex-1"} min-w-0 flex items-center text-sm text-login-75
|
|
3032
|
+
${DENSITY_TD[density]}
|
|
3033
|
+
`,
|
|
3034
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
3035
|
+
className: `min-w-0 w-full ${wrapperAlign}`,
|
|
3036
|
+
children: content
|
|
3037
|
+
})
|
|
3038
|
+
});
|
|
2790
3039
|
}
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
function Body({ list, columns, menuItems, redirectPath, variant = "default", idKey }) {
|
|
3040
|
+
function Body({ data, columns, idKey, variant, density, striped, redirectPath, onRowClick, renderExpandedRow, selectable, selectedIds, onSelectionChange, menuItems }) {
|
|
3041
|
+
const router = useRouter();
|
|
2794
3042
|
const [openMenuId, setOpenMenuId] = useState(null);
|
|
2795
3043
|
const [anchor, setAnchor] = useState(null);
|
|
2796
|
-
const
|
|
3044
|
+
const [expandedId, setExpandedId] = useState(null);
|
|
2797
3045
|
const menuRef = useRef(null);
|
|
2798
3046
|
const tbodyRef = useRef(null);
|
|
2799
3047
|
const menuWasOpenOnMouseDown = useRef(false);
|
|
2800
|
-
|
|
3048
|
+
const closeMenu = useCallback(() => setOpenMenuId(null), []);
|
|
3049
|
+
useClickOutside(menuRef, closeMenu, openMenuId !== null);
|
|
2801
3050
|
useEffect(() => {
|
|
2802
3051
|
const el = tbodyRef.current;
|
|
2803
3052
|
if (!el) return;
|
|
2804
|
-
|
|
2805
|
-
el.
|
|
2806
|
-
|
|
2807
|
-
|
|
3053
|
+
el.addEventListener("scroll", closeMenu);
|
|
3054
|
+
return () => el.removeEventListener("scroll", closeMenu);
|
|
3055
|
+
}, [closeMenu]);
|
|
3056
|
+
function openMenu(id, coords) {
|
|
3057
|
+
setAnchor(coords);
|
|
3058
|
+
setOpenMenuId(id);
|
|
3059
|
+
}
|
|
3060
|
+
const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds]);
|
|
3061
|
+
function toggleSelect(id) {
|
|
3062
|
+
onSelectionChange(selectedSet.has(id) ? selectedIds.filter((s) => s !== id) : [...selectedIds, id]);
|
|
3063
|
+
}
|
|
3064
|
+
const hasMenu = Boolean(menuItems);
|
|
3065
|
+
const hasExpand = Boolean(renderExpandedRow);
|
|
2808
3066
|
return /* @__PURE__ */ jsx("tbody", {
|
|
2809
3067
|
ref: tbodyRef,
|
|
2810
|
-
className: `
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
const
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
};
|
|
2832
|
-
const buttonClass = openMenuId === id ? menuButtonColors.active : menuButtonColors.inactive;
|
|
2833
|
-
return /* @__PURE__ */ jsxs("tr", {
|
|
2834
|
-
className: `
|
|
2835
|
-
flex w-full group/row transition-colors
|
|
2836
|
-
${redirectConfig.path ? "cursor-pointer" : ""}
|
|
2837
|
-
${variant === "default" && redirectConfig.path ? "hover:bg-login-600/80" : ""}
|
|
2838
|
-
${variant === "minimal" ? "hover:bg-login-600/70 border-b border-login-600/20 last:border-0" : ""}
|
|
2839
|
-
`,
|
|
3068
|
+
className: `block overflow-y-auto flex-1 min-h-0 divide-y ${VARIANT_TBODY[variant]}`,
|
|
3069
|
+
children: data.map((row, rowIdx) => {
|
|
3070
|
+
const id = resolveId(row, idKey, columns);
|
|
3071
|
+
const url = resolveRedirectUrl(redirectPath, row, id);
|
|
3072
|
+
const isClickable = Boolean(url || onRowClick || hasExpand);
|
|
3073
|
+
const isMenuOpen = openMenuId === id;
|
|
3074
|
+
const isExpanded = expandedId === id;
|
|
3075
|
+
const isSelected = selectable && selectedSet.has(id);
|
|
3076
|
+
const expandedContent = renderExpandedRow?.(row);
|
|
3077
|
+
const rowClass = [
|
|
3078
|
+
"flex w-full transition-colors duration-100",
|
|
3079
|
+
isClickable ? "cursor-pointer" : "",
|
|
3080
|
+
VARIANT_ROW_HOVER[variant],
|
|
3081
|
+
striped ? VARIANT_ROW_STRIPED[variant] : "",
|
|
3082
|
+
isSelected ? "bg-login/5" : ""
|
|
3083
|
+
].filter(Boolean).join(" ");
|
|
3084
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [/* @__PURE__ */ jsxs("tr", {
|
|
3085
|
+
className: rowClass,
|
|
3086
|
+
onMouseEnter: () => {
|
|
3087
|
+
if (url) router.prefetch(url);
|
|
3088
|
+
},
|
|
2840
3089
|
onMouseDown: () => {
|
|
2841
3090
|
menuWasOpenOnMouseDown.current = openMenuId !== null;
|
|
2842
3091
|
},
|
|
@@ -2845,297 +3094,531 @@ function Body({ list, columns, menuItems, redirectPath, variant = "default", idK
|
|
|
2845
3094
|
menuWasOpenOnMouseDown.current = false;
|
|
2846
3095
|
return;
|
|
2847
3096
|
}
|
|
2848
|
-
if (
|
|
2849
|
-
|
|
3097
|
+
if (hasExpand) {
|
|
3098
|
+
setExpandedId(isExpanded ? null : id);
|
|
3099
|
+
return;
|
|
3100
|
+
}
|
|
3101
|
+
if (onRowClick) {
|
|
3102
|
+
onRowClick(row, id);
|
|
3103
|
+
return;
|
|
3104
|
+
}
|
|
3105
|
+
if (url) router.push(url);
|
|
2850
3106
|
},
|
|
2851
3107
|
onContextMenu: (e) => {
|
|
3108
|
+
if (!hasMenu) return;
|
|
2852
3109
|
e.preventDefault();
|
|
2853
|
-
|
|
3110
|
+
openMenu(id, {
|
|
2854
3111
|
top: e.clientY,
|
|
2855
3112
|
right: window.innerWidth - e.clientX
|
|
2856
3113
|
});
|
|
2857
|
-
setOpenMenuId(id);
|
|
2858
3114
|
},
|
|
2859
|
-
children: [
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
badgeClass = "bg-green-500/20 text-green-400";
|
|
2869
|
-
break;
|
|
2870
|
-
case "yellow":
|
|
2871
|
-
badgeClass = "bg-yellow-500/20 text-yellow-400";
|
|
2872
|
-
break;
|
|
2873
|
-
case "red":
|
|
2874
|
-
badgeClass = "bg-red-500/20 text-red-400";
|
|
2875
|
-
break;
|
|
2876
|
-
case "blue":
|
|
2877
|
-
badgeClass = "bg-blue-500/20 text-blue-400";
|
|
2878
|
-
break;
|
|
2879
|
-
case "gray":
|
|
2880
|
-
badgeClass = "bg-gray-500/20 text-gray-400";
|
|
2881
|
-
break;
|
|
2882
|
-
}
|
|
2883
|
-
badgeClass += " px-2 py-1 rounded";
|
|
2884
|
-
}
|
|
2885
|
-
}
|
|
2886
|
-
return /* @__PURE__ */ jsx("td", {
|
|
2887
|
-
className: `
|
|
2888
|
-
flex-1 min-w-0 px-6 py-4 whitespace-nowrap text-sm flex items-center text-login-100
|
|
2889
|
-
${variant === "minimal" ? "px-4! py-2!" : ""}
|
|
2890
|
-
`,
|
|
2891
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
2892
|
-
className: "relative w-full min-w-0",
|
|
2893
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
2894
|
-
className: `block max-w-full truncate ${badgeClass}`,
|
|
2895
|
-
children: formatValue(col.key, value)
|
|
2896
|
-
})
|
|
2897
|
-
})
|
|
2898
|
-
}, col.key);
|
|
2899
|
-
}), menuItems && /* @__PURE__ */ jsx("td", {
|
|
2900
|
-
className: "shrink-0 w-16 flex flex-row items-center justify-end p-2 px-4\n whitespace-nowrap text-right text-sm font-medium",
|
|
2901
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
2902
|
-
className: "relative",
|
|
2903
|
-
children: [/* @__PURE__ */ jsx("button", {
|
|
3115
|
+
children: [
|
|
3116
|
+
selectable && /* @__PURE__ */ jsx("td", {
|
|
3117
|
+
className: "flex items-center justify-center",
|
|
3118
|
+
style: {
|
|
3119
|
+
width: "3rem",
|
|
3120
|
+
minWidth: "3rem",
|
|
3121
|
+
flexShrink: 0
|
|
3122
|
+
},
|
|
3123
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
2904
3124
|
type: "button",
|
|
2905
|
-
|
|
2906
|
-
|
|
3125
|
+
"aria-label": isSelected ? "Deselect row" : "Select row",
|
|
3126
|
+
"aria-checked": isSelected,
|
|
3127
|
+
role: "checkbox",
|
|
2907
3128
|
onClick: (e) => {
|
|
2908
3129
|
e.stopPropagation();
|
|
2909
|
-
|
|
2910
|
-
const coords = {
|
|
2911
|
-
top: rect.bottom + 4,
|
|
2912
|
-
right: window.innerWidth - rect.right
|
|
2913
|
-
};
|
|
2914
|
-
setAnchor(openMenuId === id ? null : coords);
|
|
2915
|
-
setOpenMenuId(openMenuId === id ? null : id);
|
|
3130
|
+
toggleSelect(id);
|
|
2916
3131
|
},
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
3132
|
+
className: `
|
|
3133
|
+
h-4 w-4 rounded border flex items-center justify-center transition-colors cursor-pointer
|
|
3134
|
+
${isSelected ? "bg-login border-login text-white" : "border-login-400 bg-transparent hover:border-login-100"}
|
|
3135
|
+
`,
|
|
3136
|
+
children: isSelected && /* @__PURE__ */ jsx("svg", {
|
|
3137
|
+
className: "h-3 w-3",
|
|
3138
|
+
viewBox: "0 0 12 12",
|
|
3139
|
+
fill: "none",
|
|
3140
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
3141
|
+
d: "M2 6l3 3 5-5",
|
|
3142
|
+
stroke: "currentColor",
|
|
3143
|
+
strokeWidth: "1.5",
|
|
3144
|
+
strokeLinecap: "round",
|
|
3145
|
+
strokeLinejoin: "round"
|
|
3146
|
+
})
|
|
2920
3147
|
})
|
|
2921
|
-
})
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
3148
|
+
})
|
|
3149
|
+
}),
|
|
3150
|
+
columns.map((col) => /* @__PURE__ */ jsx(Cell, {
|
|
3151
|
+
col,
|
|
3152
|
+
row,
|
|
3153
|
+
density
|
|
3154
|
+
}, col.key)),
|
|
3155
|
+
hasExpand && /* @__PURE__ */ jsx("td", {
|
|
3156
|
+
className: "flex items-center justify-center",
|
|
3157
|
+
style: {
|
|
3158
|
+
width: "2.5rem",
|
|
3159
|
+
minWidth: "2.5rem",
|
|
3160
|
+
flexShrink: 0
|
|
3161
|
+
},
|
|
3162
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: `
|
|
3163
|
+
h-4 w-4 transition-transform duration-200
|
|
3164
|
+
${isExpanded ? "rotate-180 text-login" : "text-login-400"}
|
|
3165
|
+
` })
|
|
3166
|
+
}),
|
|
3167
|
+
hasMenu && /* @__PURE__ */ jsx("td", {
|
|
3168
|
+
className: "flex items-center justify-end pr-3",
|
|
3169
|
+
style: {
|
|
3170
|
+
width: "3.5rem",
|
|
3171
|
+
minWidth: "3.5rem",
|
|
3172
|
+
flexShrink: 0
|
|
3173
|
+
},
|
|
3174
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
3175
|
+
className: "relative",
|
|
3176
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
3177
|
+
type: "button",
|
|
3178
|
+
"aria-label": "Row actions",
|
|
3179
|
+
"aria-expanded": isMenuOpen,
|
|
3180
|
+
"aria-haspopup": "menu",
|
|
3181
|
+
onMouseDown: (e) => e.nativeEvent.stopImmediatePropagation(),
|
|
3182
|
+
onClick: (e) => {
|
|
3183
|
+
e.stopPropagation();
|
|
3184
|
+
if (isMenuOpen) setOpenMenuId(null);
|
|
3185
|
+
else {
|
|
3186
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
3187
|
+
openMenu(id, {
|
|
3188
|
+
top: rect.bottom + 4,
|
|
3189
|
+
right: window.innerWidth - rect.right
|
|
3190
|
+
});
|
|
3191
|
+
}
|
|
3192
|
+
},
|
|
3193
|
+
className: `
|
|
3194
|
+
p-1.5 rounded flex items-center justify-center transition-colors
|
|
3195
|
+
${isMenuOpen ? "bg-login-500 text-login-75" : "text-login-300 hover:bg-login-500/60 hover:text-login-75"}
|
|
3196
|
+
`,
|
|
3197
|
+
children: /* @__PURE__ */ jsx(EllipsisVertical, { className: "h-4 w-4" })
|
|
3198
|
+
}), isMenuOpen && anchor && /* @__PURE__ */ jsx(Menu, {
|
|
3199
|
+
ref: menuRef,
|
|
3200
|
+
anchor,
|
|
3201
|
+
onClose: closeMenu,
|
|
3202
|
+
children: menuItems(row, id)
|
|
3203
|
+
})]
|
|
3204
|
+
})
|
|
2927
3205
|
})
|
|
2928
|
-
|
|
2929
|
-
},
|
|
3206
|
+
]
|
|
3207
|
+
}), hasExpand && isExpanded && /* @__PURE__ */ jsx("tr", {
|
|
3208
|
+
className: "flex w-full bg-login-700/25 border-b border-login-600/20",
|
|
3209
|
+
children: /* @__PURE__ */ jsx("td", {
|
|
3210
|
+
className: "w-full px-6 py-4",
|
|
3211
|
+
onClick: (e) => e.stopPropagation(),
|
|
3212
|
+
children: expandedContent
|
|
3213
|
+
})
|
|
3214
|
+
})] }, id + rowIdx);
|
|
2930
3215
|
})
|
|
2931
3216
|
});
|
|
2932
3217
|
}
|
|
2933
3218
|
//#endregion
|
|
2934
|
-
//#region src/components/table/
|
|
2935
|
-
function
|
|
2936
|
-
return
|
|
2937
|
-
}
|
|
2938
|
-
|
|
2939
|
-
const router = useRouter();
|
|
2940
|
-
const pathname = usePathname();
|
|
2941
|
-
const searchParams = useSearchParams();
|
|
2942
|
-
const [column, setColumn] = useState(searchParams.get("column") ?? "");
|
|
2943
|
-
const [order, setOrder] = useState(parseOrder(searchParams.get("order")));
|
|
2944
|
-
useEffect(() => {
|
|
2945
|
-
if (!column || !order) return;
|
|
2946
|
-
const params = new URLSearchParams(searchParams.toString());
|
|
2947
|
-
if (searchParams.get("order") !== order || searchParams.get("column") !== column) {
|
|
2948
|
-
params.set("order", order);
|
|
2949
|
-
params.set("column", column);
|
|
2950
|
-
params.set("page", "1");
|
|
2951
|
-
router.push(`${pathname}?${params.toString()}`);
|
|
2952
|
-
}
|
|
2953
|
-
}, [
|
|
2954
|
-
order,
|
|
2955
|
-
column,
|
|
2956
|
-
pathname,
|
|
2957
|
-
router,
|
|
2958
|
-
searchParams
|
|
2959
|
-
]);
|
|
2960
|
-
function handleChange(key) {
|
|
2961
|
-
setColumn(key);
|
|
2962
|
-
setOrder((prev) => key === column && prev === "asc" ? "desc" : "asc");
|
|
2963
|
-
}
|
|
2964
|
-
return /* @__PURE__ */ jsx("thead", {
|
|
2965
|
-
className: `
|
|
2966
|
-
block w-full
|
|
2967
|
-
${variant === "default" ? "bg-login-700" : "bg-transparent border-b border-login-600"}
|
|
2968
|
-
`,
|
|
2969
|
-
children: /* @__PURE__ */ jsxs("tr", {
|
|
3219
|
+
//#region src/components/table/skeleton.tsx
|
|
3220
|
+
function Skeleton({ columns, rows, variant, density, hasMenu, hasSelect }) {
|
|
3221
|
+
return /* @__PURE__ */ jsx("tbody", {
|
|
3222
|
+
className: `block divide-y divide-login-600/15 ${VARIANT_TBODY[variant]}`,
|
|
3223
|
+
children: Array.from({ length: rows }).map((_, rowIdx) => /* @__PURE__ */ jsxs("tr", {
|
|
2970
3224
|
className: "flex w-full",
|
|
2971
|
-
children: [
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
3225
|
+
children: [
|
|
3226
|
+
hasSelect && /* @__PURE__ */ jsx("td", {
|
|
3227
|
+
className: "flex items-center justify-center",
|
|
3228
|
+
style: {
|
|
3229
|
+
width: "3rem",
|
|
3230
|
+
minWidth: "3rem",
|
|
3231
|
+
flexShrink: 0
|
|
3232
|
+
},
|
|
3233
|
+
children: /* @__PURE__ */ jsx("span", { className: "block h-4 w-4 rounded animate-shimmer" })
|
|
3234
|
+
}),
|
|
3235
|
+
columns.map((col, colIdx) => /* @__PURE__ */ jsx("td", {
|
|
3236
|
+
style: col.width ? {
|
|
3237
|
+
width: col.width,
|
|
3238
|
+
flexShrink: 0
|
|
3239
|
+
} : void 0,
|
|
2975
3240
|
className: `
|
|
2976
|
-
flex-1 min-w-0
|
|
2977
|
-
${
|
|
2978
|
-
${variant === "minimal" ? "px-4!" : ""}
|
|
3241
|
+
flex-1 min-w-0 flex items-center
|
|
3242
|
+
${DENSITY_TD[density]}
|
|
2979
3243
|
`,
|
|
2980
|
-
children: /* @__PURE__ */
|
|
2981
|
-
className: "
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
2987
|
-
className: "flex flex-col",
|
|
2988
|
-
children: column === key ? order === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4 stroke-login-200 opacity-0 group-hover:opacity-100" })
|
|
2989
|
-
})]
|
|
3244
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
3245
|
+
className: "block h-4 rounded animate-shimmer",
|
|
3246
|
+
style: {
|
|
3247
|
+
width: colIdx === 0 ? `${55 + (rowIdx * 17 + colIdx * 31) % 30}%` : `${40 + (rowIdx * 13 + colIdx * 23) % 40}%`,
|
|
3248
|
+
animationDelay: `${(rowIdx * columns.length + colIdx) * 40}ms`
|
|
3249
|
+
}
|
|
2990
3250
|
})
|
|
2991
|
-
}, key)
|
|
2992
|
-
|
|
2993
|
-
|
|
3251
|
+
}, col.key)),
|
|
3252
|
+
hasMenu && /* @__PURE__ */ jsx("td", {
|
|
3253
|
+
className: "flex items-center justify-end pr-3",
|
|
3254
|
+
style: {
|
|
3255
|
+
width: "3.5rem",
|
|
3256
|
+
minWidth: "3.5rem",
|
|
3257
|
+
flexShrink: 0
|
|
3258
|
+
},
|
|
3259
|
+
children: /* @__PURE__ */ jsx("span", { className: "block h-5 w-5 rounded animate-shimmer" })
|
|
3260
|
+
})
|
|
3261
|
+
]
|
|
3262
|
+
}, rowIdx))
|
|
2994
3263
|
});
|
|
2995
3264
|
}
|
|
2996
3265
|
//#endregion
|
|
2997
|
-
//#region src/components/table/
|
|
2998
|
-
function
|
|
2999
|
-
if (
|
|
3000
|
-
className: "
|
|
3001
|
-
children:
|
|
3266
|
+
//#region src/components/table/empty.tsx
|
|
3267
|
+
function Empty({ emptyState }) {
|
|
3268
|
+
if (emptyState) return /* @__PURE__ */ jsx("tbody", {
|
|
3269
|
+
className: "block w-full",
|
|
3270
|
+
children: /* @__PURE__ */ jsx("tr", {
|
|
3271
|
+
className: "flex w-full",
|
|
3272
|
+
children: /* @__PURE__ */ jsx("td", {
|
|
3273
|
+
className: "w-full",
|
|
3274
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
3275
|
+
className: "flex items-center justify-center min-h-[160px] py-8 px-6",
|
|
3276
|
+
children: emptyState
|
|
3277
|
+
})
|
|
3278
|
+
})
|
|
3279
|
+
})
|
|
3002
3280
|
});
|
|
3003
|
-
return /* @__PURE__ */ jsx("
|
|
3004
|
-
className:
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
columns,
|
|
3018
|
-
menuItems,
|
|
3019
|
-
redirectPath,
|
|
3020
|
-
variant,
|
|
3021
|
-
idKey
|
|
3022
|
-
})]
|
|
3281
|
+
return /* @__PURE__ */ jsx("tbody", {
|
|
3282
|
+
className: "block w-full",
|
|
3283
|
+
children: /* @__PURE__ */ jsx("tr", {
|
|
3284
|
+
className: "flex w-full",
|
|
3285
|
+
children: /* @__PURE__ */ jsx("td", {
|
|
3286
|
+
className: "w-full",
|
|
3287
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
3288
|
+
className: "flex flex-col items-center justify-center gap-3 min-h-[160px] py-8 text-login-300",
|
|
3289
|
+
children: [/* @__PURE__ */ jsx(TableIcon, { className: "h-10 w-10 opacity-30" }), /* @__PURE__ */ jsx("span", {
|
|
3290
|
+
className: "text-sm",
|
|
3291
|
+
children: "No data found"
|
|
3292
|
+
})]
|
|
3293
|
+
})
|
|
3294
|
+
})
|
|
3023
3295
|
})
|
|
3024
3296
|
});
|
|
3025
3297
|
}
|
|
3026
3298
|
//#endregion
|
|
3027
3299
|
//#region src/components/table/pagination.tsx
|
|
3028
|
-
function
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
const
|
|
3033
|
-
const
|
|
3034
|
-
const
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
function updateQuery(p) {
|
|
3040
|
-
const params = new URLSearchParams(searchParams.toString());
|
|
3041
|
-
params.set("page", String(p));
|
|
3042
|
-
router.push(`${pathname}?${params.toString()}`);
|
|
3043
|
-
}
|
|
3044
|
-
function goPrevious() {
|
|
3045
|
-
if (current <= 1) return;
|
|
3046
|
-
const next = current - 1;
|
|
3047
|
-
setCurrent(next);
|
|
3048
|
-
updateQuery(next);
|
|
3300
|
+
function computeTotalPages(totalRows, pageSize) {
|
|
3301
|
+
return Math.max(1, pageSize > 0 ? Math.ceil(totalRows / pageSize) : 1);
|
|
3302
|
+
}
|
|
3303
|
+
function pageRange(current, total) {
|
|
3304
|
+
const delta = 2;
|
|
3305
|
+
const left = Math.max(1, current - delta);
|
|
3306
|
+
const right = Math.min(total, current + delta);
|
|
3307
|
+
const pages = [];
|
|
3308
|
+
if (left > 1) {
|
|
3309
|
+
pages.push(1);
|
|
3310
|
+
if (left > 2) pages.push("…");
|
|
3049
3311
|
}
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
updateQuery(next);
|
|
3312
|
+
for (let i = left; i <= right; i++) pages.push(i);
|
|
3313
|
+
if (right < total) {
|
|
3314
|
+
if (right < total - 1) pages.push("…");
|
|
3315
|
+
pages.push(total);
|
|
3055
3316
|
}
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
}
|
|
3070
|
-
for (let i = left; i <= right; i++) pages.push(i);
|
|
3071
|
-
if (right < total) {
|
|
3072
|
-
if (right < total - 1) pages.push("...");
|
|
3073
|
-
pages.push(total);
|
|
3074
|
-
}
|
|
3075
|
-
return pages;
|
|
3076
|
-
}
|
|
3077
|
-
const pages = getPages(current, totalPages);
|
|
3078
|
-
const start = Math.max(1, (current - 1) * pageSize + 1);
|
|
3079
|
-
const end = Math.min(current * pageSize, totalRows !== void 0 ? totalRows : current * pageSize);
|
|
3317
|
+
return pages;
|
|
3318
|
+
}
|
|
3319
|
+
function PaginationShell({ page, totalPages, totalRows, pageSize, onPageChange, variant }) {
|
|
3320
|
+
const start = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
3321
|
+
const end = Math.min(page * pageSize, totalRows);
|
|
3322
|
+
const pages = pageRange(page, totalPages);
|
|
3323
|
+
const btnBase = `
|
|
3324
|
+
flex items-center justify-center rounded-md border text-sm transition-colors duration-100
|
|
3325
|
+
disabled:opacity-35 disabled:cursor-not-allowed
|
|
3326
|
+
`;
|
|
3327
|
+
const btnStyle = variant === "original" ? "border-login-500/50 bg-login-700 hover:bg-login-600 text-login-100" : "border-login-500/40 bg-transparent hover:bg-login-700/60 text-login-100";
|
|
3328
|
+
const pageActive = variant === "original" ? "border-login bg-login/10 text-login" : "border-login text-login bg-transparent";
|
|
3329
|
+
const pageInactive = variant === "original" ? "border-login-500/50 bg-login-700 text-login-100 hover:bg-login-600" : "border-transparent bg-transparent text-login-200 hover:text-login-75 hover:bg-login-700/60";
|
|
3080
3330
|
return /* @__PURE__ */ jsxs("div", {
|
|
3081
|
-
className: "flex items-center justify-between w-full
|
|
3082
|
-
children: [/* @__PURE__ */ jsx("
|
|
3083
|
-
className: "text-
|
|
3084
|
-
children: totalRows
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
end,
|
|
3089
|
-
" of ",
|
|
3090
|
-
totalRows,
|
|
3091
|
-
" results"
|
|
3092
|
-
] }) : null
|
|
3093
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
3094
|
-
className: "flex items-center gap-3",
|
|
3331
|
+
className: "flex items-center justify-between w-full gap-4 flex-wrap",
|
|
3332
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
3333
|
+
className: "text-xs text-login-300 tabular-nums",
|
|
3334
|
+
children: totalRows === 0 ? "No results" : `${start}-${end} of ${totalRows}`
|
|
3335
|
+
}), /* @__PURE__ */ jsxs("nav", {
|
|
3336
|
+
className: "flex items-center gap-1.5",
|
|
3337
|
+
"aria-label": "Pagination",
|
|
3095
3338
|
children: [
|
|
3096
3339
|
/* @__PURE__ */ jsx("button", {
|
|
3097
3340
|
type: "button",
|
|
3098
|
-
|
|
3099
|
-
disabled:
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
border border-login-500/50 text-sm transition-colors duration-150
|
|
3104
|
-
`,
|
|
3105
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5" })
|
|
3106
|
-
}),
|
|
3107
|
-
/* @__PURE__ */ jsx("nav", {
|
|
3108
|
-
className: "flex items-center gap-1",
|
|
3109
|
-
"aria-label": "Pagination",
|
|
3110
|
-
children: pages.map((p, i) => typeof p === "string" ? /* @__PURE__ */ jsx("span", {
|
|
3111
|
-
className: "px-3 py-1 text-sm",
|
|
3112
|
-
children: p
|
|
3113
|
-
}, `e-${i}`) : /* @__PURE__ */ jsx("button", {
|
|
3114
|
-
type: "button",
|
|
3115
|
-
onClick: () => setPage(p),
|
|
3116
|
-
"aria-current": p === current ? "page" : void 0,
|
|
3117
|
-
className: `
|
|
3118
|
-
px-3 py-1 rounded-lg text-sm border transition-colors duration-150
|
|
3119
|
-
${p === current ? "bg-login text-white border-login" : "bg-login-700 border-login-500/50 hover:bg-login-600"}
|
|
3120
|
-
`,
|
|
3121
|
-
children: p
|
|
3122
|
-
}, p))
|
|
3341
|
+
"aria-label": "Previous page",
|
|
3342
|
+
disabled: page <= 1,
|
|
3343
|
+
onClick: () => onPageChange(page - 1),
|
|
3344
|
+
className: `${btnBase} ${btnStyle} h-8 w-8`,
|
|
3345
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
3123
3346
|
}),
|
|
3347
|
+
pages.map((p, i) => p === "…" ? /* @__PURE__ */ jsx("span", {
|
|
3348
|
+
className: "w-8 text-center text-sm text-login-400 select-none",
|
|
3349
|
+
children: "…"
|
|
3350
|
+
}, `ellipsis-${i}`) : /* @__PURE__ */ jsx("button", {
|
|
3351
|
+
type: "button",
|
|
3352
|
+
"aria-current": p === page ? "page" : void 0,
|
|
3353
|
+
onClick: () => onPageChange(p),
|
|
3354
|
+
className: `${btnBase} h-8 min-w-8 px-2 tabular-nums ${p === page ? pageActive : pageInactive}`,
|
|
3355
|
+
children: p
|
|
3356
|
+
}, p)),
|
|
3124
3357
|
/* @__PURE__ */ jsx("button", {
|
|
3125
3358
|
type: "button",
|
|
3126
|
-
|
|
3127
|
-
disabled:
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
border border-login-500/50 text-sm transition-colors duration-150
|
|
3132
|
-
`,
|
|
3133
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5" })
|
|
3359
|
+
"aria-label": "Next page",
|
|
3360
|
+
disabled: page >= totalPages,
|
|
3361
|
+
onClick: () => onPageChange(page + 1),
|
|
3362
|
+
className: `${btnBase} ${btnStyle} h-8 w-8`,
|
|
3363
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
3134
3364
|
})
|
|
3135
3365
|
]
|
|
3136
3366
|
})]
|
|
3137
3367
|
});
|
|
3138
3368
|
}
|
|
3369
|
+
function PaginationLocalState({ totalRows, pageSize, variant = "original" }) {
|
|
3370
|
+
const [page, setPage] = useState(1);
|
|
3371
|
+
return /* @__PURE__ */ jsx(PaginationShell, {
|
|
3372
|
+
page,
|
|
3373
|
+
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3374
|
+
totalRows,
|
|
3375
|
+
pageSize,
|
|
3376
|
+
onPageChange: setPage,
|
|
3377
|
+
variant
|
|
3378
|
+
});
|
|
3379
|
+
}
|
|
3380
|
+
function PaginationURLState({ totalRows, pageSize, variant = "original" }) {
|
|
3381
|
+
const router = useRouter();
|
|
3382
|
+
const pathname = usePathname();
|
|
3383
|
+
const searchParams = useSearchParams();
|
|
3384
|
+
const page = Math.max(1, parseInt(searchParams.get("page") ?? "1", 10) || 1);
|
|
3385
|
+
function onPageChange(p) {
|
|
3386
|
+
const params = new URLSearchParams(searchParams.toString());
|
|
3387
|
+
params.set("page", String(p));
|
|
3388
|
+
router.replace(`${pathname}?${params.toString()}`);
|
|
3389
|
+
}
|
|
3390
|
+
return /* @__PURE__ */ jsx(PaginationShell, {
|
|
3391
|
+
page,
|
|
3392
|
+
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3393
|
+
totalRows,
|
|
3394
|
+
pageSize,
|
|
3395
|
+
onPageChange,
|
|
3396
|
+
variant
|
|
3397
|
+
});
|
|
3398
|
+
}
|
|
3399
|
+
function Pagination(props) {
|
|
3400
|
+
const { totalRows, pageSize, variant = "original", urlState, page, onPageChange } = props;
|
|
3401
|
+
if (urlState) return /* @__PURE__ */ jsx(Suspense, {
|
|
3402
|
+
fallback: /* @__PURE__ */ jsx(PaginationShell, {
|
|
3403
|
+
page: 1,
|
|
3404
|
+
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3405
|
+
totalRows,
|
|
3406
|
+
pageSize,
|
|
3407
|
+
onPageChange: () => {},
|
|
3408
|
+
variant
|
|
3409
|
+
}),
|
|
3410
|
+
children: /* @__PURE__ */ jsx(PaginationURLState, { ...props })
|
|
3411
|
+
});
|
|
3412
|
+
if (page !== void 0 && onPageChange !== void 0) return /* @__PURE__ */ jsx(PaginationShell, {
|
|
3413
|
+
page,
|
|
3414
|
+
totalPages: computeTotalPages(totalRows, pageSize),
|
|
3415
|
+
totalRows,
|
|
3416
|
+
pageSize,
|
|
3417
|
+
onPageChange,
|
|
3418
|
+
variant
|
|
3419
|
+
});
|
|
3420
|
+
return /* @__PURE__ */ jsx(PaginationLocalState, { ...props });
|
|
3421
|
+
}
|
|
3422
|
+
//#endregion
|
|
3423
|
+
//#region src/components/table/table.tsx
|
|
3424
|
+
function TableShell({ data, columns, idKey, variant, density, striped, loading, loadingRows, emptyState, redirectPath, onRowClick, renderExpandedRow, selectable, selectedIds, onSelectionChange, sort, onSort, page, onPageChange, totalRows, pageSize, hidePagination, menuItems, className }) {
|
|
3425
|
+
const allIds = data.map((row) => resolveId(row, idKey, columns));
|
|
3426
|
+
const allIdsSet = useMemo(() => new Set(allIds), [allIds]);
|
|
3427
|
+
const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.includes(id));
|
|
3428
|
+
const someSelected = !allSelected && allIds.some((id) => selectedIds.includes(id));
|
|
3429
|
+
function handleSelectAll() {
|
|
3430
|
+
if (allSelected) onSelectionChange(selectedIds.filter((id) => !allIdsSet.has(id)));
|
|
3431
|
+
else onSelectionChange([.../* @__PURE__ */ new Set([...selectedIds, ...allIds])]);
|
|
3432
|
+
}
|
|
3433
|
+
const isEmpty = !loading && data.length === 0;
|
|
3434
|
+
const showPagination = !hidePagination && pageSize > 0 && totalRows > 0;
|
|
3435
|
+
const hasMenu = Boolean(menuItems);
|
|
3436
|
+
const hasSelect = Boolean(selectable);
|
|
3437
|
+
const hasExpand = Boolean(renderExpandedRow);
|
|
3438
|
+
const paginationPad = variant === "original" ? "px-4 pb-4 pt-3" : "pt-4";
|
|
3439
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3440
|
+
className: [
|
|
3441
|
+
"flex flex-col min-h-0 w-full",
|
|
3442
|
+
VARIANT_CONTAINER[variant],
|
|
3443
|
+
className
|
|
3444
|
+
].filter(Boolean).join(" "),
|
|
3445
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
3446
|
+
className: "flex-1 min-h-0 overflow-x-auto",
|
|
3447
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
3448
|
+
className: "min-w-full w-max flex flex-col flex-1 min-h-0 divide-y divide-login-600/20",
|
|
3449
|
+
children: [/* @__PURE__ */ jsx(Header, {
|
|
3450
|
+
columns,
|
|
3451
|
+
sort,
|
|
3452
|
+
onSort,
|
|
3453
|
+
hasMenu,
|
|
3454
|
+
hasSelect,
|
|
3455
|
+
hasExpand,
|
|
3456
|
+
allSelected,
|
|
3457
|
+
someSelected,
|
|
3458
|
+
onSelectAll: handleSelectAll,
|
|
3459
|
+
variant,
|
|
3460
|
+
density
|
|
3461
|
+
}), loading ? /* @__PURE__ */ jsx(Skeleton, {
|
|
3462
|
+
columns,
|
|
3463
|
+
rows: loadingRows,
|
|
3464
|
+
variant,
|
|
3465
|
+
density,
|
|
3466
|
+
hasMenu,
|
|
3467
|
+
hasSelect
|
|
3468
|
+
}) : isEmpty ? /* @__PURE__ */ jsx(Empty, { emptyState }) : /* @__PURE__ */ jsx(Body, {
|
|
3469
|
+
data,
|
|
3470
|
+
columns,
|
|
3471
|
+
idKey,
|
|
3472
|
+
variant,
|
|
3473
|
+
density,
|
|
3474
|
+
striped,
|
|
3475
|
+
redirectPath,
|
|
3476
|
+
onRowClick,
|
|
3477
|
+
renderExpandedRow,
|
|
3478
|
+
selectable,
|
|
3479
|
+
selectedIds,
|
|
3480
|
+
onSelectionChange,
|
|
3481
|
+
menuItems
|
|
3482
|
+
})]
|
|
3483
|
+
})
|
|
3484
|
+
}), showPagination && /* @__PURE__ */ jsx("div", {
|
|
3485
|
+
className: paginationPad,
|
|
3486
|
+
children: /* @__PURE__ */ jsx(Pagination, {
|
|
3487
|
+
page,
|
|
3488
|
+
totalRows,
|
|
3489
|
+
pageSize,
|
|
3490
|
+
onPageChange,
|
|
3491
|
+
variant
|
|
3492
|
+
})
|
|
3493
|
+
})]
|
|
3494
|
+
});
|
|
3495
|
+
}
|
|
3496
|
+
function useInternalSelection(props) {
|
|
3497
|
+
const [internal, setInternal] = useState([]);
|
|
3498
|
+
return {
|
|
3499
|
+
selectedIds: props.selectedIds ?? internal,
|
|
3500
|
+
onSelectionChange: props.onSelectionChange ?? setInternal
|
|
3501
|
+
};
|
|
3502
|
+
}
|
|
3503
|
+
function applyDefaults(props) {
|
|
3504
|
+
return {
|
|
3505
|
+
variant: props.variant ?? "original",
|
|
3506
|
+
density: props.density ?? "comfortable",
|
|
3507
|
+
selectable: props.selectable ?? false,
|
|
3508
|
+
loading: props.loading ?? false,
|
|
3509
|
+
loadingRows: props.loadingRows ?? props.pageSize ?? 5,
|
|
3510
|
+
striped: props.striped ?? false,
|
|
3511
|
+
hidePagination: props.hidePagination ?? false,
|
|
3512
|
+
pageSize: props.pageSize ?? 0
|
|
3513
|
+
};
|
|
3514
|
+
}
|
|
3515
|
+
function TableLocalState(props) {
|
|
3516
|
+
const defaults = applyDefaults(props);
|
|
3517
|
+
const selection = useInternalSelection(props);
|
|
3518
|
+
const [sort, setSort] = useState(void 0);
|
|
3519
|
+
const [page, setPage] = useState(1);
|
|
3520
|
+
const ps = defaults.pageSize;
|
|
3521
|
+
const allRows = props.data.length;
|
|
3522
|
+
const sorted = useMemo(() => {
|
|
3523
|
+
if (!sort) return props.data;
|
|
3524
|
+
return [...props.data].sort((a, b) => {
|
|
3525
|
+
const av = a[sort.column];
|
|
3526
|
+
const bv = b[sort.column];
|
|
3527
|
+
const cmp = String(av ?? "").localeCompare(String(bv ?? ""), void 0, {
|
|
3528
|
+
numeric: true,
|
|
3529
|
+
sensitivity: "base"
|
|
3530
|
+
});
|
|
3531
|
+
return sort.order === "asc" ? cmp : -cmp;
|
|
3532
|
+
});
|
|
3533
|
+
}, [props.data, sort]);
|
|
3534
|
+
const displayData = ps > 0 ? sorted.slice((page - 1) * ps, page * ps) : sorted;
|
|
3535
|
+
function handleSort(newSort) {
|
|
3536
|
+
setSort(newSort);
|
|
3537
|
+
setPage(1);
|
|
3538
|
+
}
|
|
3539
|
+
return /* @__PURE__ */ jsx(TableShell, {
|
|
3540
|
+
...props,
|
|
3541
|
+
...defaults,
|
|
3542
|
+
...selection,
|
|
3543
|
+
data: displayData,
|
|
3544
|
+
sort,
|
|
3545
|
+
onSort: handleSort,
|
|
3546
|
+
page,
|
|
3547
|
+
onPageChange: setPage,
|
|
3548
|
+
totalRows: ps > 0 ? allRows : props.totalRows ?? allRows
|
|
3549
|
+
});
|
|
3550
|
+
}
|
|
3551
|
+
function TableURLState(props) {
|
|
3552
|
+
const defaults = applyDefaults(props);
|
|
3553
|
+
const selection = useInternalSelection(props);
|
|
3554
|
+
const router = useRouter();
|
|
3555
|
+
const pathname = usePathname();
|
|
3556
|
+
const searchParams = useSearchParams();
|
|
3557
|
+
const urlColumn = searchParams.get("column") ?? "";
|
|
3558
|
+
const urlOrder = searchParams.get("order") ?? "asc";
|
|
3559
|
+
const urlPage = Math.max(1, parseInt(searchParams.get("page") ?? "1", 10) || 1);
|
|
3560
|
+
const sort = urlColumn ? {
|
|
3561
|
+
column: urlColumn,
|
|
3562
|
+
order: urlOrder
|
|
3563
|
+
} : void 0;
|
|
3564
|
+
function handleSort(newSort) {
|
|
3565
|
+
const p = new URLSearchParams(searchParams.toString());
|
|
3566
|
+
p.set("column", newSort.column);
|
|
3567
|
+
p.set("order", newSort.order);
|
|
3568
|
+
p.set("page", "1");
|
|
3569
|
+
router.replace(`${pathname}?${p.toString()}`);
|
|
3570
|
+
}
|
|
3571
|
+
function handlePageChange(newPage) {
|
|
3572
|
+
const p = new URLSearchParams(searchParams.toString());
|
|
3573
|
+
p.set("page", String(newPage));
|
|
3574
|
+
router.replace(`${pathname}?${p.toString()}`);
|
|
3575
|
+
}
|
|
3576
|
+
return /* @__PURE__ */ jsx(TableShell, {
|
|
3577
|
+
...props,
|
|
3578
|
+
...defaults,
|
|
3579
|
+
...selection,
|
|
3580
|
+
sort,
|
|
3581
|
+
onSort: handleSort,
|
|
3582
|
+
page: urlPage,
|
|
3583
|
+
onPageChange: handlePageChange,
|
|
3584
|
+
totalRows: props.totalRows ?? props.data.length
|
|
3585
|
+
});
|
|
3586
|
+
}
|
|
3587
|
+
function TableControlled(props) {
|
|
3588
|
+
const defaults = applyDefaults(props);
|
|
3589
|
+
const selection = useInternalSelection(props);
|
|
3590
|
+
return /* @__PURE__ */ jsx(TableShell, {
|
|
3591
|
+
...props,
|
|
3592
|
+
...defaults,
|
|
3593
|
+
...selection,
|
|
3594
|
+
sort: props.sort,
|
|
3595
|
+
onSort: props.onSort,
|
|
3596
|
+
page: props.page ?? 1,
|
|
3597
|
+
onPageChange: props.onPageChange ?? (() => {}),
|
|
3598
|
+
totalRows: props.totalRows ?? props.data.length
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
function Table(props) {
|
|
3602
|
+
if (props.sort !== void 0 || props.onSort !== void 0) return /* @__PURE__ */ jsx(TableControlled, { ...props });
|
|
3603
|
+
if (props.urlState) {
|
|
3604
|
+
const defaults = applyDefaults(props);
|
|
3605
|
+
return /* @__PURE__ */ jsx(Suspense, {
|
|
3606
|
+
fallback: /* @__PURE__ */ jsx(TableShell, {
|
|
3607
|
+
...props,
|
|
3608
|
+
...defaults,
|
|
3609
|
+
selectedIds: props.selectedIds ?? [],
|
|
3610
|
+
onSelectionChange: props.onSelectionChange ?? (() => {}),
|
|
3611
|
+
sort: void 0,
|
|
3612
|
+
onSort: () => {},
|
|
3613
|
+
page: 1,
|
|
3614
|
+
onPageChange: () => {},
|
|
3615
|
+
totalRows: props.totalRows ?? props.data.length
|
|
3616
|
+
}),
|
|
3617
|
+
children: /* @__PURE__ */ jsx(TableURLState, { ...props })
|
|
3618
|
+
});
|
|
3619
|
+
}
|
|
3620
|
+
return /* @__PURE__ */ jsx(TableLocalState, { ...props });
|
|
3621
|
+
}
|
|
3139
3622
|
//#endregion
|
|
3140
3623
|
//#region src/components/confirm/confirmPopup.tsx
|
|
3141
3624
|
function ConfirmPopup({ isOpen, header, description, confirmText = "Confirm", cancelText = "Cancel", onConfirm, onCancel, variant = "default" }) {
|