smart-admin-web 10.20.0 → 10.21.0

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.
Files changed (146) hide show
  1. package/dist/api/index.d.ts +19 -1
  2. package/dist/api/index.js +85 -66
  3. package/dist/api/index.js.map +1 -1
  4. package/dist/api/schema.d.ts +448 -1
  5. package/dist/assets/icons/ph-subset.json.js +1 -1
  6. package/dist/components/FormContainer/index.vue.js +87 -75
  7. package/dist/components/FormContainer/index.vue.js.map +1 -1
  8. package/dist/components/UserPicker/UserAvatar.vue.d.ts +8 -0
  9. package/dist/components/UserPicker/UserAvatar.vue.js +8 -0
  10. package/dist/components/UserPicker/UserAvatar.vue.js.map +1 -0
  11. package/dist/components/UserPicker/UserAvatar2.vue.js +38 -0
  12. package/dist/components/UserPicker/UserAvatar2.vue.js.map +1 -0
  13. package/dist/components/UserPicker/index.vue.js +1 -1
  14. package/dist/components/UserPicker/index2.vue.js +328 -186
  15. package/dist/components/UserPicker/index2.vue.js.map +1 -1
  16. package/dist/index.js +248 -246
  17. package/dist/layouts/NoticeBell.vue.js +2 -2
  18. package/dist/layouts/NoticeBell2.vue.js +18 -17
  19. package/dist/layouts/NoticeBell2.vue.js.map +1 -1
  20. package/dist/lib/runtime.js +1 -1
  21. package/dist/lib/watermark.d.ts +1 -1
  22. package/dist/locales/en-US.d.ts +62 -3
  23. package/dist/locales/en-US.js +66 -7
  24. package/dist/locales/en-US.js.map +1 -1
  25. package/dist/locales/kernelMenuTitles.js +2 -1
  26. package/dist/locales/kernelMenuTitles.js.map +1 -1
  27. package/dist/locales/zh-CN.d.ts +62 -3
  28. package/dist/locales/zh-CN.js +66 -7
  29. package/dist/locales/zh-CN.js.map +1 -1
  30. package/dist/router/viewRegistry.js +6 -6
  31. package/dist/router/viewRegistry.js.map +1 -1
  32. package/dist/style.css +1 -1
  33. package/dist/theme/naive-theme.js +72 -67
  34. package/dist/theme/naive-theme.js.map +1 -1
  35. package/dist/types/api.d.ts +91 -0
  36. package/dist/types/api.js +17 -15
  37. package/dist/types/api.js.map +1 -1
  38. package/dist/utils/shake.d.ts +1 -0
  39. package/dist/utils/shake.js +30 -0
  40. package/dist/utils/shake.js.map +1 -0
  41. package/dist/views/login/LoginForm.vue.js +2 -2
  42. package/dist/views/login/LoginForm2.vue.js +135 -135
  43. package/dist/views/login/LoginForm2.vue.js.map +1 -1
  44. package/dist/views/login/components/LoginDesk.vue.js +1 -1
  45. package/dist/views/login/components/LoginDesk2.vue.js +59 -47
  46. package/dist/views/login/components/LoginDesk2.vue.js.map +1 -1
  47. package/dist/views/personal/notice2.vue.js +1 -1
  48. package/dist/views/personal/notice2.vue.js.map +1 -1
  49. package/dist/views/personal/sessions.vue.js +2 -2
  50. package/dist/views/personal/sessions2.vue.js +41 -40
  51. package/dist/views/personal/sessions2.vue.js.map +1 -1
  52. package/dist/views/system/ai-usage/index.vue.js +3 -3
  53. package/dist/views/system/ai-usage/index2.vue.js +13 -12
  54. package/dist/views/system/ai-usage/index2.vue.js.map +1 -1
  55. package/dist/views/system/config/components/AdvancedSection.vue.js +3 -3
  56. package/dist/views/system/config/components/AdvancedSection2.vue.js +2 -1
  57. package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -1
  58. package/dist/views/system/dict/index.vue.js +2 -2
  59. package/dist/views/system/dict/index2.vue.js +12 -1
  60. package/dist/views/system/dict/index2.vue.js.map +1 -1
  61. package/dist/views/system/file/index2.vue.js +1 -0
  62. package/dist/views/system/file/index2.vue.js.map +1 -1
  63. package/dist/views/system/job/index.vue.js +3 -3
  64. package/dist/views/system/job/index2.vue.js +182 -181
  65. package/dist/views/system/job/index2.vue.js.map +1 -1
  66. package/dist/views/system/job-log/components/AttemptTable2.vue.js +8 -3
  67. package/dist/views/system/job-log/components/AttemptTable2.vue.js.map +1 -1
  68. package/dist/views/system/job-log/index.vue.js +1 -1
  69. package/dist/views/system/job-log/index2.vue.js +5 -5
  70. package/dist/views/system/job-log/index2.vue.js.map +1 -1
  71. package/dist/views/system/log/exception/index.vue.js +2 -2
  72. package/dist/views/system/log/exception/index2.vue.js +8 -5
  73. package/dist/views/system/log/exception/index2.vue.js.map +1 -1
  74. package/dist/views/system/log/login/index2.vue.js +21 -12
  75. package/dist/views/system/log/login/index2.vue.js.map +1 -1
  76. package/dist/views/system/log/op/index.vue.js +2 -2
  77. package/dist/views/system/log/op/index2.vue.js +50 -40
  78. package/dist/views/system/log/op/index2.vue.js.map +1 -1
  79. package/dist/views/system/menu/components/ButtonManager.vue.js +2 -2
  80. package/dist/views/system/menu/components/ButtonManager2.vue.js +45 -36
  81. package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
  82. package/dist/views/system/menu/index.vue.js +2 -2
  83. package/dist/views/system/menu/index2.vue.js +11 -11
  84. package/dist/views/system/menu/index2.vue.js.map +1 -1
  85. package/dist/views/system/module/index.vue.js +1 -1
  86. package/dist/views/system/module/index2.vue.js +171 -117
  87. package/dist/views/system/module/index2.vue.js.map +1 -1
  88. package/dist/views/system/notice/index.vue.js +3 -3
  89. package/dist/views/system/notice/index2.vue.js +1 -0
  90. package/dist/views/system/notice/index2.vue.js.map +1 -1
  91. package/dist/views/system/org/index.vue.js +2 -2
  92. package/dist/views/system/org/index2.vue.js +70 -67
  93. package/dist/views/system/org/index2.vue.js.map +1 -1
  94. package/dist/views/system/position/index.vue.js +2 -2
  95. package/dist/views/system/position/index2.vue.js +57 -48
  96. package/dist/views/system/position/index2.vue.js.map +1 -1
  97. package/dist/views/system/recycle/index.vue.js +1 -1
  98. package/dist/views/system/recycle/index2.vue.js +3 -1
  99. package/dist/views/system/recycle/index2.vue.js.map +1 -1
  100. package/dist/views/system/role/components/GrantMenuSheet.vue.d.ts +2 -0
  101. package/dist/views/system/role/components/GrantMenuSheet.vue.js +2 -2
  102. package/dist/views/system/role/components/GrantMenuSheet2.vue.js +54 -49
  103. package/dist/views/system/role/components/GrantMenuSheet2.vue.js.map +1 -1
  104. package/dist/views/system/role/components/GrantMenuTable.vue.js +1 -1
  105. package/dist/views/system/role/components/GrantMenuTable2.vue.js +159 -195
  106. package/dist/views/system/role/components/GrantMenuTable2.vue.js.map +1 -1
  107. package/dist/views/system/role/components/grantMenuGroups.d.ts +54 -0
  108. package/dist/views/system/role/components/grantMenuGroups.js +116 -76
  109. package/dist/views/system/role/components/grantMenuGroups.js.map +1 -1
  110. package/dist/views/system/role/index.vue.js +2 -2
  111. package/dist/views/system/role/index2.vue.js +152 -145
  112. package/dist/views/system/role/index2.vue.js.map +1 -1
  113. package/dist/views/system/session/index2.vue.js +39 -35
  114. package/dist/views/system/session/index2.vue.js.map +1 -1
  115. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.d.ts +10 -0
  116. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js +5 -0
  117. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js.map +1 -0
  118. package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js +96 -0
  119. package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js.map +1 -0
  120. package/dist/views/system/user/components/UserGrantMenuSheet.vue.d.ts +13 -0
  121. package/dist/views/system/user/components/UserGrantMenuSheet.vue.js +8 -0
  122. package/dist/views/system/user/components/UserGrantMenuSheet.vue.js.map +1 -0
  123. package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js +216 -0
  124. package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js.map +1 -0
  125. package/dist/views/system/user/components/UserGrantMenuTable.vue.d.ts +13 -0
  126. package/dist/views/system/user/components/UserGrantMenuTable.vue.js +8 -0
  127. package/dist/views/system/user/components/UserGrantMenuTable.vue.js.map +1 -0
  128. package/dist/views/system/user/components/UserGrantMenuTable2.vue.js +186 -0
  129. package/dist/views/system/user/components/UserGrantMenuTable2.vue.js.map +1 -0
  130. package/dist/views/system/user/components/UserGrantNodeRow.vue.d.ts +31 -0
  131. package/dist/views/system/user/components/UserGrantNodeRow.vue.js +8 -0
  132. package/dist/views/system/user/components/UserGrantNodeRow.vue.js.map +1 -0
  133. package/dist/views/system/user/components/UserGrantNodeRow2.vue.js +171 -0
  134. package/dist/views/system/user/components/UserGrantNodeRow2.vue.js.map +1 -0
  135. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.d.ts +21 -0
  136. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js +5 -0
  137. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js.map +1 -0
  138. package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js +178 -0
  139. package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js.map +1 -0
  140. package/dist/views/system/user/components/userGrantState.d.ts +64 -0
  141. package/dist/views/system/user/components/userGrantState.js +117 -0
  142. package/dist/views/system/user/components/userGrantState.js.map +1 -0
  143. package/dist/views/system/user/index.vue.js +2 -2
  144. package/dist/views/system/user/index2.vue.js +250 -207
  145. package/dist/views/system/user/index2.vue.js.map +1 -1
  146. package/package.json +3 -3
