@faasjs/ant-design 8.0.0-beta.23 → 8.0.0-beta.25

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/index.d.ts CHANGED
@@ -752,7 +752,7 @@ type TableFaasDataResponse<T = any> = {
752
752
  * }
753
753
  * ```
754
754
  */
755
- declare function Table<T extends Record<string, any>, ExtendTypes = any>(props: TableProps<T, ExtendTypes>): _$react_jsx_runtime0.JSX.Element | null;
755
+ declare function Table<T extends Record<string, any>, ExtendTypes = any>(props: TableProps<T, ExtendTypes>): _$react_jsx_runtime0.JSX.Element;
756
756
  //#endregion
757
757
  //#region src/data.d.ts
758
758
  /**
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { ErrorBoundary as ErrorBoundary$1, FaasDataWrapper as FaasDataWrapper$1, FaasReactClient, OptionalWrapper, createSplittingContext, faas, useEqualCallback, useEqualEffect, useFaas, withFaasData as withFaasData$1 } from "@faasjs/react";
1
+ import { ErrorBoundary as ErrorBoundary$1, FaasDataWrapper as FaasDataWrapper$1, FaasReactClient, OptionalWrapper, createSplittingContext, faas, useEqualCallback, useEqualEffect, useEqualMemo, useFaas, withFaasData as withFaasData$1 } from "@faasjs/react";
2
2
  import { Alert, Button, Col, ConfigProvider as ConfigProvider$1, DatePicker, Descriptions, Drawer, Form as Form$1, Input, InputNumber, Modal, Radio, Result, Row, Select, Skeleton, Space, Spin, Switch, Table as Table$1, Tabs as Tabs$1, Typography, message, notification, theme } from "antd";
3
3
  import { BrowserRouter, Route, Routes as Routes$1, useLocation, useNavigate } from "react-router-dom";
4
4
  import { cloneDeep, defaultsDeep, isNil, uniqBy } from "lodash-es";
5
- import { Suspense, cloneElement, createContext, createElement, isValidElement, lazy, useCallback, useContext, useState } from "react";
5
+ import { Suspense, cloneElement, createContext, createElement, isValidElement, lazy, useContext, useState } from "react";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { CheckOutlined, CloseOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
8
8
  import dayjs from "dayjs";
@@ -930,6 +930,24 @@ function processProps(propsCopy, config) {
930
930
  }
931
931
  return propsCopy;
932
932
  }
933
+ function createComputedProps(props, config, hidden, setConditionalHidden) {
934
+ const propsCopy = cloneDeep(props);
935
+ delete propsCopy.extendTypes;
936
+ if (propsCopy.if) {
937
+ const condition = propsCopy.if;
938
+ const originShouldUpdate = propsCopy.shouldUpdate;
939
+ propsCopy.shouldUpdate = (prev, cur) => {
940
+ const show = condition(cur);
941
+ const shouldUpdate = hidden !== show;
942
+ setConditionalHidden(!show);
943
+ const origin = originShouldUpdate ? typeof originShouldUpdate === "boolean" ? originShouldUpdate : originShouldUpdate(prev, cur, {}) : true;
944
+ return shouldUpdate || origin;
945
+ };
946
+ delete propsCopy.if;
947
+ delete propsCopy.hidden;
948
+ }
949
+ return processProps(propsCopy, config);
950
+ }
933
951
  /**
934
952
  * Render a FaasJS-aware Ant Design form field or nested field group.
935
953
  *
@@ -958,33 +976,14 @@ function processProps(propsCopy, config) {
958
976
  * ```
959
977
  */
