com-angel-authorization 1.0.9 → 1.0.11

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.
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var vue_exports = {};
22
22
  __export(vue_exports, {
23
23
  Can: () => Can,
24
+ MENU_LEAF_NO: () => MENU_LEAF_NO,
25
+ MENU_LEAF_YES: () => MENU_LEAF_YES,
24
26
  MENU_LIST_TYPE_PARAM: () => MENU_LIST_TYPE_PARAM,
25
27
  MENU_TYPE_BUTTON: () => MENU_TYPE_BUTTON,
26
28
  MENU_TYPE_LABEL: () => MENU_TYPE_LABEL,
@@ -57,6 +59,7 @@ __export(vue_exports, {
57
59
  extractRecords: () => extractRecords,
58
60
  getAppClientId: () => getAppClientId,
59
61
  getDeviceWorkerId: () => getDeviceWorkerId,
62
+ isMenuLeaf: () => isMenuLeaf,
60
63
  mapAuthorizationResource: () => mapAuthorizationResource,
61
64
  mapMenuResource: () => mapMenuResource,
62
65
  resolveMenuDepth: () => resolveMenuDepth,
@@ -366,6 +369,8 @@ var Can = (0, import_vue2.defineComponent)({
366
369
  var import_vue3 = require("vue");
367
370
 
368
371
  // src/resources/types.ts
372
+ var MENU_LEAF_YES = 1;
373
+ var MENU_LEAF_NO = 0;
369
374
  var RESOURCE_TYPE_API = "api";
370
375
  var MENU_TYPE_PAGE = "page";
371
376
  var MENU_TYPE_MENU = "menu";
@@ -594,10 +599,13 @@ function mapMenuResource(item) {
594
599
  const rawDepth = row.depth;
595
600
  const parsedDepth = Number(rawDepth);
596
601
  const depth = Number.isFinite(parsedDepth) && parsedDepth > 0 ? Math.floor(parsedDepth) : parentId ? ROOT_MENU_DEPTH + 1 : ROOT_MENU_DEPTH;
602
+ const rawLeaf = row.leaf;
603
+ const leaf = rawLeaf === true || rawLeaf === 1 || rawLeaf === "1" || String(rawLeaf).toLowerCase() === "true" ? MENU_LEAF_YES : Number(rawLeaf) === MENU_LEAF_YES ? MENU_LEAF_YES : 0;
597
604
  return {
598
605
  resourceId: String(resourceId),
599
606
  parentId,
600
607
  depth,
608
+ leaf,
601
609
  type: toMenuType(row.type),
602
610
  name: String(row.name ?? ""),
603
611
  identification: String(row.identification ?? row.identity ?? row.path ?? ""),
@@ -606,6 +614,9 @@ function mapMenuResource(item) {
606
614
  status: toResourceStatus(row.status)
607
615
  };
608
616
  }
617
+ function isMenuLeaf(row) {
618
+ return Number(row.leaf) === MENU_LEAF_YES;
619
+ }
609
620
  function resolveMenuDepth(parentId, menus) {
610
621
  if (!parentId) return ROOT_MENU_DEPTH;
611
622
  const parent = menus.find((item) => item.resourceId === parentId);
@@ -615,6 +626,9 @@ function resolveMenuDepth(parentId, menus) {
615
626
  function buildListUrl(type, params) {
616
627
  const parts = [];
617
628
  appendQueryParam(parts, "type", type);
629
+ if (params?.depth !== void 0 && params?.depth !== null && String(params.depth) !== "") {
630
+ appendQueryParam(parts, "depth", String(params.depth));
631
+ }
618
632
  appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
619
633
  appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
620
634
  appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
@@ -712,7 +726,10 @@ function createMenuResourceApi(request) {
712
726
  async list(params, signal) {
713
727
  const json = await request({
714
728
  method: "GET",
715
- url: buildListUrl(MENU_LIST_TYPE_PARAM, params),
729
+ url: buildListUrl(MENU_LIST_TYPE_PARAM, {
730
+ pagination: params?.pagination,
731
+ depth: params?.depth ?? ROOT_MENU_DEPTH
732
+ }),
716
733
  signal
717
734
  });
718
735
  const records = extractRecords(json).map(mapMenuResource).filter((item) => item !== null);
@@ -722,6 +739,14 @@ function createMenuResourceApi(request) {
722
739
  ...pagination
723
740
  };
724
741
  },
742
+ async listSubResources(resourceId, signal) {
743
+ const json = await request({
744
+ method: "GET",
745
+ url: `/authorization-resources/${encodeURIComponent(resourceId)}/sub-resources`,
746
+ signal
747
+ });
748
+ return extractRecords(json).map(mapMenuResource).filter((item) => item !== null);
749
+ },
725
750
  listPermissionPoints(params, signal) {
726
751
  return permissionApi.list(params, signal);
727
752
  },
@@ -1511,6 +1536,30 @@ var s2 = {
1511
1536
  borderBottom: "1px solid #f2f4f7",
1512
1537
  verticalAlign: "middle"
1513
1538
  },
1539
+ treeCell: {
1540
+ display: "flex",
1541
+ alignItems: "center",
1542
+ gap: "6px"
1543
+ },
1544
+ treeToggle: {
1545
+ width: "22px",
1546
+ height: "22px",
1547
+ border: "1px solid #d0d5dd",
1548
+ borderRadius: "4px",
1549
+ background: "#fff",
1550
+ color: "#475467",
1551
+ cursor: "pointer",
1552
+ fontSize: "10px",
1553
+ lineHeight: "20px",
1554
+ padding: "0",
1555
+ flexShrink: "0"
1556
+ },
1557
+ treeSpacer: {
1558
+ width: "22px",
1559
+ height: "22px",
1560
+ flexShrink: "0",
1561
+ display: "inline-block"
1562
+ },
1514
1563
  empty: {
1515
1564
  padding: "28px",
1516
1565
  textAlign: "center",
@@ -1647,7 +1696,9 @@ var s2 = {
1647
1696
  border: "none",
1648
1697
  display: "flex",
1649
1698
  flexDirection: "column",
1650
- gap: "8px"
1699
+ gap: "8px",
1700
+ backgroundColor: "transparent",
1701
+ color: "#101828"
1651
1702
  },
1652
1703
  label: { fontSize: "13px", color: "#344054", fontWeight: "500" },
1653
1704
  input: {
@@ -1661,14 +1712,29 @@ var s2 = {
1661
1712
  boxSizing: "border-box",
1662
1713
  width: "100%"
1663
1714
  },
1664
- radioGroup: { display: "flex", flexWrap: "wrap", gap: "16px" },
1715
+ control: {
1716
+ width: "16px",
1717
+ height: "16px",
1718
+ margin: "0",
1719
+ flexShrink: "0",
1720
+ accentColor: "#049BAD",
1721
+ backgroundColor: "#ffffff",
1722
+ colorScheme: "light"
1723
+ },
1724
+ radioGroup: {
1725
+ display: "flex",
1726
+ flexWrap: "wrap",
1727
+ gap: "16px",
1728
+ backgroundColor: "transparent"
1729
+ },
1665
1730
  radioItem: {
1666
1731
  display: "flex",
1667
1732
  alignItems: "center",
1668
1733
  gap: "6px",
1669
1734
  fontSize: "14px",
1670
1735
  color: "#344054",
1671
- cursor: "pointer"
1736
+ cursor: "pointer",
1737
+ backgroundColor: "transparent"
1672
1738
  },
1673
1739
  multiSelect: {
1674
1740
  maxHeight: "160px",
@@ -1676,7 +1742,8 @@ var s2 = {
1676
1742
  border: "1px solid #eaecf0",
1677
1743
  borderRadius: "8px",
1678
1744
  padding: "8px",
1679
- background: "#f9fafb"
1745
+ backgroundColor: "#ffffff",
1746
+ color: "#101828"
1680
1747
  },
1681
1748
  checkItem: {
1682
1749
  display: "flex",
@@ -1685,7 +1752,8 @@ var s2 = {
1685
1752
  padding: "6px 4px",
1686
1753
  fontSize: "13px",
1687
1754
  color: "#344054",
1688
- cursor: "pointer"
1755
+ cursor: "pointer",
1756
+ backgroundColor: "transparent"
1689
1757
  },
1690
1758
  hint: { fontSize: "13px", color: "#98a2b3", padding: "8px" },
1691
1759
  dialogFooter: {
@@ -1713,6 +1781,9 @@ var MenuManager = (0, import_vue4.defineComponent)({
1713
1781
  },
1714
1782
  setup(props, { slots }) {
1715
1783
  const records = (0, import_vue4.ref)([]);
1784
+ const childrenMap = (0, import_vue4.ref)({});
1785
+ const expandedIds = (0, import_vue4.ref)({});
1786
+ const expandingIds = (0, import_vue4.ref)({});
1716
1787
  const permissionPoints = (0, import_vue4.ref)([]);
1717
1788
  const loading = (0, import_vue4.ref)(false);
1718
1789
  const error = (0, import_vue4.ref)("");
@@ -1733,17 +1804,39 @@ var MenuManager = (0, import_vue4.defineComponent)({
1733
1804
  );
1734
1805
  return map;
1735
1806
  });
1807
+ const allKnownMenus = (0, import_vue4.computed)(() => {
1808
+ const map = /* @__PURE__ */ new Map();
1809
+ records.value.forEach((row) => map.set(row.resourceId, row));
1810
+ Object.values(childrenMap.value).forEach((list) => {
1811
+ list.forEach((row) => map.set(row.resourceId, row));
1812
+ });
1813
+ return Array.from(map.values());
1814
+ });
1736
1815
  const parentOptions = (0, import_vue4.computed)(
1737
- () => records.value.filter((row) => !editing.value || row.resourceId !== editing.value.resourceId).map((row) => ({
1816
+ () => allKnownMenus.value.filter((row) => !editing.value || row.resourceId !== editing.value.resourceId).map((row) => ({
1738
1817
  value: row.resourceId,
1739
1818
  label: `${row.name}\uFF08${MENU_TYPE_LABEL[row.type]}\uFF09`
1740
1819
  }))
1741
1820
  );
1821
+ const flatRows = (0, import_vue4.computed)(() => {
1822
+ const rows = [];
1823
+ const walk = (list) => {
1824
+ list.forEach((row) => {
1825
+ rows.push(row);
1826
+ if (expandedIds.value[row.resourceId] && childrenMap.value[row.resourceId]?.length) {
1827
+ walk(childrenMap.value[row.resourceId]);
1828
+ }
1829
+ });
1830
+ };
1831
+ walk(records.value);
1832
+ return rows;
1833
+ });
1742
1834
  async function loadList(direction = "current", token = pageToken.value) {
1743
1835
  loading.value = true;
1744
1836
  error.value = "";
1745
1837
  try {
1746
1838
  const result = await props.api.list({
1839
+ depth: ROOT_MENU_DEPTH,
1747
1840
  pagination: {
1748
1841
  pageToken: token,
1749
1842
  pageSize: pageSize.value,
@@ -1751,6 +1844,9 @@ var MenuManager = (0, import_vue4.defineComponent)({
1751
1844
  }
1752
1845
  });
1753
1846
  records.value = result.records;
1847
+ childrenMap.value = {};
1848
+ expandedIds.value = {};
1849
+ expandingIds.value = {};
1754
1850
  pageToken.value = result.pageToken;
1755
1851
  hasPreviousPage.value = result.hasPreviousPage;
1756
1852
  hasNextPage.value = result.hasNextPage;
@@ -1769,6 +1865,29 @@ var MenuManager = (0, import_vue4.defineComponent)({
1769
1865
  } catch {
1770
1866
  }
1771
1867
  }
1868
+ async function toggleExpand(row) {
1869
+ if (isMenuLeaf(row)) return;
1870
+ const id = row.resourceId;
1871
+ if (expandedIds.value[id]) {
1872
+ expandedIds.value = { ...expandedIds.value, [id]: false };
1873
+ return;
1874
+ }
1875
+ if (!childrenMap.value[id]) {
1876
+ expandingIds.value = { ...expandingIds.value, [id]: true };
1877
+ error.value = "";
1878
+ try {
1879
+ const children = await props.api.listSubResources(id);
1880
+ childrenMap.value = { ...childrenMap.value, [id]: children };
1881
+ expandedIds.value = { ...expandedIds.value, [id]: true };
1882
+ } catch (err) {
1883
+ error.value = err instanceof Error ? err.message : "\u52A0\u8F7D\u4E0B\u7EA7\u83DC\u5355\u5931\u8D25";
1884
+ } finally {
1885
+ expandingIds.value = { ...expandingIds.value, [id]: false };
1886
+ }
1887
+ return;
1888
+ }
1889
+ expandedIds.value = { ...expandedIds.value, [id]: true };
1890
+ }
1772
1891
  function openCreate() {
1773
1892
  editing.value = null;
1774
1893
  Object.assign(form, emptyForm2());
@@ -1779,7 +1898,7 @@ var MenuManager = (0, import_vue4.defineComponent)({
1779
1898
  editing.value = row;
1780
1899
  Object.assign(form, {
1781
1900
  parentId: row.parentId ?? null,
1782
- depth: resolveMenuDepth(row.parentId ?? null, records.value),
1901
+ depth: resolveMenuDepth(row.parentId ?? null, allKnownMenus.value),
1783
1902
  type: row.type,
1784
1903
  name: row.name,
1785
1904
  identification: row.identification,
@@ -1887,13 +2006,41 @@ var MenuManager = (0, import_vue4.defineComponent)({
1887
2006
  (0, import_vue4.h)("tr", [
1888
2007
  (0, import_vue4.h)("td", { colspan: 6, style: s2.empty }, "\u52A0\u8F7D\u4E2D\u2026")
1889
2008
  ])
1890
- ] : records.value.length === 0 ? [
2009
+ ] : flatRows.value.length === 0 ? [
1891
2010
  (0, import_vue4.h)("tr", [
1892
2011
  (0, import_vue4.h)("td", { colspan: 6, style: s2.empty }, "\u6682\u65E0\u6570\u636E")
1893
2012
  ])
1894
- ] : records.value.map(
1895
- (row) => (0, import_vue4.h)("tr", { key: row.resourceId }, [
1896
- (0, import_vue4.h)("td", { style: s2.td }, row.name),
2013
+ ] : flatRows.value.map((row) => {
2014
+ const leaf = isMenuLeaf(row);
2015
+ const expanded = Boolean(expandedIds.value[row.resourceId]);
2016
+ const expanding = Boolean(expandingIds.value[row.resourceId]);
2017
+ const indent = Math.max(0, (row.depth || 1) - 1) * 18;
2018
+ return (0, import_vue4.h)("tr", { key: row.resourceId }, [
2019
+ (0, import_vue4.h)("td", { style: s2.td }, [
2020
+ (0, import_vue4.h)(
2021
+ "div",
2022
+ {
2023
+ style: {
2024
+ ...s2.treeCell,
2025
+ paddingLeft: `${indent}px`
2026
+ }
2027
+ },
2028
+ [
2029
+ leaf ? (0, import_vue4.h)("span", { style: s2.treeSpacer }) : (0, import_vue4.h)(
2030
+ "button",
2031
+ {
2032
+ type: "button",
2033
+ style: s2.treeToggle,
2034
+ disabled: expanding,
2035
+ "aria-label": expanded ? "\u6536\u8D77" : "\u5C55\u5F00",
2036
+ onClick: () => void toggleExpand(row)
2037
+ },
2038
+ expanding ? "\u2026" : expanded ? "\u25BC" : "\u25B6"
2039
+ ),
2040
+ (0, import_vue4.h)("span", row.name)
2041
+ ]
2042
+ )
2043
+ ]),
1897
2044
  (0, import_vue4.h)("td", { style: s2.td }, [
1898
2045
  (0, import_vue4.h)(
1899
2046
  "code",
@@ -1936,8 +2083,8 @@ var MenuManager = (0, import_vue4.defineComponent)({
1936
2083
  "\u5220\u9664"
1937
2084
  )
1938
2085
  ])
1939
- ])
1940
- )
2086
+ ]);
2087
+ })
1941
2088
  )
1942
2089
  ])
1943
2090
  ]),
@@ -2029,7 +2176,7 @@ var MenuManager = (0, import_vue4.defineComponent)({
2029
2176
  const value = e.target.value;
2030
2177
  const parentId = value ? value : null;
2031
2178
  form.parentId = parentId;
2032
- form.depth = resolveMenuDepth(parentId, records.value);
2179
+ form.depth = resolveMenuDepth(parentId, allKnownMenus.value);
2033
2180
  }
2034
2181
  },
2035
2182
  [
@@ -2044,14 +2191,6 @@ var MenuManager = (0, import_vue4.defineComponent)({
2044
2191
  ]
2045
2192
  )
2046
2193
  ]),
2047
- (0, import_vue4.h)("div", { style: s2.field }, [
2048
- (0, import_vue4.h)("span", { style: s2.label }, "\u83DC\u5355\u5C42\u7EA7\uFF08depth\uFF09"),
2049
- (0, import_vue4.h)("input", {
2050
- style: s2.input,
2051
- value: form.depth,
2052
- readOnly: true
2053
- })
2054
- ]),
2055
2194
  (0, import_vue4.h)("fieldset", { style: s2.fieldset }, [
2056
2195
  (0, import_vue4.h)("legend", { style: s2.label }, "\u83DC\u5355\u7C7B\u578B"),
2057
2196
  (0, import_vue4.h)(
@@ -2062,6 +2201,7 @@ var MenuManager = (0, import_vue4.defineComponent)({
2062
2201
  (0, import_vue4.h)("input", {
2063
2202
  type: "radio",
2064
2203
  name: "menu-type",
2204
+ style: s2.control,
2065
2205
  checked: form.type === opt.value,
2066
2206
  onChange: () => {
2067
2207
  form.type = opt.value;
@@ -2113,6 +2253,7 @@ var MenuManager = (0, import_vue4.defineComponent)({
2113
2253
  [
2114
2254
  (0, import_vue4.h)("input", {
2115
2255
  type: "checkbox",
2256
+ style: s2.control,
2116
2257
  checked: form.permissionPointIds.includes(
2117
2258
  p.resourceId
2118
2259
  ),
@@ -2146,6 +2287,7 @@ var MenuManager = (0, import_vue4.defineComponent)({
2146
2287
  (0, import_vue4.h)("input", {
2147
2288
  type: "radio",
2148
2289
  name: "menu-status",
2290
+ style: s2.control,
2149
2291
  checked: form.status === opt.value,
2150
2292
  onChange: () => {
2151
2293
  form.status = opt.value;
@@ -2435,6 +2577,8 @@ var SystemAdmin = (0, import_vue5.defineComponent)({
2435
2577
  // Annotate the CommonJS export names for ESM import in node:
2436
2578
  0 && (module.exports = {
2437
2579
  Can,
2580
+ MENU_LEAF_NO,
2581
+ MENU_LEAF_YES,
2438
2582
  MENU_LIST_TYPE_PARAM,
2439
2583
  MENU_TYPE_BUTTON,
2440
2584
  MENU_TYPE_LABEL,
@@ -2471,6 +2615,7 @@ var SystemAdmin = (0, import_vue5.defineComponent)({
2471
2615
  extractRecords,
2472
2616
  getAppClientId,
2473
2617
  getDeviceWorkerId,
2618
+ isMenuLeaf,
2474
2619
  mapAuthorizationResource,
2475
2620
  mapMenuResource,
2476
2621
  resolveMenuDepth,