@@ -0,0 +1,216 @@
1
+ import { defineComponent as le, ref as g, shallowRef as G, reactive as ne, computed as d, openBlock as m, createBlock as M, unref as a, normalizeStyle as se, withCtx as o, createVNode as f, createElementBlock as O, createElementVNode as h, createTextVNode as N, toDisplayString as v, createCommentVNode as w, normalizeClass as oe } from "vue";
2
+ import { useMessage as re, NModal as ue, NSpin as ie, NAlert as B, NTabs as ce, NTabPane as U, NButton as V } from "naive-ui";
3
+ import { useI18n as de } from "vue-i18n";
4
+ import { useWindowSize as fe } from "@vueuse/core";
5
+ import { menuApi as ve, userApi as D } from "../../../../api/index.js";
6
+ import { useAuthStore as me } from "../../../../stores/auth.js";
7
+ import { translateError as z } from "../../../../utils/error.js";
8
+ import pe from "./UserGrantMenuTable.vue.js";
9
+ import ye from "./UserGrantEffectiveTable2.vue.js";
10
+ import { expiryLimit as ge, countDraft as he, diffDraft as I, READONLY_REASON_KEYS as we, draftFromGrants as P, invalidExpiry as _e } from "./userGrantState.js";
11
+ const be = {
12
+ key: 0,
13
+ class: "ugs"
14
+ }, xe = { class: "ugs-notes" }, Ge = { class: "ugs-hint" }, Me = { class: "ugs-summary" }, Ne = {
15
+ key: 0,
16
+ class: "ugs-dirty"
17
+ }, ke = 640, ze = /* @__PURE__ */ le({
18
+ __name: "UserGrantMenuSheet",
19
+ emits: ["saved"],
20
+ setup(Ee, { expose: q, emit: L }) {
21
+ const W = L, { t: n } = de(), _ = re(), Y = me(), u = g(!1), k = g(!1), i = g(!1), E = g("grant"), p = g(null), b = G([]), S = G([]), s = G(null), y = G(/* @__PURE__ */ new Map()), c = ne(/* @__PURE__ */ new Map());
22
+ let x = 0;
23
+ const { width: $ } = fe(), R = d(() => $.value <= ke), F = d(
24
+ () => R.value ? { width: "calc(100vw - 16px)", height: "calc(100dvh - 16px)" } : { width: "min(1040px, calc(100vw - 48px))", height: "min(780px, calc(100dvh - 48px))" }
25
+ ), H = {
26
+ display: "flex",
27
+ flexDirection: "column",
28
+ flex: "1 1 0",
29
+ minHeight: "0",
30
+ padding: "0",
31
+ overflow: "hidden"
32
+ }, K = { padding: "0" }, A = d(() => ge(s.value, /* @__PURE__ */ new Date())), j = d(() => he(c)), J = d(() => {
33
+ const t = I(y.value, c);
34
+ return t.upserts.length + t.removes.length > 0;
35
+ }), T = d(() => {
36
+ const t = s.value;
37
+ if (!t || t.targetEditable) return "";
38
+ const e = t.readOnlyReason != null ? we[t.readOnlyReason] : void 0;
39
+ return e ? n("userGrant.readonly", { reason: n(e) }) : n("userGrant.readonlyNoReason");
40
+ }), Q = d(() => {
41
+ var l, r;
42
+ const t = ((l = s.value) == null ? void 0 : l.modules) ?? [], e = Y.currentModuleId;
43
+ return e != null && t.some((C) => C.id === e) ? e : ((r = t[0]) == null ? void 0 : r.id) ?? 0;
44
+ });
45
+ function X() {
46
+ b.value = [], S.value = [], y.value = /* @__PURE__ */ new Map(), c.clear(), s.value = null;
47
+ }
48
+ async function Z(t) {
49
+ const e = ++x;
50
+ p.value = t, E.value = "grant", X(), u.value = !0, k.value = !0;
51
+ try {
52
+ const [l, r, C] = await Promise.all([
53
+ ve.tree(),
54
+ D.getMenuGrants(t.id),
55
+ D.getEffectiveMenus(t.id)
56
+ ]);
57
+ if (e !== x) return;
58
+ b.value = l, S.value = r, y.value = P(r);
59
+ for (const [te, ae] of P(r)) c.set(te, ae);
60
+ s.value = C;
61
+ } catch (l) {
62
+ if (e !== x) return;
63
+ _.error(z(l)), u.value = !1;
64
+ } finally {
65
+ e === x && (k.value = !1);
66
+ }
67
+ }
68
+ async function ee() {
69
+ if (i.value || !p.value) return;
70
+ const t = _e(y.value, c, A.value, /* @__PURE__ */ new Date());
71
+ if (t.length) {
72
+ _.warning(n("userGrant.invalidExpiry", { count: t.length }));
73
+ return;
74
+ }
75
+ const { upserts: e, removes: l } = I(y.value, c);
76
+ if (!e.length && !l.length) {
77
+ u.value = !1;
78
+ return;
79
+ }
80
+ i.value = !0;
81
+ try {
82
+ await D.setMenuGrants(p.value.id, e, l), _.success(n("userGrant.saved")), u.value = !1, W("saved");
83
+ } catch (r) {
84
+ _.error(z(r));
85
+ } finally {
86
+ i.value = !1;
87
+ }
88
+ }
89
+ return q({ open: Z }), (t, e) => (m(), M(a(ue), {
90
+ show: u.value,
91
+ "onUpdate:show": e[2] || (e[2] = (l) => u.value = l),
92
+ preset: "card",
93
+ title: p.value ? a(n)("userGrant.title", { name: p.value.name }) : "",
94
+ closable: !i.value,
95
+ "close-on-esc": !i.value,
96
+ "mask-closable": !1,
97
+ "auto-focus": !1,
98
+ style: se(F.value),
99
+ "content-style": H,
100
+ "footer-style": K
101
+ }, {
102
+ footer: o(() => {
103
+ var l;
104
+ return [
105
+ h("footer", {
106
+ class: oe(["ugs-foot", { "is-narrow": R.value }])
107
+ }, [
108
+ h("div", Me, [
109
+ h("span", null, v(a(n)("userGrant.summary", j.value)), 1),
110
+ J.value ? (m(), O("span", Ne, v(a(n)("userGrant.unsaved")), 1)) : w("", !0)
111
+ ]),
112
+ f(a(V), {
113
+ disabled: i.value,
114
+ onClick: e[1] || (e[1] = (r) => u.value = !1)
115
+ }, {
116
+ default: o(() => [
117
+ N(v(a(n)("common.cancel")), 1)
118
+ ]),
119
+ _: 1
120
+ }, 8, ["disabled"]),
121
+ (l = s.value) != null && l.targetEditable ? (m(), M(a(V), {
122
+ key: 0,
123
+ type: "primary",
124
+ loading: i.value,
125
+ onClick: ee
126
+ }, {
127
+ default: o(() => [
128
+ N(v(a(n)("common.save")), 1)
129
+ ]),
130
+ _: 1
131
+ }, 8, ["loading"])) : w("", !0)
132
+ ], 2)
133
+ ];
134
+ }),
135
+ default: o(() => [
136
+ f(a(ie), {
137
+ show: k.value,
138
+ class: "ugs-spin"
139
+ }, {
140
+ default: o(() => [
141
+ s.value ? (m(), O("div", be, [
142
+ h("div", xe, [
143
+ T.value ? (m(), M(a(B), {
144
+ key: 0,
145
+ type: "warning",
146
+ bordered: !1
147
+ }, {
148
+ default: o(() => [
149
+ N(v(T.value), 1)
150
+ ]),
151
+ _: 1
152
+ })) : w("", !0),
153
+ s.value.hasRoles ? w("", !0) : (m(), M(a(B), {
154
+ key: 1,
155
+ type: "info",
156
+ bordered: !1
157
+ }, {
158
+ default: o(() => [
159
+ N(v(a(n)("userGrant.noRoles")), 1)
160
+ ]),
161
+ _: 1
162
+ })),
163
+ h("p", Ge, v(a(n)("userGrant.hint")), 1)
164
+ ]),
165
+ f(a(ce), {
166
+ value: E.value,
167
+ "onUpdate:value": e[0] || (e[0] = (l) => E.value = l),
168
+ type: "line",
169
+ class: "ugs-tabs"
170
+ }, {
171
+ default: o(() => [
172
+ f(a(U), {
173
+ name: "grant",
174
+ "display-directive": "show",
175
+ tab: a(n)("userGrant.tabGrant")
176
+ }, {
177
+ default: o(() => [
178
+ f(pe, {
179
+ tree: b.value,
180
+ effective: s.value,
181
+ draft: c,
182
+ "default-module-id": Q.value,
183
+ "max-date": A.value
184
+ }, null, 8, ["tree", "effective", "draft", "default-module-id", "max-date"])
185
+ ]),
186
+ _: 1
187
+ }, 8, ["tab"]),
188
+ f(a(U), {
189
+ name: "effective",
190
+ tab: a(n)("userGrant.tabEffective")
191
+ }, {
192
+ default: o(() => [
193
+ f(ye, {
194
+ tree: b.value,
195
+ effective: s.value,
196
+ grants: S.value
197
+ }, null, 8, ["tree", "effective", "grants"])
198
+ ]),
199
+ _: 1
200
+ }, 8, ["tab"])
201
+ ]),
202
+ _: 1
203
+ }, 8, ["value"])
204
+ ])) : w("", !0)
205
+ ]),
206
+ _: 1
207
+ }, 8, ["show"])
208
+ ]),
209
+ _: 1
210
+ }, 8, ["show", "title", "closable", "close-on-esc", "style"]));
211
+ }
212
+ });
213
+ export {
214
+ ze as default
215
+ };
216
+ //# sourceMappingURL=UserGrantMenuSheet2.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserGrantMenuSheet2.vue.js","sources":["../../../../../src/views/system/user/components/UserGrantMenuSheet.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 用户「授权菜单」弹窗:壳的尺寸与底栏照角色页 GrantMenuSheet(定高、只有列表滚动、底栏常驻),\n// 内容是两个页签——「单独授权」三态列表与「有效权限」只读表。打开时一次拉齐菜单树、授权记录与有效权限;\n// 保存只提交变更集(与打开时的快照比)。目标用户不可编辑(自己 / 超管 / 范围外 / 对方是管理员)时整体只读并说明原因。\nimport { computed, reactive, ref, shallowRef, type CSSProperties } from 'vue'\nimport { NAlert, NButton, NModal, NSpin, NTabPane, NTabs, useMessage } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { useWindowSize } from '@vueuse/core'\nimport { menuApi, userApi } from '#/api'\nimport { useAuthStore } from '#/stores/auth'\nimport { translateError } from '#/utils/error'\nimport type { MenuTreeNode } from '#/types/menu'\nimport type { UserMenuEffective, UserMenuGrantItem } from '#/types/api'\nimport UserGrantMenuTable from './UserGrantMenuTable.vue'\nimport UserGrantEffectiveTable from './UserGrantEffectiveTable.vue'\nimport {\n READONLY_REASON_KEYS,\n countDraft,\n diffDraft,\n draftFromGrants,\n invalidExpiry,\n expiryLimit,\n type Draft,\n} from './userGrantState'\n\nconst emit = defineEmits<{ (e: 'saved'): void }>()\nconst { t } = useI18n()\nconst message = useMessage()\nconst auth = useAuthStore()\n\nconst show = ref(false)\nconst loading = ref(false)\nconst saving = ref(false)\nconst tab = ref<'grant' | 'effective'>('grant')\nconst user = ref<{ id: number; name: string } | null>(null)\nconst tree = shallowRef<MenuTreeNode[]>([])\nconst grants = shallowRef<UserMenuGrantItem[]>([])\nconst effective = shallowRef<UserMenuEffective | null>(null)\n/** 打开时的快照;草稿另建一份,免得两边共用同一批对象、改一处两处都变。每次换一份新 Map,依赖它的计算属性才会重算。 */\nconst baseline = shallowRef<Draft>(new Map())\nconst draft = reactive<Draft>(new Map())\n/** 打开请求的序号:慢的旧响应回来时序号已变,不许再写任何状态。 */\nlet openSeq = 0\n\n/** 窄于此宽度弹窗几乎铺满视口(同角色页)。 */\nconst COMPACT = 640\nconst { width: winW } = useWindowSize()\nconst compact = computed(() => winW.value <= COMPACT)\nconst modalStyle = computed(() =>\n compact.value\n ? { width: 'calc(100vw - 16px)', height: 'calc(100dvh - 16px)' }\n : { width: 'min(1040px, calc(100vw - 48px))', height: 'min(780px, calc(100dvh - 48px))' },\n)\nconst contentStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n flex: '1 1 0',\n minHeight: '0',\n padding: '0',\n overflow: 'hidden',\n}\nconst footerStyle = { padding: '0' }\n\nconst maxDate = computed(() => expiryLimit(effective.value, new Date()))\nconst counts = computed(() => countDraft(draft))\nconst dirty = computed(() => {\n const d = diffDraft(baseline.value, draft)\n return d.upserts.length + d.removes.length > 0\n})\nconst readonlyText = computed(() => {\n const e = effective.value\n if (!e || e.targetEditable) return ''\n const key = e.readOnlyReason != null ? READONLY_REASON_KEYS[e.readOnlyReason] : undefined\n return key ? t('userGrant.readonly', { reason: t(key) }) : t('userGrant.readonlyNoReason')\n})\n/** 默认停在当前所在的应用;不在清单里(如已被去掉)就落到第一个。 */\nconst defaultModuleId = computed(() => {\n const modules = effective.value?.modules ?? []\n const current = auth.currentModuleId\n return current != null && modules.some(m => m.id === current) ? current : (modules[0]?.id ?? 0)\n})\n\n/** 清掉上一个用户留下的全部数据,加载期间底栏不会显示别人的数字。 */\nfunction reset() {\n tree.value = []\n grants.value = []\n baseline.value = new Map()\n draft.clear()\n effective.value = null\n}\n\nasync function open(target: { id: number; name: string }) {\n const seq = ++openSeq\n user.value = target\n tab.value = 'grant'\n reset()\n show.value = true\n loading.value = true\n try {\n const [menuTree, records, eff] = await Promise.all([\n menuApi.tree(),\n userApi.getMenuGrants(target.id),\n userApi.getEffectiveMenus(target.id),\n ])\n if (seq !== openSeq) return\n tree.value = menuTree\n grants.value = records\n baseline.value = draftFromGrants(records)\n for (const [id, entry] of draftFromGrants(records)) draft.set(id, entry)\n effective.value = eff\n } catch (e) {\n if (seq !== openSeq) return\n message.error(translateError(e))\n show.value = false\n } finally {\n if (seq === openSeq) loading.value = false\n }\n}\n\nasync function save() {\n if (saving.value || !user.value) return\n const bad = invalidExpiry(baseline.value, draft, maxDate.value, new Date())\n if (bad.length) {\n message.warning(t('userGrant.invalidExpiry', { count: bad.length }))\n return\n }\n const { upserts, removes } = diffDraft(baseline.value, draft)\n if (!upserts.length && !removes.length) {\n show.value = false\n return\n }\n saving.value = true\n try {\n await userApi.setMenuGrants(user.value.id, upserts, removes)\n message.success(t('userGrant.saved'))\n show.value = false\n emit('saved')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n saving.value = false\n }\n}\n\ndefineExpose({ open })\n</script>\n\n<template>\n <n-modal\n v-model:show=\"show\"\n preset=\"card\"\n :title=\"user ? t('userGrant.title', { name: user.name }) : ''\"\n :closable=\"!saving\"\n :close-on-esc=\"!saving\"\n :mask-closable=\"false\"\n :auto-focus=\"false\"\n :style=\"modalStyle\"\n :content-style=\"contentStyle\"\n :footer-style=\"footerStyle\"\n >\n <n-spin :show=\"loading\" class=\"ugs-spin\">\n <div v-if=\"effective\" class=\"ugs\">\n <div class=\"ugs-notes\">\n <n-alert v-if=\"readonlyText\" type=\"warning\" :bordered=\"false\">{{ readonlyText }}</n-alert>\n <n-alert v-if=\"!effective.hasRoles\" type=\"info\" :bordered=\"false\">\n {{ t('userGrant.noRoles') }}\n </n-alert>\n <p class=\"ugs-hint\">{{ t('userGrant.hint') }}</p>\n </div>\n <n-tabs v-model:value=\"tab\" type=\"line\" class=\"ugs-tabs\">\n <!-- 单独授权页签切走时保留挂载:应用选择、搜索词、折叠状态不丢 -->\n <n-tab-pane name=\"grant\" display-directive=\"show\" :tab=\"t('userGrant.tabGrant')\">\n <UserGrantMenuTable\n :tree=\"tree\"\n :effective=\"effective\"\n :draft=\"draft\"\n :default-module-id=\"defaultModuleId\"\n :max-date=\"maxDate\"\n />\n </n-tab-pane>\n <n-tab-pane name=\"effective\" :tab=\"t('userGrant.tabEffective')\">\n <UserGrantEffectiveTable :tree=\"tree\" :effective=\"effective\" :grants=\"grants\" />\n </n-tab-pane>\n </n-tabs>\n </div>\n </n-spin>\n\n <template #footer>\n <footer class=\"ugs-foot\" :class=\"{ 'is-narrow': compact }\">\n <div class=\"ugs-summary\">\n <span>{{ t('userGrant.summary', counts) }}</span>\n <span v-if=\"dirty\" class=\"ugs-dirty\">{{ t('userGrant.unsaved') }}</span>\n </div>\n <n-button :disabled=\"saving\" @click=\"show = false\">{{ t('common.cancel') }}</n-button>\n <n-button v-if=\"effective?.targetEditable\" type=\"primary\" :loading=\"saving\" @click=\"save\">\n {{ t('common.save') }}\n </n-button>\n </footer>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.ugs-spin,\n.ugs-spin :deep(.n-spin-content),\n.ugs,\n.ugs-tabs {\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n min-height: 0;\n}\n.ugs-notes {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 20px 0;\n}\n.ugs-hint {\n margin: 0;\n font-size: 13px;\n color: var(--text-2);\n}\n.ugs-tabs :deep(.n-tabs-nav) {\n padding: 0 20px;\n}\n.ugs-tabs :deep(.n-tab-pane),\n.ugs-tabs :deep(.n-tabs-pane-wrapper) {\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n min-height: 0;\n padding: 0;\n}\n.ugs-foot {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px 14px;\n border-top: 1px solid var(--hairline);\n}\n.ugs-summary {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-wrap: wrap;\n gap: 4px 12px;\n font-size: 13px;\n color: var(--text-2);\n}\n.ugs-dirty {\n color: var(--warn);\n}\n.ugs-foot.is-narrow {\n flex-wrap: wrap;\n}\n.ugs-foot.is-narrow .ugs-summary {\n flex: 1 1 100%;\n}\n</style>\n"],"names":["COMPACT","emit","__emit","t","useI18n","message","useMessage","auth","useAuthStore","show","ref","loading","saving","tab","user","tree","shallowRef","grants","effective","baseline","draft","reactive","openSeq","winW","useWindowSize","compact","computed","modalStyle","contentStyle","footerStyle","maxDate","expiryLimit","counts","countDraft","dirty","d","diffDraft","readonlyText","e","key","READONLY_REASON_KEYS","defaultModuleId","modules","_a","current","m","_b","reset","open","target","seq","menuTree","records","eff","menuApi","userApi","draftFromGrants","id","entry","translateError","save","bad","invalidExpiry","upserts","removes","__expose","_createBlock","_unref","NModal","$event","_createElementVNode","_normalizeClass","_hoisted_4","_toDisplayString","_createElementBlock","_hoisted_5","_createVNode","NButton","NSpin","_openBlock","_hoisted_1","_hoisted_2","NAlert","_hoisted_3","NTabs","NTabPane","UserGrantMenuTable","UserGrantEffectiveTable"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { MenuTreeNode } from '../../../../types/menu';
2
+ import { UserMenuEffective } from '../../../../types/api';
3
+ import { Draft } from './userGrantState';
4
+ type __VLS_Props = {
5
+ tree: MenuTreeNode[];
6
+ effective: UserMenuEffective;
7
+ draft: Draft;
8
+ defaultModuleId: number;
9
+ maxDate: string | null;
10
+ };
11
+ declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import o from "./UserGrantMenuTable2.vue.js";
2
+ /* empty css */
3
+ import r from "../../../../_virtual/_plugin-vue_export-helper.js";
4
+ const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-438bbbc2"]]);
5
+ export {
6
+ m as default
7
+ };
8
+ //# sourceMappingURL=UserGrantMenuTable.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserGrantMenuTable.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,186 @@
1
+ import { defineComponent as Q, ref as B, computed as i, watch as W, reactive as X, openBlock as l, createElementBlock as s, createElementVNode as g, createVNode as c, unref as d, withCtx as R, Fragment as h, renderList as S, toDisplayString as D, createBlock as I, mergeProps as M, createCommentVNode as V, withDirectives as Y, vShow as Z } from "vue";
2
+ import { NSelect as ee, NInput as te, NButton as oe } from "naive-ui";
3
+ import { useI18n as ae } from "vue-i18n";
4
+ import $ from "../../../../components/AppIcon.vue.js";
5
+ import { translateMenuTitle as z } from "../../../../locales/menuTitle.js";
6
+ import { pruneSuperAdminOnly as ne, buildGroups as re } from "../../role/components/grantMenuGroups.js";
7
+ import N from "./UserGrantNodeRow.vue.js";
8
+ import { triStateOf as le, leakedCodes as se, setTriState as ie } from "./userGrantState.js";
9
+ const ue = { class: "ut" }, de = { class: "ut-toolbar" }, pe = { class: "ut-scroll" }, ce = {
10
+ key: 0,
11
+ class: "ut-head"
12
+ }, fe = {
13
+ key: 0,
14
+ class: "ut-head-title"
15
+ }, me = {
16
+ key: 0,
17
+ class: "ut-anchor"
18
+ }, ge = { class: "ut-tag" }, he = {
19
+ key: 0,
20
+ class: "ut-empty"
21
+ }, v = 0, Se = /* @__PURE__ */ Q({
22
+ __name: "UserGrantMenuTable",
23
+ props: {
24
+ tree: {},
25
+ effective: {},
26
+ draft: {},
27
+ defaultModuleId: {},
28
+ maxDate: {}
29
+ },
30
+ setup(A) {
31
+ const n = A, { t: p } = ae(), k = B(""), _ = i(() => k.value.trim().toLowerCase()), f = B(n.defaultModuleId);
32
+ W(
33
+ () => n.defaultModuleId,
34
+ (e) => f.value = e
35
+ );
36
+ const C = i(() => ne(n.tree)), O = i(() => re(C.value, /* @__PURE__ */ new Set(), p("role.apiOnlyRow"))), P = i(() => new Map(n.effective.nodes.map((e) => [e.menuId, e]))), j = i(
37
+ () => new Set(n.effective.nodes.filter((e) => e.effective).map((e) => e.menuId))
38
+ ), q = i(() => {
39
+ const e = /* @__PURE__ */ new Map(), a = (t) => {
40
+ for (const o of t)
41
+ e.set(o.id, z(o.title, o.path || void 0)), a(o.children);
42
+ };
43
+ return a(n.tree), e;
44
+ }), F = i(
45
+ () => new Map(C.value.map((e) => [e.id, e.moduleId ?? v]))
46
+ ), E = (e) => F.value.get(e.id) ?? v, H = i(() => {
47
+ const e = n.effective.modules.map((a) => ({
48
+ label: z(a.title),
49
+ value: a.id
50
+ }));
51
+ return O.value.some((a) => E(a) === v) && e.push({ label: p("menu.moduleUnassigned"), value: v }), e;
52
+ }), J = (e, a) => e.title.toLowerCase().includes(a) || e.buttons.some((t) => t.title.toLowerCase().includes(a)), G = i(() => {
53
+ const e = _.value, a = [];
54
+ for (const t of O.value) {
55
+ if (E(t) !== f.value) continue;
56
+ if (!e || t.title.toLowerCase().includes(e)) {
57
+ a.push({ group: t, menus: t.menus });
58
+ continue;
59
+ }
60
+ const o = t.menus.filter((r) => J(r, e));
61
+ o.length && a.push({ group: t, menus: o });
62
+ }
63
+ return a;
64
+ }), m = X(/* @__PURE__ */ new Set()), U = (e) => !!_.value || !m.has(e);
65
+ function K(e) {
66
+ m.has(e) ? m.delete(e) : m.add(e);
67
+ }
68
+ function w(e, a, t) {
69
+ const o = P.value.get(e), r = (o == null ? void 0 : o.grantable) ?? !1, u = le(n.draft, e);
70
+ return {
71
+ title: a,
72
+ path: t,
73
+ node: o,
74
+ state: u,
75
+ entry: n.draft.get(e),
76
+ editable: n.effective.targetEditable && r,
77
+ notGrantable: n.effective.targetEditable && !r,
78
+ maxDate: n.maxDate,
79
+ leaked: u === "deny" ? se(n.tree, j.value, e).map((L) => ({
80
+ code: L.code,
81
+ from: L.carriers.map((T) => q.value.get(T) ?? String(T)).join("、")
82
+ })) : []
83
+ };
84
+ }
85
+ const y = (e, a) => ie(n.draft, e, a, n.maxDate);
86
+ function x(e, a) {
87
+ const t = n.draft.get(e);
88
+ t && (t.expireDate = a);
89
+ }
90
+ function b(e, a) {
91
+ const t = n.draft.get(e);
92
+ t && (t.remark = a);
93
+ }
94
+ return (e, a) => (l(), s("div", ue, [
95
+ g("div", de, [
96
+ c(d(ee), {
97
+ value: f.value,
98
+ "onUpdate:value": a[0] || (a[0] = (t) => f.value = t),
99
+ class: "ut-module",
100
+ options: H.value,
101
+ "aria-label": d(p)("menu.module")
102
+ }, null, 8, ["value", "options", "aria-label"]),
103
+ c(d(te), {
104
+ value: k.value,
105
+ "onUpdate:value": a[1] || (a[1] = (t) => k.value = t),
106
+ clearable: "",
107
+ placeholder: d(p)("role.grantSearch"),
108
+ "input-props": { "aria-label": d(p)("role.grantSearch"), autocomplete: "off" },
109
+ style: { flex: "1", "min-width": "0" }
110
+ }, {
111
+ prefix: R(() => [
112
+ c($, {
113
+ class: "faint",
114
+ icon: "ph:magnifying-glass",
115
+ size: 15
116
+ })
117
+ ]),
118
+ _: 1
119
+ }, 8, ["value", "placeholder", "input-props"])
120
+ ]),
121
+ g("div", pe, [
122
+ (l(!0), s(h, null, S(G.value, (t) => (l(), s("section", {
123
+ key: t.group.id,
124
+ class: "ut-group"
125
+ }, [
126
+ t.group.standalone ? V("", !0) : (l(), s("header", ce, [
127
+ c(d(oe), {
128
+ text: "",
129
+ class: "ut-fold",
130
+ "aria-expanded": U(t.group.id),
131
+ "aria-label": t.group.title,
132
+ onClick: (o) => K(t.group.id)
133
+ }, {
134
+ default: R(() => [
135
+ c($, {
136
+ icon: U(t.group.id) ? "ph:caret-down" : "ph:caret-right",
137
+ size: 14
138
+ }, null, 8, ["icon"])
139
+ ]),
140
+ _: 2
141
+ }, 1032, ["aria-expanded", "aria-label", "onClick"]),
142
+ t.group.synthetic ? (l(), s("span", fe, D(t.group.title), 1)) : (l(), I(N, M({
143
+ key: 1,
144
+ level: "catalog"
145
+ }, { ref_for: !0 }, w(t.group.id, t.group.title), {
146
+ "onUpdate:state": (o) => y(t.group.id, o),
147
+ "onUpdate:expireDate": (o) => x(t.group.id, o),
148
+ "onUpdate:remark": (o) => b(t.group.id, o)
149
+ }), null, 16, ["onUpdate:state", "onUpdate:expireDate", "onUpdate:remark"]))
150
+ ])),
151
+ Y(g("div", null, [
152
+ (l(!0), s(h, null, S(t.menus, (o) => (l(), s(h, {
153
+ key: o.anchor ? `anchor-${o.id}` : o.id
154
+ }, [
155
+ o.anchor ? (l(), s("div", me, [
156
+ g("span", ge, D(o.title), 1)
157
+ ])) : (l(), I(N, M({
158
+ key: 1,
159
+ level: "page"
160
+ }, { ref_for: !0 }, w(o.id, o.title, o.path), {
161
+ "onUpdate:state": (r) => y(o.id, r),
162
+ "onUpdate:expireDate": (r) => x(o.id, r),
163
+ "onUpdate:remark": (r) => b(o.id, r)
164
+ }), null, 16, ["onUpdate:state", "onUpdate:expireDate", "onUpdate:remark"])),
165
+ (l(!0), s(h, null, S(o.buttons, (r) => (l(), I(N, M({
166
+ key: r.id,
167
+ level: "button"
168
+ }, { ref_for: !0 }, w(r.id, r.title), {
169
+ "onUpdate:state": (u) => y(r.id, u),
170
+ "onUpdate:expireDate": (u) => x(r.id, u),
171
+ "onUpdate:remark": (u) => b(r.id, u)
172
+ }), null, 16, ["onUpdate:state", "onUpdate:expireDate", "onUpdate:remark"]))), 128))
173
+ ], 64))), 128))
174
+ ], 512), [
175
+ [Z, U(t.group.id)]
176
+ ])
177
+ ]))), 128)),
178
+ G.value.length ? V("", !0) : (l(), s("div", he, D(_.value ? d(p)("role.grantNoMatch") : d(p)("role.grantNoMenus")), 1))
179
+ ])
180
+ ]));
181
+ }
182
+ });
183
+ export {
184
+ Se as default
185
+ };
186
+ //# sourceMappingURL=UserGrantMenuTable2.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserGrantMenuTable2.vue.js","sources":["../../../../../src/views/system/user/components/UserGrantMenuTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 用户授权弹窗的节点列表:应用切换 + 搜索 + 目录卡片(目录 → 页面 → 按钮,每个节点一行三态)。\n// 分组复用角色页 grantMenuGroups.buildGroups 的结构(不用它的勾选态),角色页的 GrantMenuTable 不动。\n// 草稿在父组件(reactive Map),这里只经 userGrantState 的纯函数改它。嵌套目录与角色页一样展平成带前缀的行。\nimport { computed, reactive, ref, watch } from 'vue'\nimport { NButton, NInput, NSelect } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport type { MenuTreeNode } from '#/types/menu'\nimport type { UserMenuEffective } from '#/types/api'\nimport {\n buildGroups,\n pruneSuperAdminOnly,\n type CatalogGroup,\n type MenuRow,\n} from '../../role/components/grantMenuGroups'\nimport UserGrantNodeRow from './UserGrantNodeRow.vue'\nimport { leakedCodes, setTriState, triStateOf, type Draft, type TriState } from './userGrantState'\n\nconst UNASSIGNED = 0\n\nconst props = defineProps<{\n tree: MenuTreeNode[]\n effective: UserMenuEffective\n draft: Draft\n defaultModuleId: number\n maxDate: string | null\n}>()\n\nconst { t } = useI18n()\nconst search = ref('')\nconst query = computed(() => search.value.trim().toLowerCase())\nconst moduleId = ref(props.defaultModuleId)\nwatch(\n () => props.defaultModuleId,\n v => (moduleId.value = v),\n)\n\n// 单独授权的目标从来不是超管:系统菜单里除用户管理、角色管理外只属于超管与内置角色,这里不列出来。\n// 只收窄列表;防漏提示(leakedCodes)与「有效权限」页签仍按完整的树算,隐藏的节点照样是它们的数据来源。\nconst visibleTree = computed(() => pruneSuperAdminOnly(props.tree))\nconst groups = computed(() => buildGroups(visibleTree.value, new Set(), t('role.apiOnlyRow')))\nconst nodeMap = computed(() => new Map(props.effective.nodes.map(n => [n.menuId, n])))\nconst effectiveIds = computed(\n () => new Set(props.effective.nodes.filter(n => n.effective).map(n => n.menuId)),\n)\nconst titles = computed(() => {\n const map = new Map<number, string>()\n const walk = (nodes: MenuTreeNode[]) => {\n for (const n of nodes) {\n map.set(n.id, translateMenuTitle(n.title, n.path || undefined))\n walk(n.children)\n }\n }\n walk(props.tree)\n return map\n})\n\n// ── 应用切换:同角色页,按顶级节点的 moduleId 分 ──\nconst moduleOfTop = computed(\n () => new Map(visibleTree.value.map(n => [n.id, n.moduleId ?? UNASSIGNED])),\n)\nconst moduleOf = (g: CatalogGroup) => moduleOfTop.value.get(g.id) ?? UNASSIGNED\nconst moduleOptions = computed(() => {\n const options = props.effective.modules.map(m => ({\n label: translateMenuTitle(m.title),\n value: m.id,\n }))\n if (groups.value.some(g => moduleOf(g) === UNASSIGNED))\n options.push({ label: t('menu.moduleUnassigned'), value: UNASSIGNED })\n return options\n})\n\n// ── 搜索:目录名命中 → 整组;否则只留页面名 / 按钮名命中的行 ──\nconst matchesRow = (m: MenuRow, q: string) =>\n m.title.toLowerCase().includes(q) || m.buttons.some(b => b.title.toLowerCase().includes(q))\nconst views = computed(() => {\n const q = query.value\n const out: { group: CatalogGroup; menus: MenuRow[] }[] = []\n for (const g of groups.value) {\n if (moduleOf(g) !== moduleId.value) continue\n if (!q || g.title.toLowerCase().includes(q)) {\n out.push({ group: g, menus: g.menus })\n continue\n }\n const menus = g.menus.filter(m => matchesRow(m, q))\n if (menus.length) out.push({ group: g, menus })\n }\n return out\n})\n\n// ── 折叠(搜索时一律展开,免得命中项藏在折叠里) ──\nconst collapsed = reactive(new Set<number>())\nconst isOpen = (id: number) => !!query.value || !collapsed.has(id)\nfunction toggle(id: number) {\n if (collapsed.has(id)) collapsed.delete(id)\n else collapsed.add(id)\n}\n\n// ── 行属性与改动 ──\nfunction rowProps(id: number, title: string, path?: string) {\n const node = nodeMap.value.get(id)\n const grantable = node?.grantable ?? false\n const state = triStateOf(props.draft, id)\n return {\n title,\n path,\n node,\n state,\n entry: props.draft.get(id),\n editable: props.effective.targetEditable && grantable,\n notGrantable: props.effective.targetEditable && !grantable,\n maxDate: props.maxDate,\n leaked:\n state === 'deny'\n ? leakedCodes(props.tree, effectiveIds.value, id).map(l => ({\n code: l.code,\n from: l.carriers.map(c => titles.value.get(c) ?? String(c)).join('、'),\n }))\n : [],\n }\n}\nconst onState = (id: number, next: TriState) => setTriState(props.draft, id, next, props.maxDate)\nfunction onExpire(id: number, v: string | null) {\n const entry = props.draft.get(id)\n if (entry) entry.expireDate = v\n}\nfunction onRemark(id: number, v: string) {\n const entry = props.draft.get(id)\n if (entry) entry.remark = v\n}\n</script>\n\n<template>\n <div class=\"ut\">\n <div class=\"ut-toolbar\">\n <n-select\n v-model:value=\"moduleId\"\n class=\"ut-module\"\n :options=\"moduleOptions\"\n :aria-label=\"t('menu.module')\"\n />\n <n-input\n v-model:value=\"search\"\n clearable\n :placeholder=\"t('role.grantSearch')\"\n :input-props=\"{ 'aria-label': t('role.grantSearch'), autocomplete: 'off' }\"\n style=\"flex: 1; min-width: 0\"\n >\n <template #prefix><AppIcon class=\"faint\" icon=\"ph:magnifying-glass\" :size=\"15\" /></template>\n </n-input>\n </div>\n\n <div class=\"ut-scroll\">\n <section v-for=\"v in views\" :key=\"v.group.id\" class=\"ut-group\">\n <header v-if=\"!v.group.standalone\" class=\"ut-head\">\n <n-button\n text\n class=\"ut-fold\"\n :aria-expanded=\"isOpen(v.group.id)\"\n :aria-label=\"v.group.title\"\n @click=\"toggle(v.group.id)\"\n >\n <AppIcon :icon=\"isOpen(v.group.id) ? 'ph:caret-down' : 'ph:caret-right'\" :size=\"14\" />\n </n-button>\n <span v-if=\"v.group.synthetic\" class=\"ut-head-title\">{{ v.group.title }}</span>\n <UserGrantNodeRow\n v-else\n level=\"catalog\"\n v-bind=\"rowProps(v.group.id, v.group.title)\"\n @update:state=\"s => onState(v.group.id, s)\"\n @update:expire-date=\"d => onExpire(v.group.id, d)\"\n @update:remark=\"r => onRemark(v.group.id, r)\"\n />\n </header>\n <div v-show=\"isOpen(v.group.id)\">\n <template v-for=\"m in v.menus\" :key=\"m.anchor ? `anchor-${m.id}` : m.id\">\n <div v-if=\"m.anchor\" class=\"ut-anchor\">\n <span class=\"ut-tag\">{{ m.title }}</span>\n </div>\n <UserGrantNodeRow\n v-else\n level=\"page\"\n v-bind=\"rowProps(m.id, m.title, m.path)\"\n @update:state=\"s => onState(m.id, s)\"\n @update:expire-date=\"d => onExpire(m.id, d)\"\n @update:remark=\"r => onRemark(m.id, r)\"\n />\n <UserGrantNodeRow\n v-for=\"b in m.buttons\"\n :key=\"b.id\"\n level=\"button\"\n v-bind=\"rowProps(b.id, b.title)\"\n @update:state=\"s => onState(b.id, s)\"\n @update:expire-date=\"d => onExpire(b.id, d)\"\n @update:remark=\"r => onRemark(b.id, r)\"\n />\n </template>\n </div>\n </section>\n\n <div v-if=\"!views.length\" class=\"ut-empty\">\n {{ query ? t('role.grantNoMatch') : t('role.grantNoMenus') }}\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.ut {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.ut-toolbar {\n flex: none;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n align-items: center;\n padding: 10px 20px 12px;\n}\n.ut-module {\n flex: none;\n width: 180px;\n}\n.ut-scroll {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n padding: 4px 20px 20px;\n scrollbar-width: thin;\n}\n.ut-group {\n border: 1px solid var(--hairline);\n border-radius: 14px;\n margin-bottom: 12px;\n overflow: hidden;\n}\n.ut-head {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 46px;\n padding: 6px 16px;\n}\n.ut-head-title {\n font-size: 15px;\n font-weight: 600;\n}\n.ut-fold {\n flex: none;\n}\n.ut-anchor {\n padding: 8px 16px;\n border-top: 1px solid var(--hairline);\n}\n.ut-tag {\n display: inline-block;\n padding: 1px 8px;\n border-radius: 6px;\n background: var(--fill);\n color: var(--text-2);\n font-size: 13px;\n font-weight: 500;\n}\n.ut-empty {\n padding: 64px 24px;\n text-align: center;\n color: var(--text-2);\n}\n@media (max-width: 640px) {\n .ut-module {\n width: 100%;\n }\n}\n</style>\n"],"names":["UNASSIGNED","props","__props","t","useI18n","search","ref","query","computed","moduleId","watch","v","visibleTree","pruneSuperAdminOnly","groups","buildGroups","nodeMap","n","effectiveIds","titles","map","walk","nodes","translateMenuTitle","moduleOfTop","moduleOf","g","moduleOptions","options","m","matchesRow","q","b","views","out","menus","collapsed","reactive","isOpen","id","toggle","rowProps","title","path","node","grantable","state","triStateOf","leakedCodes","l","c","onState","next","setTriState","onExpire","entry","onRemark","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","_unref","NSelect","$event","NInput","AppIcon","_hoisted_3","_Fragment","_renderList","_hoisted_4","NButton","_hoisted_5","_toDisplayString","_createBlock","UserGrantNodeRow","_mergeProps","s","d","r","_hoisted_6","_hoisted_7","_vShow","_hoisted_8"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { UserMenuEffectiveNode } from '../../../../types/api';
2
+ import { DraftEntry, TriState } from './userGrantState';
3
+ type __VLS_Props = {
4
+ title: string;
5
+ path?: string;
6
+ level: 'catalog' | 'page' | 'button';
7
+ node?: UserMenuEffectiveNode;
8
+ state: TriState;
9
+ entry?: DraftEntry;
10
+ /** 目标用户可编辑且这个节点所属模块可授 */
11
+ editable: boolean;
12
+ /** 只因模块不可转授而不能改(悬浮说明) */
13
+ notGrantable: boolean;
14
+ /** 到期日上限 yyyy-MM-dd;null = 不限 */
15
+ maxDate: string | null;
16
+ leaked: {
17
+ code: string;
18
+ from: string;
19
+ }[];
20
+ };
21
+ declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
22
+ "update:state": (v: TriState) => any;
23
+ "update:expireDate": (v: string | null) => any;
24
+ "update:remark": (v: string) => any;
25
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
26
+ "onUpdate:state"?: ((v: TriState) => any) | undefined;
27
+ "onUpdate:expireDate"?: ((v: string | null) => any) | undefined;
28
+ "onUpdate:remark"?: ((v: string) => any) | undefined;
29
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
30
+ declare const _default: typeof __VLS_export;
31
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import o from "./UserGrantNodeRow2.vue.js";
2
+ /* empty css */
3
+ import r from "../../../../_virtual/_plugin-vue_export-helper.js";
4
+ const f = /* @__PURE__ */ r(o, [["__scopeId", "data-v-665d8f94"]]);
5
+ export {
6
+ f as default
7
+ };
8
+ //# sourceMappingURL=UserGrantNodeRow.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserGrantNodeRow.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}