@universe-platform/ui 0.1.0-beta.10 → 0.1.0-beta.12
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/globals.css +142 -21
- package/dist/index.d.mts +28 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.js +1545 -583
- package/dist/index.mjs +1532 -571
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -68,6 +68,7 @@ __export(src_exports, {
|
|
|
68
68
|
DatePickerCell: () => DatePickerCell,
|
|
69
69
|
LinkPickerCell: () => LinkPickerCell,
|
|
70
70
|
PASTEL_PALETTES: () => PASTEL_PALETTES,
|
|
71
|
+
RelationFilterPopover: () => RelationFilterPopover,
|
|
71
72
|
RelationPickerCell: () => RelationPickerCell,
|
|
72
73
|
TEXT_REPRESENTABLE_TYPES: () => TEXT_REPRESENTABLE_TYPES,
|
|
73
74
|
TableBlock: () => TableBlock,
|
|
@@ -224,7 +225,7 @@ var COLUMN_DEFAULT_INPUT_CONFIG = {
|
|
|
224
225
|
NUMBER: { inputType: "number", placeholder: "\u05D4\u05D6\u05DF \u05DE\u05E1\u05E4\u05E8" },
|
|
225
226
|
BOOLEAN: { inputType: "select" },
|
|
226
227
|
DATE: { inputType: "date" },
|
|
227
|
-
RELATION: { inputType: "
|
|
228
|
+
RELATION: { inputType: "select", placeholder: "\u05D1\u05D7\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D4 \u05DB\u05D1\u05E8\u05D9\u05E8\u05EA \u05DE\u05D7\u05D3\u05DC" },
|
|
228
229
|
GOOGLE_DRIVE_FILE: { inputType: "text" },
|
|
229
230
|
CURRENCY: { inputType: "number", placeholder: "\u05D4\u05D6\u05DF \u05DE\u05E1\u05E4\u05E8" },
|
|
230
231
|
TIME: { inputType: "time" },
|
|
@@ -235,7 +236,7 @@ var COLUMN_DEFAULT_INPUT_CONFIG = {
|
|
|
235
236
|
};
|
|
236
237
|
|
|
237
238
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
238
|
-
var
|
|
239
|
+
var import_react14 = __toESM(require("react"));
|
|
239
240
|
|
|
240
241
|
// src/hooks/useToast.ts
|
|
241
242
|
var import_react2 = require("react");
|
|
@@ -1525,7 +1526,8 @@ function LinkPickerCell({ value, onChange, readOnly = false }) {
|
|
|
1525
1526
|
}
|
|
1526
1527
|
|
|
1527
1528
|
// src/components/TableBlock/fields/RelationPickerCell.tsx
|
|
1528
|
-
var import_react7 = require("react");
|
|
1529
|
+
var import_react7 = __toESM(require("react"));
|
|
1530
|
+
var import_react_dom = require("react-dom");
|
|
1529
1531
|
var import_lucide_react6 = require("lucide-react");
|
|
1530
1532
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1531
1533
|
function isRawObjectId(str) {
|
|
@@ -1584,6 +1586,30 @@ function resolveRelationLabel(opt, column) {
|
|
|
1584
1586
|
}
|
|
1585
1587
|
return "";
|
|
1586
1588
|
}
|
|
1589
|
+
var ITEM_HEIGHT = 35;
|
|
1590
|
+
var CONTAINER_HEIGHT = 200;
|
|
1591
|
+
var OVERSCAN = 5;
|
|
1592
|
+
var BATCH_SIZE = 50;
|
|
1593
|
+
var RelationPickerRow = import_react7.default.memo(function RelationPickerRow2({
|
|
1594
|
+
id,
|
|
1595
|
+
label,
|
|
1596
|
+
isSelected,
|
|
1597
|
+
onSelect,
|
|
1598
|
+
height
|
|
1599
|
+
}) {
|
|
1600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1601
|
+
"div",
|
|
1602
|
+
{
|
|
1603
|
+
onClick: () => onSelect(id),
|
|
1604
|
+
style: { height: `${height}px` },
|
|
1605
|
+
className: `flex items-center justify-between px-2.5 rounded cursor-pointer text-xs transition-colors ${isSelected ? "bg-blue-50 text-blue-900 font-medium" : "hover:bg-slate-50 text-slate-700"}`,
|
|
1606
|
+
children: [
|
|
1607
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate flex-1", children: label }),
|
|
1608
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Check, { className: "w-3.5 h-3.5 text-blue-600 shrink-0 mr-1" })
|
|
1609
|
+
]
|
|
1610
|
+
}
|
|
1611
|
+
);
|
|
1612
|
+
});
|
|
1587
1613
|
function RelationPickerCell({
|
|
1588
1614
|
value,
|
|
1589
1615
|
onChange,
|
|
@@ -1592,42 +1618,147 @@ function RelationPickerCell({
|
|
|
1592
1618
|
rowId,
|
|
1593
1619
|
readOnly = false
|
|
1594
1620
|
}) {
|
|
1595
|
-
var _a;
|
|
1621
|
+
var _a, _b, _c;
|
|
1596
1622
|
const [isOpen, setIsOpen] = (0, import_react7.useState)(false);
|
|
1597
1623
|
const [searchQuery, setSearchQuery] = (0, import_react7.useState)("");
|
|
1624
|
+
const [isRemoteSearching, setIsRemoteSearching] = (0, import_react7.useState)(false);
|
|
1625
|
+
const [isLoadingMore, setIsLoadingMore] = (0, import_react7.useState)(false);
|
|
1626
|
+
const [hasMore, setHasMore] = (0, import_react7.useState)(true);
|
|
1627
|
+
const [items, setItems] = (0, import_react7.useState)([]);
|
|
1628
|
+
const [skip, setSkip] = (0, import_react7.useState)(0);
|
|
1629
|
+
const [scrollTop, setScrollTop] = (0, import_react7.useState)(0);
|
|
1598
1630
|
const containerRef = (0, import_react7.useRef)(null);
|
|
1631
|
+
const dropdownRef = (0, import_react7.useRef)(null);
|
|
1599
1632
|
const searchInputRef = (0, import_react7.useRef)(null);
|
|
1633
|
+
const listContainerRef = (0, import_react7.useRef)(null);
|
|
1634
|
+
const sentinelRef = (0, import_react7.useRef)(null);
|
|
1635
|
+
const [dropdownCoords, setDropdownCoords] = (0, import_react7.useState)(null);
|
|
1636
|
+
const updateDropdownCoords = (0, import_react7.useCallback)(() => {
|
|
1637
|
+
if (!containerRef.current) return;
|
|
1638
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
1639
|
+
const dropdownHeight = 280;
|
|
1640
|
+
const dropdownWidth = Math.max(220, Math.min(320, rect.width || 220));
|
|
1641
|
+
let right = window.innerWidth - rect.right;
|
|
1642
|
+
if (right + dropdownWidth > window.innerWidth - 10) {
|
|
1643
|
+
right = window.innerWidth - dropdownWidth - 10;
|
|
1644
|
+
}
|
|
1645
|
+
if (right < 10) {
|
|
1646
|
+
right = 10;
|
|
1647
|
+
}
|
|
1648
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
1649
|
+
let top = rect.bottom + 4;
|
|
1650
|
+
if (spaceBelow < dropdownHeight && rect.top > dropdownHeight) {
|
|
1651
|
+
top = Math.max(10, rect.top - dropdownHeight - 4);
|
|
1652
|
+
} else {
|
|
1653
|
+
top = Math.min(window.innerHeight - dropdownHeight - 10, top);
|
|
1654
|
+
}
|
|
1655
|
+
setDropdownCoords({ top, right, width: dropdownWidth });
|
|
1656
|
+
}, []);
|
|
1657
|
+
(0, import_react7.useEffect)(() => {
|
|
1658
|
+
if (!isOpen) return;
|
|
1659
|
+
updateDropdownCoords();
|
|
1660
|
+
const handleScrollOrResize = () => updateDropdownCoords();
|
|
1661
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
1662
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
1663
|
+
return () => {
|
|
1664
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
1665
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
1666
|
+
};
|
|
1667
|
+
}, [isOpen, updateDropdownCoords]);
|
|
1668
|
+
const stableLabelCacheRef = (0, import_react7.useRef)(/* @__PURE__ */ new Map());
|
|
1669
|
+
const skipRef = (0, import_react7.useRef)(0);
|
|
1670
|
+
const isLoadingMoreRef = (0, import_react7.useRef)(false);
|
|
1600
1671
|
const allowMultiple = Boolean((_a = column.config) == null ? void 0 : _a.allowMultiple);
|
|
1672
|
+
const referencedTableId = (_b = column.config) == null ? void 0 : _b.referencedTableId;
|
|
1673
|
+
const displayField = (_c = column.config) == null ? void 0 : _c.displayField;
|
|
1601
1674
|
const selectedIds = (0, import_react7.useMemo)(() => normalizeRelationValue(value), [value]);
|
|
1602
1675
|
const isStandalone = !context || context.relationOptions === void 0;
|
|
1603
1676
|
const optionsLoaded = isStandalone || context.relationOptions[column.name] !== void 0;
|
|
1604
|
-
const
|
|
1677
|
+
const baseOptions = (0, import_react7.useMemo)(() => {
|
|
1605
1678
|
var _a2;
|
|
1606
1679
|
return ((_a2 = context == null ? void 0 : context.relationOptions) == null ? void 0 : _a2[column.name]) || [];
|
|
1607
1680
|
}, [context == null ? void 0 : context.relationOptions, column.name]);
|
|
1608
1681
|
const processedOptions = (0, import_react7.useMemo)(() => {
|
|
1609
|
-
return
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
};
|
|
1615
|
-
}).filter((opt) => opt._displayLabel && opt._displayLabel.trim() !== "" && !isRawObjectId(opt._displayLabel));
|
|
1616
|
-
}, [rawOptions, column]);
|
|
1682
|
+
return items.map((opt) => ({
|
|
1683
|
+
id: String(opt.id),
|
|
1684
|
+
_displayLabel: resolveRelationLabel(opt, column) || opt.label || ""
|
|
1685
|
+
})).filter((opt) => opt._displayLabel && opt._displayLabel.trim() !== "" && !isRawObjectId(opt._displayLabel));
|
|
1686
|
+
}, [items, column]);
|
|
1617
1687
|
const getDisplayForId = (0, import_react7.useCallback)((id) => {
|
|
1618
|
-
|
|
1619
|
-
if (
|
|
1620
|
-
|
|
1688
|
+
var _a2, _b2, _c2;
|
|
1689
|
+
if (!id) return "-";
|
|
1690
|
+
const strId = String(id).trim();
|
|
1691
|
+
if (!strId) return "-";
|
|
1692
|
+
if (stableLabelCacheRef.current.has(strId)) {
|
|
1693
|
+
const cached = stableLabelCacheRef.current.get(strId);
|
|
1694
|
+
if (cached && cached !== "-" && !isRawObjectId(cached)) {
|
|
1695
|
+
return cached;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
const dictOpt = (_c2 = (_b2 = (_a2 = context == null ? void 0 : context.relationDictionaryRef) == null ? void 0 : _a2.current) == null ? void 0 : _b2[column.name]) == null ? void 0 : _c2.get(strId);
|
|
1699
|
+
if (dictOpt) {
|
|
1700
|
+
const lbl = resolveRelationLabel(dictOpt, column) || dictOpt.label || dictOpt.name;
|
|
1701
|
+
if (lbl && !isRawObjectId(String(lbl))) {
|
|
1702
|
+
stableLabelCacheRef.current.set(strId, String(lbl));
|
|
1703
|
+
return String(lbl);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
const foundInItems = items.find((o) => String(o.id) === strId);
|
|
1707
|
+
if (foundInItems) {
|
|
1708
|
+
const lbl = resolveRelationLabel(foundInItems, column) || foundInItems.label || foundInItems.name;
|
|
1709
|
+
if (lbl && !isRawObjectId(String(lbl))) {
|
|
1710
|
+
stableLabelCacheRef.current.set(strId, String(lbl));
|
|
1711
|
+
return String(lbl);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
const foundInBase = (baseOptions || []).find((o) => String(o.id) === strId);
|
|
1715
|
+
if (foundInBase) {
|
|
1716
|
+
const lbl = resolveRelationLabel(foundInBase, column) || foundInBase.label || foundInBase.name;
|
|
1717
|
+
if (lbl && !isRawObjectId(String(lbl))) {
|
|
1718
|
+
stableLabelCacheRef.current.set(strId, String(lbl));
|
|
1719
|
+
return String(lbl);
|
|
1720
|
+
}
|
|
1621
1721
|
}
|
|
1622
1722
|
return "-";
|
|
1623
|
-
}, [
|
|
1723
|
+
}, [items, baseOptions, column, context]);
|
|
1624
1724
|
const handleOpen = (e) => {
|
|
1625
1725
|
if (readOnly) return;
|
|
1626
1726
|
e == null ? void 0 : e.stopPropagation();
|
|
1627
|
-
|
|
1727
|
+
const nextOpen = !isOpen;
|
|
1728
|
+
if (nextOpen) {
|
|
1729
|
+
updateDropdownCoords();
|
|
1730
|
+
}
|
|
1731
|
+
setIsOpen(nextOpen);
|
|
1732
|
+
if (!nextOpen) return;
|
|
1628
1733
|
setSearchQuery("");
|
|
1629
|
-
|
|
1630
|
-
|
|
1734
|
+
setScrollTop(0);
|
|
1735
|
+
setSkip(0);
|
|
1736
|
+
skipRef.current = 0;
|
|
1737
|
+
setHasMore(true);
|
|
1738
|
+
const fetcher = (context == null ? void 0 : context.executeAction) ? (p) => context.executeAction("FETCH_RELATION", p) : (context == null ? void 0 : context.refetchRelation) ? (p) => context.refetchRelation(column.name, p) : null;
|
|
1739
|
+
if (fetcher && referencedTableId) {
|
|
1740
|
+
setIsLoadingMore(true);
|
|
1741
|
+
isLoadingMoreRef.current = true;
|
|
1742
|
+
fetcher({
|
|
1743
|
+
referencedTableId,
|
|
1744
|
+
displayField,
|
|
1745
|
+
take: BATCH_SIZE,
|
|
1746
|
+
limit: BATCH_SIZE,
|
|
1747
|
+
skip: 0
|
|
1748
|
+
}).then((res) => {
|
|
1749
|
+
const newData = Array.isArray(res) ? res : (res == null ? void 0 : res.data) && Array.isArray(res.data) ? res.data : [];
|
|
1750
|
+
setItems(newData);
|
|
1751
|
+
setSkip(BATCH_SIZE);
|
|
1752
|
+
skipRef.current = BATCH_SIZE;
|
|
1753
|
+
if (newData.length < BATCH_SIZE) {
|
|
1754
|
+
setHasMore(false);
|
|
1755
|
+
}
|
|
1756
|
+
}).catch((err) => {
|
|
1757
|
+
console.warn("[RelationPickerCell] Initial fetch failed:", err);
|
|
1758
|
+
}).finally(() => {
|
|
1759
|
+
setIsLoadingMore(false);
|
|
1760
|
+
isLoadingMoreRef.current = false;
|
|
1761
|
+
});
|
|
1631
1762
|
}
|
|
1632
1763
|
};
|
|
1633
1764
|
(0, import_react7.useEffect)(() => {
|
|
@@ -1638,7 +1769,105 @@ function RelationPickerCell({
|
|
|
1638
1769
|
}, 50);
|
|
1639
1770
|
}
|
|
1640
1771
|
}, [isOpen]);
|
|
1641
|
-
|
|
1772
|
+
(0, import_react7.useEffect)(() => {
|
|
1773
|
+
if (!isOpen) return;
|
|
1774
|
+
const query = searchQuery.trim();
|
|
1775
|
+
const fetcher = (context == null ? void 0 : context.executeAction) ? (p) => context.executeAction("FETCH_RELATION", p) : (context == null ? void 0 : context.refetchRelation) ? (p) => context.refetchRelation(column.name, p) : null;
|
|
1776
|
+
if (!fetcher || !referencedTableId) return;
|
|
1777
|
+
setSkip(0);
|
|
1778
|
+
skipRef.current = 0;
|
|
1779
|
+
setHasMore(true);
|
|
1780
|
+
setScrollTop(0);
|
|
1781
|
+
if (listContainerRef.current) {
|
|
1782
|
+
listContainerRef.current.scrollTop = 0;
|
|
1783
|
+
}
|
|
1784
|
+
setIsRemoteSearching(true);
|
|
1785
|
+
const timer = setTimeout(() => {
|
|
1786
|
+
fetcher({
|
|
1787
|
+
referencedTableId,
|
|
1788
|
+
displayField,
|
|
1789
|
+
search: query,
|
|
1790
|
+
take: BATCH_SIZE,
|
|
1791
|
+
limit: BATCH_SIZE,
|
|
1792
|
+
skip: 0
|
|
1793
|
+
}).then((res) => {
|
|
1794
|
+
const newData = Array.isArray(res) ? res : (res == null ? void 0 : res.data) && Array.isArray(res.data) ? res.data : [];
|
|
1795
|
+
setItems(newData);
|
|
1796
|
+
setSkip(BATCH_SIZE);
|
|
1797
|
+
skipRef.current = BATCH_SIZE;
|
|
1798
|
+
if (newData.length < BATCH_SIZE) {
|
|
1799
|
+
setHasMore(false);
|
|
1800
|
+
}
|
|
1801
|
+
}).catch((err) => {
|
|
1802
|
+
console.warn("[RelationPickerCell] Remote search failed:", err);
|
|
1803
|
+
}).finally(() => {
|
|
1804
|
+
setIsRemoteSearching(false);
|
|
1805
|
+
});
|
|
1806
|
+
}, 250);
|
|
1807
|
+
return () => clearTimeout(timer);
|
|
1808
|
+
}, [searchQuery, isOpen, referencedTableId, displayField, context, column.name]);
|
|
1809
|
+
const handleLoadMore = (0, import_react7.useCallback)(async () => {
|
|
1810
|
+
if (isLoadingMoreRef.current || !hasMore || !referencedTableId) return;
|
|
1811
|
+
const fetcher = (context == null ? void 0 : context.executeAction) ? (p) => context.executeAction("FETCH_RELATION", p) : (context == null ? void 0 : context.refetchRelation) ? (p) => context.refetchRelation(column.name, p) : null;
|
|
1812
|
+
if (!fetcher) return;
|
|
1813
|
+
isLoadingMoreRef.current = true;
|
|
1814
|
+
setIsLoadingMore(true);
|
|
1815
|
+
const currentQuery = searchQuery.trim();
|
|
1816
|
+
const currentSkip = skipRef.current;
|
|
1817
|
+
try {
|
|
1818
|
+
const res = await fetcher({
|
|
1819
|
+
referencedTableId,
|
|
1820
|
+
displayField,
|
|
1821
|
+
search: currentQuery,
|
|
1822
|
+
take: BATCH_SIZE,
|
|
1823
|
+
limit: BATCH_SIZE,
|
|
1824
|
+
skip: currentSkip
|
|
1825
|
+
});
|
|
1826
|
+
const newData = Array.isArray(res) ? res : (res == null ? void 0 : res.data) && Array.isArray(res.data) ? res.data : [];
|
|
1827
|
+
if (newData.length < BATCH_SIZE) {
|
|
1828
|
+
setHasMore(false);
|
|
1829
|
+
}
|
|
1830
|
+
if (newData.length > 0) {
|
|
1831
|
+
setItems((prev) => {
|
|
1832
|
+
const seen = new Set(prev.map((i) => String(i.id)));
|
|
1833
|
+
const unique = newData.filter((i) => !seen.has(String(i.id)));
|
|
1834
|
+
return [...prev, ...unique];
|
|
1835
|
+
});
|
|
1836
|
+
setSkip((prev) => prev + BATCH_SIZE);
|
|
1837
|
+
skipRef.current += BATCH_SIZE;
|
|
1838
|
+
}
|
|
1839
|
+
} catch (err) {
|
|
1840
|
+
console.warn("[RelationPickerCell] Load more failed:", err);
|
|
1841
|
+
} finally {
|
|
1842
|
+
isLoadingMoreRef.current = false;
|
|
1843
|
+
setIsLoadingMore(false);
|
|
1844
|
+
}
|
|
1845
|
+
}, [hasMore, referencedTableId, searchQuery, context, column.name, displayField]);
|
|
1846
|
+
(0, import_react7.useEffect)(() => {
|
|
1847
|
+
if (!isOpen || !hasMore) return;
|
|
1848
|
+
const sentinel = sentinelRef.current;
|
|
1849
|
+
if (!sentinel) return;
|
|
1850
|
+
const observer = new IntersectionObserver(
|
|
1851
|
+
(entries) => {
|
|
1852
|
+
var _a2;
|
|
1853
|
+
if (((_a2 = entries[0]) == null ? void 0 : _a2.isIntersecting) && !isLoadingMoreRef.current) {
|
|
1854
|
+
handleLoadMore();
|
|
1855
|
+
}
|
|
1856
|
+
},
|
|
1857
|
+
{ root: listContainerRef.current, threshold: 0.1 }
|
|
1858
|
+
);
|
|
1859
|
+
observer.observe(sentinel);
|
|
1860
|
+
return () => observer.disconnect();
|
|
1861
|
+
}, [isOpen, hasMore, handleLoadMore]);
|
|
1862
|
+
const handleListScroll = (e) => {
|
|
1863
|
+
const currentScrollTop = e.currentTarget.scrollTop;
|
|
1864
|
+
setScrollTop(currentScrollTop);
|
|
1865
|
+
const { clientHeight, scrollHeight } = e.currentTarget;
|
|
1866
|
+
if (scrollHeight - (currentScrollTop + clientHeight) < 60 && hasMore && !isLoadingMoreRef.current) {
|
|
1867
|
+
handleLoadMore();
|
|
1868
|
+
}
|
|
1869
|
+
};
|
|
1870
|
+
const handleSelectOption = (0, import_react7.useCallback)((optId) => {
|
|
1642
1871
|
if (!allowMultiple) {
|
|
1643
1872
|
onChange([optId]);
|
|
1644
1873
|
setIsOpen(false);
|
|
@@ -1649,7 +1878,7 @@ function RelationPickerCell({
|
|
|
1649
1878
|
onChange([...selectedIds, optId]);
|
|
1650
1879
|
}
|
|
1651
1880
|
}
|
|
1652
|
-
};
|
|
1881
|
+
}, [allowMultiple, onChange, selectedIds]);
|
|
1653
1882
|
const handleRemove = (idToRemove) => {
|
|
1654
1883
|
onChange(selectedIds.filter((id) => id !== idToRemove));
|
|
1655
1884
|
};
|
|
@@ -1660,7 +1889,8 @@ function RelationPickerCell({
|
|
|
1660
1889
|
(0, import_react7.useEffect)(() => {
|
|
1661
1890
|
if (!isOpen) return;
|
|
1662
1891
|
function handleClickOutside(event) {
|
|
1663
|
-
|
|
1892
|
+
const target = event.target;
|
|
1893
|
+
if (containerRef.current && !containerRef.current.contains(target) && dropdownRef.current && !dropdownRef.current.contains(target)) {
|
|
1664
1894
|
setIsOpen(false);
|
|
1665
1895
|
}
|
|
1666
1896
|
}
|
|
@@ -1676,13 +1906,19 @@ function RelationPickerCell({
|
|
|
1676
1906
|
document.removeEventListener("keydown", handleKeyDown);
|
|
1677
1907
|
};
|
|
1678
1908
|
}, [isOpen]);
|
|
1679
|
-
const
|
|
1909
|
+
const displayedOptions = (0, import_react7.useMemo)(() => {
|
|
1680
1910
|
const query = searchQuery.trim().toLowerCase();
|
|
1681
1911
|
if (!query) return processedOptions;
|
|
1682
1912
|
return processedOptions.filter((opt) => {
|
|
1683
1913
|
return (opt._displayLabel || "").toLowerCase().includes(query);
|
|
1684
1914
|
});
|
|
1685
1915
|
}, [processedOptions, searchQuery]);
|
|
1916
|
+
const totalItems = displayedOptions.length;
|
|
1917
|
+
const totalHeight = totalItems * ITEM_HEIGHT;
|
|
1918
|
+
const startIndex = Math.max(0, Math.floor(scrollTop / ITEM_HEIGHT) - OVERSCAN);
|
|
1919
|
+
const endIndex = Math.min(totalItems, Math.ceil((scrollTop + CONTAINER_HEIGHT) / ITEM_HEIGHT) + OVERSCAN);
|
|
1920
|
+
const visibleOptions = displayedOptions.slice(startIndex, endIndex);
|
|
1921
|
+
const topPadding = startIndex * ITEM_HEIGHT;
|
|
1686
1922
|
if (!optionsLoaded && selectedIds.length > 0) {
|
|
1687
1923
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "px-2 py-1 flex items-center h-full w-full", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "inline-block w-16 h-4 bg-slate-100 animate-pulse rounded" }) });
|
|
1688
1924
|
}
|
|
@@ -1804,51 +2040,101 @@ function RelationPickerCell({
|
|
|
1804
2040
|
)
|
|
1805
2041
|
}
|
|
1806
2042
|
),
|
|
1807
|
-
isOpen &&
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
2043
|
+
isOpen && dropdownCoords && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
|
|
2044
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2045
|
+
"div",
|
|
2046
|
+
{
|
|
2047
|
+
ref: dropdownRef,
|
|
2048
|
+
id: `relation-dropdown-${column.name}-${rowId || "cell"}`,
|
|
2049
|
+
dir: "rtl",
|
|
2050
|
+
style: {
|
|
2051
|
+
position: "fixed",
|
|
2052
|
+
top: `${dropdownCoords.top}px`,
|
|
2053
|
+
right: `${dropdownCoords.right}px`,
|
|
2054
|
+
width: `${dropdownCoords.width}px`,
|
|
2055
|
+
zIndex: 99999
|
|
2056
|
+
},
|
|
2057
|
+
className: "bg-white rounded-md shadow-2xl border border-slate-200 p-1 animate-in fade-in duration-100 flex flex-col",
|
|
2058
|
+
onClick: (e) => e.stopPropagation(),
|
|
2059
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
2060
|
+
children: [
|
|
2061
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative mb-1", children: [
|
|
2062
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Search, { className: "w-3.5 h-3.5 text-slate-400 absolute right-2 top-2 pointer-events-none" }),
|
|
2063
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2064
|
+
"input",
|
|
2065
|
+
{
|
|
2066
|
+
ref: searchInputRef,
|
|
2067
|
+
type: "text",
|
|
2068
|
+
placeholder: "\u05D7\u05E4\u05E9...",
|
|
2069
|
+
value: searchQuery,
|
|
2070
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
2071
|
+
onKeyDown: (e) => {
|
|
2072
|
+
if (e.key === "Escape") {
|
|
2073
|
+
e.stopPropagation();
|
|
2074
|
+
setIsOpen(false);
|
|
2075
|
+
}
|
|
2076
|
+
},
|
|
2077
|
+
className: "w-full h-7 pr-7 pl-7 bg-slate-50 border border-slate-200 rounded text-xs text-slate-800 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 transition-colors"
|
|
2078
|
+
}
|
|
2079
|
+
),
|
|
2080
|
+
isRemoteSearching && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Loader2, { className: "w-3.5 h-3.5 text-blue-500 animate-spin absolute left-2 top-2 pointer-events-none" })
|
|
2081
|
+
] }),
|
|
1817
2082
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1818
|
-
"
|
|
2083
|
+
"div",
|
|
1819
2084
|
{
|
|
1820
|
-
ref:
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
2085
|
+
ref: listContainerRef,
|
|
2086
|
+
onScroll: handleListScroll,
|
|
2087
|
+
style: { maxHeight: `${CONTAINER_HEIGHT}px` },
|
|
2088
|
+
className: "overflow-y-auto relative",
|
|
2089
|
+
children: displayedOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { height: `${totalHeight}px`, position: "relative", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2091
|
+
"div",
|
|
2092
|
+
{
|
|
2093
|
+
style: {
|
|
2094
|
+
position: "absolute",
|
|
2095
|
+
top: 0,
|
|
2096
|
+
left: 0,
|
|
2097
|
+
right: 0,
|
|
2098
|
+
transform: `translateY(${topPadding}px)`
|
|
2099
|
+
},
|
|
2100
|
+
children: visibleOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2101
|
+
RelationPickerRow,
|
|
2102
|
+
{
|
|
2103
|
+
id: opt.id,
|
|
2104
|
+
label: opt._displayLabel,
|
|
2105
|
+
isSelected: selectedIds.includes(opt.id),
|
|
2106
|
+
onSelect: handleSelectOption,
|
|
2107
|
+
height: ITEM_HEIGHT
|
|
2108
|
+
},
|
|
2109
|
+
opt.id
|
|
2110
|
+
))
|
|
2111
|
+
}
|
|
2112
|
+
) }),
|
|
2113
|
+
hasMore && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: sentinelRef, className: "pt-1 pb-0.5 px-2 text-center", children: isLoadingMore ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-center gap-1.5 text-xs text-slate-400 py-1", children: [
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Loader2, { className: "w-3 h-3 text-blue-500 animate-spin shrink-0" }),
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u05D8\u05D5\u05E2\u05DF \u05E2\u05D5\u05D3 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA..." })
|
|
2116
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2117
|
+
"button",
|
|
2118
|
+
{
|
|
2119
|
+
type: "button",
|
|
2120
|
+
onClick: (e) => {
|
|
2121
|
+
e.stopPropagation();
|
|
2122
|
+
handleLoadMore();
|
|
2123
|
+
},
|
|
2124
|
+
className: "text-[11px] text-blue-600 hover:text-blue-700 hover:underline py-1 px-2 font-medium",
|
|
2125
|
+
children: "\u05D8\u05E2\u05DF \u05E2\u05D5\u05D3 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA..."
|
|
2126
|
+
}
|
|
2127
|
+
) })
|
|
2128
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "py-2.5 px-2 text-center text-xs text-slate-400 select-none", children: isRemoteSearching ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-center gap-1.5 py-1", children: [
|
|
2129
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Loader2, { className: "w-3 h-3 text-blue-500 animate-spin shrink-0" }),
|
|
2130
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u05DE\u05D7\u05E4\u05E9 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA..." })
|
|
2131
|
+
] }) : items.length === 0 ? "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D6\u05DE\u05D9\u05E0\u05D5\u05EA" : "\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA" })
|
|
1832
2132
|
}
|
|
1833
2133
|
)
|
|
1834
|
-
]
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
"div",
|
|
1839
|
-
{
|
|
1840
|
-
onClick: () => handleSelectOption(opt.id),
|
|
1841
|
-
className: `flex items-center justify-between px-2.5 py-1.5 rounded cursor-pointer text-xs transition-colors ${isSelected ? "bg-blue-50 text-blue-900 font-medium" : "hover:bg-slate-50 text-slate-700"}`,
|
|
1842
|
-
children: [
|
|
1843
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate flex-1", children: opt._displayLabel }),
|
|
1844
|
-
isSelected && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Check, { className: "w-3.5 h-3.5 text-blue-600 shrink-0 mr-1" })
|
|
1845
|
-
]
|
|
1846
|
-
},
|
|
1847
|
-
opt.id
|
|
1848
|
-
);
|
|
1849
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "py-2.5 px-2 text-center text-xs text-slate-400 select-none", children: processedOptions.length === 0 ? "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D6\u05DE\u05D9\u05E0\u05D5\u05EA" : "\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA" }) })
|
|
1850
|
-
]
|
|
1851
|
-
}
|
|
2134
|
+
]
|
|
2135
|
+
}
|
|
2136
|
+
),
|
|
2137
|
+
document.body
|
|
1852
2138
|
)
|
|
1853
2139
|
]
|
|
1854
2140
|
}
|
|
@@ -2269,7 +2555,7 @@ var FORM_INPUTS = {
|
|
|
2269
2555
|
};
|
|
2270
2556
|
|
|
2271
2557
|
// src/components/TableBlock/fields/SubTableViewer.tsx
|
|
2272
|
-
var
|
|
2558
|
+
var import_react12 = require("react");
|
|
2273
2559
|
|
|
2274
2560
|
// src/utils/phone.ts
|
|
2275
2561
|
function sanitizePhoneNumber(phone) {
|
|
@@ -2427,6 +2713,7 @@ function useColumnReorder({
|
|
|
2427
2713
|
}
|
|
2428
2714
|
|
|
2429
2715
|
// src/components/TableBlock/columnTitleUtils.tsx
|
|
2716
|
+
var import_react11 = require("react");
|
|
2430
2717
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2431
2718
|
var canvas = null;
|
|
2432
2719
|
function measureTextWidth(text, font = '600 14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif') {
|
|
@@ -2467,10 +2754,10 @@ function splitHeaderTitle(name) {
|
|
|
2467
2754
|
}
|
|
2468
2755
|
function calculateMinColumnWidth(name, isSubTable = false, colType) {
|
|
2469
2756
|
const font = isSubTable ? '600 12px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' : '600 14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
2470
|
-
const chromeWidth = isSubTable ?
|
|
2471
|
-
let baseMin = isSubTable ?
|
|
2757
|
+
const chromeWidth = isSubTable ? 24 : 26;
|
|
2758
|
+
let baseMin = isSubTable ? 30 : 36;
|
|
2472
2759
|
if ((colType == null ? void 0 : colType.toUpperCase()) === "GOOGLE_CONTACT") {
|
|
2473
|
-
baseMin = isSubTable ?
|
|
2760
|
+
baseMin = isSubTable ? 100 : 110;
|
|
2474
2761
|
}
|
|
2475
2762
|
if (!name) return baseMin;
|
|
2476
2763
|
const { isSingleWord, line1, line2 } = splitHeaderTitle(name);
|
|
@@ -2484,12 +2771,16 @@ function calculateMinColumnWidth(name, isSubTable = false, colType) {
|
|
|
2484
2771
|
return Math.max(baseMin, Math.ceil(maxLine + chromeWidth));
|
|
2485
2772
|
}
|
|
2486
2773
|
function ColumnHeaderTitle({ name, width, isSubTable = false }) {
|
|
2774
|
+
const [isMounted, setIsMounted] = (0, import_react11.useState)(false);
|
|
2775
|
+
(0, import_react11.useEffect)(() => {
|
|
2776
|
+
setIsMounted(true);
|
|
2777
|
+
}, []);
|
|
2487
2778
|
const { isSingleWord, line1, line2 } = splitHeaderTitle(name);
|
|
2488
|
-
if (isSingleWord || !line2) {
|
|
2489
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-nowrap select-none overflow-hidden text-right flex-1", title: name, children:
|
|
2779
|
+
if (!isMounted || isSingleWord || !line2) {
|
|
2780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-nowrap select-none overflow-hidden text-right flex-1", title: name, children: name });
|
|
2490
2781
|
}
|
|
2491
2782
|
const font = isSubTable ? '600 12px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' : '600 14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
2492
|
-
const chromeWidth = isSubTable ?
|
|
2783
|
+
const chromeWidth = isSubTable ? 24 : 26;
|
|
2493
2784
|
const fullTitleWidth = measureTextWidth(name, font) + chromeWidth;
|
|
2494
2785
|
if (width !== void 0 && width >= fullTitleWidth) {
|
|
2495
2786
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-nowrap select-none overflow-hidden text-right flex-1", title: name, children: name });
|
|
@@ -2623,18 +2914,18 @@ function SubTableCell({
|
|
|
2623
2914
|
const isContact = colType === "GOOGLE_CONTACT";
|
|
2624
2915
|
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
2625
2916
|
const serverValue = (_b = record.data[column.name]) != null ? _b : colType === "BOOLEAN" ? false : "";
|
|
2626
|
-
const [draftValue, setDraftValue] = (0,
|
|
2627
|
-
const [isDirty, setIsDirty] = (0,
|
|
2628
|
-
const [validationError, setValidationError] = (0,
|
|
2629
|
-
const cellRef = (0,
|
|
2630
|
-
const draftRef = (0,
|
|
2631
|
-
const isDirtyRef = (0,
|
|
2632
|
-
const serverValueRef = (0,
|
|
2633
|
-
const recordIdRef = (0,
|
|
2634
|
-
const columnRef = (0,
|
|
2635
|
-
const onCommitRef = (0,
|
|
2636
|
-
const isCommittingRef = (0,
|
|
2637
|
-
const lastFailedValRef = (0,
|
|
2917
|
+
const [draftValue, setDraftValue] = (0, import_react12.useState)(serverValue);
|
|
2918
|
+
const [isDirty, setIsDirty] = (0, import_react12.useState)(false);
|
|
2919
|
+
const [validationError, setValidationError] = (0, import_react12.useState)(null);
|
|
2920
|
+
const cellRef = (0, import_react12.useRef)(null);
|
|
2921
|
+
const draftRef = (0, import_react12.useRef)(draftValue);
|
|
2922
|
+
const isDirtyRef = (0, import_react12.useRef)(isDirty);
|
|
2923
|
+
const serverValueRef = (0, import_react12.useRef)(serverValue);
|
|
2924
|
+
const recordIdRef = (0, import_react12.useRef)(record.id);
|
|
2925
|
+
const columnRef = (0, import_react12.useRef)(column);
|
|
2926
|
+
const onCommitRef = (0, import_react12.useRef)(onCommit);
|
|
2927
|
+
const isCommittingRef = (0, import_react12.useRef)(false);
|
|
2928
|
+
const lastFailedValRef = (0, import_react12.useRef)(void 0);
|
|
2638
2929
|
const { addToast } = useToast();
|
|
2639
2930
|
draftRef.current = draftValue;
|
|
2640
2931
|
isDirtyRef.current = isDirty;
|
|
@@ -2642,7 +2933,7 @@ function SubTableCell({
|
|
|
2642
2933
|
recordIdRef.current = record.id;
|
|
2643
2934
|
columnRef.current = column;
|
|
2644
2935
|
onCommitRef.current = onCommit;
|
|
2645
|
-
(0,
|
|
2936
|
+
(0, import_react12.useEffect)(() => {
|
|
2646
2937
|
if (!isDirtyRef.current) {
|
|
2647
2938
|
setDraftValue(serverValue);
|
|
2648
2939
|
draftRef.current = serverValue;
|
|
@@ -2650,7 +2941,7 @@ function SubTableCell({
|
|
|
2650
2941
|
lastFailedValRef.current = void 0;
|
|
2651
2942
|
}
|
|
2652
2943
|
}, [serverValue]);
|
|
2653
|
-
const commit = (0,
|
|
2944
|
+
const commit = (0, import_react12.useCallback)(async (valToCommit) => {
|
|
2654
2945
|
if (isCommittingRef.current) return false;
|
|
2655
2946
|
if (!isDirtyRef.current) return true;
|
|
2656
2947
|
if (valToCommit === serverValueRef.current) {
|
|
@@ -2691,7 +2982,7 @@ function SubTableCell({
|
|
|
2691
2982
|
isCommittingRef.current = false;
|
|
2692
2983
|
}
|
|
2693
2984
|
}, [addToast]);
|
|
2694
|
-
const discard = (0,
|
|
2985
|
+
const discard = (0, import_react12.useCallback)(() => {
|
|
2695
2986
|
setDraftValue(serverValueRef.current);
|
|
2696
2987
|
draftRef.current = serverValueRef.current;
|
|
2697
2988
|
setIsDirty(false);
|
|
@@ -2699,7 +2990,7 @@ function SubTableCell({
|
|
|
2699
2990
|
setValidationError(null);
|
|
2700
2991
|
lastFailedValRef.current = void 0;
|
|
2701
2992
|
}, []);
|
|
2702
|
-
(0,
|
|
2993
|
+
(0, import_react12.useEffect)(() => {
|
|
2703
2994
|
return () => {
|
|
2704
2995
|
if (isDirtyRef.current && !isCommittingRef.current) {
|
|
2705
2996
|
const val = draftRef.current;
|
|
@@ -2801,7 +3092,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2801
3092
|
var _a, _b, _c, _d, _e, _f;
|
|
2802
3093
|
const { addToast } = useToast();
|
|
2803
3094
|
const entries = Array.isArray(value) ? value : [];
|
|
2804
|
-
const [linkedRecords, setLinkedRecords] = (0,
|
|
3095
|
+
const [linkedRecords, setLinkedRecords] = (0, import_react12.useState)(() => {
|
|
2805
3096
|
const initial = [];
|
|
2806
3097
|
for (const entry of entries) {
|
|
2807
3098
|
if (entry.recordId && entry._resolvedData) {
|
|
@@ -2810,25 +3101,25 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2810
3101
|
}
|
|
2811
3102
|
return initial;
|
|
2812
3103
|
});
|
|
2813
|
-
const [targetSchema, setTargetSchema] = (0,
|
|
2814
|
-
const [isLoading, setIsLoading] = (0,
|
|
2815
|
-
const [isSearchOpen, setIsSearchOpen] = (0,
|
|
2816
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
2817
|
-
const [searchResults, setSearchResults] = (0,
|
|
2818
|
-
const [isSearching, setIsSearching] = (0,
|
|
2819
|
-
const [isCreating, setIsCreating] = (0,
|
|
2820
|
-
const [newRecordData, setNewRecordData] = (0,
|
|
2821
|
-
const [conflictModalState, setConflictModalState] = (0,
|
|
3104
|
+
const [targetSchema, setTargetSchema] = (0, import_react12.useState)(null);
|
|
3105
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
3106
|
+
const [isSearchOpen, setIsSearchOpen] = (0, import_react12.useState)(false);
|
|
3107
|
+
const [searchQuery, setSearchQuery] = (0, import_react12.useState)("");
|
|
3108
|
+
const [searchResults, setSearchResults] = (0, import_react12.useState)([]);
|
|
3109
|
+
const [isSearching, setIsSearching] = (0, import_react12.useState)(false);
|
|
3110
|
+
const [isCreating, setIsCreating] = (0, import_react12.useState)(false);
|
|
3111
|
+
const [newRecordData, setNewRecordData] = (0, import_react12.useState)({});
|
|
3112
|
+
const [conflictModalState, setConflictModalState] = (0, import_react12.useState)({
|
|
2822
3113
|
isOpen: false,
|
|
2823
3114
|
fieldName: "",
|
|
2824
3115
|
matchingRecords: []
|
|
2825
3116
|
});
|
|
2826
|
-
const searchRef = (0,
|
|
2827
|
-
const searchTimerRef = (0,
|
|
3117
|
+
const searchRef = (0, import_react12.useRef)(null);
|
|
3118
|
+
const searchTimerRef = (0, import_react12.useRef)(null);
|
|
2828
3119
|
const executeAction = context == null ? void 0 : context.executeAction;
|
|
2829
3120
|
const referencedTableId = ((_a = column.config) == null ? void 0 : _a.referencedTableId) || column.referencedTableId;
|
|
2830
|
-
const fetchedIdsRef = (0,
|
|
2831
|
-
(0,
|
|
3121
|
+
const fetchedIdsRef = (0, import_react12.useRef)(/* @__PURE__ */ new Set());
|
|
3122
|
+
(0, import_react12.useEffect)(() => {
|
|
2832
3123
|
if (entries.length > 0) {
|
|
2833
3124
|
setLinkedRecords((prev) => {
|
|
2834
3125
|
const existingIds = new Set(prev.map((r) => r.id));
|
|
@@ -2843,7 +3134,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2843
3134
|
});
|
|
2844
3135
|
}
|
|
2845
3136
|
}, [entries]);
|
|
2846
|
-
(0,
|
|
3137
|
+
(0, import_react12.useEffect)(() => {
|
|
2847
3138
|
if (!referencedTableId || !executeAction) {
|
|
2848
3139
|
setIsLoading(false);
|
|
2849
3140
|
return;
|
|
@@ -2870,7 +3161,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2870
3161
|
recordIdsToFetch.forEach((id) => fetchedIdsRef.current.delete(id));
|
|
2871
3162
|
}).finally(() => setIsLoading(false));
|
|
2872
3163
|
}, [referencedTableId, executeAction, entries, targetSchema]);
|
|
2873
|
-
(0,
|
|
3164
|
+
(0, import_react12.useEffect)(() => {
|
|
2874
3165
|
const handleClick = (e) => {
|
|
2875
3166
|
if (searchRef.current && !searchRef.current.contains(e.target)) {
|
|
2876
3167
|
setIsSearchOpen(false);
|
|
@@ -2879,7 +3170,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2879
3170
|
if (isSearchOpen) document.addEventListener("mousedown", handleClick);
|
|
2880
3171
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
2881
3172
|
}, [isSearchOpen]);
|
|
2882
|
-
const handleSearch = (0,
|
|
3173
|
+
const handleSearch = (0, import_react12.useCallback)((query) => {
|
|
2883
3174
|
setSearchQuery(query);
|
|
2884
3175
|
if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
|
|
2885
3176
|
if (!query.trim()) {
|
|
@@ -2905,16 +3196,16 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2905
3196
|
}
|
|
2906
3197
|
}, 300);
|
|
2907
3198
|
}, [executeAction, referencedTableId, entries]);
|
|
2908
|
-
const [localColumnOrder, setLocalColumnOrder] = (0,
|
|
2909
|
-
(0,
|
|
3199
|
+
const [localColumnOrder, setLocalColumnOrder] = (0, import_react12.useState)(null);
|
|
3200
|
+
(0, import_react12.useEffect)(() => {
|
|
2910
3201
|
setLocalColumnOrder(null);
|
|
2911
3202
|
}, [column.name, (_b = column.config) == null ? void 0 : _b.subTableColumnOrder]);
|
|
2912
|
-
const rawTargetColumns = (0,
|
|
3203
|
+
const rawTargetColumns = (0, import_react12.useMemo)(() => {
|
|
2913
3204
|
return ((targetSchema == null ? void 0 : targetSchema.columns) || []).filter(
|
|
2914
3205
|
(c) => c.name !== "_id" && c.type !== "SUB_TABLE"
|
|
2915
3206
|
);
|
|
2916
3207
|
}, [targetSchema == null ? void 0 : targetSchema.columns]);
|
|
2917
|
-
const targetColumns = (0,
|
|
3208
|
+
const targetColumns = (0, import_react12.useMemo)(() => {
|
|
2918
3209
|
var _a2;
|
|
2919
3210
|
const activeOrder = localColumnOrder || ((_a2 = column.config) == null ? void 0 : _a2.subTableColumnOrder);
|
|
2920
3211
|
if (!activeOrder || !Array.isArray(activeOrder) || activeOrder.length === 0) {
|
|
@@ -2965,8 +3256,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2965
3256
|
return calculateMinColumnWidth(colName, true, col == null ? void 0 : col.type);
|
|
2966
3257
|
}
|
|
2967
3258
|
});
|
|
2968
|
-
const [relationOptions, setRelationOptions] = (0,
|
|
2969
|
-
(0,
|
|
3259
|
+
const [relationOptions, setRelationOptions] = (0, import_react12.useState)({});
|
|
3260
|
+
(0, import_react12.useEffect)(() => {
|
|
2970
3261
|
if (!executeAction || !(targetSchema == null ? void 0 : targetSchema.columns) || targetSchema.columns.length === 0) return;
|
|
2971
3262
|
const relationCols = targetSchema.columns.filter((c) => {
|
|
2972
3263
|
var _a2, _b2;
|
|
@@ -2977,7 +3268,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2977
3268
|
try {
|
|
2978
3269
|
const options = await executeAction("FETCH_RELATION", {
|
|
2979
3270
|
referencedTableId: (_a2 = col.config) == null ? void 0 : _a2.referencedTableId,
|
|
2980
|
-
displayField: (_b2 = col.config) == null ? void 0 : _b2.displayField
|
|
3271
|
+
displayField: (_b2 = col.config) == null ? void 0 : _b2.displayField,
|
|
3272
|
+
limit: 1e3
|
|
2981
3273
|
});
|
|
2982
3274
|
if (options && Array.isArray(options)) {
|
|
2983
3275
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
@@ -2987,18 +3279,35 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2987
3279
|
}
|
|
2988
3280
|
});
|
|
2989
3281
|
}, [executeAction, targetColumns]);
|
|
2990
|
-
const refetchRelation = (0,
|
|
2991
|
-
var _a2, _b2, _c2;
|
|
3282
|
+
const refetchRelation = (0, import_react12.useCallback)(async (colName, params) => {
|
|
3283
|
+
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
2992
3284
|
const col = targetColumns.find((c) => c.name === colName);
|
|
2993
|
-
if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !((_b2 = col.config) == null ? void 0 : _b2.referencedTableId) || !executeAction) return;
|
|
3285
|
+
if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !((_b2 = col.config) == null ? void 0 : _b2.referencedTableId) || !executeAction) return [];
|
|
2994
3286
|
try {
|
|
2995
|
-
const options = await executeAction("FETCH_RELATION", {
|
|
3287
|
+
const options = await executeAction("FETCH_RELATION", {
|
|
3288
|
+
referencedTableId: col.config.referencedTableId,
|
|
3289
|
+
displayField: (_c2 = col.config) == null ? void 0 : _c2.displayField,
|
|
3290
|
+
limit: (_d2 = params == null ? void 0 : params.limit) != null ? _d2 : 1e3,
|
|
3291
|
+
skip: (_e2 = params == null ? void 0 : params.skip) != null ? _e2 : 0,
|
|
3292
|
+
search: (_f2 = params == null ? void 0 : params.search) != null ? _f2 : ""
|
|
3293
|
+
});
|
|
2996
3294
|
if (options && Array.isArray(options)) {
|
|
2997
|
-
|
|
3295
|
+
if (params == null ? void 0 : params.append) {
|
|
3296
|
+
setRelationOptions((prev) => {
|
|
3297
|
+
const existing = prev[col.name] || [];
|
|
3298
|
+
const existingIds = new Set(existing.map((o) => String(o.id)));
|
|
3299
|
+
const uniqueNew = options.filter((o) => !existingIds.has(String(o.id)));
|
|
3300
|
+
return __spreadProps(__spreadValues({}, prev), { [col.name]: [...existing, ...uniqueNew] });
|
|
3301
|
+
});
|
|
3302
|
+
} else if (!(params == null ? void 0 : params.search)) {
|
|
3303
|
+
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
3304
|
+
}
|
|
3305
|
+
return options;
|
|
2998
3306
|
}
|
|
2999
3307
|
} catch (err) {
|
|
3000
3308
|
console.warn(`[SubTableViewer] Could not refetch relation options for column ${col.name}:`, err);
|
|
3001
3309
|
}
|
|
3310
|
+
return [];
|
|
3002
3311
|
}, [targetColumns, executeAction]);
|
|
3003
3312
|
const updateParentLinkage = async (updated) => {
|
|
3004
3313
|
const isNewRow = rowId.startsWith("temp_");
|
|
@@ -3131,8 +3440,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3131
3440
|
);
|
|
3132
3441
|
updateParentLinkage(updated);
|
|
3133
3442
|
};
|
|
3134
|
-
const isMountedRef = (0,
|
|
3135
|
-
(0,
|
|
3443
|
+
const isMountedRef = (0, import_react12.useRef)(true);
|
|
3444
|
+
(0, import_react12.useEffect)(() => {
|
|
3136
3445
|
isMountedRef.current = true;
|
|
3137
3446
|
return () => {
|
|
3138
3447
|
isMountedRef.current = false;
|
|
@@ -3219,7 +3528,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3219
3528
|
}
|
|
3220
3529
|
};
|
|
3221
3530
|
const handleRecordCellChange = handleCommitRecordCell;
|
|
3222
|
-
const handleQuietSubTableCellChange = (0,
|
|
3531
|
+
const handleQuietSubTableCellChange = (0, import_react12.useCallback)((recordId, colName, value2) => {
|
|
3223
3532
|
setLinkedRecords(
|
|
3224
3533
|
(prev) => prev.map((r) => r.id === recordId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value2 }) }) : r)
|
|
3225
3534
|
);
|
|
@@ -3667,12 +3976,352 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3667
3976
|
}
|
|
3668
3977
|
|
|
3669
3978
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
3979
|
+
var import_lucide_react8 = require("lucide-react");
|
|
3980
|
+
|
|
3981
|
+
// src/components/TableBlock/RelationFilterPopover.tsx
|
|
3982
|
+
var import_react13 = require("react");
|
|
3670
3983
|
var import_lucide_react7 = require("lucide-react");
|
|
3671
3984
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
3985
|
+
function calculatePopoverCoords(rect) {
|
|
3986
|
+
if (!rect || typeof window === "undefined") return null;
|
|
3987
|
+
const popoverWidth = 260;
|
|
3988
|
+
const popoverHeight = 360;
|
|
3989
|
+
let right = window.innerWidth - rect.right;
|
|
3990
|
+
if (right + popoverWidth > window.innerWidth - 10) {
|
|
3991
|
+
right = window.innerWidth - popoverWidth - 10;
|
|
3992
|
+
}
|
|
3993
|
+
if (right < 10) {
|
|
3994
|
+
right = 10;
|
|
3995
|
+
}
|
|
3996
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
3997
|
+
let top = rect.bottom + 6;
|
|
3998
|
+
if (spaceBelow < popoverHeight && rect.top > popoverHeight) {
|
|
3999
|
+
top = Math.max(10, rect.top - popoverHeight - 6);
|
|
4000
|
+
} else {
|
|
4001
|
+
top = Math.min(window.innerHeight - popoverHeight - 10, top);
|
|
4002
|
+
}
|
|
4003
|
+
return { top, right };
|
|
4004
|
+
}
|
|
4005
|
+
function RelationFilterPopover({
|
|
4006
|
+
isOpen,
|
|
4007
|
+
onClose,
|
|
4008
|
+
column,
|
|
4009
|
+
triggerRect,
|
|
4010
|
+
options,
|
|
4011
|
+
filterValue,
|
|
4012
|
+
selectedValues,
|
|
4013
|
+
onSelectionChange,
|
|
4014
|
+
isLoading = false
|
|
4015
|
+
}) {
|
|
4016
|
+
const popoverRef = (0, import_react13.useRef)(null);
|
|
4017
|
+
const searchInputRef = (0, import_react13.useRef)(null);
|
|
4018
|
+
const selectAllRef = (0, import_react13.useRef)(null);
|
|
4019
|
+
const [searchQuery, setSearchQuery] = (0, import_react13.useState)("");
|
|
4020
|
+
const [coords, setCoords] = (0, import_react13.useState)(
|
|
4021
|
+
() => calculatePopoverCoords(triggerRect)
|
|
4022
|
+
);
|
|
4023
|
+
const [mode, setMode] = (0, import_react13.useState)("include");
|
|
4024
|
+
const [checkedSet, setCheckedSet] = (0, import_react13.useState)(/* @__PURE__ */ new Set());
|
|
4025
|
+
const [excludedSet, setExcludedSet] = (0, import_react13.useState)(/* @__PURE__ */ new Set());
|
|
4026
|
+
const prevIsOpenRef = (0, import_react13.useRef)(isOpen);
|
|
4027
|
+
(0, import_react13.useEffect)(() => {
|
|
4028
|
+
const justOpened = isOpen && !prevIsOpenRef.current;
|
|
4029
|
+
prevIsOpenRef.current = isOpen;
|
|
4030
|
+
if (justOpened) {
|
|
4031
|
+
const activeVal = filterValue != null ? filterValue : selectedValues;
|
|
4032
|
+
if (activeVal && typeof activeVal === "object" && !Array.isArray(activeVal) && "operator" in activeVal && activeVal.operator === "notIn") {
|
|
4033
|
+
setMode("exclude");
|
|
4034
|
+
setExcludedSet(new Set(activeVal.values || []));
|
|
4035
|
+
setCheckedSet(/* @__PURE__ */ new Set());
|
|
4036
|
+
} else if (Array.isArray(activeVal) && activeVal.length > 0) {
|
|
4037
|
+
setMode("include");
|
|
4038
|
+
setCheckedSet(new Set(activeVal));
|
|
4039
|
+
setExcludedSet(/* @__PURE__ */ new Set());
|
|
4040
|
+
} else {
|
|
4041
|
+
setMode("include");
|
|
4042
|
+
setCheckedSet(/* @__PURE__ */ new Set());
|
|
4043
|
+
setExcludedSet(/* @__PURE__ */ new Set());
|
|
4044
|
+
}
|
|
4045
|
+
}
|
|
4046
|
+
}, [isOpen, filterValue, selectedValues]);
|
|
4047
|
+
const updatePosition = (0, import_react13.useCallback)(() => {
|
|
4048
|
+
const next = calculatePopoverCoords(triggerRect);
|
|
4049
|
+
if (next) setCoords(next);
|
|
4050
|
+
}, [triggerRect]);
|
|
4051
|
+
(0, import_react13.useEffect)(() => {
|
|
4052
|
+
if (isOpen) {
|
|
4053
|
+
updatePosition();
|
|
4054
|
+
setTimeout(() => {
|
|
4055
|
+
var _a;
|
|
4056
|
+
return (_a = searchInputRef.current) == null ? void 0 : _a.focus();
|
|
4057
|
+
}, 50);
|
|
4058
|
+
} else {
|
|
4059
|
+
setSearchQuery("");
|
|
4060
|
+
}
|
|
4061
|
+
}, [isOpen, updatePosition]);
|
|
4062
|
+
(0, import_react13.useEffect)(() => {
|
|
4063
|
+
if (!isOpen) return;
|
|
4064
|
+
const handleScrollOrResize = () => updatePosition();
|
|
4065
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
4066
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
4067
|
+
return () => {
|
|
4068
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
4069
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
4070
|
+
};
|
|
4071
|
+
}, [isOpen, updatePosition]);
|
|
4072
|
+
(0, import_react13.useEffect)(() => {
|
|
4073
|
+
if (!isOpen) return;
|
|
4074
|
+
const handleMouseDown = (e) => {
|
|
4075
|
+
if (popoverRef.current && !popoverRef.current.contains(e.target)) {
|
|
4076
|
+
onClose();
|
|
4077
|
+
}
|
|
4078
|
+
};
|
|
4079
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
4080
|
+
return () => {
|
|
4081
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
4082
|
+
};
|
|
4083
|
+
}, [isOpen, onClose]);
|
|
4084
|
+
(0, import_react13.useEffect)(() => {
|
|
4085
|
+
if (!isOpen) return;
|
|
4086
|
+
const handleKeyDown = (e) => {
|
|
4087
|
+
if (e.key === "Escape") {
|
|
4088
|
+
onClose();
|
|
4089
|
+
}
|
|
4090
|
+
};
|
|
4091
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
4092
|
+
return () => {
|
|
4093
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
4094
|
+
};
|
|
4095
|
+
}, [isOpen, onClose]);
|
|
4096
|
+
const filteredOptions = (0, import_react13.useMemo)(() => {
|
|
4097
|
+
if (!searchQuery.trim()) return options;
|
|
4098
|
+
const q = searchQuery.trim().toLowerCase();
|
|
4099
|
+
return options.filter((opt) => opt.label.toLowerCase().includes(q));
|
|
4100
|
+
}, [options, searchQuery]);
|
|
4101
|
+
const isOptionChecked = (0, import_react13.useCallback)(
|
|
4102
|
+
(label) => {
|
|
4103
|
+
if (mode === "exclude") {
|
|
4104
|
+
return !excludedSet.has(label);
|
|
4105
|
+
}
|
|
4106
|
+
return checkedSet.has(label);
|
|
4107
|
+
},
|
|
4108
|
+
[mode, excludedSet, checkedSet]
|
|
4109
|
+
);
|
|
4110
|
+
const allFilteredSelected = (0, import_react13.useMemo)(() => {
|
|
4111
|
+
if (filteredOptions.length === 0) return false;
|
|
4112
|
+
return filteredOptions.every((opt) => isOptionChecked(opt.label));
|
|
4113
|
+
}, [filteredOptions, isOptionChecked]);
|
|
4114
|
+
const someFilteredSelected = (0, import_react13.useMemo)(() => {
|
|
4115
|
+
return filteredOptions.some((opt) => isOptionChecked(opt.label));
|
|
4116
|
+
}, [filteredOptions, isOptionChecked]);
|
|
4117
|
+
(0, import_react13.useEffect)(() => {
|
|
4118
|
+
if (selectAllRef.current) {
|
|
4119
|
+
selectAllRef.current.indeterminate = !allFilteredSelected && someFilteredSelected;
|
|
4120
|
+
}
|
|
4121
|
+
}, [allFilteredSelected, someFilteredSelected]);
|
|
4122
|
+
const handleToggleOption = (label) => {
|
|
4123
|
+
if (mode === "exclude") {
|
|
4124
|
+
const nextExcluded = new Set(excludedSet);
|
|
4125
|
+
if (nextExcluded.has(label)) {
|
|
4126
|
+
nextExcluded.delete(label);
|
|
4127
|
+
} else {
|
|
4128
|
+
nextExcluded.add(label);
|
|
4129
|
+
}
|
|
4130
|
+
setExcludedSet(nextExcluded);
|
|
4131
|
+
if (nextExcluded.size === 0) {
|
|
4132
|
+
onSelectionChange(void 0);
|
|
4133
|
+
} else {
|
|
4134
|
+
onSelectionChange({ operator: "notIn", values: Array.from(nextExcluded) });
|
|
4135
|
+
}
|
|
4136
|
+
} else {
|
|
4137
|
+
const nextChecked = new Set(checkedSet);
|
|
4138
|
+
if (nextChecked.has(label)) {
|
|
4139
|
+
nextChecked.delete(label);
|
|
4140
|
+
} else {
|
|
4141
|
+
nextChecked.add(label);
|
|
4142
|
+
}
|
|
4143
|
+
setCheckedSet(nextChecked);
|
|
4144
|
+
if (nextChecked.size === 0) {
|
|
4145
|
+
onSelectionChange(void 0);
|
|
4146
|
+
} else if (options.length > 0 && nextChecked.size >= options.length) {
|
|
4147
|
+
setMode("exclude");
|
|
4148
|
+
setExcludedSet(/* @__PURE__ */ new Set());
|
|
4149
|
+
onSelectionChange(void 0);
|
|
4150
|
+
} else {
|
|
4151
|
+
onSelectionChange(Array.from(nextChecked));
|
|
4152
|
+
}
|
|
4153
|
+
}
|
|
4154
|
+
};
|
|
4155
|
+
const handleToggleSelectAll = (checked) => {
|
|
4156
|
+
if (checked) {
|
|
4157
|
+
setMode("exclude");
|
|
4158
|
+
setExcludedSet(/* @__PURE__ */ new Set());
|
|
4159
|
+
setCheckedSet(/* @__PURE__ */ new Set());
|
|
4160
|
+
onSelectionChange(void 0);
|
|
4161
|
+
} else {
|
|
4162
|
+
setMode("include");
|
|
4163
|
+
setCheckedSet(/* @__PURE__ */ new Set());
|
|
4164
|
+
setExcludedSet(/* @__PURE__ */ new Set());
|
|
4165
|
+
onSelectionChange(void 0);
|
|
4166
|
+
}
|
|
4167
|
+
};
|
|
4168
|
+
const handleResetFilter = () => {
|
|
4169
|
+
setMode("include");
|
|
4170
|
+
setCheckedSet(/* @__PURE__ */ new Set());
|
|
4171
|
+
setExcludedSet(/* @__PURE__ */ new Set());
|
|
4172
|
+
setSearchQuery("");
|
|
4173
|
+
onSelectionChange(void 0);
|
|
4174
|
+
};
|
|
4175
|
+
if (!isOpen || !coords) return null;
|
|
4176
|
+
const selectedCount = (0, import_react13.useMemo)(() => {
|
|
4177
|
+
if (mode === "exclude") {
|
|
4178
|
+
return Math.max(0, options.length - excludedSet.size);
|
|
4179
|
+
}
|
|
4180
|
+
return checkedSet.size;
|
|
4181
|
+
}, [mode, options.length, excludedSet.size, checkedSet.size]);
|
|
4182
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4183
|
+
"div",
|
|
4184
|
+
{
|
|
4185
|
+
ref: popoverRef,
|
|
4186
|
+
dir: "rtl",
|
|
4187
|
+
style: {
|
|
4188
|
+
top: `${coords.top}px`,
|
|
4189
|
+
right: `${coords.right}px`
|
|
4190
|
+
},
|
|
4191
|
+
className: "fixed z-[99999] w-[260px] bg-white rounded-xl shadow-2xl border border-slate-200 p-2.5 text-right select-none animate-in fade-in duration-100",
|
|
4192
|
+
onClick: (e) => e.stopPropagation(),
|
|
4193
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
4194
|
+
children: [
|
|
4195
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between border-b border-slate-100 pb-2 mb-2", children: [
|
|
4196
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1.5 min-w-0", children: [
|
|
4197
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-xs font-bold text-slate-700 truncate", children: [
|
|
4198
|
+
"\u05E1\u05D9\u05E0\u05D5\u05DF \u05DC\u05E4\u05D9 ",
|
|
4199
|
+
column.name
|
|
4200
|
+
] }),
|
|
4201
|
+
mode === "exclude" && excludedSet.size > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-[10px] text-amber-600 font-semibold", children: [
|
|
4202
|
+
"(\u05D4\u05DB\u05DC \u05DC\u05DE\u05E2\u05D8 ",
|
|
4203
|
+
excludedSet.size,
|
|
4204
|
+
")"
|
|
4205
|
+
] }) : mode === "exclude" && excludedSet.size === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] text-brand font-semibold", children: "(\u05D4\u05DB\u05DC \u05E0\u05D1\u05D7\u05E8)" }) : selectedCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-[10px] text-brand font-semibold", children: [
|
|
4206
|
+
"(",
|
|
4207
|
+
selectedCount,
|
|
4208
|
+
" \u05E0\u05D1\u05D7\u05E8\u05D5)"
|
|
4209
|
+
] }) : null
|
|
4210
|
+
] }),
|
|
4211
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4212
|
+
"button",
|
|
4213
|
+
{
|
|
4214
|
+
type: "button",
|
|
4215
|
+
onClick: onClose,
|
|
4216
|
+
className: "text-slate-400 hover:text-slate-600 p-0.5 rounded hover:bg-slate-100 transition-colors cursor-pointer",
|
|
4217
|
+
title: "\u05E1\u05D2\u05D5\u05E8",
|
|
4218
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.X, { className: "w-3.5 h-3.5" })
|
|
4219
|
+
}
|
|
4220
|
+
)
|
|
4221
|
+
] }),
|
|
4222
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative mb-2", children: [
|
|
4223
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.Search, { className: "w-3.5 h-3.5 text-slate-400 absolute right-2.5 top-1/2 -translate-y-1/2 pointer-events-none" }),
|
|
4224
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4225
|
+
"input",
|
|
4226
|
+
{
|
|
4227
|
+
ref: searchInputRef,
|
|
4228
|
+
type: "text",
|
|
4229
|
+
placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA...",
|
|
4230
|
+
value: searchQuery,
|
|
4231
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
4232
|
+
className: "h-7 text-xs pr-7 pl-6 w-full rounded-md border border-slate-200 bg-slate-50 focus:bg-white focus:border-brand focus:ring-1 focus:ring-brand text-slate-800 transition-all placeholder:text-slate-400"
|
|
4233
|
+
}
|
|
4234
|
+
),
|
|
4235
|
+
searchQuery && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4236
|
+
"button",
|
|
4237
|
+
{
|
|
4238
|
+
type: "button",
|
|
4239
|
+
onClick: () => setSearchQuery(""),
|
|
4240
|
+
className: "absolute left-1.5 top-1/2 -translate-y-1/2 p-0.5 text-slate-400 hover:text-slate-600 rounded",
|
|
4241
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.X, { className: "w-3 h-3" })
|
|
4242
|
+
}
|
|
4243
|
+
)
|
|
4244
|
+
] }),
|
|
4245
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between px-1.5 py-1 mb-1 rounded hover:bg-slate-50 transition-colors border-b border-slate-100 pb-1.5", children: [
|
|
4246
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-xs font-medium text-slate-700 flex-1", children: [
|
|
4247
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4248
|
+
"input",
|
|
4249
|
+
{
|
|
4250
|
+
ref: selectAllRef,
|
|
4251
|
+
type: "checkbox",
|
|
4252
|
+
checked: allFilteredSelected,
|
|
4253
|
+
onChange: (e) => handleToggleSelectAll(e.target.checked),
|
|
4254
|
+
className: "w-3.5 h-3.5 rounded border-slate-300 text-brand focus:ring-brand cursor-pointer accent-[#0d9488]"
|
|
4255
|
+
}
|
|
4256
|
+
),
|
|
4257
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "\u05D1\u05D7\u05E8 \u05D4\u05DB\u05DC" })
|
|
4258
|
+
] }),
|
|
4259
|
+
(mode === "exclude" || checkedSet.size > 0) && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4260
|
+
"button",
|
|
4261
|
+
{
|
|
4262
|
+
type: "button",
|
|
4263
|
+
onClick: handleResetFilter,
|
|
4264
|
+
className: "text-[11px] text-blue-600 hover:text-blue-700 hover:underline flex items-center gap-1 cursor-pointer",
|
|
4265
|
+
title: "\u05E0\u05E7\u05D4 \u05E1\u05D9\u05E0\u05D5\u05DF \u05D5\u05D4\u05E6\u05D2 \u05D4\u05DB\u05DC",
|
|
4266
|
+
children: [
|
|
4267
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.RotateCcw, { className: "w-2.5 h-2.5" }),
|
|
4268
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "\u05E0\u05E7\u05D4" })
|
|
4269
|
+
]
|
|
4270
|
+
}
|
|
4271
|
+
)
|
|
4272
|
+
] }),
|
|
4273
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-h-[250px] overflow-y-auto space-y-0.5 custom-scrollbar pr-0.5", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-center py-6 text-slate-400 text-xs", children: [
|
|
4274
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "w-4 h-4 border-2 border-brand border-t-transparent rounded-full animate-spin ml-2" }),
|
|
4275
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "\u05D8\u05D5\u05E2\u05DF \u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA..." })
|
|
4276
|
+
] }) : filteredOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "py-6 text-center text-xs text-slate-400", children: "\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA" }) : filteredOptions.map((opt) => {
|
|
4277
|
+
const isChecked = isOptionChecked(opt.label);
|
|
4278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4279
|
+
"label",
|
|
4280
|
+
{
|
|
4281
|
+
className: `flex items-center gap-2 px-2 py-1 rounded cursor-pointer transition-colors text-xs ${isChecked ? "text-slate-800 font-medium bg-slate-50/60" : "text-slate-500 hover:bg-slate-50"}`,
|
|
4282
|
+
children: [
|
|
4283
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4284
|
+
"input",
|
|
4285
|
+
{
|
|
4286
|
+
type: "checkbox",
|
|
4287
|
+
checked: isChecked,
|
|
4288
|
+
onChange: () => handleToggleOption(opt.label),
|
|
4289
|
+
className: "w-3.5 h-3.5 rounded border-slate-300 text-brand focus:ring-brand cursor-pointer accent-[#0d9488]"
|
|
4290
|
+
}
|
|
4291
|
+
),
|
|
4292
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "truncate flex-1", title: opt.label, children: opt.label })
|
|
4293
|
+
]
|
|
4294
|
+
},
|
|
4295
|
+
opt.id
|
|
4296
|
+
);
|
|
4297
|
+
}) }),
|
|
4298
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "border-t border-slate-100 pt-1.5 mt-1 flex items-center justify-between text-[11px] text-slate-400 px-1", children: [
|
|
4299
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
4300
|
+
filteredOptions.length,
|
|
4301
|
+
" \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA"
|
|
4302
|
+
] }),
|
|
4303
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4304
|
+
"button",
|
|
4305
|
+
{
|
|
4306
|
+
type: "button",
|
|
4307
|
+
onClick: onClose,
|
|
4308
|
+
className: "text-slate-600 hover:text-slate-900 font-medium px-2 py-0.5 rounded hover:bg-slate-100 transition-colors cursor-pointer",
|
|
4309
|
+
children: "\u05E1\u05D2\u05D5\u05E8"
|
|
4310
|
+
}
|
|
4311
|
+
)
|
|
4312
|
+
] })
|
|
4313
|
+
]
|
|
4314
|
+
}
|
|
4315
|
+
);
|
|
4316
|
+
}
|
|
4317
|
+
|
|
4318
|
+
// src/components/TableBlock/TableBlockClient.tsx
|
|
4319
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
3672
4320
|
function TableBlockClient({
|
|
3673
4321
|
data: initialRecords,
|
|
3674
4322
|
settings: schema,
|
|
3675
4323
|
executeAction,
|
|
4324
|
+
exportAction,
|
|
3676
4325
|
emitEvent,
|
|
3677
4326
|
pageState,
|
|
3678
4327
|
isLoading,
|
|
@@ -3685,6 +4334,7 @@ function TableBlockClient({
|
|
|
3685
4334
|
"data-testid": dataTestId
|
|
3686
4335
|
}) {
|
|
3687
4336
|
const { showError, addToast } = useToast();
|
|
4337
|
+
const [isExporting, setIsExporting] = (0, import_react14.useState)(false);
|
|
3688
4338
|
const tableKey = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id) || (schema == null ? void 0 : schema.name) || "default";
|
|
3689
4339
|
const { columnWidths, startResize } = useColumnResize({
|
|
3690
4340
|
storageKey: `table_widths_${tableKey}`,
|
|
@@ -3695,14 +4345,18 @@ function TableBlockClient({
|
|
|
3695
4345
|
return calculateMinColumnWidth(colName, false, col == null ? void 0 : col.type);
|
|
3696
4346
|
}
|
|
3697
4347
|
});
|
|
3698
|
-
const
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
const [
|
|
3703
|
-
const [
|
|
3704
|
-
const [
|
|
3705
|
-
(0,
|
|
4348
|
+
const executeActionRef = (0, import_react14.useRef)(executeAction);
|
|
4349
|
+
(0, import_react14.useEffect)(() => {
|
|
4350
|
+
executeActionRef.current = executeAction;
|
|
4351
|
+
}, [executeAction]);
|
|
4352
|
+
const [isMounted, setIsMounted] = (0, import_react14.useState)(false);
|
|
4353
|
+
const [isInitialLoading, setIsInitialLoading] = (0, import_react14.useState)(true);
|
|
4354
|
+
const [page, setPage] = (0, import_react14.useState)(1);
|
|
4355
|
+
const [limit, setLimit] = (0, import_react14.useState)(50);
|
|
4356
|
+
const [totalRecords, setTotalRecords] = (0, import_react14.useState)(0);
|
|
4357
|
+
const [totalPages, setTotalPages] = (0, import_react14.useState)(1);
|
|
4358
|
+
const [showSummary, setShowSummary] = (0, import_react14.useState)(false);
|
|
4359
|
+
(0, import_react14.useEffect)(() => {
|
|
3706
4360
|
if (typeof window !== "undefined") {
|
|
3707
4361
|
const savedSummary = localStorage.getItem(`table_summary_${tableKey}`);
|
|
3708
4362
|
if (savedSummary !== null) {
|
|
@@ -3751,7 +4405,7 @@ function TableBlockClient({
|
|
|
3751
4405
|
return __spreadProps(__spreadValues({}, row), { id: String(row.id || ""), data: rowData });
|
|
3752
4406
|
});
|
|
3753
4407
|
};
|
|
3754
|
-
const mergeColumnDefs = (0,
|
|
4408
|
+
const mergeColumnDefs = (0, import_react14.useCallback)((existingCols, incomingCols) => {
|
|
3755
4409
|
if (!incomingCols || incomingCols.length === 0) return existingCols || [];
|
|
3756
4410
|
if (!existingCols || existingCols.length === 0) return incomingCols;
|
|
3757
4411
|
const existingMap = new Map(existingCols.map((c) => [c.name, c]));
|
|
@@ -3771,18 +4425,18 @@ function TableBlockClient({
|
|
|
3771
4425
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
3772
4426
|
});
|
|
3773
4427
|
}, []);
|
|
3774
|
-
const [localColumns, setLocalColumns] = (0,
|
|
3775
|
-
(0,
|
|
4428
|
+
const [localColumns, setLocalColumns] = (0, import_react14.useState)(() => (schema == null ? void 0 : schema.columns) || []);
|
|
4429
|
+
(0, import_react14.useEffect)(() => {
|
|
3776
4430
|
if ((schema == null ? void 0 : schema.columns) && schema.columns.length > 0) {
|
|
3777
4431
|
setLocalColumns((prev) => mergeColumnDefs(prev, schema.columns));
|
|
3778
4432
|
}
|
|
3779
4433
|
}, [schema == null ? void 0 : schema.columns, mergeColumnDefs]);
|
|
3780
|
-
const [dirty, setDirty] = (0,
|
|
3781
|
-
const dirtyRef = (0,
|
|
3782
|
-
(0,
|
|
4434
|
+
const [dirty, setDirty] = (0, import_react14.useState)({ added: [], modified: {}, deleted: [] });
|
|
4435
|
+
const dirtyRef = (0, import_react14.useRef)(dirty);
|
|
4436
|
+
(0, import_react14.useEffect)(() => {
|
|
3783
4437
|
dirtyRef.current = dirty;
|
|
3784
4438
|
}, [dirty]);
|
|
3785
|
-
const mergeWithDirty = (0,
|
|
4439
|
+
const mergeWithDirty = (0, import_react14.useCallback)((baseRecords) => {
|
|
3786
4440
|
const { added, modified, deleted } = dirtyRef.current;
|
|
3787
4441
|
const nonDeleted = (baseRecords || []).filter((r) => !deleted.includes(r.id));
|
|
3788
4442
|
const modifiedRecords = nonDeleted.map((r) => {
|
|
@@ -3795,9 +4449,10 @@ function TableBlockClient({
|
|
|
3795
4449
|
const uniqueAdded = added.filter((r) => !baseIds.has(r.id));
|
|
3796
4450
|
return [...uniqueAdded, ...modifiedRecords];
|
|
3797
4451
|
}, []);
|
|
3798
|
-
const [data, setData] = (0,
|
|
3799
|
-
const [serverRecords, setServerRecords] = (0,
|
|
3800
|
-
|
|
4452
|
+
const [data, setData] = (0, import_react14.useState)(() => normalizeRecords(initialRecords));
|
|
4453
|
+
const [serverRecords, setServerRecords] = (0, import_react14.useState)(() => normalizeRecords(initialRecords));
|
|
4454
|
+
const filteredData = data;
|
|
4455
|
+
(0, import_react14.useEffect)(() => {
|
|
3801
4456
|
if (initialRecords) {
|
|
3802
4457
|
const norm = normalizeRecords(initialRecords);
|
|
3803
4458
|
setServerRecords(norm);
|
|
@@ -3814,27 +4469,114 @@ function TableBlockClient({
|
|
|
3814
4469
|
}
|
|
3815
4470
|
return false;
|
|
3816
4471
|
};
|
|
3817
|
-
const [baseRecordsMap, setBaseRecordsMap] = (0,
|
|
4472
|
+
const [baseRecordsMap, setBaseRecordsMap] = (0, import_react14.useState)(() => {
|
|
3818
4473
|
const map = /* @__PURE__ */ new Map();
|
|
3819
4474
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
3820
4475
|
return map;
|
|
3821
4476
|
});
|
|
3822
|
-
(0,
|
|
4477
|
+
(0, import_react14.useEffect)(() => {
|
|
3823
4478
|
if (initialRecords && initialRecords.length > 0) {
|
|
3824
4479
|
const map = /* @__PURE__ */ new Map();
|
|
3825
4480
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
3826
4481
|
setBaseRecordsMap(map);
|
|
3827
4482
|
}
|
|
3828
4483
|
}, [initialRecords]);
|
|
3829
|
-
const
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
4484
|
+
const [searchQuery, setSearchQuery] = (0, import_react14.useState)("");
|
|
4485
|
+
const [columnFilters, setColumnFilters] = (0, import_react14.useState)({});
|
|
4486
|
+
const [activeSearchCol, setActiveSearchCol] = (0, import_react14.useState)(null);
|
|
4487
|
+
const activeSearchRef = (0, import_react14.useRef)(null);
|
|
4488
|
+
const [activeRelationCol, setActiveRelationCol] = (0, import_react14.useState)(null);
|
|
4489
|
+
const [relationTriggerRect, setRelationTriggerRect] = (0, import_react14.useState)(null);
|
|
4490
|
+
const filterButtonRefs = (0, import_react14.useRef)({});
|
|
4491
|
+
const [relationOptions, setRelationOptions] = (0, import_react14.useState)({});
|
|
4492
|
+
const [relationFilterOptions, setRelationFilterOptions] = (0, import_react14.useState)({});
|
|
4493
|
+
const [loadingFilterCol, setLoadingFilterCol] = (0, import_react14.useState)(null);
|
|
4494
|
+
const relationDictionaryRef = (0, import_react14.useRef)({});
|
|
4495
|
+
const mergeRelationOptions = (0, import_react14.useCallback)((colName, newOptions) => {
|
|
4496
|
+
if (!Array.isArray(newOptions) || newOptions.length === 0) return;
|
|
4497
|
+
if (!relationDictionaryRef.current[colName]) {
|
|
4498
|
+
relationDictionaryRef.current[colName] = /* @__PURE__ */ new Map();
|
|
4499
|
+
}
|
|
4500
|
+
const dict = relationDictionaryRef.current[colName];
|
|
4501
|
+
let hasNew = false;
|
|
4502
|
+
for (const opt of newOptions) {
|
|
4503
|
+
if (!opt) continue;
|
|
4504
|
+
const id = String(opt.id || opt._id || "");
|
|
4505
|
+
if (!id) continue;
|
|
4506
|
+
const existing = dict.get(id);
|
|
4507
|
+
if (!existing || opt.label && !existing.label) {
|
|
4508
|
+
dict.set(id, opt);
|
|
4509
|
+
hasNew = true;
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4512
|
+
if (hasNew) {
|
|
4513
|
+
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
4514
|
+
[colName]: Array.from(dict.values())
|
|
4515
|
+
}));
|
|
4516
|
+
}
|
|
4517
|
+
}, []);
|
|
4518
|
+
(0, import_react14.useEffect)(() => {
|
|
4519
|
+
if (!activeSearchCol) return;
|
|
4520
|
+
const handleMouseDown = (e) => {
|
|
4521
|
+
if (activeSearchRef.current && !activeSearchRef.current.contains(e.target)) {
|
|
4522
|
+
setActiveSearchCol(null);
|
|
4523
|
+
}
|
|
4524
|
+
};
|
|
4525
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
4526
|
+
return () => {
|
|
4527
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
4528
|
+
};
|
|
4529
|
+
}, [activeSearchCol]);
|
|
4530
|
+
const filtersKey = (0, import_react14.useMemo)(() => {
|
|
4531
|
+
const active = {};
|
|
4532
|
+
Object.entries(columnFilters).forEach(([k, v]) => {
|
|
4533
|
+
if (Array.isArray(v) && v.length > 0) active[k] = v;
|
|
4534
|
+
else if (v && typeof v === "object" && "operator" in v && Array.isArray(v.values) && v.values.length > 0) active[k] = v;
|
|
4535
|
+
else if (typeof v === "string" && v.trim()) active[k] = v.trim();
|
|
4536
|
+
});
|
|
4537
|
+
return JSON.stringify(active);
|
|
4538
|
+
}, [columnFilters]);
|
|
4539
|
+
const [debouncedSearch, setDebouncedSearch] = (0, import_react14.useState)(searchQuery);
|
|
4540
|
+
(0, import_react14.useEffect)(() => {
|
|
4541
|
+
const timer = setTimeout(() => {
|
|
4542
|
+
setDebouncedSearch(searchQuery.trim());
|
|
4543
|
+
}, 300);
|
|
4544
|
+
return () => clearTimeout(timer);
|
|
4545
|
+
}, [searchQuery]);
|
|
4546
|
+
const isSearchMountedRef = (0, import_react14.useRef)(false);
|
|
4547
|
+
(0, import_react14.useEffect)(() => {
|
|
4548
|
+
if (!isSearchMountedRef.current) {
|
|
4549
|
+
isSearchMountedRef.current = true;
|
|
4550
|
+
return;
|
|
4551
|
+
}
|
|
4552
|
+
setPage(1);
|
|
4553
|
+
}, [debouncedSearch]);
|
|
4554
|
+
const [isFetching, setIsFetching] = (0, import_react14.useState)(false);
|
|
4555
|
+
const fetchRequestIdRef = (0, import_react14.useRef)(0);
|
|
4556
|
+
const fetchTableData = (0, import_react14.useCallback)((targetPage, targetLimit, targetSearch, targetFiltersKey) => {
|
|
4557
|
+
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
4558
|
+
const action = executeActionRef.current;
|
|
4559
|
+
if (!tableId || !action) return Promise.resolve();
|
|
4560
|
+
const currentRequestId = ++fetchRequestIdRef.current;
|
|
4561
|
+
setIsFetching(true);
|
|
4562
|
+
let activeFilters = {};
|
|
4563
|
+
try {
|
|
4564
|
+
activeFilters = JSON.parse(targetFiltersKey);
|
|
4565
|
+
} catch (e) {
|
|
4566
|
+
}
|
|
4567
|
+
const skip = (targetPage - 1) * targetLimit;
|
|
4568
|
+
return action("FETCH_TABLE_DATA", {
|
|
4569
|
+
tableId,
|
|
4570
|
+
page: targetPage,
|
|
4571
|
+
limit: targetLimit,
|
|
4572
|
+
skip,
|
|
4573
|
+
search: targetSearch || void 0,
|
|
4574
|
+
columnFilters: Object.keys(activeFilters).length > 0 ? activeFilters : void 0
|
|
4575
|
+
}).then((res) => {
|
|
4576
|
+
var _a;
|
|
4577
|
+
if (currentRequestId !== fetchRequestIdRef.current) return;
|
|
4578
|
+
if (res) {
|
|
4579
|
+
if (((_a = res.schema) == null ? void 0 : _a.columns) && res.schema.columns.length > 0) {
|
|
3838
4580
|
setLocalColumns((prev) => mergeColumnDefs(prev, res.schema.columns));
|
|
3839
4581
|
}
|
|
3840
4582
|
if (res.records && Array.isArray(res.records)) {
|
|
@@ -3847,37 +4589,50 @@ function TableBlockClient({
|
|
|
3847
4589
|
}
|
|
3848
4590
|
if (res.meta) {
|
|
3849
4591
|
const total = typeof res.meta.totalRecords === "number" ? res.meta.totalRecords : 0;
|
|
3850
|
-
const pages = typeof res.meta.totalPages === "number" ? res.meta.totalPages : Math.ceil(total /
|
|
4592
|
+
const pages = typeof res.meta.totalPages === "number" ? res.meta.totalPages : Math.ceil(total / targetLimit) || 1;
|
|
3851
4593
|
setTotalRecords(total);
|
|
3852
4594
|
setTotalPages(pages);
|
|
3853
|
-
if (activePage > pages && pages >= 1) {
|
|
3854
|
-
setPage(pages);
|
|
3855
|
-
}
|
|
3856
4595
|
} else if (res.records && Array.isArray(res.records)) {
|
|
3857
4596
|
setTotalRecords(res.records.length);
|
|
3858
|
-
setTotalPages(Math.ceil(res.records.length /
|
|
4597
|
+
setTotalPages(Math.ceil(res.records.length / targetLimit) || 1);
|
|
4598
|
+
}
|
|
4599
|
+
if (res.relationOptions && typeof res.relationOptions === "object") {
|
|
4600
|
+
for (const [colName, opts] of Object.entries(res.relationOptions)) {
|
|
4601
|
+
if (Array.isArray(opts)) {
|
|
4602
|
+
mergeRelationOptions(colName, opts);
|
|
4603
|
+
}
|
|
4604
|
+
}
|
|
3859
4605
|
}
|
|
3860
4606
|
}
|
|
3861
4607
|
}).catch((err) => {
|
|
3862
|
-
|
|
4608
|
+
if (currentRequestId === fetchRequestIdRef.current) {
|
|
4609
|
+
console.error("[TableBlock] Failed to fetch table data:", err);
|
|
4610
|
+
}
|
|
4611
|
+
}).finally(() => {
|
|
4612
|
+
if (currentRequestId === fetchRequestIdRef.current) {
|
|
4613
|
+
setIsFetching(false);
|
|
4614
|
+
setIsInitialLoading(false);
|
|
4615
|
+
}
|
|
3863
4616
|
});
|
|
3864
|
-
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id,
|
|
3865
|
-
(0,
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
});
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
4617
|
+
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, mergeColumnDefs, mergeWithDirty, mergeRelationOptions]);
|
|
4618
|
+
(0, import_react14.useEffect)(() => {
|
|
4619
|
+
fetchTableData(page, limit, debouncedSearch, filtersKey);
|
|
4620
|
+
}, [page, limit, debouncedSearch, filtersKey, fetchTableData]);
|
|
4621
|
+
const refetchTableData = (0, import_react14.useCallback)(() => {
|
|
4622
|
+
return fetchTableData(page, limit, debouncedSearch, filtersKey);
|
|
4623
|
+
}, [page, limit, debouncedSearch, filtersKey, fetchTableData]);
|
|
4624
|
+
const handleApplyColumnFilter = (0, import_react14.useCallback)((colName, nextVal) => {
|
|
4625
|
+
setColumnFilters((prev) => {
|
|
4626
|
+
const next = __spreadValues({}, prev);
|
|
4627
|
+
if (nextVal === void 0 || Array.isArray(nextVal) && nextVal.length === 0 || typeof nextVal === "string" && !nextVal.trim() || typeof nextVal === "object" && "values" in nextVal && Array.isArray(nextVal.values) && nextVal.values.length === 0) {
|
|
4628
|
+
delete next[colName];
|
|
4629
|
+
} else {
|
|
4630
|
+
next[colName] = nextVal;
|
|
4631
|
+
}
|
|
4632
|
+
return next;
|
|
4633
|
+
});
|
|
4634
|
+
setPage(1);
|
|
4635
|
+
}, []);
|
|
3881
4636
|
const handleLimitChange = (newLimit) => {
|
|
3882
4637
|
setLimit(newLimit);
|
|
3883
4638
|
setPage(1);
|
|
@@ -3891,37 +4646,15 @@ function TableBlockClient({
|
|
|
3891
4646
|
const handleNextPage = () => {
|
|
3892
4647
|
setPage((prev) => Math.min(totalPages, prev + 1));
|
|
3893
4648
|
};
|
|
3894
|
-
(0,
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
}
|
|
3898
|
-
}, [error, showError]);
|
|
3899
|
-
const [searchQuery, setSearchQuery] = (0, import_react12.useState)("");
|
|
3900
|
-
const [columnFilters, setColumnFilters] = (0, import_react12.useState)({});
|
|
3901
|
-
const [activeSearchCol, setActiveSearchCol] = (0, import_react12.useState)(null);
|
|
3902
|
-
const activeSearchRef = (0, import_react12.useRef)(null);
|
|
3903
|
-
(0, import_react12.useEffect)(() => {
|
|
3904
|
-
if (!activeSearchCol) return;
|
|
3905
|
-
const handleMouseDown = (e) => {
|
|
3906
|
-
if (activeSearchRef.current && !activeSearchRef.current.contains(e.target)) {
|
|
3907
|
-
setActiveSearchCol(null);
|
|
3908
|
-
}
|
|
3909
|
-
};
|
|
3910
|
-
document.addEventListener("mousedown", handleMouseDown);
|
|
3911
|
-
return () => {
|
|
3912
|
-
document.removeEventListener("mousedown", handleMouseDown);
|
|
3913
|
-
};
|
|
3914
|
-
}, [activeSearchCol]);
|
|
3915
|
-
const [selectedIds, setSelectedIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
3916
|
-
const [pendingDeletions, setPendingDeletions] = (0, import_react12.useState)([]);
|
|
3917
|
-
const [isSaving, setIsSaving] = (0, import_react12.useState)(false);
|
|
4649
|
+
const [selectedIds, setSelectedIds] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
4650
|
+
const [pendingDeletions, setPendingDeletions] = (0, import_react14.useState)([]);
|
|
4651
|
+
const [isSaving, setIsSaving] = (0, import_react14.useState)(false);
|
|
3918
4652
|
const isUpdatingActive = Boolean(isUpdating || isSaving);
|
|
3919
|
-
const [isSaveSuccess, setIsSaveSuccess] = (0,
|
|
3920
|
-
const [
|
|
3921
|
-
const
|
|
3922
|
-
const
|
|
3923
|
-
|
|
3924
|
-
var _a, _b, _c;
|
|
4653
|
+
const [isSaveSuccess, setIsSaveSuccess] = (0, import_react14.useState)(false);
|
|
4654
|
+
const [expandedRowIds, setExpandedRowIds] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
4655
|
+
const schemaColsString = (0, import_react14.useMemo)(() => JSON.stringify(localColumns || []), [localColumns]);
|
|
4656
|
+
const refetchRelation = (0, import_react14.useCallback)(async (colName, params) => {
|
|
4657
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
3925
4658
|
let parsedCols = [];
|
|
3926
4659
|
try {
|
|
3927
4660
|
parsedCols = JSON.parse(schemaColsString);
|
|
@@ -3931,19 +4664,125 @@ function TableBlockClient({
|
|
|
3931
4664
|
var _a2;
|
|
3932
4665
|
return c.name === colName && ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION";
|
|
3933
4666
|
});
|
|
3934
|
-
if (!col || !((_a = col.config) == null ? void 0 : _a.referencedTableId)) return;
|
|
4667
|
+
if (!col || !((_a = col.config) == null ? void 0 : _a.referencedTableId)) return [];
|
|
3935
4668
|
try {
|
|
3936
4669
|
if (executeAction) {
|
|
3937
|
-
const
|
|
3938
|
-
|
|
3939
|
-
|
|
4670
|
+
const take = (_c = (_b = params == null ? void 0 : params.take) != null ? _b : params == null ? void 0 : params.limit) != null ? _c : 1e3;
|
|
4671
|
+
const payload = {
|
|
4672
|
+
referencedTableId: (_d = col.config) == null ? void 0 : _d.referencedTableId,
|
|
4673
|
+
displayField: (_e = col.config) == null ? void 0 : _e.displayField
|
|
4674
|
+
};
|
|
4675
|
+
if (params == null ? void 0 : params.recordIds) {
|
|
4676
|
+
payload.recordIds = params.recordIds;
|
|
4677
|
+
} else {
|
|
4678
|
+
payload.take = take;
|
|
4679
|
+
payload.limit = take;
|
|
4680
|
+
payload.skip = (_f = params == null ? void 0 : params.skip) != null ? _f : 0;
|
|
4681
|
+
payload.search = (_g = params == null ? void 0 : params.search) != null ? _g : "";
|
|
4682
|
+
}
|
|
4683
|
+
const options = await executeAction("FETCH_RELATION", payload);
|
|
4684
|
+
const list = Array.isArray(options) ? options : (options == null ? void 0 : options.data) && Array.isArray(options.data) ? options.data : [];
|
|
4685
|
+
if (list && Array.isArray(list)) {
|
|
4686
|
+
mergeRelationOptions(colName, list);
|
|
4687
|
+
return list;
|
|
3940
4688
|
}
|
|
3941
4689
|
}
|
|
3942
4690
|
} catch (err) {
|
|
3943
4691
|
console.warn(`[TableBlock] Could not fetch relation options for column ${colName}:`, err);
|
|
3944
4692
|
}
|
|
3945
|
-
|
|
3946
|
-
|
|
4693
|
+
return [];
|
|
4694
|
+
}, [schemaColsString, executeAction, mergeRelationOptions]);
|
|
4695
|
+
const fetchRelationFilterOptions = (0, import_react14.useCallback)(async (colName) => {
|
|
4696
|
+
var _a;
|
|
4697
|
+
let parsedCols = [];
|
|
4698
|
+
try {
|
|
4699
|
+
parsedCols = JSON.parse(schemaColsString);
|
|
4700
|
+
} catch (e) {
|
|
4701
|
+
}
|
|
4702
|
+
const col = parsedCols.find((c) => {
|
|
4703
|
+
var _a2;
|
|
4704
|
+
return c.name === colName && ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION";
|
|
4705
|
+
});
|
|
4706
|
+
if (!col || !((_a = col.config) == null ? void 0 : _a.referencedTableId) || !executeAction) return;
|
|
4707
|
+
const currentTableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
4708
|
+
setLoadingFilterCol(colName);
|
|
4709
|
+
try {
|
|
4710
|
+
const res = await executeAction("FETCH_RELATION", {
|
|
4711
|
+
referencedTableId: col.config.referencedTableId,
|
|
4712
|
+
currentTableId,
|
|
4713
|
+
columnName: colName,
|
|
4714
|
+
isFilter: true,
|
|
4715
|
+
displayField: col.config.displayField,
|
|
4716
|
+
take: 1e3
|
|
4717
|
+
});
|
|
4718
|
+
const list = Array.isArray(res) ? res : (res == null ? void 0 : res.data) && Array.isArray(res.data) ? res.data : [];
|
|
4719
|
+
setRelationFilterOptions((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
4720
|
+
[colName]: list
|
|
4721
|
+
}));
|
|
4722
|
+
if (list.length > 0) {
|
|
4723
|
+
mergeRelationOptions(colName, list);
|
|
4724
|
+
}
|
|
4725
|
+
} catch (err) {
|
|
4726
|
+
console.warn(`[TableBlock] Failed to fetch distinct relation filter options for ${colName}:`, err);
|
|
4727
|
+
} finally {
|
|
4728
|
+
setLoadingFilterCol(null);
|
|
4729
|
+
}
|
|
4730
|
+
}, [schemaColsString, schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, executeAction, mergeRelationOptions]);
|
|
4731
|
+
const requestedRelationIdsRef = (0, import_react14.useRef)({});
|
|
4732
|
+
(0, import_react14.useEffect)(() => {
|
|
4733
|
+
if (!executeAction || !data || data.length === 0) return;
|
|
4734
|
+
let parsedCols = [];
|
|
4735
|
+
try {
|
|
4736
|
+
parsedCols = JSON.parse(schemaColsString);
|
|
4737
|
+
} catch (e) {
|
|
4738
|
+
}
|
|
4739
|
+
const relationCols = parsedCols.filter(
|
|
4740
|
+
(c) => {
|
|
4741
|
+
var _a;
|
|
4742
|
+
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "RELATION";
|
|
4743
|
+
}
|
|
4744
|
+
);
|
|
4745
|
+
if (relationCols.length === 0) return;
|
|
4746
|
+
relationCols.forEach(async (col) => {
|
|
4747
|
+
var _a, _b;
|
|
4748
|
+
const referencedTableId = (_a = col.config) == null ? void 0 : _a.referencedTableId;
|
|
4749
|
+
if (!referencedTableId) return;
|
|
4750
|
+
const extractedIds = /* @__PURE__ */ new Set();
|
|
4751
|
+
data.forEach((row) => {
|
|
4752
|
+
if (!(row == null ? void 0 : row.data)) return;
|
|
4753
|
+
const ids = normalizeRelationValue(row.data[col.name]);
|
|
4754
|
+
ids.forEach((id) => {
|
|
4755
|
+
if (/^[0-9a-fA-F]{24}$/.test(id)) {
|
|
4756
|
+
extractedIds.add(id);
|
|
4757
|
+
}
|
|
4758
|
+
});
|
|
4759
|
+
});
|
|
4760
|
+
if (extractedIds.size === 0) return;
|
|
4761
|
+
const existingOptions = relationOptions[col.name] || [];
|
|
4762
|
+
const existingIds = new Set(existingOptions.map((o) => String(o.id)));
|
|
4763
|
+
if (!requestedRelationIdsRef.current[col.name]) {
|
|
4764
|
+
requestedRelationIdsRef.current[col.name] = /* @__PURE__ */ new Set();
|
|
4765
|
+
}
|
|
4766
|
+
const inFlight = requestedRelationIdsRef.current[col.name];
|
|
4767
|
+
const missingIds = Array.from(extractedIds).filter((id) => !existingIds.has(id) && !inFlight.has(id));
|
|
4768
|
+
if (missingIds.length === 0) return;
|
|
4769
|
+
missingIds.forEach((id) => inFlight.add(id));
|
|
4770
|
+
try {
|
|
4771
|
+
const resolved = await executeAction("FETCH_RELATION", {
|
|
4772
|
+
referencedTableId,
|
|
4773
|
+
displayField: (_b = col.config) == null ? void 0 : _b.displayField,
|
|
4774
|
+
recordIds: missingIds
|
|
4775
|
+
});
|
|
4776
|
+
const items = Array.isArray(resolved) ? resolved : (resolved == null ? void 0 : resolved.data) && Array.isArray(resolved.data) ? resolved.data : [];
|
|
4777
|
+
if (items.length > 0) {
|
|
4778
|
+
mergeRelationOptions(col.name, items);
|
|
4779
|
+
}
|
|
4780
|
+
} catch (err) {
|
|
4781
|
+
console.warn(`[TableBlock] Failed to populate relations for ${col.name}:`, err);
|
|
4782
|
+
}
|
|
4783
|
+
});
|
|
4784
|
+
}, [data, schemaColsString, executeAction, relationOptions, mergeRelationOptions]);
|
|
4785
|
+
(0, import_react14.useEffect)(() => {
|
|
3947
4786
|
let parsedCols = [];
|
|
3948
4787
|
try {
|
|
3949
4788
|
parsedCols = JSON.parse(schemaColsString);
|
|
@@ -3957,7 +4796,7 @@ function TableBlockClient({
|
|
|
3957
4796
|
refetchRelation(col.name);
|
|
3958
4797
|
});
|
|
3959
4798
|
}, [schemaColsString, refetchRelation]);
|
|
3960
|
-
const normalizedColumns = (0,
|
|
4799
|
+
const normalizedColumns = (0, import_react14.useMemo)(() => {
|
|
3961
4800
|
return (localColumns || []).map((col, idx) => {
|
|
3962
4801
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
3963
4802
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
@@ -3971,17 +4810,17 @@ function TableBlockClient({
|
|
|
3971
4810
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
3972
4811
|
});
|
|
3973
4812
|
}, [localColumns]);
|
|
3974
|
-
const filteredColumns = (0,
|
|
4813
|
+
const filteredColumns = (0, import_react14.useMemo)(() => {
|
|
3975
4814
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
3976
4815
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name) && !col.isHidden);
|
|
3977
4816
|
}, [normalizedColumns]);
|
|
3978
|
-
const customizableColumns = (0,
|
|
4817
|
+
const customizableColumns = (0, import_react14.useMemo)(() => {
|
|
3979
4818
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
3980
4819
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name));
|
|
3981
4820
|
}, [normalizedColumns]);
|
|
3982
|
-
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = (0,
|
|
3983
|
-
const dropdownRef = (0,
|
|
3984
|
-
(0,
|
|
4821
|
+
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = (0, import_react14.useState)(false);
|
|
4822
|
+
const dropdownRef = (0, import_react14.useRef)(null);
|
|
4823
|
+
(0, import_react14.useEffect)(() => {
|
|
3985
4824
|
const handleClickOutside = (e) => {
|
|
3986
4825
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
3987
4826
|
setIsColumnsDropdownOpen(false);
|
|
@@ -4191,46 +5030,45 @@ function TableBlockClient({
|
|
|
4191
5030
|
setData((prev) => [newRow, ...prev]);
|
|
4192
5031
|
setDirty((prev) => __spreadProps(__spreadValues({}, prev), { added: [newRow, ...prev.added] }));
|
|
4193
5032
|
};
|
|
4194
|
-
const handleCellChange = (rowId, colName, value) => {
|
|
5033
|
+
const handleCellChange = (0, import_react14.useCallback)((rowId, colName, value) => {
|
|
4195
5034
|
setData((prev) => prev.map(
|
|
4196
5035
|
(row) => row.id === rowId ? __spreadProps(__spreadValues({}, row), { data: __spreadProps(__spreadValues({}, row.data), { [colName]: value }) }) : row
|
|
4197
5036
|
));
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
added: prev.added.map(
|
|
4202
|
-
(r) => r.id === rowId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value }) }) : r
|
|
4203
|
-
)
|
|
4204
|
-
}));
|
|
4205
|
-
} else {
|
|
4206
|
-
const origData = baseRecordsMap.get(rowId) || {};
|
|
4207
|
-
const origValue = origData[colName];
|
|
4208
|
-
setDirty((prev) => {
|
|
4209
|
-
const currentMods = __spreadValues({}, prev.modified[rowId] || {});
|
|
4210
|
-
if (isEqualValues(value, origValue)) {
|
|
4211
|
-
delete currentMods[colName];
|
|
4212
|
-
} else {
|
|
4213
|
-
currentMods[colName] = value;
|
|
4214
|
-
}
|
|
4215
|
-
const nextModified = __spreadValues({}, prev.modified);
|
|
4216
|
-
if (Object.keys(currentMods).length === 0) {
|
|
4217
|
-
delete nextModified[rowId];
|
|
4218
|
-
} else {
|
|
4219
|
-
nextModified[rowId] = currentMods;
|
|
4220
|
-
}
|
|
5037
|
+
setDirty((prev) => {
|
|
5038
|
+
const isAdded = prev.added.some((r) => r.id === rowId);
|
|
5039
|
+
if (isAdded) {
|
|
4221
5040
|
return __spreadProps(__spreadValues({}, prev), {
|
|
4222
|
-
|
|
5041
|
+
added: prev.added.map(
|
|
5042
|
+
(r) => r.id === rowId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value }) }) : r
|
|
5043
|
+
)
|
|
4223
5044
|
});
|
|
5045
|
+
}
|
|
5046
|
+
const origData = baseRecordsMap.get(rowId) || {};
|
|
5047
|
+
const origValue = origData[colName];
|
|
5048
|
+
const currentMods = __spreadValues({}, prev.modified[rowId] || {});
|
|
5049
|
+
if (isEqualValues(value, origValue)) {
|
|
5050
|
+
delete currentMods[colName];
|
|
5051
|
+
} else {
|
|
5052
|
+
currentMods[colName] = value;
|
|
5053
|
+
}
|
|
5054
|
+
const nextModified = __spreadValues({}, prev.modified);
|
|
5055
|
+
if (Object.keys(currentMods).length === 0) {
|
|
5056
|
+
delete nextModified[rowId];
|
|
5057
|
+
} else {
|
|
5058
|
+
nextModified[rowId] = currentMods;
|
|
5059
|
+
}
|
|
5060
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
5061
|
+
modified: nextModified
|
|
4224
5062
|
});
|
|
4225
|
-
}
|
|
4226
|
-
};
|
|
4227
|
-
const triggerSaveSuccess = (0,
|
|
5063
|
+
});
|
|
5064
|
+
}, [baseRecordsMap]);
|
|
5065
|
+
const triggerSaveSuccess = (0, import_react14.useCallback)(() => {
|
|
4228
5066
|
setIsSaveSuccess(true);
|
|
4229
5067
|
setTimeout(() => {
|
|
4230
5068
|
setIsSaveSuccess(false);
|
|
4231
5069
|
}, 2500);
|
|
4232
5070
|
}, []);
|
|
4233
|
-
const handleQuietCellChange = (0,
|
|
5071
|
+
const handleQuietCellChange = (0, import_react14.useCallback)((rowId, colName, value) => {
|
|
4234
5072
|
setData((prev) => prev.map(
|
|
4235
5073
|
(row) => row.id === rowId ? __spreadProps(__spreadValues({}, row), { data: __spreadProps(__spreadValues({}, row.data), { [colName]: value }) }) : row
|
|
4236
5074
|
));
|
|
@@ -4254,22 +5092,28 @@ function TableBlockClient({
|
|
|
4254
5092
|
});
|
|
4255
5093
|
}
|
|
4256
5094
|
}, []);
|
|
4257
|
-
const toggleSelectAll = (checked) => {
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
5095
|
+
const toggleSelectAll = (0, import_react14.useCallback)((checked) => {
|
|
5096
|
+
setSelectedIds(checked ? new Set(filteredData.map((r) => r.id)) : /* @__PURE__ */ new Set());
|
|
5097
|
+
}, [filteredData]);
|
|
5098
|
+
const toggleSelectRow = (0, import_react14.useCallback)((rowId, checked) => {
|
|
5099
|
+
setSelectedIds((prev) => {
|
|
5100
|
+
const next = new Set(prev);
|
|
5101
|
+
if (checked) next.add(rowId);
|
|
5102
|
+
else next.delete(rowId);
|
|
5103
|
+
return next;
|
|
5104
|
+
});
|
|
5105
|
+
}, []);
|
|
5106
|
+
const handleToggleExpand = (0, import_react14.useCallback)((rowId) => {
|
|
5107
|
+
setExpandedRowIds((prev) => {
|
|
5108
|
+
const next = new Set(prev);
|
|
5109
|
+
if (next.has(rowId)) next.delete(rowId);
|
|
5110
|
+
else next.add(rowId);
|
|
5111
|
+
return next;
|
|
5112
|
+
});
|
|
5113
|
+
}, []);
|
|
5114
|
+
const handleMarkForDeletion = (0, import_react14.useCallback)((fileId) => {
|
|
5115
|
+
setPendingDeletions((prev) => [...prev, fileId]);
|
|
5116
|
+
}, []);
|
|
4273
5117
|
const handleDeleteSelected = () => {
|
|
4274
5118
|
const idsToDelete = Array.from(selectedIds);
|
|
4275
5119
|
if (idsToDelete.length === 0) return;
|
|
@@ -4348,9 +5192,6 @@ function TableBlockClient({
|
|
|
4348
5192
|
setData(serverRecords.map((r) => __spreadProps(__spreadValues({}, r), { data: __spreadValues({}, r.data) })));
|
|
4349
5193
|
setSelectedIds(/* @__PURE__ */ new Set());
|
|
4350
5194
|
setPendingDeletions([]);
|
|
4351
|
-
if (emitEvent) {
|
|
4352
|
-
emitEvent("SELECTION_CHANGE", { selectedIds: [], componentId });
|
|
4353
|
-
}
|
|
4354
5195
|
};
|
|
4355
5196
|
const handleSave = async () => {
|
|
4356
5197
|
var _a, _b;
|
|
@@ -4498,7 +5339,7 @@ function TableBlockClient({
|
|
|
4498
5339
|
setIsSaving(false);
|
|
4499
5340
|
}
|
|
4500
5341
|
};
|
|
4501
|
-
const getRowRelationLabels = (0,
|
|
5342
|
+
const getRowRelationLabels = (0, import_react14.useCallback)((rowVal, col) => {
|
|
4502
5343
|
const ids = normalizeRelationValue(rowVal);
|
|
4503
5344
|
if (ids.length === 0) return [];
|
|
4504
5345
|
const options = relationOptions[col.name] || [];
|
|
@@ -4506,19 +5347,23 @@ function TableBlockClient({
|
|
|
4506
5347
|
const opt = options.find((o) => o.id === id || o._id === id);
|
|
4507
5348
|
if (opt) {
|
|
4508
5349
|
const resolved = resolveRelationLabel(opt, col);
|
|
4509
|
-
if (resolved) return resolved;
|
|
4510
|
-
if (opt.label) return String(opt.label);
|
|
4511
|
-
if (opt.name) return String(opt.name);
|
|
5350
|
+
if (resolved && !isRawObjectId(resolved)) return resolved;
|
|
5351
|
+
if (opt.label && !isRawObjectId(String(opt.label))) return String(opt.label);
|
|
5352
|
+
if (opt.name && !isRawObjectId(String(opt.name))) return String(opt.name);
|
|
4512
5353
|
}
|
|
4513
5354
|
if (typeof rowVal === "object" && rowVal !== null) {
|
|
4514
|
-
if (rowVal._displayLabel) return String(rowVal._displayLabel);
|
|
4515
|
-
if (rowVal.label) return String(rowVal.label);
|
|
5355
|
+
if (rowVal._displayLabel && !isRawObjectId(String(rowVal._displayLabel))) return String(rowVal._displayLabel);
|
|
5356
|
+
if (rowVal.label && !isRawObjectId(String(rowVal.label))) return String(rowVal.label);
|
|
4516
5357
|
}
|
|
4517
|
-
return
|
|
4518
|
-
});
|
|
5358
|
+
return "";
|
|
5359
|
+
}).filter(Boolean);
|
|
4519
5360
|
}, [relationOptions]);
|
|
4520
|
-
const getUniqueRelationOptions = (0,
|
|
5361
|
+
const getUniqueRelationOptions = (0, import_react14.useCallback)((col) => {
|
|
5362
|
+
if (relationFilterOptions[col.name]) {
|
|
5363
|
+
return relationFilterOptions[col.name];
|
|
5364
|
+
}
|
|
4521
5365
|
const seenIds = /* @__PURE__ */ new Set();
|
|
5366
|
+
const seenLabels = /* @__PURE__ */ new Set();
|
|
4522
5367
|
const results = [];
|
|
4523
5368
|
const options = relationOptions[col.name] || [];
|
|
4524
5369
|
data.forEach((row) => {
|
|
@@ -4529,58 +5374,23 @@ function TableBlockClient({
|
|
|
4529
5374
|
seenIds.add(id);
|
|
4530
5375
|
const opt = options.find((o) => o.id === id || o._id === id);
|
|
4531
5376
|
let label = opt ? resolveRelationLabel(opt, col) : "";
|
|
4532
|
-
if (!label && opt)
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
});
|
|
4538
|
-
return results.sort((a, b) => a.label.localeCompare(b.label));
|
|
4539
|
-
}, [data, relationOptions]);
|
|
4540
|
-
const filteredData = (0, import_react12.useMemo)(() => {
|
|
4541
|
-
const hasGlobalSearch = Boolean(searchQuery && searchQuery.trim() !== "");
|
|
4542
|
-
const activeFilters = Object.entries(columnFilters).filter(([, val]) => Boolean(val && val.trim() !== ""));
|
|
4543
|
-
const hasColumnFilters = activeFilters.length > 0;
|
|
4544
|
-
if (!hasGlobalSearch && !hasColumnFilters) return data;
|
|
4545
|
-
const lowerGlobal = hasGlobalSearch ? searchQuery.trim().toLowerCase() : "";
|
|
4546
|
-
return data.filter((row) => {
|
|
4547
|
-
var _a;
|
|
4548
|
-
if (!row || !row.data) return false;
|
|
4549
|
-
if (hasGlobalSearch) {
|
|
4550
|
-
const matchesGlobal = (localColumns || []).some((col) => {
|
|
4551
|
-
var _a2;
|
|
4552
|
-
const rawVal = row.data[col.name];
|
|
4553
|
-
if (rawVal === void 0 || rawVal === null) return false;
|
|
4554
|
-
if (((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION") {
|
|
4555
|
-
const labels = getRowRelationLabels(rawVal, col);
|
|
4556
|
-
return labels.some((l) => l.toLowerCase().includes(lowerGlobal));
|
|
5377
|
+
if (!label && opt) {
|
|
5378
|
+
const fallback = opt.label || opt.name || opt.title;
|
|
5379
|
+
if (fallback && typeof fallback === "string" && !isRawObjectId(fallback)) {
|
|
5380
|
+
label = fallback.trim();
|
|
5381
|
+
}
|
|
4557
5382
|
}
|
|
4558
|
-
if (
|
|
4559
|
-
|
|
5383
|
+
if (label && label.trim() && label !== id && !isRawObjectId(label) && !seenLabels.has(label.trim())) {
|
|
5384
|
+
seenLabels.add(label.trim());
|
|
5385
|
+
results.push({ id, label: label.trim() });
|
|
4560
5386
|
}
|
|
4561
|
-
return String(rawVal).toLowerCase().includes(lowerGlobal);
|
|
4562
|
-
});
|
|
4563
|
-
if (!matchesGlobal) return false;
|
|
4564
|
-
}
|
|
4565
|
-
for (const [colName, filterVal] of activeFilters) {
|
|
4566
|
-
const lowerFilter = filterVal.trim().toLowerCase();
|
|
4567
|
-
const col = (localColumns || []).find((c) => c.name === colName);
|
|
4568
|
-
const rawVal = row.data[colName];
|
|
4569
|
-
if (((_a = col == null ? void 0 : col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION") {
|
|
4570
|
-
const labels = getRowRelationLabels(rawVal, col);
|
|
4571
|
-
const matches = labels.some((l) => l.toLowerCase().includes(lowerFilter));
|
|
4572
|
-
if (!matches) return false;
|
|
4573
|
-
} else {
|
|
4574
|
-
if (rawVal === void 0 || rawVal === null) return false;
|
|
4575
|
-
const strVal = typeof rawVal === "object" ? JSON.stringify(rawVal).toLowerCase() : String(rawVal).toLowerCase();
|
|
4576
|
-
if (!strVal.includes(lowerFilter)) return false;
|
|
4577
5387
|
}
|
|
4578
|
-
}
|
|
4579
|
-
return true;
|
|
5388
|
+
});
|
|
4580
5389
|
});
|
|
4581
|
-
|
|
5390
|
+
return results.sort((a, b) => a.label.localeCompare(b.label));
|
|
5391
|
+
}, [data, relationOptions, relationFilterOptions]);
|
|
4582
5392
|
const errorMessage = error ? typeof error === "string" ? error : error.message || String(error) : null;
|
|
4583
|
-
const columnTotals = (0,
|
|
5393
|
+
const columnTotals = (0, import_react14.useMemo)(() => {
|
|
4584
5394
|
const totals = {};
|
|
4585
5395
|
if (!showSummary) return totals;
|
|
4586
5396
|
filteredColumns.forEach((col) => {
|
|
@@ -4598,42 +5408,120 @@ function TableBlockClient({
|
|
|
4598
5408
|
});
|
|
4599
5409
|
return totals;
|
|
4600
5410
|
}, [filteredData, filteredColumns, showSummary]);
|
|
4601
|
-
|
|
5411
|
+
const hasSelectedRows = selectedIds.size > 0;
|
|
5412
|
+
const hasActiveSearchOrFilter = Boolean(searchQuery && searchQuery.trim() !== "") || Object.values(columnFilters).some(
|
|
5413
|
+
(v) => Array.isArray(v) ? v.length > 0 : v && typeof v === "object" && "values" in v ? v.values.length > 0 : typeof v === "string" && Boolean(v.trim())
|
|
5414
|
+
);
|
|
5415
|
+
let exportButtonText = "\u05D9\u05D9\u05E6\u05D0 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD";
|
|
5416
|
+
let ExportButtonIcon = import_lucide_react8.Download;
|
|
5417
|
+
if (hasSelectedRows) {
|
|
5418
|
+
exportButtonText = `\u05D9\u05D9\u05E6\u05D0 ${selectedIds.size} \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA`;
|
|
5419
|
+
ExportButtonIcon = import_lucide_react8.Download;
|
|
5420
|
+
} else if (hasActiveSearchOrFilter) {
|
|
5421
|
+
exportButtonText = "\u05D9\u05D9\u05E6\u05D0 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E1\u05D9\u05E0\u05D5\u05DF";
|
|
5422
|
+
ExportButtonIcon = import_lucide_react8.Filter;
|
|
5423
|
+
}
|
|
5424
|
+
const handleExportCsv = async () => {
|
|
5425
|
+
if (isExporting) return;
|
|
5426
|
+
const systemFields = ["_id", "id", "createdAt", "updatedAt", "createdBy", "updatedBy", "orgId", "tableId"];
|
|
5427
|
+
const userHiddenColumns = normalizedColumns.filter((c) => c.isHidden && !systemFields.includes(c.name)).map((c) => c.name);
|
|
5428
|
+
if (userHiddenColumns.length > 0) {
|
|
5429
|
+
addToast({
|
|
5430
|
+
message: "\u05DE\u05D9\u05D9\u05E6\u05D0 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD... \u05E9\u05D9\u05DD \u05DC\u05D1: \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA \u05DE\u05D5\u05E1\u05EA\u05E8\u05D5\u05EA \u05DC\u05D0 \u05D9\u05D9\u05DB\u05DC\u05DC\u05D5 \u05D1\u05E7\u05D5\u05D1\u05E5",
|
|
5431
|
+
type: "info",
|
|
5432
|
+
duration: 3e3
|
|
5433
|
+
});
|
|
5434
|
+
} else {
|
|
5435
|
+
addToast({
|
|
5436
|
+
message: "\u05DE\u05D9\u05D9\u05E6\u05D0 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD...",
|
|
5437
|
+
type: "info",
|
|
5438
|
+
duration: 3e3
|
|
5439
|
+
});
|
|
5440
|
+
}
|
|
5441
|
+
setIsExporting(true);
|
|
5442
|
+
try {
|
|
5443
|
+
const targetTableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
5444
|
+
if (!targetTableId) {
|
|
5445
|
+
showError("\u05DE\u05D6\u05D4\u05D4 \u05D4\u05D8\u05D1\u05DC\u05D4 \u05D7\u05E1\u05E8 (tableId)", "\u05E9\u05D2\u05D9\u05D0\u05EA \u05D9\u05D9\u05E6\u05D5\u05D0");
|
|
5446
|
+
return;
|
|
5447
|
+
}
|
|
5448
|
+
const payload = {
|
|
5449
|
+
tableId: targetTableId,
|
|
5450
|
+
orgId,
|
|
5451
|
+
search: searchQuery.trim() || void 0,
|
|
5452
|
+
columnFilters: Object.keys(columnFilters).length > 0 ? columnFilters : void 0,
|
|
5453
|
+
selectedRowIds: hasSelectedRows ? Array.from(selectedIds) : [],
|
|
5454
|
+
hiddenColumnIds: userHiddenColumns
|
|
5455
|
+
};
|
|
5456
|
+
let res;
|
|
5457
|
+
if (exportAction) {
|
|
5458
|
+
res = await exportAction(payload);
|
|
5459
|
+
} else if (executeAction) {
|
|
5460
|
+
res = await executeAction("EXPORT_TABLE_TO_CSV", payload);
|
|
5461
|
+
} else {
|
|
5462
|
+
throw new Error("\u05E8\u05DB\u05D9\u05D1 \u05D4\u05EA\u05E7\u05E9\u05D5\u05E8\u05EA \u05DC\u05D0 \u05D0\u05D5\u05EA\u05D7\u05DC");
|
|
5463
|
+
}
|
|
5464
|
+
const result = (res == null ? void 0 : res.data) || res;
|
|
5465
|
+
if ((result == null ? void 0 : result.success) === false) {
|
|
5466
|
+
throw new Error(result.error || "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05D9\u05D9\u05E6\u05D5\u05D0 \u05D4\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD");
|
|
5467
|
+
}
|
|
5468
|
+
const csvString = (result == null ? void 0 : result.csvString) || (result == null ? void 0 : result.csv);
|
|
5469
|
+
if (!csvString) {
|
|
5470
|
+
throw new Error("\u05DC\u05D0 \u05D4\u05EA\u05E7\u05D1\u05DC\u05D5 \u05E0\u05EA\u05D5\u05E0\u05D9 CSV \u05DE\u05D4\u05E9\u05E8\u05EA");
|
|
5471
|
+
}
|
|
5472
|
+
const fileName = (result == null ? void 0 : result.fileName) || `${((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name) || "table").trim()}_export.csv`;
|
|
5473
|
+
const blob = new Blob([csvString], { type: "text/csv;charset=utf-8;" });
|
|
5474
|
+
const url = URL.createObjectURL(blob);
|
|
5475
|
+
const link = document.createElement("a");
|
|
5476
|
+
link.href = url;
|
|
5477
|
+
link.setAttribute("download", fileName);
|
|
5478
|
+
document.body.appendChild(link);
|
|
5479
|
+
link.click();
|
|
5480
|
+
document.body.removeChild(link);
|
|
5481
|
+
URL.revokeObjectURL(url);
|
|
5482
|
+
} catch (err) {
|
|
5483
|
+
console.error("[TableBlock] Export to CSV failed:", err);
|
|
5484
|
+
showError((err == null ? void 0 : err.message) || String(err), "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05D9\u05D9\u05E6\u05D5\u05D0 \u05D4\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD");
|
|
5485
|
+
} finally {
|
|
5486
|
+
setIsExporting(false);
|
|
5487
|
+
}
|
|
5488
|
+
};
|
|
5489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4602
5490
|
"div",
|
|
4603
5491
|
{
|
|
4604
5492
|
id: componentId,
|
|
4605
5493
|
"data-testid": dataTestId || (componentId ? `table-block-${componentId}` : void 0),
|
|
4606
|
-
className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs min-h-
|
|
5494
|
+
className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs flex-1 min-h-0 overflow-hidden ${className}`,
|
|
4607
5495
|
dir: "rtl",
|
|
4608
5496
|
children: [
|
|
4609
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
4610
|
-
/* @__PURE__ */ (0,
|
|
4611
|
-
/* @__PURE__ */ (0,
|
|
5497
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-3 bg-rose-50 border-b border-rose-200 text-rose-700 text-sm flex items-center justify-between shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5498
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-4 h-4 text-rose-500 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
5499
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: errorMessage })
|
|
4612
5500
|
] }) }),
|
|
4613
|
-
/* @__PURE__ */ (0,
|
|
4614
|
-
/* @__PURE__ */ (0,
|
|
4615
|
-
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0,
|
|
4616
|
-
/* @__PURE__ */ (0,
|
|
5501
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 p-3.5 sm:p-4 bg-slate-50 border-b border-slate-200 shrink-0", children: [
|
|
5502
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
5503
|
+
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: schema.title || schema.name }) }),
|
|
5504
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4617
5505
|
"button",
|
|
4618
5506
|
{
|
|
4619
5507
|
onClick: handleAddRow,
|
|
4620
5508
|
disabled: isInitialLoading || isLoading || isUpdatingActive,
|
|
4621
5509
|
className: `w-9 h-9 text-white rounded-lg shadow-xs flex items-center justify-center transition-all ${isInitialLoading || isLoading || isUpdatingActive ? "bg-emerald-950/80 text-emerald-400/60 pointer-events-none cursor-not-allowed" : "bg-emerald-600 hover:bg-emerald-700 active:bg-emerald-800 cursor-pointer"}`,
|
|
4622
5510
|
title: isInitialLoading ? "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." : "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
4623
|
-
children: /* @__PURE__ */ (0,
|
|
5511
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
|
|
4624
5512
|
}
|
|
4625
5513
|
),
|
|
4626
|
-
/* @__PURE__ */ (0,
|
|
5514
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4627
5515
|
"button",
|
|
4628
5516
|
{
|
|
4629
5517
|
onClick: handleDuplicateRow,
|
|
4630
5518
|
disabled: isInitialLoading || isLoading || isUpdatingActive || selectedIds.size !== 1,
|
|
4631
5519
|
className: "w-9 h-9 bg-blue-50 hover:bg-blue-100 border border-blue-200 text-blue-700 rounded-lg shadow-2xs flex items-center justify-center transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
4632
5520
|
title: "\u05E9\u05DB\u05E4\u05DC \u05E9\u05D5\u05E8\u05D4 \u05E0\u05D1\u05D7\u05E8\u05EA",
|
|
4633
|
-
children: /* @__PURE__ */ (0,
|
|
5521
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react8.Copy, { className: "w-4 h-4 text-blue-600 shrink-0" })
|
|
4634
5522
|
}
|
|
4635
5523
|
),
|
|
4636
|
-
/* @__PURE__ */ (0,
|
|
5524
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4637
5525
|
"button",
|
|
4638
5526
|
{
|
|
4639
5527
|
onClick: handleDeleteSelected,
|
|
@@ -4641,12 +5529,12 @@ function TableBlockClient({
|
|
|
4641
5529
|
className: "w-9 h-9 bg-rose-50 hover:bg-rose-100 border border-rose-200 text-rose-700 rounded-lg shadow-2xs flex items-center justify-center relative transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
4642
5530
|
title: "\u05DE\u05D7\u05E7 \u05E9\u05D5\u05E8\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA",
|
|
4643
5531
|
children: [
|
|
4644
|
-
/* @__PURE__ */ (0,
|
|
4645
|
-
selectedIds.size > 0 && /* @__PURE__ */ (0,
|
|
5532
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-4.5 h-4.5 text-rose-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
|
|
5533
|
+
selectedIds.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "absolute -top-1.5 -right-1.5 bg-rose-600 text-white min-w-[18px] h-[18px] px-1 rounded-full text-[10px] font-bold flex items-center justify-center shadow-xs", children: selectedIds.size })
|
|
4646
5534
|
]
|
|
4647
5535
|
}
|
|
4648
5536
|
),
|
|
4649
|
-
/* @__PURE__ */ (0,
|
|
5537
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4650
5538
|
"button",
|
|
4651
5539
|
{
|
|
4652
5540
|
onClick: toggleSummary,
|
|
@@ -4654,13 +5542,13 @@ function TableBlockClient({
|
|
|
4654
5542
|
className: `h-9 px-3 border font-semibold rounded-lg shadow-2xs flex items-center gap-1.5 text-xs transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer ${showSummary ? "bg-indigo-50 border-indigo-200 text-indigo-700 hover:bg-indigo-100" : "bg-white border-slate-300 text-slate-700 hover:bg-slate-100"}`,
|
|
4655
5543
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E9\u05D5\u05E8\u05EA \u05E1\u05D9\u05DB\u05D5\u05DD",
|
|
4656
5544
|
children: [
|
|
4657
|
-
/* @__PURE__ */ (0,
|
|
4658
|
-
/* @__PURE__ */ (0,
|
|
5545
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-4 h-4 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
|
|
5546
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "hidden sm:inline", children: "\u05E1\u05DB\u05D9\u05DE\u05D4" })
|
|
4659
5547
|
]
|
|
4660
5548
|
}
|
|
4661
5549
|
),
|
|
4662
|
-
/* @__PURE__ */ (0,
|
|
4663
|
-
/* @__PURE__ */ (0,
|
|
5550
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "relative", ref: dropdownRef, children: [
|
|
5551
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4664
5552
|
"button",
|
|
4665
5553
|
{
|
|
4666
5554
|
onClick: () => setIsColumnsDropdownOpen((prev) => !prev),
|
|
@@ -4668,16 +5556,16 @@ function TableBlockClient({
|
|
|
4668
5556
|
className: "h-9 px-3 bg-white hover:bg-slate-100 border border-slate-300 text-slate-700 font-semibold rounded-lg shadow-2xs flex items-center gap-1.5 text-xs transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
4669
5557
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA",
|
|
4670
5558
|
children: [
|
|
4671
|
-
/* @__PURE__ */ (0,
|
|
4672
|
-
/* @__PURE__ */ (0,
|
|
5559
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-4 h-4 text-slate-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" }) }),
|
|
5560
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: `w-3.5 h-3.5 text-slate-500 transition-transform ${isColumnsDropdownOpen ? "rotate-180" : ""}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })
|
|
4673
5561
|
]
|
|
4674
5562
|
}
|
|
4675
5563
|
),
|
|
4676
|
-
isColumnsDropdownOpen && /* @__PURE__ */ (0,
|
|
4677
|
-
/* @__PURE__ */ (0,
|
|
4678
|
-
/* @__PURE__ */ (0,
|
|
4679
|
-
/* @__PURE__ */ (0,
|
|
4680
|
-
/* @__PURE__ */ (0,
|
|
5564
|
+
isColumnsDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "absolute right-0 top-full mt-1.5 w-56 bg-white border border-slate-200 rounded-xl shadow-xl z-50 p-1.5 dir-rtl animate-in fade-in slide-in-from-top-2 duration-150", children: [
|
|
5565
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "px-2 py-1.5 text-xs font-bold text-slate-500 border-b border-slate-100 mb-1 flex items-center justify-between", children: [
|
|
5566
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
5567
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "\u05D4\u05E6\u05D2\u05EA \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA" }),
|
|
5568
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-[10px] font-normal text-slate-400", children: [
|
|
4681
5569
|
"(",
|
|
4682
5570
|
customizableColumns.filter((c) => !c.isHidden).length,
|
|
4683
5571
|
"/",
|
|
@@ -4685,7 +5573,7 @@ function TableBlockClient({
|
|
|
4685
5573
|
")"
|
|
4686
5574
|
] })
|
|
4687
5575
|
] }),
|
|
4688
|
-
/* @__PURE__ */ (0,
|
|
5576
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4689
5577
|
"button",
|
|
4690
5578
|
{
|
|
4691
5579
|
type: "button",
|
|
@@ -4695,7 +5583,7 @@ function TableBlockClient({
|
|
|
4695
5583
|
}
|
|
4696
5584
|
)
|
|
4697
5585
|
] }),
|
|
4698
|
-
/* @__PURE__ */ (0,
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "max-h-60 overflow-y-auto space-y-0.5", children: customizableColumns.map((col) => {
|
|
4699
5587
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
4700
5588
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
4701
5589
|
const isProtected = isRequired || isUnique;
|
|
@@ -4709,7 +5597,7 @@ function TableBlockClient({
|
|
|
4709
5597
|
protectedExplanation = "\u05E9\u05D3\u05D4 \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9 - \u05DC\u05D0 \u05E0\u05D9\u05EA\u05DF \u05DC\u05D4\u05D5\u05E8\u05D9\u05D3 \u05E2\u05DE\u05D5\u05D3\u05D4 \u05D6\u05D5 \u05DE\u05D4\u05EA\u05E6\u05D5\u05D2\u05D4";
|
|
4710
5598
|
}
|
|
4711
5599
|
const badgeLabel = isRequired && isUnique ? "\u05D7\u05D5\u05D1\u05D4 + \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9" : isRequired ? "\u05E9\u05D3\u05D4 \u05D7\u05D5\u05D1\u05D4" : "\u05E9\u05D3\u05D4 \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9";
|
|
4712
|
-
return /* @__PURE__ */ (0,
|
|
5600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4713
5601
|
"div",
|
|
4714
5602
|
{
|
|
4715
5603
|
onClick: () => {
|
|
@@ -4720,8 +5608,8 @@ function TableBlockClient({
|
|
|
4720
5608
|
title: isProtected ? protectedExplanation : void 0,
|
|
4721
5609
|
className: `group flex items-center justify-between px-2.5 py-1.5 rounded-lg text-xs transition-colors select-none ${isProtected ? "opacity-75 bg-slate-50 border border-slate-100/70 cursor-not-allowed" : "hover:bg-slate-100 active:bg-slate-200 cursor-pointer"}`,
|
|
4722
5610
|
children: [
|
|
4723
|
-
/* @__PURE__ */ (0,
|
|
4724
|
-
/* @__PURE__ */ (0,
|
|
5611
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
5612
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4725
5613
|
"input",
|
|
4726
5614
|
{
|
|
4727
5615
|
type: "checkbox",
|
|
@@ -4732,16 +5620,16 @@ function TableBlockClient({
|
|
|
4732
5620
|
className: "w-3.5 h-3.5 rounded border-slate-300 text-brand focus:ring-brand/20 cursor-pointer disabled:cursor-not-allowed disabled:opacity-60"
|
|
4733
5621
|
}
|
|
4734
5622
|
),
|
|
4735
|
-
/* @__PURE__ */ (0,
|
|
5623
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: `font-medium truncate ${isProtected ? "text-slate-500" : "text-slate-700"}`, children: col.name })
|
|
4736
5624
|
] }),
|
|
4737
|
-
isProtected && /* @__PURE__ */ (0,
|
|
5625
|
+
isProtected && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4738
5626
|
"div",
|
|
4739
5627
|
{
|
|
4740
5628
|
className: "flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold bg-amber-50 text-amber-800 border border-amber-200/80 cursor-help",
|
|
4741
5629
|
title: protectedExplanation,
|
|
4742
5630
|
children: [
|
|
4743
|
-
/* @__PURE__ */ (0,
|
|
4744
|
-
/* @__PURE__ */ (0,
|
|
5631
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-3 h-3 text-amber-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: "2.2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" }) }),
|
|
5632
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: badgeLabel })
|
|
4745
5633
|
]
|
|
4746
5634
|
}
|
|
4747
5635
|
)
|
|
@@ -4752,9 +5640,23 @@ function TableBlockClient({
|
|
|
4752
5640
|
}) })
|
|
4753
5641
|
] })
|
|
4754
5642
|
] }),
|
|
4755
|
-
/* @__PURE__ */ (0,
|
|
4756
|
-
|
|
4757
|
-
|
|
5643
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
5644
|
+
"button",
|
|
5645
|
+
{
|
|
5646
|
+
onClick: handleExportCsv,
|
|
5647
|
+
disabled: isLoading || isUpdatingActive || isExporting,
|
|
5648
|
+
className: `h-9 px-3 font-semibold rounded-lg shadow-2xs flex items-center gap-1.5 text-xs transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer border ${hasSelectedRows ? "bg-blue-50 hover:bg-blue-100 border-blue-200 text-blue-700" : hasActiveSearchOrFilter ? "bg-amber-50 hover:bg-amber-100 border-amber-200 text-amber-800" : "bg-white hover:bg-slate-100 border-slate-300 text-slate-700"}`,
|
|
5649
|
+
title: exportButtonText,
|
|
5650
|
+
"data-testid": "export-csv-button",
|
|
5651
|
+
children: [
|
|
5652
|
+
isExporting ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react8.Loader2, { className: "w-4 h-4 shrink-0 animate-spin text-slate-500" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ExportButtonIcon, { className: "w-4 h-4 shrink-0" }),
|
|
5653
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: isExporting ? "\u05DE\u05D9\u05D9\u05E6\u05D0..." : exportButtonText })
|
|
5654
|
+
]
|
|
5655
|
+
}
|
|
5656
|
+
),
|
|
5657
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
|
|
5658
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
|
|
5659
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4758
5660
|
"input",
|
|
4759
5661
|
{
|
|
4760
5662
|
placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
|
|
@@ -4764,28 +5666,28 @@ function TableBlockClient({
|
|
|
4764
5666
|
className: "w-full h-9 px-3 pr-9 text-xs border border-slate-300 rounded-lg bg-white shadow-2xs focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-slate-800 disabled:opacity-50"
|
|
4765
5667
|
}
|
|
4766
5668
|
),
|
|
4767
|
-
searchQuery ? /* @__PURE__ */ (0,
|
|
5669
|
+
searchQuery ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4768
5670
|
"button",
|
|
4769
5671
|
{
|
|
4770
5672
|
type: "button",
|
|
4771
5673
|
onClick: () => setSearchQuery(""),
|
|
4772
5674
|
className: "absolute right-2.5 top-2.5 text-slate-400 hover:text-slate-600 transition-colors p-0.5 rounded-full hover:bg-slate-100 cursor-pointer",
|
|
4773
5675
|
title: "Clear search",
|
|
4774
|
-
children: /* @__PURE__ */ (0,
|
|
5676
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react8.X, { className: "w-3.5 h-3.5" })
|
|
4775
5677
|
}
|
|
4776
|
-
) : /* @__PURE__ */ (0,
|
|
5678
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-4 h-4 text-slate-400 absolute right-2.5 top-2.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
|
|
4777
5679
|
] })
|
|
4778
5680
|
] }),
|
|
4779
|
-
/* @__PURE__ */ (0,
|
|
4780
|
-
isUpdatingActive ? /* @__PURE__ */ (0,
|
|
4781
|
-
/* @__PURE__ */ (0,
|
|
5681
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5682
|
+
isUpdatingActive ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-xs text-blue-600 font-semibold flex items-center gap-1.5 bg-blue-50 border border-blue-200 px-3 py-1.5 rounded-lg animate-pulse", children: [
|
|
5683
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
|
|
4782
5684
|
"\u05DE\u05E2\u05D3\u05DB\u05DF..."
|
|
4783
|
-
] }) : isSaveSuccess ? /* @__PURE__ */ (0,
|
|
4784
|
-
/* @__PURE__ */ (0,
|
|
5685
|
+
] }) : isSaveSuccess ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-xs text-emerald-700 font-semibold flex items-center gap-1.5 bg-emerald-50 border border-emerald-200 px-3 py-1.5 rounded-lg animate-in fade-in duration-200", children: [
|
|
5686
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
|
|
4785
5687
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
4786
|
-
] }) : hasChanges ? /* @__PURE__ */ (0,
|
|
4787
|
-
/* @__PURE__ */ (0,
|
|
4788
|
-
/* @__PURE__ */ (0,
|
|
5688
|
+
] }) : hasChanges ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1.5 animate-in fade-in", children: [
|
|
5689
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-xs font-semibold text-amber-700", children: "\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5" }),
|
|
5690
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4789
5691
|
"button",
|
|
4790
5692
|
{
|
|
4791
5693
|
type: "button",
|
|
@@ -4794,30 +5696,31 @@ function TableBlockClient({
|
|
|
4794
5696
|
className: "p-1 text-amber-700 hover:text-amber-900 hover:bg-amber-100/80 active:bg-amber-200/80 rounded-md transition-colors cursor-pointer disabled:opacity-50 disabled:pointer-events-none",
|
|
4795
5697
|
title: "\u05D1\u05D8\u05DC \u05D0\u05EA \u05DB\u05DC \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5",
|
|
4796
5698
|
"aria-label": "\u05D1\u05D8\u05DC \u05D0\u05EA \u05DB\u05DC \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5",
|
|
4797
|
-
children: /* @__PURE__ */ (0,
|
|
5699
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react8.RotateCcw, { className: "w-3.5 h-3.5" })
|
|
4798
5700
|
}
|
|
4799
5701
|
)
|
|
4800
5702
|
] }) : null,
|
|
4801
|
-
/* @__PURE__ */ (0,
|
|
5703
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4802
5704
|
"button",
|
|
4803
5705
|
{
|
|
4804
5706
|
onClick: handleSave,
|
|
4805
5707
|
disabled: isUpdatingActive || isLoading || !hasChanges,
|
|
4806
5708
|
className: `h-9 px-4 text-xs font-bold rounded-lg shadow-2xs transition-all flex items-center justify-center cursor-pointer ${hasChanges && !isUpdatingActive && !isLoading ? "bg-brand hover:bg-brand-hover active:bg-[#00897b] text-white shadow-teal-500/20" : "opacity-50 grayscale bg-slate-200 text-slate-400 cursor-not-allowed"}`,
|
|
4807
|
-
children: /* @__PURE__ */ (0,
|
|
5709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
|
|
4808
5710
|
}
|
|
4809
5711
|
)
|
|
4810
5712
|
] })
|
|
4811
5713
|
] }),
|
|
4812
|
-
/* @__PURE__ */ (0,
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
/* @__PURE__ */ (0,
|
|
5714
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `overflow-x-auto overflow-y-auto relative max-h-[calc(100vh-240px)] min-h-[260px] flex-1 transition-opacity duration-200 ${isMounted ? "opacity-100" : "opacity-0"}`, children: [
|
|
5715
|
+
isFetching && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "absolute top-0 left-0 right-0 h-0.5 bg-blue-500/20 overflow-hidden z-30", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-full h-full bg-brand animate-pulse" }) }),
|
|
5716
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
|
|
5717
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
|
|
5718
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
|
|
4816
5719
|
] }),
|
|
4817
|
-
/* @__PURE__ */ (0,
|
|
4818
|
-
/* @__PURE__ */ (0,
|
|
4819
|
-
/* @__PURE__ */ (0,
|
|
4820
|
-
/* @__PURE__ */ (0,
|
|
5720
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("table", { className: "w-full text-sm text-right border-collapse table-auto", children: [
|
|
5721
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("thead", { className: "bg-white text-slate-700 sticky top-0 z-10 shadow-xs", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tr", { className: "h-12 min-h-[48px]", children: [
|
|
5722
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("th", { className: "border-b border-l border-slate-200 p-1.5 text-center shrink-0 h-12 min-h-[48px] align-middle bg-white", style: { width: 72, minWidth: 72, maxWidth: 72 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-center gap-1.5", children: [
|
|
5723
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4821
5724
|
"input",
|
|
4822
5725
|
{
|
|
4823
5726
|
type: "checkbox",
|
|
@@ -4830,7 +5733,7 @@ function TableBlockClient({
|
|
|
4830
5733
|
filteredColumns.some((c) => {
|
|
4831
5734
|
var _a;
|
|
4832
5735
|
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
4833
|
-
}) && /* @__PURE__ */ (0,
|
|
5736
|
+
}) && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-5 h-5 shrink-0" })
|
|
4834
5737
|
] }) }),
|
|
4835
5738
|
filteredColumns.map((col) => {
|
|
4836
5739
|
var _a, _b;
|
|
@@ -4841,16 +5744,25 @@ function TableBlockClient({
|
|
|
4841
5744
|
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
4842
5745
|
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
4843
5746
|
const isRelation = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION";
|
|
4844
|
-
const filterVal = columnFilters[col.name]
|
|
4845
|
-
|
|
5747
|
+
const filterVal = columnFilters[col.name];
|
|
5748
|
+
const hasActiveFilter = Array.isArray(filterVal) ? filterVal.length > 0 : filterVal && typeof filterVal === "object" && "values" in filterVal ? filterVal.values.length > 0 : Boolean(filterVal && filterVal.trim() !== "");
|
|
5749
|
+
let filterTooltip = "\u05D7\u05E4\u05E9 \u05D5\u05E1\u05E0\u05DF \u05D1\u05E2\u05DE\u05D5\u05D3\u05D4 \u05D6\u05D5";
|
|
5750
|
+
if (Array.isArray(filterVal)) {
|
|
5751
|
+
filterTooltip = `\u05DE\u05E1\u05D5\u05E0\u05DF \u05DC\u05E4\u05D9: ${filterVal.length} \u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA`;
|
|
5752
|
+
} else if (filterVal && typeof filterVal === "object" && "operator" in filterVal && filterVal.operator === "notIn") {
|
|
5753
|
+
filterTooltip = `\u05DE\u05D5\u05D7\u05E8\u05D2\u05D9\u05DD: ${filterVal.values.length} \u05E4\u05E8\u05D9\u05D8\u05D9\u05DD (\u05D4\u05DB\u05DC \u05DC\u05DE\u05E2\u05D8)`;
|
|
5754
|
+
} else if (typeof filterVal === "string" && filterVal.trim()) {
|
|
5755
|
+
filterTooltip = `\u05DE\u05E1\u05D5\u05E0\u05DF \u05DC\u05E4\u05D9: "${filterVal}" (\u05DC\u05D7\u05E5 \u05DC\u05E2\u05E8\u05D9\u05DB\u05D4)`;
|
|
5756
|
+
}
|
|
5757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4846
5758
|
"th",
|
|
4847
5759
|
__spreadProps(__spreadValues({
|
|
4848
5760
|
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
4849
5761
|
title: isSearching ? void 0 : col.name
|
|
4850
5762
|
}, dragProps), {
|
|
4851
|
-
className: `relative border-b border-l border-slate-200 px-2
|
|
5763
|
+
className: `group relative border-b border-l border-slate-200 px-2 py-1 font-semibold text-slate-700 select-none transition-colors h-12 min-h-[48px] align-middle bg-white ${isSearching ? "cursor-default bg-blue-50/40" : "cursor-grab active:cursor-grabbing hover:bg-slate-100"} ${isDragging ? "opacity-40 bg-slate-200 border-dashed border-2 border-brand" : ""} ${isDragOver ? "bg-blue-50 border-r-4 border-r-brand text-brand font-bold" : ""}`,
|
|
4852
5764
|
children: [
|
|
4853
|
-
/* @__PURE__ */ (0,
|
|
5765
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4854
5766
|
"div",
|
|
4855
5767
|
{
|
|
4856
5768
|
onMouseDown: (e) => {
|
|
@@ -4862,7 +5774,7 @@ function TableBlockClient({
|
|
|
4862
5774
|
title: "\u05E9\u05E0\u05D4 \u05D2\u05D5\u05D3\u05DC \u05E2\u05DE\u05D5\u05D3\u05D4"
|
|
4863
5775
|
}
|
|
4864
5776
|
),
|
|
4865
|
-
isSearching ? /* @__PURE__ */ (0,
|
|
5777
|
+
isSearching && !isRelation ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4866
5778
|
"div",
|
|
4867
5779
|
{
|
|
4868
5780
|
ref: activeSearchRef,
|
|
@@ -4870,46 +5782,15 @@ function TableBlockClient({
|
|
|
4870
5782
|
onClick: (e) => e.stopPropagation(),
|
|
4871
5783
|
onMouseDown: (e) => e.stopPropagation(),
|
|
4872
5784
|
children: [
|
|
4873
|
-
|
|
4874
|
-
"select",
|
|
4875
|
-
{
|
|
4876
|
-
autoFocus: true,
|
|
4877
|
-
value: filterVal,
|
|
4878
|
-
onChange: (e) => {
|
|
4879
|
-
const val = e.target.value;
|
|
4880
|
-
setColumnFilters((prev) => {
|
|
4881
|
-
const next = __spreadValues({}, prev);
|
|
4882
|
-
if (val) next[col.name] = val;
|
|
4883
|
-
else delete next[col.name];
|
|
4884
|
-
return next;
|
|
4885
|
-
});
|
|
4886
|
-
},
|
|
4887
|
-
onKeyDown: (e) => {
|
|
4888
|
-
if (e.key === "Escape" || e.key === "Enter") {
|
|
4889
|
-
setActiveSearchCol(null);
|
|
4890
|
-
}
|
|
4891
|
-
},
|
|
4892
|
-
className: "h-7 text-xs px-1.5 w-full rounded border border-blue-400 bg-white text-slate-800 focus:outline-none focus:ring-1 focus:ring-blue-400 cursor-pointer truncate",
|
|
4893
|
-
children: [
|
|
4894
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "\u05D4\u05DB\u05DC" }),
|
|
4895
|
-
getUniqueRelationOptions(col).map((opt) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: opt.label, children: opt.label }, opt.id))
|
|
4896
|
-
]
|
|
4897
|
-
}
|
|
4898
|
-
) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "relative flex items-center w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5785
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "relative flex items-center w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4899
5786
|
"input",
|
|
4900
5787
|
{
|
|
4901
5788
|
autoFocus: true,
|
|
4902
5789
|
type: "text",
|
|
4903
5790
|
placeholder: `\u05D7\u05E4\u05E9 \u05D1-${col.name}...`,
|
|
4904
|
-
value: filterVal,
|
|
5791
|
+
value: typeof filterVal === "string" ? filterVal : "",
|
|
4905
5792
|
onChange: (e) => {
|
|
4906
|
-
|
|
4907
|
-
setColumnFilters((prev) => {
|
|
4908
|
-
const next = __spreadValues({}, prev);
|
|
4909
|
-
if (val) next[col.name] = val;
|
|
4910
|
-
else delete next[col.name];
|
|
4911
|
-
return next;
|
|
4912
|
-
});
|
|
5793
|
+
handleApplyColumnFilter(col.name, e.target.value);
|
|
4913
5794
|
},
|
|
4914
5795
|
onKeyDown: (e) => {
|
|
4915
5796
|
if (e.key === "Escape" || e.key === "Enter") {
|
|
@@ -4919,7 +5800,7 @@ function TableBlockClient({
|
|
|
4919
5800
|
className: "h-7 text-xs px-2 w-full rounded border border-blue-400 bg-white text-slate-800 focus:outline-none focus:ring-1 focus:ring-blue-400"
|
|
4920
5801
|
}
|
|
4921
5802
|
) }),
|
|
4922
|
-
/* @__PURE__ */ (0,
|
|
5803
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4923
5804
|
"button",
|
|
4924
5805
|
{
|
|
4925
5806
|
type: "button",
|
|
@@ -4929,59 +5810,60 @@ function TableBlockClient({
|
|
|
4929
5810
|
},
|
|
4930
5811
|
onClick: (e) => {
|
|
4931
5812
|
e.stopPropagation();
|
|
4932
|
-
|
|
4933
|
-
const next = __spreadValues({}, prev);
|
|
4934
|
-
delete next[col.name];
|
|
4935
|
-
return next;
|
|
4936
|
-
});
|
|
5813
|
+
handleApplyColumnFilter(col.name, void 0);
|
|
4937
5814
|
setActiveSearchCol(null);
|
|
4938
5815
|
},
|
|
4939
5816
|
className: "p-1 text-slate-400 hover:text-slate-700 hover:bg-slate-200/70 rounded transition-colors cursor-pointer shrink-0",
|
|
4940
5817
|
title: "\u05E0\u05E7\u05D4 \u05D5\u05E1\u05D2\u05D5\u05E8 \u05D7\u05D9\u05E4\u05D5\u05E9",
|
|
4941
|
-
children: /* @__PURE__ */ (0,
|
|
5818
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react8.X, { className: "w-3.5 h-3.5" })
|
|
4942
5819
|
}
|
|
4943
5820
|
)
|
|
4944
5821
|
]
|
|
4945
5822
|
}
|
|
4946
|
-
) : /* @__PURE__ */ (0,
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
5823
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col items-center justify-center w-full h-full min-w-0 select-none py-0.5", title: col.name, children: [
|
|
5824
|
+
((_b = col.type) == null ? void 0 : _b.toUpperCase()) !== "SUB_TABLE" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5825
|
+
"button",
|
|
5826
|
+
{
|
|
5827
|
+
ref: (el) => {
|
|
5828
|
+
filterButtonRefs.current[col.name] = el;
|
|
5829
|
+
},
|
|
5830
|
+
type: "button",
|
|
5831
|
+
onClick: (e) => {
|
|
5832
|
+
e.stopPropagation();
|
|
5833
|
+
e.preventDefault();
|
|
5834
|
+
if (isRelation) {
|
|
5835
|
+
if (activeRelationCol === col.name) {
|
|
5836
|
+
setActiveRelationCol(null);
|
|
5837
|
+
setRelationTriggerRect(null);
|
|
5838
|
+
} else {
|
|
5839
|
+
const btn = filterButtonRefs.current[col.name];
|
|
5840
|
+
if (btn) {
|
|
5841
|
+
setRelationTriggerRect(btn.getBoundingClientRect());
|
|
5842
|
+
}
|
|
5843
|
+
setActiveRelationCol(col.name);
|
|
5844
|
+
fetchRelationFilterOptions(col.name);
|
|
5845
|
+
}
|
|
5846
|
+
} else {
|
|
4956
5847
|
setActiveSearchCol(col.name);
|
|
4957
|
-
}
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
}
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
{
|
|
4966
|
-
className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
|
|
4967
|
-
fill: "none",
|
|
4968
|
-
viewBox: "0 0 24 24",
|
|
4969
|
-
stroke: "currentColor",
|
|
4970
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
|
|
4971
|
-
}
|
|
4972
|
-
)
|
|
4973
|
-
] })
|
|
5848
|
+
}
|
|
5849
|
+
},
|
|
5850
|
+
className: `p-0.5 rounded transition-colors cursor-pointer mb-0.5 shrink-0 ${hasActiveFilter ? "opacity-100 text-blue-600 bg-blue-100 hover:bg-blue-200" : activeRelationCol === col.name ? "opacity-100 text-blue-600 bg-blue-100" : "opacity-0 group-hover:opacity-100 text-slate-400 hover:text-slate-600 hover:bg-slate-200/60"}`,
|
|
5851
|
+
title: filterTooltip,
|
|
5852
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react8.Filter, { className: "w-3 h-3" })
|
|
5853
|
+
}
|
|
5854
|
+
),
|
|
5855
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ColumnHeaderTitle, { name: col.name, width: currentWidth, isSubTable: false })
|
|
4974
5856
|
] })
|
|
4975
5857
|
]
|
|
4976
5858
|
}),
|
|
4977
5859
|
col.name
|
|
4978
5860
|
);
|
|
4979
5861
|
}),
|
|
4980
|
-
/* @__PURE__ */ (0,
|
|
5862
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("th", { className: "w-full min-w-[50px] border-b border-slate-200 pointer-events-none h-12 min-h-[48px] bg-white" })
|
|
4981
5863
|
] }) }),
|
|
4982
|
-
/* @__PURE__ */ (0,
|
|
4983
|
-
/* @__PURE__ */ (0,
|
|
4984
|
-
/* @__PURE__ */ (0,
|
|
5864
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tbody", { className: `bg-white transition-opacity duration-150 ${isFetching ? "opacity-50 pointer-events-none" : "opacity-100"}`, children: (isStateEmpty || filteredData.length === 0) && !isLoading && !isFetching ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { colSpan: filteredColumns.length + 2, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
5865
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" }) }),
|
|
5866
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
|
|
4985
5867
|
] }) }) }) : filteredData.map((row) => {
|
|
4986
5868
|
const hasSubTableCols = filteredColumns.some((c) => {
|
|
4987
5869
|
var _a;
|
|
@@ -4992,108 +5874,40 @@ function TableBlockClient({
|
|
|
4992
5874
|
var _a;
|
|
4993
5875
|
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
4994
5876
|
});
|
|
4995
|
-
return /* @__PURE__ */ (0,
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
5027
|
-
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
5028
|
-
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
5029
|
-
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
5030
|
-
let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
|
|
5031
|
-
if (value === void 0 && col.defaultValue !== void 0) {
|
|
5032
|
-
value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
|
|
5033
|
-
if (colType === "CURRENCY" || colType === "NUMBER") {
|
|
5034
|
-
if (isNaN(value)) value = null;
|
|
5035
|
-
}
|
|
5036
|
-
}
|
|
5037
|
-
if (value === void 0) value = null;
|
|
5038
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5039
|
-
"td",
|
|
5040
|
-
{
|
|
5041
|
-
className: `border-b border-l border-slate-200 p-0 relative ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
5042
|
-
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
5043
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5044
|
-
InputComponent,
|
|
5045
|
-
{
|
|
5046
|
-
value,
|
|
5047
|
-
column: col,
|
|
5048
|
-
rowId: row.id,
|
|
5049
|
-
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
5050
|
-
context: {
|
|
5051
|
-
tableName: (schema == null ? void 0 : schema.name) || (schema == null ? void 0 : schema.tableName) || (schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.id) || "Table",
|
|
5052
|
-
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
5053
|
-
onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
|
|
5054
|
-
relationOptions,
|
|
5055
|
-
refetchRelation,
|
|
5056
|
-
executeAction,
|
|
5057
|
-
emitEvent,
|
|
5058
|
-
pageState,
|
|
5059
|
-
componentId,
|
|
5060
|
-
orgId,
|
|
5061
|
-
updateQuietly: handleQuietCellChange,
|
|
5062
|
-
triggerSaveSuccess,
|
|
5063
|
-
rowData: row.data
|
|
5064
|
-
}
|
|
5065
|
-
}
|
|
5066
|
-
)
|
|
5067
|
-
},
|
|
5068
|
-
col.name
|
|
5069
|
-
);
|
|
5070
|
-
}),
|
|
5071
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
|
|
5072
|
-
] }),
|
|
5073
|
-
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
5074
|
-
ExpandedSubTables,
|
|
5075
|
-
{
|
|
5076
|
-
rowId: row.id,
|
|
5077
|
-
rowData: row.data,
|
|
5078
|
-
subTableColumns,
|
|
5079
|
-
filteredColumnsLength: filteredColumns.length,
|
|
5080
|
-
handleCellChange,
|
|
5081
|
-
context: {
|
|
5082
|
-
executeAction,
|
|
5083
|
-
orgId,
|
|
5084
|
-
parentTableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
5085
|
-
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
5086
|
-
rowData: row.data,
|
|
5087
|
-
updateQuietly: handleQuietCellChange,
|
|
5088
|
-
triggerSaveSuccess,
|
|
5089
|
-
onUpdateColumnConfig: handleUpdateColumnConfig
|
|
5090
|
-
}
|
|
5091
|
-
}
|
|
5092
|
-
)
|
|
5093
|
-
] }, row.id);
|
|
5877
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5878
|
+
TableRow,
|
|
5879
|
+
{
|
|
5880
|
+
row,
|
|
5881
|
+
isSelected: selectedIds.has(row.id),
|
|
5882
|
+
isExpanded,
|
|
5883
|
+
filteredColumns,
|
|
5884
|
+
columnWidths,
|
|
5885
|
+
hasSubTableCols,
|
|
5886
|
+
subTableColumns,
|
|
5887
|
+
isLoading: isLoading || isFetching,
|
|
5888
|
+
isUpdatingActive,
|
|
5889
|
+
onToggleSelect: toggleSelectRow,
|
|
5890
|
+
onToggleExpand: handleToggleExpand,
|
|
5891
|
+
handleCellChange,
|
|
5892
|
+
handleQuietCellChange,
|
|
5893
|
+
handleUpdateColumnConfig,
|
|
5894
|
+
onMarkForDeletion: handleMarkForDeletion,
|
|
5895
|
+
triggerSaveSuccess,
|
|
5896
|
+
schema,
|
|
5897
|
+
orgId,
|
|
5898
|
+
componentId,
|
|
5899
|
+
pageState,
|
|
5900
|
+
relationOptions,
|
|
5901
|
+
relationDictionaryRef,
|
|
5902
|
+
refetchRelation,
|
|
5903
|
+
executeAction,
|
|
5904
|
+
emitEvent
|
|
5905
|
+
},
|
|
5906
|
+
row.id
|
|
5907
|
+
);
|
|
5094
5908
|
}) }),
|
|
5095
|
-
showSummary && filteredData.length > 0 && /* @__PURE__ */ (0,
|
|
5096
|
-
/* @__PURE__ */ (0,
|
|
5909
|
+
showSummary && filteredData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tfoot", { className: "bg-slate-50 border-t-2 border-slate-300 sticky bottom-0 z-10 shadow-[0_-2px_4px_rgba(0,0,0,0.02)]", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tr", { children: [
|
|
5910
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "border-b border-l border-slate-200 p-1.5 text-center font-bold text-slate-600 text-xs", children: '\u05E1\u05D4"\u05DB' }),
|
|
5097
5911
|
filteredColumns.map((col) => {
|
|
5098
5912
|
var _a, _b;
|
|
5099
5913
|
const typeUpper = (_a = col.type) == null ? void 0 : _a.toUpperCase();
|
|
@@ -5107,16 +5921,16 @@ function TableBlockClient({
|
|
|
5107
5921
|
displayVal = symbol ? `${symbol} ${displayVal}` : displayVal;
|
|
5108
5922
|
}
|
|
5109
5923
|
}
|
|
5110
|
-
return /* @__PURE__ */ (0,
|
|
5924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "border-b border-l border-slate-200 p-2 text-sm font-semibold text-slate-700 bg-slate-50 relative", children: isNumeric && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex items-center text-right justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "truncate", children: displayVal }) }) }, col.name);
|
|
5111
5925
|
}),
|
|
5112
|
-
/* @__PURE__ */ (0,
|
|
5926
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "border-b border-slate-200 bg-slate-50 pointer-events-none" })
|
|
5113
5927
|
] }) })
|
|
5114
5928
|
] })
|
|
5115
5929
|
] }),
|
|
5116
|
-
/* @__PURE__ */ (0,
|
|
5117
|
-
/* @__PURE__ */ (0,
|
|
5118
|
-
/* @__PURE__ */ (0,
|
|
5119
|
-
/* @__PURE__ */ (0,
|
|
5930
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-3 px-4 py-3 bg-slate-50 border-t border-slate-200 text-xs text-slate-600 rounded-b-xl shrink-0", children: [
|
|
5931
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5932
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-medium text-slate-700", children: "\u05E9\u05D5\u05E8\u05D5\u05EA \u05DC\u05E2\u05DE\u05D5\u05D3:" }),
|
|
5933
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
5120
5934
|
"select",
|
|
5121
5935
|
{
|
|
5122
5936
|
value: limit,
|
|
@@ -5124,27 +5938,27 @@ function TableBlockClient({
|
|
|
5124
5938
|
disabled: isLoading || isUpdatingActive,
|
|
5125
5939
|
className: "bg-white border border-slate-300 rounded-lg px-2.5 py-1 text-slate-700 font-semibold shadow-2xs cursor-pointer focus:outline-none focus:ring-2 focus:ring-brand disabled:opacity-50",
|
|
5126
5940
|
children: [
|
|
5127
|
-
/* @__PURE__ */ (0,
|
|
5128
|
-
/* @__PURE__ */ (0,
|
|
5129
|
-
/* @__PURE__ */ (0,
|
|
5941
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: 20, children: "20" }),
|
|
5942
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: 50, children: "50" }),
|
|
5943
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: 100, children: "100" })
|
|
5130
5944
|
]
|
|
5131
5945
|
}
|
|
5132
5946
|
)
|
|
5133
5947
|
] }),
|
|
5134
|
-
/* @__PURE__ */ (0,
|
|
5135
|
-
/* @__PURE__ */ (0,
|
|
5948
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
5949
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-medium text-slate-600", children: [
|
|
5136
5950
|
"\u05E2\u05DE\u05D5\u05D3 ",
|
|
5137
|
-
/* @__PURE__ */ (0,
|
|
5951
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { className: "text-slate-900", children: page }),
|
|
5138
5952
|
" \u05DE\u05EA\u05D5\u05DA ",
|
|
5139
|
-
/* @__PURE__ */ (0,
|
|
5140
|
-
totalRecords > 0 && /* @__PURE__ */ (0,
|
|
5953
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { className: "text-slate-900", children: totalPages || 1 }),
|
|
5954
|
+
totalRecords > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-slate-500 font-normal", children: [
|
|
5141
5955
|
" (",
|
|
5142
5956
|
totalRecords,
|
|
5143
5957
|
' \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D1\u05E1\u05D4"\u05DB)'
|
|
5144
5958
|
] })
|
|
5145
5959
|
] }),
|
|
5146
|
-
/* @__PURE__ */ (0,
|
|
5147
|
-
/* @__PURE__ */ (0,
|
|
5960
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
5961
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5148
5962
|
"button",
|
|
5149
5963
|
{
|
|
5150
5964
|
onClick: handlePrevPage,
|
|
@@ -5154,7 +5968,7 @@ function TableBlockClient({
|
|
|
5154
5968
|
children: "\u05D4\u05E7\u05D5\u05D3\u05DD"
|
|
5155
5969
|
}
|
|
5156
5970
|
),
|
|
5157
|
-
/* @__PURE__ */ (0,
|
|
5971
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5158
5972
|
"button",
|
|
5159
5973
|
{
|
|
5160
5974
|
onClick: handleNextPage,
|
|
@@ -5166,7 +5980,31 @@ function TableBlockClient({
|
|
|
5166
5980
|
)
|
|
5167
5981
|
] })
|
|
5168
5982
|
] })
|
|
5169
|
-
] })
|
|
5983
|
+
] }),
|
|
5984
|
+
activeRelationCol && (() => {
|
|
5985
|
+
const activeColDef = filteredColumns.find((c) => c.name === activeRelationCol);
|
|
5986
|
+
if (!activeColDef) return null;
|
|
5987
|
+
const rawSelected = columnFilters[activeRelationCol];
|
|
5988
|
+
const currentSelected = typeof rawSelected === "object" && rawSelected !== null ? rawSelected : void 0;
|
|
5989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5990
|
+
RelationFilterPopover,
|
|
5991
|
+
{
|
|
5992
|
+
isOpen: Boolean(activeRelationCol),
|
|
5993
|
+
onClose: () => {
|
|
5994
|
+
setActiveRelationCol(null);
|
|
5995
|
+
setRelationTriggerRect(null);
|
|
5996
|
+
},
|
|
5997
|
+
column: activeColDef,
|
|
5998
|
+
triggerRect: relationTriggerRect,
|
|
5999
|
+
options: getUniqueRelationOptions(activeColDef),
|
|
6000
|
+
filterValue: currentSelected,
|
|
6001
|
+
onSelectionChange: (newSelected) => {
|
|
6002
|
+
handleApplyColumnFilter(activeRelationCol, newSelected);
|
|
6003
|
+
},
|
|
6004
|
+
isLoading: loadingFilterCol === activeRelationCol
|
|
6005
|
+
}
|
|
6006
|
+
);
|
|
6007
|
+
})()
|
|
5170
6008
|
]
|
|
5171
6009
|
}
|
|
5172
6010
|
);
|
|
@@ -5180,11 +6018,11 @@ function ExpandedSubTables({
|
|
|
5180
6018
|
context
|
|
5181
6019
|
}) {
|
|
5182
6020
|
var _a;
|
|
5183
|
-
const [activeTab, setActiveTab] = (0,
|
|
6021
|
+
const [activeTab, setActiveTab] = (0, import_react14.useState)((_a = subTableColumns[0]) == null ? void 0 : _a.name);
|
|
5184
6022
|
if (subTableColumns.length === 0) return null;
|
|
5185
6023
|
if (subTableColumns.length === 1) {
|
|
5186
6024
|
const stCol = subTableColumns[0];
|
|
5187
|
-
return /* @__PURE__ */ (0,
|
|
6025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5188
6026
|
SubTableViewer,
|
|
5189
6027
|
{
|
|
5190
6028
|
rowId,
|
|
@@ -5196,8 +6034,8 @@ function ExpandedSubTables({
|
|
|
5196
6034
|
) }) });
|
|
5197
6035
|
}
|
|
5198
6036
|
const activeCol = subTableColumns.find((c) => c.name === activeTab) || subTableColumns[0];
|
|
5199
|
-
return /* @__PURE__ */ (0,
|
|
5200
|
-
/* @__PURE__ */ (0,
|
|
6037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50 overflow-hidden", children: [
|
|
6038
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex border-b border-slate-200 bg-slate-100/50 px-2 pt-2 gap-1 overflow-hidden", children: subTableColumns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5201
6039
|
"button",
|
|
5202
6040
|
{
|
|
5203
6041
|
type: "button",
|
|
@@ -5207,7 +6045,7 @@ function ExpandedSubTables({
|
|
|
5207
6045
|
},
|
|
5208
6046
|
col.name
|
|
5209
6047
|
)) }),
|
|
5210
|
-
/* @__PURE__ */ (0,
|
|
6048
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5211
6049
|
SubTableViewer,
|
|
5212
6050
|
{
|
|
5213
6051
|
rowId,
|
|
@@ -5220,11 +6058,134 @@ function ExpandedSubTables({
|
|
|
5220
6058
|
) })
|
|
5221
6059
|
] }) });
|
|
5222
6060
|
}
|
|
6061
|
+
var TableRow = import_react14.default.memo(function TableRow2({
|
|
6062
|
+
row,
|
|
6063
|
+
isSelected,
|
|
6064
|
+
isExpanded,
|
|
6065
|
+
filteredColumns,
|
|
6066
|
+
columnWidths,
|
|
6067
|
+
hasSubTableCols,
|
|
6068
|
+
subTableColumns,
|
|
6069
|
+
isLoading,
|
|
6070
|
+
isUpdatingActive,
|
|
6071
|
+
onToggleSelect,
|
|
6072
|
+
onToggleExpand,
|
|
6073
|
+
handleCellChange,
|
|
6074
|
+
handleQuietCellChange,
|
|
6075
|
+
handleUpdateColumnConfig,
|
|
6076
|
+
onMarkForDeletion,
|
|
6077
|
+
triggerSaveSuccess,
|
|
6078
|
+
schema,
|
|
6079
|
+
orgId,
|
|
6080
|
+
componentId,
|
|
6081
|
+
pageState,
|
|
6082
|
+
relationOptions,
|
|
6083
|
+
relationDictionaryRef,
|
|
6084
|
+
refetchRelation,
|
|
6085
|
+
executeAction,
|
|
6086
|
+
emitEvent
|
|
6087
|
+
}) {
|
|
6088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react14.default.Fragment, { children: [
|
|
6089
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tr", { className: `hover:bg-blue-50/30 transition-colors group ${isSelected ? "bg-blue-50/40" : ""}`, children: [
|
|
6090
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", style: { width: 72, minWidth: 72, maxWidth: 72 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-center gap-1.5", children: [
|
|
6091
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6092
|
+
"input",
|
|
6093
|
+
{
|
|
6094
|
+
type: "checkbox",
|
|
6095
|
+
checked: isSelected,
|
|
6096
|
+
onChange: (e) => onToggleSelect(row.id, e.target.checked),
|
|
6097
|
+
disabled: isLoading || isUpdatingActive,
|
|
6098
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
6099
|
+
}
|
|
6100
|
+
),
|
|
6101
|
+
hasSubTableCols && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6102
|
+
"button",
|
|
6103
|
+
{
|
|
6104
|
+
type: "button",
|
|
6105
|
+
onClick: () => onToggleExpand(row.id),
|
|
6106
|
+
className: "w-5 h-5 rounded-full bg-slate-500 hover:bg-slate-600 text-white flex items-center justify-center transition-colors cursor-pointer shrink-0 shadow-sm",
|
|
6107
|
+
title: isExpanded ? "\u05E1\u05D2\u05D5\u05E8 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4" : "\u05E4\u05EA\u05D7 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4",
|
|
6108
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: `w-3 h-3 transition-transform duration-150 ${isExpanded ? "rotate-90" : "rotate-180"}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "3", d: "M9 5l7 7-7 7" }) })
|
|
6109
|
+
}
|
|
6110
|
+
)
|
|
6111
|
+
] }) }),
|
|
6112
|
+
filteredColumns.map((col) => {
|
|
6113
|
+
var _a;
|
|
6114
|
+
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
6115
|
+
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
6116
|
+
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
6117
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
6118
|
+
let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
|
|
6119
|
+
if (value === void 0 && col.defaultValue !== void 0) {
|
|
6120
|
+
value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
|
|
6121
|
+
if (colType === "CURRENCY" || colType === "NUMBER") {
|
|
6122
|
+
if (isNaN(value)) value = null;
|
|
6123
|
+
}
|
|
6124
|
+
}
|
|
6125
|
+
if (value === void 0) value = null;
|
|
6126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6127
|
+
"td",
|
|
6128
|
+
{
|
|
6129
|
+
className: `border-b border-l border-slate-200 p-0 relative ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
6130
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
6131
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6132
|
+
InputComponent,
|
|
6133
|
+
{
|
|
6134
|
+
value,
|
|
6135
|
+
column: col,
|
|
6136
|
+
rowId: row.id,
|
|
6137
|
+
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
6138
|
+
context: {
|
|
6139
|
+
tableName: (schema == null ? void 0 : schema.name) || (schema == null ? void 0 : schema.tableName) || (schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.id) || "Table",
|
|
6140
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
6141
|
+
onMarkForDeletion,
|
|
6142
|
+
relationOptions,
|
|
6143
|
+
relationDictionaryRef,
|
|
6144
|
+
refetchRelation,
|
|
6145
|
+
executeAction,
|
|
6146
|
+
emitEvent,
|
|
6147
|
+
pageState,
|
|
6148
|
+
componentId,
|
|
6149
|
+
orgId,
|
|
6150
|
+
updateQuietly: handleQuietCellChange,
|
|
6151
|
+
triggerSaveSuccess,
|
|
6152
|
+
rowData: row.data
|
|
6153
|
+
}
|
|
6154
|
+
}
|
|
6155
|
+
)
|
|
6156
|
+
},
|
|
6157
|
+
col.name
|
|
6158
|
+
);
|
|
6159
|
+
}),
|
|
6160
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
|
|
6161
|
+
] }),
|
|
6162
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6163
|
+
ExpandedSubTables,
|
|
6164
|
+
{
|
|
6165
|
+
rowId: row.id,
|
|
6166
|
+
rowData: row.data,
|
|
6167
|
+
subTableColumns,
|
|
6168
|
+
filteredColumnsLength: filteredColumns.length,
|
|
6169
|
+
handleCellChange,
|
|
6170
|
+
context: {
|
|
6171
|
+
executeAction,
|
|
6172
|
+
orgId,
|
|
6173
|
+
parentTableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
6174
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
6175
|
+
rowData: row.data,
|
|
6176
|
+
updateQuietly: handleQuietCellChange,
|
|
6177
|
+
triggerSaveSuccess,
|
|
6178
|
+
onUpdateColumnConfig: handleUpdateColumnConfig
|
|
6179
|
+
}
|
|
6180
|
+
}
|
|
6181
|
+
)
|
|
6182
|
+
] });
|
|
6183
|
+
});
|
|
5223
6184
|
|
|
5224
6185
|
// src/components/TableBlock/TableBlock.tsx
|
|
5225
|
-
var
|
|
6186
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
5226
6187
|
function TableBlock(props) {
|
|
5227
|
-
return /* @__PURE__ */ (0,
|
|
6188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TableBlockClient, __spreadValues({}, props));
|
|
5228
6189
|
}
|
|
5229
6190
|
|
|
5230
6191
|
// src/registry.ts
|
|
@@ -5241,6 +6202,7 @@ var UNIVERSE_COMPONENTS = {
|
|
|
5241
6202
|
DatePickerCell,
|
|
5242
6203
|
LinkPickerCell,
|
|
5243
6204
|
PASTEL_PALETTES,
|
|
6205
|
+
RelationFilterPopover,
|
|
5244
6206
|
RelationPickerCell,
|
|
5245
6207
|
TEXT_REPRESENTABLE_TYPES,
|
|
5246
6208
|
TableBlock,
|