com-angel-authorization 1.0.9 → 1.0.10

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",
@@ -1713,6 +1762,9 @@ var MenuManager = (0, import_vue4.defineComponent)({
1713
1762
  },
1714
1763
  setup(props, { slots }) {
1715
1764
  const records = (0, import_vue4.ref)([]);
1765
+ const childrenMap = (0, import_vue4.ref)({});
1766
+ const expandedIds = (0, import_vue4.ref)({});
1767
+ const expandingIds = (0, import_vue4.ref)({});
1716
1768
  const permissionPoints = (0, import_vue4.ref)([]);
1717
1769
  const loading = (0, import_vue4.ref)(false);
1718
1770
  const error = (0, import_vue4.ref)("");
@@ -1733,17 +1785,39 @@ var MenuManager = (0, import_vue4.defineComponent)({
1733
1785
  );
1734
1786
  return map;
1735
1787
  });
1788
+ const allKnownMenus = (0, import_vue4.computed)(() => {
1789
+ const map = /* @__PURE__ */ new Map();
1790
+ records.value.forEach((row) => map.set(row.resourceId, row));
1791
+ Object.values(childrenMap.value).forEach((list) => {
1792
+ list.forEach((row) => map.set(row.resourceId, row));
1793
+ });
1794
+ return Array.from(map.values());
1795
+ });
1736
1796
  const parentOptions = (0, import_vue4.computed)(
1737
- () => records.value.filter((row) => !editing.value || row.resourceId !== editing.value.resourceId).map((row) => ({
1797
+ () => allKnownMenus.value.filter((row) => !editing.value || row.resourceId !== editing.value.resourceId).map((row) => ({
1738
1798
  value: row.resourceId,
1739
1799
  label: `${row.name}\uFF08${MENU_TYPE_LABEL[row.type]}\uFF09`
1740
1800
  }))
1741
1801
  );
1802
+ const flatRows = (0, import_vue4.computed)(() => {
1803
+ const rows = [];
1804
+ const walk = (list) => {
1805
+ list.forEach((row) => {
1806
+ rows.push(row);
1807
+ if (expandedIds.value[row.resourceId] && childrenMap.value[row.resourceId]?.length) {
1808
+ walk(childrenMap.value[row.resourceId]);
1809
+ }
1810
+ });
1811
+ };
1812
+ walk(records.value);
1813
+ return rows;
1814
+ });
1742
1815
  async function loadList(direction = "current", token = pageToken.value) {
1743
1816
  loading.value = true;
1744
1817
  error.value = "";
1745
1818
  try {
1746
1819
  const result = await props.api.list({
1820
+ depth: ROOT_MENU_DEPTH,
1747
1821
  pagination: {
1748
1822
  pageToken: token,
1749
1823
  pageSize: pageSize.value,
@@ -1751,6 +1825,9 @@ var MenuManager = (0, import_vue4.defineComponent)({
1751
1825
  }
1752
1826
  });
1753
1827
  records.value = result.records;
1828
+ childrenMap.value = {};
1829
+ expandedIds.value = {};
1830
+ expandingIds.value = {};
1754
1831
  pageToken.value = result.pageToken;
1755
1832
  hasPreviousPage.value = result.hasPreviousPage;
1756
1833
  hasNextPage.value = result.hasNextPage;
@@ -1769,6 +1846,29 @@ var MenuManager = (0, import_vue4.defineComponent)({
1769
1846
  } catch {
1770
1847
  }
1771
1848
  }
1849
+ async function toggleExpand(row) {
1850
+ if (isMenuLeaf(row)) return;
1851
+ const id = row.resourceId;
1852
+ if (expandedIds.value[id]) {
1853
+ expandedIds.value = { ...expandedIds.value, [id]: false };
1854
+ return;
1855
+ }
1856
+ if (!childrenMap.value[id]) {
1857
+ expandingIds.value = { ...expandingIds.value, [id]: true };
1858
+ error.value = "";
1859
+ try {
1860
+ const children = await props.api.listSubResources(id);
1861
+ childrenMap.value = { ...childrenMap.value, [id]: children };
1862
+ expandedIds.value = { ...expandedIds.value, [id]: true };
1863
+ } catch (err) {
1864
+ error.value = err instanceof Error ? err.message : "\u52A0\u8F7D\u4E0B\u7EA7\u83DC\u5355\u5931\u8D25";
1865
+ } finally {
1866
+ expandingIds.value = { ...expandingIds.value, [id]: false };
1867
+ }
1868
+ return;
1869
+ }
1870
+ expandedIds.value = { ...expandedIds.value, [id]: true };
1871
+ }
1772
1872
  function openCreate() {
1773
1873
  editing.value = null;
1774
1874
  Object.assign(form, emptyForm2());
@@ -1779,7 +1879,7 @@ var MenuManager = (0, import_vue4.defineComponent)({
1779
1879
  editing.value = row;
1780
1880
  Object.assign(form, {
1781
1881
  parentId: row.parentId ?? null,
1782
- depth: resolveMenuDepth(row.parentId ?? null, records.value),
1882
+ depth: resolveMenuDepth(row.parentId ?? null, allKnownMenus.value),
1783
1883
  type: row.type,
1784
1884
  name: row.name,
1785
1885
  identification: row.identification,
@@ -1887,13 +1987,41 @@ var MenuManager = (0, import_vue4.defineComponent)({
1887
1987
  (0, import_vue4.h)("tr", [
1888
1988
  (0, import_vue4.h)("td", { colspan: 6, style: s2.empty }, "\u52A0\u8F7D\u4E2D\u2026")
1889
1989
  ])
1890
- ] : records.value.length === 0 ? [
1990
+ ] : flatRows.value.length === 0 ? [
1891
1991
  (0, import_vue4.h)("tr", [
1892
1992
  (0, import_vue4.h)("td", { colspan: 6, style: s2.empty }, "\u6682\u65E0\u6570\u636E")
1893
1993
  ])
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),
1994
+ ] : flatRows.value.map((row) => {
1995
+ const leaf = isMenuLeaf(row);
1996
+ const expanded = Boolean(expandedIds.value[row.resourceId]);
1997
+ const expanding = Boolean(expandingIds.value[row.resourceId]);
1998
+ const indent = Math.max(0, (row.depth || 1) - 1) * 18;
1999
+ return (0, import_vue4.h)("tr", { key: row.resourceId }, [
2000
+ (0, import_vue4.h)("td", { style: s2.td }, [
2001
+ (0, import_vue4.h)(
2002
+ "div",
2003
+ {
2004
+ style: {
2005
+ ...s2.treeCell,
2006
+ paddingLeft: `${indent}px`
2007
+ }
2008
+ },
2009
+ [
2010
+ leaf ? (0, import_vue4.h)("span", { style: s2.treeSpacer }) : (0, import_vue4.h)(
2011
+ "button",
2012
+ {
2013
+ type: "button",
2014
+ style: s2.treeToggle,
2015
+ disabled: expanding,
2016
+ "aria-label": expanded ? "\u6536\u8D77" : "\u5C55\u5F00",
2017
+ onClick: () => void toggleExpand(row)
2018
+ },
2019
+ expanding ? "\u2026" : expanded ? "\u25BC" : "\u25B6"
2020
+ ),
2021
+ (0, import_vue4.h)("span", row.name)
2022
+ ]
2023
+ )
2024
+ ]),
1897
2025
  (0, import_vue4.h)("td", { style: s2.td }, [
1898
2026
  (0, import_vue4.h)(
1899
2027
  "code",
@@ -1936,8 +2064,8 @@ var MenuManager = (0, import_vue4.defineComponent)({
1936
2064
  "\u5220\u9664"
1937
2065
  )
1938
2066
  ])
1939
- ])
1940
- )
2067
+ ]);
2068
+ })
1941
2069
  )
1942
2070
  ])
1943
2071
  ]),
@@ -2029,7 +2157,7 @@ var MenuManager = (0, import_vue4.defineComponent)({
2029
2157
  const value = e.target.value;
2030
2158
  const parentId = value ? value : null;
2031
2159
  form.parentId = parentId;
2032
- form.depth = resolveMenuDepth(parentId, records.value);
2160
+ form.depth = resolveMenuDepth(parentId, allKnownMenus.value);
2033
2161
  }
2034
2162
  },
2035
2163
  [
@@ -2435,6 +2563,8 @@ var SystemAdmin = (0, import_vue5.defineComponent)({
2435
2563
  // Annotate the CommonJS export names for ESM import in node:
2436
2564
  0 && (module.exports = {
2437
2565
  Can,
2566
+ MENU_LEAF_NO,
2567
+ MENU_LEAF_YES,
2438
2568
  MENU_LIST_TYPE_PARAM,
2439
2569
  MENU_TYPE_BUTTON,
2440
2570
  MENU_TYPE_LABEL,
@@ -2471,6 +2601,7 @@ var SystemAdmin = (0, import_vue5.defineComponent)({
2471
2601
  extractRecords,
2472
2602
  getAppClientId,
2473
2603
  getDeviceWorkerId,
2604
+ isMenuLeaf,
2474
2605
  mapAuthorizationResource,
2475
2606
  mapMenuResource,
2476
2607
  resolveMenuDepth,