960
978
  function FormItem(props) {
961
- const [computedProps, setComputedProps] = useState();
962
- const [extendTypes, setExtendTypes] = useState();
963
979
  const { theme } = useConfigContext();
964
980
  const [hidden, setHidden] = useState(props.hidden || false);
965
- useEqualEffect(() => {
966
- const { extendTypes, ...propsCopy } = { ...props };
967
- if (extendTypes) setExtendTypes(extendTypes);
968
- if (propsCopy.if) {
969
- const condition = propsCopy.if;
970
- const originShouldUpdate = propsCopy.shouldUpdate;
971
- propsCopy.shouldUpdate = (prev, cur) => {
972
- const show = condition(cur);
973
- const shouldUpdate = hidden !== show;
974
- setHidden(!show);
975
- const origin = originShouldUpdate ? typeof originShouldUpdate === "boolean" ? originShouldUpdate : originShouldUpdate(prev, cur, {}) : true;
976
- return shouldUpdate || origin;
977
- };
978
- delete propsCopy.if;
979
- delete propsCopy.hidden;
980
- }
981
- setComputedProps(processProps(propsCopy, theme.common));
982
- }, [
981
+ const computedProps = useEqualMemo(() => createComputedProps(props, theme.common, hidden, setHidden), [
983
982
  hidden,
984
983
  props,
985
984
  theme.common
986
985
  ]);
987
- if (!computedProps) return null;
986
+ const extendTypes = props.extendTypes;
988
987
  const itemType = computedProps.type ?? "string";
989
988
  if (hidden) return /* @__PURE__ */ jsx(Form$1.Item, {
990
989
  ...computedProps,
@@ -1565,6 +1564,284 @@ function processValue(item, value) {
1565
1564
  if (["date", "time"].includes(itemType)) return transferred.format(itemType === "date" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss");
1566
1565
  return transferred;
1567
1566
  }
1567
+ function toTableFilters(options, includeBlank = false) {
1568
+ const filters = options.map((option) => ({
1569
+ text: option.label,
1570
+ value: option.value
1571
+ }));
1572
+ if (includeBlank) filters.push({
1573
+ text: /* @__PURE__ */ jsx(Blank, {}),
1574
+ value: null
1575
+ });
1576
+ return filters;
1577
+ }
1578
+ function generateFilterDropdown(item, search) {
1579
+ if (item.filterDropdown && item.filterDropdown !== true) return;
1580
+ if (!item.options?.length) return;
1581
+ if (item.options.length < 11) {
1582
+ if (!item.filters) item.filters = toTableFilters(item.options);
1583
+ return;
1584
+ }
1585
+ item.filterDropdown = ({ setSelectedKeys, selectedKeys, confirm }) => /* @__PURE__ */ jsx("div", {
1586
+ style: {
1587
+ padding: 8,
1588
+ width: "200px"
1589
+ },
1590
+ onKeyDown: (e) => e.stopPropagation(),
1591
+ children: /* @__PURE__ */ jsx(Select, {
1592
+ options: item.options,
1593
+ allowClear: true,
1594
+ showSearch: true,
1595
+ style: { width: "100%" },
1596
+ placeholder: `${search} ${item.title}`,
1597
+ value: selectedKeys,
1598
+ onChange: (v) => {
1599
+ setSelectedKeys(v?.length ? v : []);
1600
+ confirm();
1601
+ },
1602
+ mode: "multiple",
1603
+ filterOption: (input, option) => {
1604
+ if (!input || !option) return true;
1605
+ if (typeof option.label !== "string") return option.value === input;
1606
+ input = input.trim();
1607
+ return option.value === input || option.label.toLowerCase().includes(input.toLowerCase());
1608
+ }
1609
+ })
1610
+ });
1611
+ }
1612
+ function createTextSearchFilterDropdown(item, search, transformValue) {
1613
+ return ({ setSelectedKeys, confirm, clearFilters }) => /* @__PURE__ */ jsx(Input.Search, {
1614
+ placeholder: `${search} ${item.title}`,
1615
+ allowClear: true,
1616
+ onSearch: (v) => {
1617
+ if (v) setSelectedKeys(transformValue ? [transformValue(v)] : [v]);
1618
+ else {
1619
+ setSelectedKeys([]);
1620
+ clearFilters?.();
1621
+ }
1622
+ confirm();
1623
+ }
1624
+ });
1625
+ }
1626
+ function createTableColumns(items, options) {
1627
+ const columns = cloneDeep(items).filter((item) => !(item.tableChildren === null || item.children === null || item.tableRender === null || item.render === null));
1628
+ for (const item of columns) {
1629
+ if (!item.key) item.key = item.id;
1630
+ if (!item.dataIndex) item.dataIndex = item.id;
1631
+ const itemType = item.type ?? "string";
1632
+ item.title = item.title ?? idToTitle(item.id);
1633
+ item.type = itemType;
1634
+ if (item.options?.length) {
1635
+ item.options = transferOptions(item.options);
1636
+ item.filters = toTableFilters(item.options, true);
1637
+ generateFilterDropdown(item, options.search);
1638
+ }
1639
+ const children = item.tableChildren || item.children;
1640
+ if (children) {
1641
+ item.render = (value, values) => cloneUnionFaasItemElement(children, {
1642
+ scene: "table",
1643
+ value,
1644
+ values,
1645
+ index: 0
1646
+ });
1647
+ delete item.children;
1648
+ delete item.tableChildren;
1649
+ continue;
1650
+ }
1651
+ const render = item.tableRender || item.render;
1652
+ if (render) {
1653
+ item.render = (value, values) => render(value, values, 0, "table");
1654
+ delete item.tableRender;
1655
+ continue;
1656
+ }
1657
+ const extendType = options.extendTypes?.[itemType];
1658
+ if (extendType) {
1659
+ const extendChildren = extendType.children;
1660
+ if (extendChildren) item.render = (value, values) => cloneUnionFaasItemElement(extendChildren, {
1661
+ scene: "table",
1662
+ value,
1663
+ values,
1664
+ index: 0
1665
+ });
1666
+ else {
1667
+ const extendRender = extendType.render;
1668
+ if (extendRender) item.render = (value, values) => extendRender(value, values, 0, "table");
1669
+ else throw Error(`${itemType} requires children or render`);
1670
+ }
1671
+ continue;
1672
+ }
1673
+ switch (itemType) {
1674
+ case "string":
1675
+ if (!item.render) item.render = (value) => processValue(item, value);
1676
+ if (item.filterDropdown !== false) {
1677
+ if (!item.onFilter && !options.faasData) item.onFilter = (value, row) => {
1678
+ if (!value || isNil(value)) return true;
1679
+ if (isNil(row[item.id])) return false;
1680
+ return row[item.id].trim().toLowerCase().includes(value.trim().toLowerCase());
1681
+ };
1682
+ if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto") item.filterDropdown = createTextSearchFilterDropdown(item, options.search);
1683
+ }
1684
+ break;
1685
+ case "string[]":
1686
+ if (!item.render) item.render = (value) => processValue(item, value);
1687
+ if (item.filterDropdown !== false) {
1688
+ if (!item.onFilter && !options.faasData) item.onFilter = (value, row) => {
1689
+ if (value === null && (!row[item.id] || !row[item.id].length)) return true;
1690
+ if (!row[item.id] || !row[item.id].length || !value) return false;
1691
+ return row[item.id].some((v) => v.trim().toLowerCase().includes(value.trim().toLowerCase()));
1692
+ };
1693
+ if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto") item.filterDropdown = createTextSearchFilterDropdown(item, options.search);
1694
+ }
1695
+ break;
1696
+ case "number":
1697
+ if (!item.render) item.render = (value) => processValue(item, value);
1698
+ if (typeof item.sorter === "undefined") item.sorter = (a, b) => a[item.id] - b[item.id];
1699
+ if (item.filterDropdown !== false) {
1700
+ if (!item.onFilter && !options.faasData) item.onFilter = (value, row) => {
1701
+ if (value === null) return true;
1702
+ if (isNil(row[item.id])) return false;
1703
+ return value == row[item.id];
1704
+ };
1705
+ if (typeof item.filterDropdown === "undefined" && !item.filters) item.filterDropdown = createTextSearchFilterDropdown(item, options.search, Number);
1706
+ }
1707
+ break;
1708
+ case "number[]":
1709
+ if (!item.render) item.render = (value) => processValue(item, value);
1710
+ if (item.filterDropdown !== false) {
1711
+ if (!item.onFilter && !options.faasData) item.onFilter = (value, row) => {
1712
+ if (value === null && (!row[item.id] || !row[item.id].length)) return true;
1713
+ if (!row[item.id] || !row[item.id].length) return false;
1714
+ return row[item.id].includes(Number(value));
1715
+ };
1716
+ if (typeof item.filterDropdown === "undefined" && !item.filters) item.filterDropdown = createTextSearchFilterDropdown(item, options.search, Number);
1717
+ }
1718
+ break;
1719
+ case "boolean":
1720
+ if (!item.render) item.render = (value) => isNil(value) ? /* @__PURE__ */ jsx(Blank, {}) : value ? /* @__PURE__ */ jsx(CheckOutlined, { style: {
1721
+ marginTop: "4px",
1722
+ color: "#52c41a"
1723
+ } }) : /* @__PURE__ */ jsx(CloseOutlined, { style: {
1724
+ marginTop: "4px",
1725
+ color: "#ff4d4f"
1726
+ } });
1727
+ if (item.filterDropdown !== false) {
1728
+ if (typeof item.filterDropdown === "undefined") item.filterDropdown = ({ setSelectedKeys, selectedKeys, confirm: confirmFilter }) => /* @__PURE__ */ jsxs(Radio.Group, {
1729
+ style: { padding: 8 },
1730
+ buttonStyle: "solid",
1731
+ value: JSON.stringify(selectedKeys[0]),
1732
+ onChange: (e) => {
1733
+ setSelectedKeys(e.target.value ? [{
1734
+ true: true,
1735
+ false: false,
1736
+ null: null
1737
+ }[e.target.value]] : []);
1738
+ confirmFilter();
1739
+ },
1740
+ children: [
1741
+ /* @__PURE__ */ jsx(Radio.Button, { children: options.all }),
1742
+ /* @__PURE__ */ jsx(Radio.Button, {
1743
+ value: "true",
1744
+ children: /* @__PURE__ */ jsx(CheckOutlined, { style: {
1745
+ color: "#52c41a",
1746
+ verticalAlign: "middle"
1747
+ } })
1748
+ }),
1749
+ /* @__PURE__ */ jsx(Radio.Button, {
1750
+ value: "false",
1751
+ children: /* @__PURE__ */ jsx(CloseOutlined, { style: {
1752
+ verticalAlign: "middle",
1753
+ color: "#ff4d4f"
1754
+ } })
1755
+ }),
1756
+ /* @__PURE__ */ jsx(Radio.Button, {
1757
+ value: "null",
1758
+ children: options.blank
1759
+ })
1760
+ ]
1761
+ });
1762
+ if (!item.onFilter && !options.faasData) item.onFilter = (value, row) => {
1763
+ switch (value) {
1764
+ case true: return !isNil(row[item.id]) && row[item.id] !== false;
1765
+ case false: return !isNil(row[item.id]) && !row[item.id];
1766
+ default: return isNil(row[item.id]);
1767
+ }
1768
+ };
1769
+ }
1770
+ break;
1771
+ case "date":
1772
+ case "time":
1773
+ if (itemType === "time") item.width = item.width ?? 200;
1774
+ if (!item.render) item.render = (value) => processValue(item, value);
1775
+ if (typeof item.sorter === "undefined") item.sorter = (a, b, order) => {
1776
+ if (isNil(a[item.id])) return order === "ascend" ? 1 : -1;
1777
+ if (isNil(b[item.id])) return order === "ascend" ? -1 : 1;
1778
+ return new Date(a[item.id]).getTime() < new Date(b[item.id]).getTime() ? -1 : 1;
1779
+ };
1780
+ if (item.filterDropdown !== false) {
1781
+ if (typeof item.filterDropdown === "undefined") item.filterDropdown = ({ setSelectedKeys, confirm }) => /* @__PURE__ */ jsx(DatePicker.RangePicker, { onChange: (dates) => {
1782
+ const start = dates?.[0];
1783
+ const end = dates?.[1];
1784
+ setSelectedKeys(start && end ? [[start.startOf("day").toISOString(), end.endOf("day").toISOString()]] : []);
1785
+ confirm();
1786
+ } });
1787
+ if (!item.onFilter && !options.faasData) item.onFilter = (value, row) => {
1788
+ if (isNil(value[0])) return true;
1789
+ if (isNil(row[item.id])) return false;
1790
+ return dayjs(row[item.id]) >= dayjs(value[0]) && dayjs(row[item.id]) <= dayjs(value[1]);
1791
+ };
1792
+ }
1793
+ break;
1794
+ case "object":
1795
+ if (!item.render) item.render = (value) => /* @__PURE__ */ jsx(Description, {
1796
+ items: item.object || [],
1797
+ dataSource: value || {},
1798
+ column: 1
1799
+ });
1800
+ break;
1801
+ case "object[]":
1802
+ if (!item.render) item.render = (value) => /* @__PURE__ */ jsx(Fragment, { children: value.map((v, i) => /* @__PURE__ */ jsx(Description, {
1803
+ items: item.object || [],
1804
+ dataSource: v || [],
1805
+ column: 1
1806
+ }, i)) });
1807
+ break;
1808
+ default:
1809
+ if (!item.render) item.render = (value) => processValue(item, value);
1810
+ if (item.filterDropdown !== false && !item.onFilter && !options.faasData) item.onFilter = (value, row) => {
1811
+ if (value === null && isNil(row[item.id])) return true;
1812
+ return value === row[item.id];
1813
+ };
1814
+ break;
1815
+ }
1816
+ }
1817
+ if (options.dataSource) {
1818
+ for (const column of columns) if (column.optionsType === "auto" && !column.options && !column.filters) {
1819
+ const normalizedOptions = uniqBy(options.dataSource, column.id).map((value) => ({
1820
+ label: value[column.id],
1821
+ value: value[column.id]
1822
+ }));
1823
+ if (!normalizedOptions.length) continue;
1824
+ column.options = normalizedOptions;
1825
+ generateFilterDropdown(column, options.search);
1826
+ }
1827
+ }
1828
+ return columns;
1829
+ }
1830
+ function applyFaasDataColumnOptions(columns, data) {
1831
+ if (!data?.options) return columns;
1832
+ let updated = false;
1833
+ const nextColumns = columns.map((column) => {
1834
+ if (!data.options?.[column.id]) return column;
1835
+ updated = true;
1836
+ const nextColumn = { ...column };
1837
+ nextColumn.options = transferOptions(data.options[column.id]);
1838
+ nextColumn.filters = toTableFilters(nextColumn.options, true);
1839
+ nextColumn.render = (value) => processValue(nextColumn, value);
1840
+ if (nextColumn.filterDropdown) delete nextColumn.filterDropdown;
1841
+ return nextColumn;
1842
+ });
1843
+ return updated ? nextColumns : columns;
1844
+ }
1568
1845
  /**
1569
1846
  * Render an Ant Design table from FaasJS item metadata.
1570
1847
  *
@@ -1601,288 +1878,24 @@ function processValue(item, value) {
1601
1878
  * ```
1602
1879
  */
1603
1880
  function Table(props) {
1604
- const [columns, setColumns] = useState();
1605
1881
  const { theme } = useConfigContext();
1606
1882
  const { all, blank, search } = theme.common;
1607
- const generateFilterDropdown = useCallback((item) => {
1608
- if (item.filterDropdown && item.filterDropdown !== true) return;
1609
- if (!item.options?.length) return;
1610
- if (item.options.length < 11) {
1611
- if (!item.filters) item.filters = item.options.map((o) => ({
1612
- text: o.label,
1613
- value: o.value
1614
- }));
1615
- return;
1616
- }
1617
- item.filterDropdown = ({ setSelectedKeys, selectedKeys, confirm }) => /* @__PURE__ */ jsx("div", {
1618
- style: {
1619
- padding: 8,
1620
- width: "200px"
1621
- },
1622
- onKeyDown: (e) => e.stopPropagation(),
1623
- children: /* @__PURE__ */ jsx(Select, {
1624
- options: item.options,
1625
- allowClear: true,
1626
- showSearch: true,
1627
- style: { width: "100%" },
1628
- placeholder: `${search} ${item.title}`,
1629
- value: selectedKeys,
1630
- onChange: (v) => {
1631
- setSelectedKeys(v?.length ? v : []);
1632
- confirm();
1633
- },
1634
- mode: "multiple",
1635
- filterOption: (input, option) => {
1636
- if (!input || !option) return true;
1637
- if (typeof option.label !== "string") return option.value === input;
1638
- input = input.trim();
1639
- return option.value === input || option.label.toLowerCase().includes(input.toLowerCase());
1640
- }
1641
- })
1642
- });
1643
- return item;
1644
- }, [search]);
1645
- useEqualEffect(() => {
1646
- const items = cloneDeep(props.items).filter((item) => !(item.tableChildren === null || item.children === null || item.tableRender === null || item.render === null));
1647
- const createTextSearchFilterDropdown = (item, transformValue) => ({ setSelectedKeys, confirm, clearFilters }) => /* @__PURE__ */ jsx(Input.Search, {
1648
- placeholder: `${search} ${item.title}`,
1649
- allowClear: true,
1650
- onSearch: (v) => {
1651
- if (v) setSelectedKeys(transformValue ? [transformValue(v)] : [v]);
1652
- else {
1653
- setSelectedKeys([]);
1654
- clearFilters?.();
1655
- }
1656
- confirm();
1657
- }
1658
- });
1659
- for (const item of items) {
1660
- if (!item.key) item.key = item.id;
1661
- if (!item.dataIndex) item.dataIndex = item.id;
1662
- const itemType = item.type ?? "string";
1663
- item.title = item.title ?? idToTitle(item.id);
1664
- item.type = itemType;
1665
- if (item.options?.length) {
1666
- item.options = transferOptions(item.options);
1667
- item.filters = item.options.map((o) => ({
1668
- text: o.label,
1669
- value: o.value
1670
- })).concat({
1671
- text: /* @__PURE__ */ jsx(Blank, {}),
1672
- value: null
1673
- });
1674
- generateFilterDropdown(item);
1675
- }
1676
- const children = item.tableChildren || item.children;
1677
- if (children) {
1678
- item.render = (value, values) => cloneUnionFaasItemElement(children, {
1679
- scene: "table",
1680
- value,
1681
- values,
1682
- index: 0
1683
- });
1684
- delete item.children;
1685
- delete item.tableChildren;
1686
- continue;
1687
- }
1688
- const render = item.tableRender || item.render;
1689
- if (render) {
1690
- item.render = (value, values) => render(value, values, 0, "table");
1691
- delete item.tableRender;
1692
- continue;
1693
- }
1694
- const extendType = props.extendTypes?.[itemType];
1695
- if (extendType) {
1696
- const extendChildren = extendType.children;
1697
- if (extendChildren) item.render = (value, values) => cloneUnionFaasItemElement(extendChildren, {
1698
- scene: "table",
1699
- value,
1700
- values,
1701
- index: 0
1702
- });
1703
- else {
1704
- const extendRender = extendType.render;
1705
- if (extendRender) item.render = (value, values) => extendRender(value, values, 0, "table");
1706
- else throw Error(`${itemType} requires children or render`);
1707
- }
1708
- continue;
1709
- }
1710
- switch (itemType) {
1711
- case "string":
1712
- if (!item.render) item.render = (value) => processValue(item, value);
1713
- if (item.filterDropdown !== false) {
1714
- if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1715
- if (!value || isNil(value)) return true;
1716
- if (isNil(row[item.id])) return false;
1717
- return row[item.id].trim().toLowerCase().includes(value.trim().toLowerCase());
1718
- };
1719
- if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto") item.filterDropdown = createTextSearchFilterDropdown(item);
1720
- }
1721
- break;
1722
- case "string[]":
1723
- if (!item.render) item.render = (value) => processValue(item, value);
1724
- if (item.filterDropdown !== false) {
1725
- if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1726
- if (value === null && (!row[item.id] || !row[item.id].length)) return true;
1727
- if (!row[item.id] || !row[item.id].length || !value) return false;
1728
- return row[item.id].some((v) => v.trim().toLowerCase().includes(value.trim().toLowerCase()));
1729
- };
1730
- if (typeof item.filterDropdown === "undefined" && !item.filters && item.optionsType !== "auto") item.filterDropdown = createTextSearchFilterDropdown(item);
1731
- }
1732
- break;
1733
- case "number":
1734
- if (!item.render) item.render = (value) => processValue(item, value);
1735
- if (typeof item.sorter === "undefined") item.sorter = (a, b) => a[item.id] - b[item.id];
1736
- if (item.filterDropdown !== false) {
1737
- if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1738
- if (value === null) return true;
1739
- if (isNil(row[item.id])) return false;
1740
- return value == row[item.id];
1741
- };
1742
- if (typeof item.filterDropdown === "undefined" && !item.filters) item.filterDropdown = createTextSearchFilterDropdown(item, Number);
1743
- }
1744
- break;
1745
- case "number[]":
1746
- if (!item.render) item.render = (value) => processValue(item, value);
1747
- if (item.filterDropdown !== false) {
1748
- if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1749
- if (value === null && (!row[item.id] || !row[item.id].length)) return true;
1750
- if (!row[item.id] || !row[item.id].length) return false;
1751
- return row[item.id].includes(Number(value));
1752
- };
1753
- if (typeof item.filterDropdown === "undefined" && !item.filters) item.filterDropdown = createTextSearchFilterDropdown(item, Number);
1754
- }
1755
- break;
1756
- case "boolean":
1757
- if (!item.render) item.render = (value) => isNil(value) ? /* @__PURE__ */ jsx(Blank, {}) : value ? /* @__PURE__ */ jsx(CheckOutlined, { style: {
1758
- marginTop: "4px",
1759
- color: "#52c41a"
1760
- } }) : /* @__PURE__ */ jsx(CloseOutlined, { style: {
1761
- marginTop: "4px",
1762
- color: "#ff4d4f"
1763
- } });
1764
- if (item.filterDropdown !== false) {
1765
- if (typeof item.filterDropdown === "undefined") item.filterDropdown = ({ setSelectedKeys, selectedKeys, confirm: confirmFilter }) => /* @__PURE__ */ jsxs(Radio.Group, {
1766
- style: { padding: 8 },
1767
- buttonStyle: "solid",
1768
- value: JSON.stringify(selectedKeys[0]),
1769
- onChange: (e) => {
1770
- setSelectedKeys(e.target.value ? [{
1771
- true: true,
1772
- false: false,
1773
- null: null
1774
- }[e.target.value]] : []);
1775
- confirmFilter();
1776
- },
1777
- children: [
1778
- /* @__PURE__ */ jsx(Radio.Button, { children: all }),
1779
- /* @__PURE__ */ jsx(Radio.Button, {
1780
- value: "true",
1781
- children: /* @__PURE__ */ jsx(CheckOutlined, { style: {
1782
- color: "#52c41a",
1783
- verticalAlign: "middle"
1784
- } })
1785
- }),
1786
- /* @__PURE__ */ jsx(Radio.Button, {
1787
- value: "false",
1788
- children: /* @__PURE__ */ jsx(CloseOutlined, { style: {
1789
- verticalAlign: "middle",
1790
- color: "#ff4d4f"
1791
- } })
1792
- }),
1793
- /* @__PURE__ */ jsx(Radio.Button, {
1794
- value: "null",
1795
- children: blank
1796
- })
1797
- ]
1798
- });
1799
- if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1800
- switch (value) {
1801
- case true: return !isNil(row[item.id]) && row[item.id] !== false;
1802
- case false: return !isNil(row[item.id]) && !row[item.id];
1803
- default: return isNil(row[item.id]);
1804
- }
1805
- };
1806
- }
1807
- break;
1808
- case "date":
1809
- case "time":
1810
- if (itemType === "time") item.width = item.width ?? 200;
1811
- if (!item.render) item.render = (value) => processValue(item, value);
1812
- if (typeof item.sorter === "undefined") item.sorter = (a, b, order) => {
1813
- if (isNil(a[item.id])) return order === "ascend" ? 1 : -1;
1814
- if (isNil(b[item.id])) return order === "ascend" ? -1 : 1;
1815
- return new Date(a[item.id]).getTime() < new Date(b[item.id]).getTime() ? -1 : 1;
1816
- };
1817
- if (item.filterDropdown !== false) {
1818
- if (typeof item.filterDropdown === "undefined") item.filterDropdown = ({ setSelectedKeys, confirm }) => /* @__PURE__ */ jsx(DatePicker.RangePicker, { onChange: (dates) => {
1819
- const start = dates?.[0];
1820
- const end = dates?.[1];
1821
- setSelectedKeys(start && end ? [[start.startOf("day").toISOString(), end.endOf("day").toISOString()]] : []);
1822
- confirm();
1823
- } });
1824
- if (!item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1825
- if (isNil(value[0])) return true;
1826
- if (isNil(row[item.id])) return false;
1827
- return dayjs(row[item.id]) >= dayjs(value[0]) && dayjs(row[item.id]) <= dayjs(value[1]);
1828
- };
1829
- }
1830
- break;
1831
- case "object":
1832
- if (!item.render) item.render = (value) => /* @__PURE__ */ jsx(Description, {
1833
- items: item.object || [],
1834
- dataSource: value || {},
1835
- column: 1
1836
- });
1837
- break;
1838
- case "object[]":
1839
- if (!item.render) item.render = (value) => /* @__PURE__ */ jsx(Fragment, { children: value.map((v, i) => /* @__PURE__ */ jsx(Description, {
1840
- items: item.object || [],
1841
- dataSource: v || [],
1842
- column: 1
1843
- }, i)) });
1844
- break;
1845
- default:
1846
- if (!item.render) item.render = (value) => processValue(item, value);
1847
- if (item.filterDropdown !== false && !item.onFilter && !props.faasData) item.onFilter = (value, row) => {
1848
- if (value === null && isNil(row[item.id])) return true;
1849
- return value === row[item.id];
1850
- };
1851
- break;
1852
- }
1853
- }
1854
- setColumns(items);
1855
- }, [
1883
+ const columns = useEqualMemo(() => createTableColumns(props.items, {
1884
+ all,
1885
+ blank,
1886
+ search,
1887
+ ...props.extendTypes ? { extendTypes: props.extendTypes } : {},
1888
+ ...props.faasData ? { faasData: props.faasData } : {},
1889
+ ...props.dataSource ? { dataSource: props.dataSource } : {}
1890
+ }), [
1856
1891
  all,
1857
1892
  blank,
1858
- generateFilterDropdown,
1893
+ props.dataSource,
1859
1894
  props.extendTypes,
1860
1895
  props.faasData,
1861
1896
  props.items,
1862
1897
  search
1863
1898
  ]);
1864
- useEqualEffect(() => {
1865
- if (!props.dataSource || !columns) return;
1866
- for (const column of columns) if (column.optionsType === "auto" && !column.options && !column.filters) {
1867
- const options = uniqBy(props.dataSource, column.id).map((v) => ({
1868
- label: v[column.id],
1869
- value: v[column.id]
1870
- }));
1871
- if (options.length) setColumns((prev) => {
1872
- const newColumns = [...prev || []];
1873
- const index = newColumns.findIndex((item) => item.id === column.id);
1874
- if (index < 0) return newColumns;
1875
- newColumns[index].options = options;
1876
- generateFilterDropdown(newColumns[index]);
1877
- return newColumns;
1878
- });
1879
- }
1880
- }, [
1881
- props.dataSource,
1882
- columns,
1883
- generateFilterDropdown
1884
- ]);
1885
- if (!columns) return null;
1886
1899
  if (props.dataSource) return /* @__PURE__ */ jsx(Table$1, {
1887
1900
  ...props,
1888
1901
  rowKey: props.rowKey || "id",
@@ -1902,71 +1915,40 @@ function Table(props) {
1902
1915
  });
1903
1916
  }
1904
1917
  function FaasDataTable({ props, columns, data, params, reload, loading }) {
1905
- const [currentColumns, setCurrentColumns] = useState(columns);
1906
- useEqualEffect(() => {
1907
- if (!data || Array.isArray(data)) return;
1908
- setCurrentColumns((prev) => {
1909
- const newColumns = [...prev];
1910
- for (const column of newColumns) if (data.options?.[column.id]) {
1911
- column.options = transferOptions(data.options[column.id]);
1912
- column.filters = column.options.map((v) => ({
1913
- text: v.label,
1914
- value: v.value
1915
- })).concat({
1916
- text: /* @__PURE__ */ jsx(Blank, {}),
1917
- value: null
1918
- });
1919
- column.render = (value) => processValue(column, value);
1920
- if (column.filterDropdown) delete column.filterDropdown;
1921
- continue;
1922
- }
1923
- return newColumns;
1924
- });
1925
- }, [data]);
1926
- if (!data) return /* @__PURE__ */ jsx(Table$1, {
1927
- ...props,
1928
- ...typeof loading === "undefined" ? {} : { loading },
1929
- rowKey: props.rowKey || "id",
1930
- columns: currentColumns,
1931
- dataSource: []
1932
- });
1933
- if (Array.isArray(data)) return /* @__PURE__ */ jsx(Table$1, {
1934
- ...props,
1935
- ...typeof loading === "undefined" ? {} : { loading },
1936
- rowKey: props.rowKey || "id",
1937
- columns: currentColumns,
1938
- dataSource: data
1939
- });
1918
+ const currentColumns = useEqualMemo(() => !data || Array.isArray(data) ? columns : applyFaasDataColumnOptions(columns, data), [columns, data]);
1919
+ const tableDataSource = !data ? [] : Array.isArray(data) ? data : data.rows;
1940
1920
  return /* @__PURE__ */ jsx(Table$1, {
1941
1921
  ...props,
1942
1922
  ...typeof loading === "undefined" ? {} : { loading },
1943
- rowKey: props.rowKey || "id",
1944
- columns: currentColumns,
1945
- dataSource: data.rows,
1946
- pagination: props.pagination === false ? false : {
1947
- ...props.pagination || Object.create(null),
1948
- ...data.pagination || Object.create(null)
1949
- },
1950
- onChange: (pagination, filters, sorter, extra) => {
1951
- if (!reload) return;
1952
- if (props.onChange) {
1953
- const processed = props.onChange(pagination, filters, sorter, extra);
1923
+ ...!data || Array.isArray(data) ? {} : {
1924
+ pagination: props.pagination === false ? false : {
1925
+ ...props.pagination || Object.create(null),
1926
+ ...data.pagination || Object.create(null)
1927
+ },
1928
+ onChange: (pagination, filters, sorter, extra) => {
1929
+ if (!reload) return;
1930
+ if (props.onChange) {
1931
+ const processed = props.onChange(pagination, filters, sorter, extra);
1932
+ reload({
1933
+ ...params || Object.create(null),
1934
+ pagination: processed.pagination,
1935
+ filters: processed.filters,
1936
+ sorter: processed.sorter,
1937
+ extra: processed.extra
1938
+ });
1939
+ return;
1940
+ }
1954
1941
  reload({
1955
1942
  ...params || Object.create(null),
1956
- pagination: processed.pagination,
1957
- filters: processed.filters,
1958
- sorter: processed.sorter,
1959
- extra: processed.extra
1943
+ pagination,
1944
+ filters,
1945
+ sorter
1960
1946
  });
1961
- return;
1962
1947
  }
1963
- reload({
1964
- ...params || Object.create(null),
1965
- pagination,
1966
- filters,
1967
- sorter
1968
- });
1969
- }
1948
+ },
1949
+ rowKey: props.rowKey || "id",
1950
+ columns: currentColumns,
1951
+ dataSource: tableDataSource
1970
1952
  });
1971
1953
  }
1972
1954
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faasjs/ant-design",
3
- "version": "8.0.0-beta.23",
3
+ "version": "8.0.0-beta.25",
4
4
  "homepage": "https://faasjs.com/doc/ant-design",
5
5
  "bugs": {
6
6
  "url": "https://github.com/faasjs/faasjs/issues"
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "devDependencies": {
29
29
  "@ant-design/icons": "*",
30
- "@faasjs/react": ">=8.0.0-beta.23",
30
+ "@faasjs/react": ">=8.0.0-beta.25",
31
31
  "@types/lodash-es": "*",
32
32
  "@types/react": "^19.0.0",
33
33
  "@types/react-dom": "^19.0.0",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@ant-design/icons": "*",
42
- "@faasjs/react": ">=8.0.0-beta.23",
42
+ "@faasjs/react": ">=8.0.0-beta.25",
43
43
  "antd": "^6.0.0",
44
44
  "lodash-es": "*",
45
45
  "react": "^19.0.0",