smart-admin-web 10.5.0 → 10.10.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.
- package/README.md +1 -1
- package/dist/api/client.js.map +1 -1
- package/dist/api/index.d.ts +3 -3
- package/dist/api/index.js +2 -2
- package/dist/api/index.js.map +1 -1
- package/dist/components/DetailPage/index.vue.js +1 -1
- package/dist/components/DetailPage/index2.vue.js.map +1 -1
- package/dist/components/IconPicker/index.vue.js.map +1 -1
- package/dist/components/ImportWizard/index.vue.js +1 -1
- package/dist/components/ImportWizard/index2.vue.js.map +1 -1
- package/dist/components/TableZoomButton/index.vue.js.map +1 -1
- package/dist/composables/useConfirm.js.map +1 -1
- package/dist/composables/useLayoutMenu.js.map +1 -1
- package/dist/composables/useRealtime.d.ts +1 -1
- package/dist/composables/useRealtime.js.map +1 -1
- package/dist/createSmartAdmin.d.ts +2 -2
- package/dist/createSmartAdmin.js +15 -14
- package/dist/createSmartAdmin.js.map +1 -1
- package/dist/index.js +27 -26
- package/dist/layouts/default.vue.js +2 -2
- package/dist/layouts/default2.vue.js.map +1 -1
- package/dist/lib/icons.js.map +1 -1
- package/dist/lib/markdown.js.map +1 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/locales/en-US.js +1 -1
- package/dist/locales/en-US.js.map +1 -1
- package/dist/locales/zh-CN.js +2 -2
- package/dist/locales/zh-CN.js.map +1 -1
- package/dist/router/detailRoutes.js.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/router/routes.js +1 -1
- package/dist/router/routes.js.map +1 -1
- package/dist/stores/user.d.ts +2 -2
- package/dist/stores/user.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/theme/mix.d.ts +3 -3
- package/dist/theme/mix.js.map +1 -1
- package/dist/types/api.d.ts +1 -1
- package/dist/types/api.js.map +1 -1
- package/dist/utils/url.d.ts +2 -0
- package/dist/utils/url.js +9 -3
- package/dist/utils/url.js.map +1 -1
- package/dist/views/error/404.vue.js +2 -2
- package/dist/views/error/4042.vue.js.map +1 -1
- package/dist/views/login/skins/SplitPanel.vue.js +1 -1
- package/dist/views/login/skins/SplitPanel2.vue.js.map +1 -1
- package/dist/views/system/log/op/index.vue.js +1 -1
- package/dist/views/system/log/op/index2.vue.js +1 -1
- package/dist/views/system/log/op/index2.vue.js.map +1 -1
- package/dist/views/system/menu/components/ButtonManager.vue.js +1 -1
- package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
- package/dist/views/system/menu/components/MenuFormModal.vue.js +3 -3
- package/dist/views/system/menu/components/MenuFormModal2.vue.js.map +1 -1
- package/dist/views/system/menu/index.vue.js +2 -2
- package/dist/views/system/menu/index2.vue.js +6 -6
- package/dist/views/system/menu/index2.vue.js.map +1 -1
- package/dist/views/system/module/index.vue.js +2 -2
- package/dist/views/system/module/index2.vue.js +2 -2
- package/dist/views/system/module/index2.vue.js.map +1 -1
- package/dist/views/system/user/components/ResetPasswordModal.vue.js +1 -1
- package/dist/views/system/user/components/ResetPasswordModal2.vue.js.map +1 -1
- package/dist/views/system/user/components/UserFormModal.vue.js +1 -1
- package/dist/views/system/user/components/UserFormModal2.vue.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -79,17 +79,17 @@ import { IMPORT_DUPLICATE_IN_DB as rt, hardErrorsOf as ot, isDuplicateOnly as tt
|
|
|
79
79
|
import { BRAND_CODES as pt, LINK_BY_ACCOUNT_CODES as st, PREVIEW_ALL_SSO_BRANDS as mt, SSO_VISIBLE_MAX as ft, brandDisplayName as lt, buildConfigProviderRows as ut, claimWeComAutoLogin as nt, isBrandCode as dt, isIconifyName as xt, mergeBindingRows as ct, previewAllBrandProviders as At, resolveProviderIcon as St, splitLoginProviders as gt } from "./utils/oauthBrand.js";
|
|
80
80
|
import { buildTree as Ct, collectSubtreeIds as ht, expandableIds as Pt, filterTree as Et } from "./utils/tree.js";
|
|
81
81
|
import { parseUserAgent as Dt, uaSummary as _t } from "./utils/ua.js";
|
|
82
|
-
import { FULLSCREEN_PATH_PREFIX as Bt, isFullscreenPath as Rt, isHttpUrl as bt } from "./utils/url.js";
|
|
83
|
-
import { default as
|
|
84
|
-
import { ACCENTS as
|
|
85
|
-
import { btnGrad as
|
|
86
|
-
import { buildThemeOverrides as
|
|
87
|
-
import { setupMarkdown as
|
|
88
|
-
import { LoadingBarBridge as
|
|
89
|
-
import { classifyNoticeAction as
|
|
90
|
-
import { registerViews as
|
|
82
|
+
import { FULLSCREEN_PATH_PREFIX as Bt, isFullscreenPath as Rt, isHttpUrl as bt, trimTrailingSlashes as wt } from "./utils/url.js";
|
|
83
|
+
import { default as Ot } from "./assets/icons/ph-subset.json.js";
|
|
84
|
+
import { ACCENTS as Nt } from "./theme/accents.js";
|
|
85
|
+
import { btnGrad as vt, derivePrimary as kt, glowSh as Ht, mix as Ft, rgba as Vt } from "./theme/mix.js";
|
|
86
|
+
import { buildThemeOverrides as Xt } from "./theme/naive-theme.js";
|
|
87
|
+
import { setupMarkdown as Gt, withXssPlugin as jt } from "./lib/markdown.js";
|
|
88
|
+
import { LoadingBarBridge as Zt, loadingBar as Jt } from "./lib/loadingBar.js";
|
|
89
|
+
import { classifyNoticeAction as Yt, isSiteRelativeUrl as qt, noticeActionLabel as $t } from "./lib/noticeActions.js";
|
|
90
|
+
import { registerViews as ra, viewComponentPaths as oa } from "./router/viewRegistry.js";
|
|
91
91
|
export {
|
|
92
|
-
|
|
92
|
+
Nt as ACCENTS,
|
|
93
93
|
f as ApiError,
|
|
94
94
|
wr as ApiSelect,
|
|
95
95
|
Uo as AppIcon,
|
|
@@ -120,7 +120,7 @@ export {
|
|
|
120
120
|
st as LINK_BY_ACCOUNT_CODES,
|
|
121
121
|
G as LONG_TIMEOUT_MS,
|
|
122
122
|
Nr as LineChart,
|
|
123
|
-
|
|
123
|
+
Zt as LoadingBarBridge,
|
|
124
124
|
Ao as MarkdownEditor,
|
|
125
125
|
go as MarkdownView,
|
|
126
126
|
ko as MenuSearch,
|
|
@@ -141,15 +141,15 @@ export {
|
|
|
141
141
|
l as authApi,
|
|
142
142
|
nr as beginVoluntaryLogout,
|
|
143
143
|
lt as brandDisplayName,
|
|
144
|
-
|
|
144
|
+
vt as btnGrad,
|
|
145
145
|
ut as buildConfigProviderRows,
|
|
146
146
|
Ue as buildRoutesForModule,
|
|
147
|
-
|
|
147
|
+
Xt as buildThemeOverrides,
|
|
148
148
|
Ct as buildTree,
|
|
149
149
|
u as cacheApi,
|
|
150
150
|
n as callApi,
|
|
151
151
|
nt as claimWeComAutoLogin,
|
|
152
|
-
|
|
152
|
+
Yt as classifyNoticeAction,
|
|
153
153
|
ye as clearClientCache,
|
|
154
154
|
j as client,
|
|
155
155
|
ht as collectSubtreeIds,
|
|
@@ -158,7 +158,7 @@ export {
|
|
|
158
158
|
s as createSmartAdmin,
|
|
159
159
|
x as dashboardApi,
|
|
160
160
|
c as dayRange,
|
|
161
|
-
|
|
161
|
+
kt as derivePrimary,
|
|
162
162
|
Le as describeMenuRoute,
|
|
163
163
|
A as dictAdminApi,
|
|
164
164
|
S as dictApi,
|
|
@@ -169,7 +169,7 @@ export {
|
|
|
169
169
|
Et as filterTree,
|
|
170
170
|
Yo as fmtBytes,
|
|
171
171
|
qo as fmtDateTime,
|
|
172
|
-
|
|
172
|
+
Ht as glowSh,
|
|
173
173
|
ot as hardErrorsOf,
|
|
174
174
|
C as highSensApi,
|
|
175
175
|
he as i18n,
|
|
@@ -180,27 +180,27 @@ export {
|
|
|
180
180
|
at as isHardError,
|
|
181
181
|
bt as isHttpUrl,
|
|
182
182
|
xt as isIconifyName,
|
|
183
|
-
|
|
183
|
+
qt as isSiteRelativeUrl,
|
|
184
184
|
h as jobApi,
|
|
185
185
|
ee as joinPermission,
|
|
186
|
-
|
|
186
|
+
Ot as kernelIconSet,
|
|
187
187
|
P as listQuery,
|
|
188
188
|
Sr as loadSite,
|
|
189
|
-
|
|
189
|
+
Jt as loadingBar,
|
|
190
190
|
E as logApi,
|
|
191
191
|
M as menuApi,
|
|
192
192
|
er as menuBadge,
|
|
193
193
|
_e as menuTitleKey,
|
|
194
194
|
ct as mergeBindingRows,
|
|
195
195
|
D as mfaApi,
|
|
196
|
-
|
|
196
|
+
Ft as mix,
|
|
197
197
|
_ as moduleApi,
|
|
198
198
|
I as monitorApi,
|
|
199
199
|
Te as namedPage,
|
|
200
200
|
B as normalizeCommit,
|
|
201
201
|
R as normalizePreview,
|
|
202
202
|
sr as noticeActionButtonType,
|
|
203
|
-
|
|
203
|
+
$t as noticeActionLabel,
|
|
204
204
|
b as noticeApi,
|
|
205
205
|
dr as noticeBus,
|
|
206
206
|
xr as onRealtime,
|
|
@@ -219,14 +219,14 @@ export {
|
|
|
219
219
|
Pe as registerLocales,
|
|
220
220
|
rr as registerMenuBadge,
|
|
221
221
|
Ie as registerMenuTitles,
|
|
222
|
-
|
|
222
|
+
ra as registerViews,
|
|
223
223
|
Ae as resetRouter,
|
|
224
224
|
St as resolveProviderIcon,
|
|
225
|
-
|
|
225
|
+
Vt as rgba,
|
|
226
226
|
U as roleApi,
|
|
227
227
|
Se as router,
|
|
228
228
|
v as sessionApi,
|
|
229
|
-
|
|
229
|
+
Gt as setupMarkdown,
|
|
230
230
|
gt as splitLoginProviders,
|
|
231
231
|
re as splitPermission,
|
|
232
232
|
Ee as t,
|
|
@@ -237,6 +237,7 @@ export {
|
|
|
237
237
|
Jo as translateErrorDetail,
|
|
238
238
|
Be as translateMenuTitle,
|
|
239
239
|
jo as triggerBlobDownload,
|
|
240
|
+
wt as trimTrailingSlashes,
|
|
240
241
|
_t as uaSummary,
|
|
241
242
|
F as unwrap,
|
|
242
243
|
V as unwrapDownload,
|
|
@@ -266,8 +267,8 @@ export {
|
|
|
266
267
|
Rr as useVisualViewportHeight,
|
|
267
268
|
W as userApi,
|
|
268
269
|
be as vAuth,
|
|
269
|
-
|
|
270
|
+
oa as viewComponentPaths,
|
|
270
271
|
Me as withExt,
|
|
271
|
-
|
|
272
|
+
jt as withXssPlugin
|
|
272
273
|
};
|
|
273
274
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./default2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const e = /* @__PURE__ */ t(o, [["__scopeId", "data-v-aa6e9642"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
e as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=default.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default2.vue.js","sources":["../../src/layouts/default.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\nimport { NWatermark, NDrawer, NDrawerContent, NButton } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useBreakpoints, breakpointsTailwind } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore, type LayoutMode } from '#/stores/app'\nimport { useUserStore } from '#/stores/user'\nimport { useLayoutMenu } from '#/composables/useLayoutMenu'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useSite } from '#/composables/useSite'\nimport { useRealtime } from '#/composables/useRealtime'\nimport { useVisualViewportHeight } from '#/composables/useVisualViewportHeight'\nimport ErrorBoundary from '#/components/ErrorBoundary/index.vue'\nimport AppHeader from './AppHeader.vue'\nimport SideNav from './components/SideNav.vue'\nimport TabsBar from './TabsBar.vue'\n\nconst { t } = useI18n()\nconst app = useAppStore()\nconst user = useUserStore()\nconst tabs = useTabsStore()\nconst { site } = useSite()\nconst { menuOptions, l1Options, l2Options, selectedL1, activeKey, onSelect, onSelectL1 } =\n useLayoutMenu()\n\n// 实时通知(SignalR):鉴权外壳挂载即连、卸载即断。后端未开启实时时连接静默失败,退回轮询/惰性 401(纯增强)。\nconst { start: startRealtime, stop: stopRealtime } = useRealtime()\nonMounted(startRealtime)\nonUnmounted(stopRealtime)\n\n// 维护 --vvh(真实可视高度):软键盘弹起时 dvh 不变,只有 visualViewport 会缩。\n// 布局壳自身用 100dvh 就够,变量留给需要贴着键盘排版的页面(见 composables/useVisualViewportHeight)。\nuseVisualViewportHeight()\n\nconst isMobile = useBreakpoints(breakpointsTailwind).smaller('md')\nconst mobileOpen = ref(false)\n\n// 窄屏忽略 layoutMode,统一走 mobile(单列 + 抽屉侧栏)。\nconst mode = computed<LayoutMode | 'mobile'>(() => (isMobile.value ? 'mobile' : app.layoutMode))\n\n// 除 horizontal(无侧栏)外都有侧栏。\nconst withSider = new Set<LayoutMode>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\n// 顶栏显示品牌的模式(其余由侧栏/rail 顶部显示品牌,保证每种布局品牌只出现一处)。\nconst headerBrandModes = new Set<string>([\n 'horizontal',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\nconst showSider = computed(() => !isMobile.value && withSider.has(app.layoutMode))\nconst sideShowBrand = computed(() => mode.value === 'vertical' || mode.value === 'vertical-mix')\nconst headerShowBrand = computed(() => isMobile.value || headerBrandModes.has(mode.value))\n// 顶栏菜单:horizontal=完整树;两个 header-first=一级;侧边优先=二级(选中的一级的子菜单)。\nconst headerTopMenu = computed<'full' | 'l1' | 'l2' | null>(() => {\n switch (mode.value) {\n case 'horizontal':\n return 'full'\n case 'vertical-hybrid-header-first':\n case 'top-hybrid-header-first':\n return 'l1'\n case 'top-hybrid-sidebar-first':\n return 'l2'\n default:\n return null\n }\n})\n// 折叠按钮:有可折叠树侧栏的模式(侧边优先的一级 rail 固定宽,不折叠)。\nconst collapsibleSider = new Set<string>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-header-first',\n])\nconst showCollapse = computed(() => !isMobile.value && collapsibleSider.has(mode.value))\n\n// 非特殊侧栏内容:vertical=完整树;两个 header-first hybrid=二级子菜单树。\nconst asideOptions = computed(() =>\n mode.value === 'vertical' ? menuOptions.value : l2Options.value,\n)\nconst asideStyle = computed(() => {\n if (mode.value === 'vertical-mix') {\n return { width: app.collapsed ? 'var(--rail-w)' : 'calc(var(--rail-w) + var(--sidebar-w))' }\n }\n if (mode.value === 'top-hybrid-sidebar-first') {\n return { width: 'var(--rail-w)' } // 一级 icon rail,固定宽\n }\n return { width: app.collapsed ? 'var(--sidebar-w-collapsed)' : 'var(--sidebar-w)' }\n})\n\nconst transitionName = computed(() =>\n app.pageTransition === 'none' ? undefined : app.pageTransition,\n)\n\nconst watermarkContent = computed(\n () => [user.userInfo?.name, app.watermarkText].filter(Boolean).join(' · ') || site.title,\n)\nconst watermarkColor = computed(() => (app.isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.06)'))\n\nfunction onMobileSelect(key: string) {\n onSelect(key)\n mobileOpen.value = false\n}\n\n// 刷新标签:store 置 excludeName(逐出缓存)+ 递增 reloadKey;这里 v-if 关开一次令当前页重挂,再放行缓存。\nconst rvShow = ref(true)\nwatch(\n () => tabs.reloadKey,\n async () => {\n rvShow.value = false\n await nextTick()\n rvShow.value = true\n await nextTick()\n tabs.excludeName = ''\n },\n)\n</script>\n\n<template>\n <div class=\"layout\" :class=\"`mode-${mode}`\">\n <!-- 侧栏 -->\n <aside\n v-if=\"showSider\"\n class=\"aside\"\n :class=\"{ 'aside--mix': mode === 'vertical-mix' }\"\n :style=\"asideStyle\"\n >\n <template v-if=\"mode === 'vertical-mix'\">\n <SideNav\n class=\"rail\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n show-brand\n @select=\"onSelectL1\"\n />\n <SideNav\n v-show=\"!app.collapsed\"\n class=\"l2col\"\n :options=\"l2Options\"\n :value=\"activeKey\"\n @select=\"onSelect\"\n />\n </template>\n <!-- 顶部混合-侧边优先:侧栏只放一级 icon rail(二级在顶栏) -->\n <SideNav\n v-else-if=\"mode === 'top-hybrid-sidebar-first'\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n @select=\"onSelectL1\"\n />\n <SideNav\n v-else\n :options=\"asideOptions\"\n :value=\"activeKey\"\n :collapsed=\"app.collapsed\"\n :show-brand=\"sideShowBrand\"\n @select=\"onSelect\"\n />\n </aside>\n\n <!-- 顶栏 -->\n <header class=\"header\" :class=\"{ 'header--static': !app.fixedHeader }\">\n <n-button\n v-if=\"isMobile\"\n quaternary\n circle\n class=\"hbg\"\n :aria-label=\"t('app.openMenu')\"\n @click=\"mobileOpen = true\"\n >\n <Icon icon=\"ph:list\" :width=\"20\" />\n </n-button>\n <div class=\"apph\">\n <AppHeader\n :show-collapse=\"showCollapse\"\n :show-brand=\"headerShowBrand\"\n :top-menu=\"headerTopMenu\"\n />\n </div>\n </header>\n\n <!-- 内容 -->\n <main class=\"content\">\n <div v-if=\"app.showTabs\" class=\"tabs\"><TabsBar /></div>\n <div class=\"page\">\n <!-- 错误边界包住整个内容区:页面组件抛异常时 Vue 会卸掉整棵子树,没有它就是白屏。\n component :key=路由 path 给稳定身份:out-in 过渡才能正确区分进/出场,否则显示上一页缓存\n (按 path 各自成键,不塌缩缓存)。每个页面经 namedPage 套了一层 <div.page-view> 单元素根,\n out-in 能瞬时过渡任何页,无需卡死自愈的看门狗。 -->\n <ErrorBoundary>\n <router-view v-slot=\"{ Component }\">\n <transition :name=\"transitionName\" mode=\"out-in\">\n <keep-alive :include=\"tabs.cachedNames\" :exclude=\"tabs.excludeName\">\n <component :is=\"Component\" v-if=\"rvShow\" :key=\"activeKey\" />\n </keep-alive>\n </transition>\n </router-view>\n </ErrorBoundary>\n </div>\n <n-watermark\n v-if=\"app.watermark\"\n :content=\"watermarkContent\"\n cross\n fullscreen\n :font-size=\"14\"\n :line-height=\"16\"\n :width=\"192\"\n :height=\"128\"\n :rotate=\"-16\"\n :font-color=\"watermarkColor\"\n />\n </main>\n\n <!-- 移动端抽屉侧栏 -->\n <n-drawer v-model:show=\"mobileOpen\" placement=\"left\" :width=\"236\">\n <n-drawer-content :native-scrollbar=\"false\" body-content-style=\"padding:0\">\n <SideNav :options=\"menuOptions\" :value=\"activeKey\" show-brand @select=\"onMobileSelect\" />\n </n-drawer-content>\n </n-drawer>\n </div>\n</template>\n\n<style scoped>\n.layout {\n display: grid;\n /* dvh 而非 vh:移动端浏览器地址栏收起时 vh 仍按最小视口算,底部会被裁掉一条 */\n height: 100dvh;\n overflow: hidden;\n background: var(--color-bg-app); /* 整页画布跟随 tokens,暗色自动切深蓝黑渐变 */\n}\n/* 竖向壳:侧栏满高在左,顶栏缩进到内容列上方 */\n.mode-vertical,\n.mode-vertical-mix,\n.mode-vertical-hybrid-header-first {\n grid-template-columns: auto 1fr;\n grid-template-rows: var(--header-h) 1fr;\n grid-template-areas: 'aside header' 'aside content';\n}\n/* 顶栏壳:顶栏通栏,侧栏在其下方左侧 */\n.mode-top-hybrid-sidebar-first,\n.mode-top-hybrid-header-first {\n grid-template-columns: auto 1fr;\n grid-template-rows: var(--header-h) 1fr;\n grid-template-areas: 'header header' 'aside content';\n}\n.mode-horizontal,\n.mode-mobile {\n grid-template-columns: 1fr;\n grid-template-rows: var(--header-h) 1fr;\n grid-template-areas: 'header' 'content';\n}\n\n.aside {\n grid-area: aside;\n height: 100%;\n overflow: hidden;\n border-right: 1px solid var(--color-border);\n background: var(--color-bg-container);\n backdrop-filter: blur(18px); /* 侧栏玻璃背景,与顶栏/弹层质感统一 */\n -webkit-backdrop-filter: blur(18px);\n transition: width 0.2s ease;\n}\n.aside--mix {\n display: flex;\n}\n.aside--mix .rail {\n width: var(--rail-w);\n flex-shrink: 0;\n border-right: 1px solid var(--color-border);\n}\n.aside--mix .l2col {\n flex: 1;\n min-width: 0;\n}\n\n.header {\n grid-area: header;\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--color-border);\n background: var(--color-header-bg);\n backdrop-filter: blur(12px);\n z-index: 10;\n}\n.header--static {\n backdrop-filter: none;\n}\n.hbg {\n align-self: center;\n margin-left: 8px;\n}\n.apph {\n flex: 1;\n min-width: 0;\n height: 100%;\n}\n\n.content {\n grid-area: content;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.tabs {\n flex-shrink: 0;\n}\n.page {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--pad-page);\n}\n</style>\n"],"names":["t","useI18n","app","useAppStore","user","useUserStore","tabs","useTabsStore","site","useSite","menuOptions","l1Options","l2Options","selectedL1","activeKey","onSelect","onSelectL1","useLayoutMenu","startRealtime","stopRealtime","useRealtime","onMounted","onUnmounted","useVisualViewportHeight","isMobile","useBreakpoints","breakpointsTailwind","mobileOpen","ref","mode","computed","withSider","headerBrandModes","showSider","sideShowBrand","headerShowBrand","headerTopMenu","collapsibleSider","showCollapse","asideOptions","asideStyle","transitionName","watermarkContent","_a","watermarkColor","onMobileSelect","key","rvShow","watch","nextTick","_createElementBlock","_normalizeClass","_Fragment","_createVNode","SideNav","_unref","_vShow","_createBlock","_createElementVNode","NButton","Icon","_hoisted_1","AppHeader","_hoisted_2","_openBlock","_hoisted_3","TabsBar","_hoisted_4","ErrorBoundary","RouterView","_withCtx","Component","_Transition","_KeepAlive","_resolveDynamicComponent","NWatermark","NDrawer","$event","NDrawerContent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"default2.vue.js","sources":["../../src/layouts/default.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\nimport { NWatermark, NDrawer, NDrawerContent, NButton } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useBreakpoints, breakpointsTailwind } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore, type LayoutMode } from '#/stores/app'\nimport { useUserStore } from '#/stores/user'\nimport { useLayoutMenu } from '#/composables/useLayoutMenu'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useSite } from '#/composables/useSite'\nimport { useRealtime } from '#/composables/useRealtime'\nimport { useVisualViewportHeight } from '#/composables/useVisualViewportHeight'\nimport ErrorBoundary from '#/components/ErrorBoundary/index.vue'\nimport AppHeader from './AppHeader.vue'\nimport SideNav from './components/SideNav.vue'\nimport TabsBar from './TabsBar.vue'\n\nconst { t } = useI18n()\nconst app = useAppStore()\nconst user = useUserStore()\nconst tabs = useTabsStore()\nconst { site } = useSite()\nconst { menuOptions, l1Options, l2Options, selectedL1, activeKey, onSelect, onSelectL1 } =\n useLayoutMenu()\n\n// 实时通知(SignalR):鉴权外壳挂载即连、卸载即断。后端未开启实时时连接静默失败,退回轮询/惰性 401(纯增强)。\nconst { start: startRealtime, stop: stopRealtime } = useRealtime()\nonMounted(startRealtime)\nonUnmounted(stopRealtime)\n\n// 维护 --vvh(真实可视高度):软键盘弹起时 dvh 不变,只有 visualViewport 会缩。\n// 布局壳自身用 100dvh 就够,变量留给需要贴着键盘排版的页面(见 composables/useVisualViewportHeight)。\nuseVisualViewportHeight()\n\nconst isMobile = useBreakpoints(breakpointsTailwind).smaller('md')\nconst mobileOpen = ref(false)\n\n// 窄屏忽略 layoutMode,统一走 mobile(单列 + 抽屉侧栏)。\nconst mode = computed<LayoutMode | 'mobile'>(() => (isMobile.value ? 'mobile' : app.layoutMode))\n\n// 除 horizontal(无侧栏)外都有侧栏。\nconst withSider = new Set<LayoutMode>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\n// 顶栏显示品牌的模式(其余由侧栏/rail 顶部显示品牌,保证每种布局品牌只出现一处)。\nconst headerBrandModes = new Set<string>([\n 'horizontal',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\nconst showSider = computed(() => !isMobile.value && withSider.has(app.layoutMode))\nconst sideShowBrand = computed(() => mode.value === 'vertical' || mode.value === 'vertical-mix')\nconst headerShowBrand = computed(() => isMobile.value || headerBrandModes.has(mode.value))\n// 顶栏菜单:horizontal=完整树;两个 header-first=一级;侧边优先=二级(选中的一级的子菜单)。\nconst headerTopMenu = computed<'full' | 'l1' | 'l2' | null>(() => {\n switch (mode.value) {\n case 'horizontal':\n return 'full'\n case 'vertical-hybrid-header-first':\n case 'top-hybrid-header-first':\n return 'l1'\n case 'top-hybrid-sidebar-first':\n return 'l2'\n default:\n return null\n }\n})\n// 折叠按钮:有可折叠树侧栏的模式(侧边优先的一级 rail 固定宽,不折叠)。\nconst collapsibleSider = new Set<string>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-header-first',\n])\nconst showCollapse = computed(() => !isMobile.value && collapsibleSider.has(mode.value))\n\n// 非特殊侧栏内容:vertical=完整树;两个 header-first hybrid=二级子菜单树。\nconst asideOptions = computed(() =>\n mode.value === 'vertical' ? menuOptions.value : l2Options.value,\n)\nconst asideStyle = computed(() => {\n if (mode.value === 'vertical-mix') {\n return { width: app.collapsed ? 'var(--rail-w)' : 'calc(var(--rail-w) + var(--sidebar-w))' }\n }\n if (mode.value === 'top-hybrid-sidebar-first') {\n return { width: 'var(--rail-w)' } // 一级 icon rail,固定宽\n }\n return { width: app.collapsed ? 'var(--sidebar-w-collapsed)' : 'var(--sidebar-w)' }\n})\n\nconst transitionName = computed(() =>\n app.pageTransition === 'none' ? undefined : app.pageTransition,\n)\n\nconst watermarkContent = computed(\n () => [user.userInfo?.name, app.watermarkText].filter(Boolean).join(' · ') || site.title,\n)\nconst watermarkColor = computed(() => (app.isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.06)'))\n\nfunction onMobileSelect(key: string) {\n onSelect(key)\n mobileOpen.value = false\n}\n\n// 刷新标签:store 置 excludeName(逐出缓存)+ 递增 reloadKey;这里 v-if 关开一次令当前页重挂,再放行缓存。\nconst rvShow = ref(true)\nwatch(\n () => tabs.reloadKey,\n async () => {\n rvShow.value = false\n await nextTick()\n rvShow.value = true\n await nextTick()\n tabs.excludeName = ''\n },\n)\n</script>\n\n<template>\n <div class=\"layout\" :class=\"`mode-${mode}`\">\n <!-- 侧栏 -->\n <aside\n v-if=\"showSider\"\n class=\"aside\"\n :class=\"{ 'aside--mix': mode === 'vertical-mix' }\"\n :style=\"asideStyle\"\n >\n <template v-if=\"mode === 'vertical-mix'\">\n <SideNav\n class=\"rail\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n show-brand\n @select=\"onSelectL1\"\n />\n <SideNav\n v-show=\"!app.collapsed\"\n class=\"l2col\"\n :options=\"l2Options\"\n :value=\"activeKey\"\n @select=\"onSelect\"\n />\n </template>\n <!-- 顶部混合-侧边优先:侧栏只放一级 icon rail(二级在顶栏) -->\n <SideNav\n v-else-if=\"mode === 'top-hybrid-sidebar-first'\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n @select=\"onSelectL1\"\n />\n <SideNav\n v-else\n :options=\"asideOptions\"\n :value=\"activeKey\"\n :collapsed=\"app.collapsed\"\n :show-brand=\"sideShowBrand\"\n @select=\"onSelect\"\n />\n </aside>\n\n <!-- 顶栏 -->\n <header class=\"header\" :class=\"{ 'header--static': !app.fixedHeader }\">\n <n-button\n v-if=\"isMobile\"\n quaternary\n circle\n class=\"hbg\"\n :aria-label=\"t('app.openMenu')\"\n @click=\"mobileOpen = true\"\n >\n <Icon icon=\"ph:list\" :width=\"20\" />\n </n-button>\n <div class=\"apph\">\n <AppHeader\n :show-collapse=\"showCollapse\"\n :show-brand=\"headerShowBrand\"\n :top-menu=\"headerTopMenu\"\n />\n </div>\n </header>\n\n <!-- 内容 -->\n <main class=\"content\">\n <div v-if=\"app.showTabs\" class=\"tabs\"><TabsBar /></div>\n <div class=\"page\">\n <!-- 错误边界包住整个内容区:页面组件抛异常时 Vue 会卸掉整棵子树,没有它就是白屏。\n component :key=路由 path 给稳定身份:out-in 过渡才能正确区分进/出场,否则显示上一页缓存\n (按 path 各自成键,不塌缩缓存)。每个页面经 namedPage 套了一层 <div.page-view> 单元素根,\n out-in 能瞬时过渡任何页。 -->\n <ErrorBoundary>\n <router-view v-slot=\"{ Component }\">\n <transition :name=\"transitionName\" mode=\"out-in\">\n <keep-alive :include=\"tabs.cachedNames\" :exclude=\"tabs.excludeName\">\n <component :is=\"Component\" v-if=\"rvShow\" :key=\"activeKey\" />\n </keep-alive>\n </transition>\n </router-view>\n </ErrorBoundary>\n </div>\n <n-watermark\n v-if=\"app.watermark\"\n :content=\"watermarkContent\"\n cross\n fullscreen\n :font-size=\"14\"\n :line-height=\"16\"\n :width=\"192\"\n :height=\"128\"\n :rotate=\"-16\"\n :font-color=\"watermarkColor\"\n />\n </main>\n\n <!-- 移动端抽屉侧栏 -->\n <n-drawer v-model:show=\"mobileOpen\" placement=\"left\" :width=\"236\">\n <n-drawer-content :native-scrollbar=\"false\" body-content-style=\"padding:0\">\n <SideNav :options=\"menuOptions\" :value=\"activeKey\" show-brand @select=\"onMobileSelect\" />\n </n-drawer-content>\n </n-drawer>\n </div>\n</template>\n\n<style scoped>\n.layout {\n display: grid;\n /* dvh 而非 vh:移动端浏览器地址栏收起时 vh 仍按最小视口算,底部会被裁掉一条 */\n height: 100dvh;\n overflow: hidden;\n background: var(--color-bg-app); /* 整页画布跟随 tokens,暗色自动切深蓝黑渐变 */\n}\n/* 竖向壳:侧栏满高在左,顶栏缩进到内容列上方 */\n.mode-vertical,\n.mode-vertical-mix,\n.mode-vertical-hybrid-header-first {\n grid-template-columns: auto 1fr;\n grid-template-rows: var(--header-h) 1fr;\n grid-template-areas: 'aside header' 'aside content';\n}\n/* 顶栏壳:顶栏通栏,侧栏在其下方左侧 */\n.mode-top-hybrid-sidebar-first,\n.mode-top-hybrid-header-first {\n grid-template-columns: auto 1fr;\n grid-template-rows: var(--header-h) 1fr;\n grid-template-areas: 'header header' 'aside content';\n}\n.mode-horizontal,\n.mode-mobile {\n grid-template-columns: 1fr;\n grid-template-rows: var(--header-h) 1fr;\n grid-template-areas: 'header' 'content';\n}\n\n.aside {\n grid-area: aside;\n height: 100%;\n overflow: hidden;\n border-right: 1px solid var(--color-border);\n background: var(--color-bg-container);\n backdrop-filter: blur(18px); /* 侧栏玻璃背景,与顶栏/弹层质感统一 */\n -webkit-backdrop-filter: blur(18px);\n transition: width 0.2s ease;\n}\n.aside--mix {\n display: flex;\n}\n.aside--mix .rail {\n width: var(--rail-w);\n flex-shrink: 0;\n border-right: 1px solid var(--color-border);\n}\n.aside--mix .l2col {\n flex: 1;\n min-width: 0;\n}\n\n.header {\n grid-area: header;\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--color-border);\n background: var(--color-header-bg);\n backdrop-filter: blur(12px);\n z-index: 10;\n}\n.header--static {\n backdrop-filter: none;\n}\n.hbg {\n align-self: center;\n margin-left: 8px;\n}\n.apph {\n flex: 1;\n min-width: 0;\n height: 100%;\n}\n\n.content {\n grid-area: content;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.tabs {\n flex-shrink: 0;\n}\n.page {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--pad-page);\n}\n</style>\n"],"names":["t","useI18n","app","useAppStore","user","useUserStore","tabs","useTabsStore","site","useSite","menuOptions","l1Options","l2Options","selectedL1","activeKey","onSelect","onSelectL1","useLayoutMenu","startRealtime","stopRealtime","useRealtime","onMounted","onUnmounted","useVisualViewportHeight","isMobile","useBreakpoints","breakpointsTailwind","mobileOpen","ref","mode","computed","withSider","headerBrandModes","showSider","sideShowBrand","headerShowBrand","headerTopMenu","collapsibleSider","showCollapse","asideOptions","asideStyle","transitionName","watermarkContent","_a","watermarkColor","onMobileSelect","key","rvShow","watch","nextTick","_createElementBlock","_normalizeClass","_Fragment","_createVNode","SideNav","_unref","_vShow","_createBlock","_createElementVNode","NButton","Icon","_hoisted_1","AppHeader","_hoisted_2","_openBlock","_hoisted_3","TabsBar","_hoisted_4","ErrorBoundary","RouterView","_withCtx","Component","_Transition","_KeepAlive","_resolveDynamicComponent","NWatermark","NDrawer","$event","NDrawerContent"],"mappings":"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"}
|
package/dist/lib/icons.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","sources":["../../src/lib/icons.ts"],"sourcesContent":["// SmartAdmin 侧图标 bootstrap:把 4 套离线集 + 本地 SVG 注册进 smart-naive-icon,并同步装入 ph 子集。\n// 选择器/渲染器逻辑在该独立 npm 包里(见 components/IconPicker、components/AppIcon.vue),这里只做「注册配置」。\n// SmartAdmin 只保留三个薄封装(本文件 + AppIcon.vue + IconPicker/index.vue)。组件本体的 bug 去组件包的仓库提 issue\n// 或本地 patch,不要把组件逻辑复制进 SmartAdmin
|
|
1
|
+
{"version":3,"file":"icons.js","sources":["../../src/lib/icons.ts"],"sourcesContent":["// SmartAdmin 侧图标 bootstrap:把 4 套离线集 + 本地 SVG 注册进 smart-naive-icon,并同步装入 ph 子集。\n// 选择器/渲染器逻辑在该独立 npm 包里(见 components/IconPicker、components/AppIcon.vue),这里只做「注册配置」。\n// SmartAdmin 只保留三个薄封装(本文件 + AppIcon.vue + IconPicker/index.vue)。组件本体的 bug 去组件包的仓库提 issue\n// 或本地 patch,不要把组件逻辑复制进 SmartAdmin 修——那样同一套逻辑就有了两份。\nimport { addCollection } from '@iconify/vue'\nimport { setupSmartIcon, type IconCollection, type IconifyJSON } from 'smart-naive-icon'\nimport phSubset from '#/assets/icons/ph-subset.json'\n\n// 增删默认离线集:装/卸 `@iconify-json/<prefix>`,并在此加/删一行同 prefix 的 loader。\n// 每套是独立懒加载 chunk;`ph` 是全站默认集,整集只在选择器打开、或渲染到子集外的图标时才拉。\nconst collections: IconCollection[] = [\n {\n prefix: 'ph',\n name: 'Phosphor',\n loader: () => import('@iconify-json/ph/icons.json').then(m => m.default as IconifyJSON),\n },\n {\n prefix: 'lucide',\n name: 'Lucide',\n loader: () => import('@iconify-json/lucide/icons.json').then(m => m.default as IconifyJSON),\n },\n {\n prefix: 'ep',\n name: 'Element Plus',\n loader: () => import('@iconify-json/ep/icons.json').then(m => m.default as IconifyJSON),\n },\n {\n prefix: 'ant-design',\n name: 'Ant Design',\n loader: () => import('@iconify-json/ant-design/icons.json').then(m => m.default as IconifyJSON),\n },\n]\n\n// 包没有「不预热」的开关:preloadIcons 拿不到 prefix 就退回第一套,故给一个必不存在的前缀把预热顶掉——\n// 只同步注册这份子集:预热整套 9000+ 图标(4.5 MB / 946 KB gz)会让首屏白拉掉 dist 四成的体积。\nconst NO_PRELOAD = '__none__'\n\n// 内核自带的本地 SVG(src/assets/svg/*.svg);消费方的经 createSmartAdmin({ icons }) 以同样的 glob 形状传入。\nconst kernelIcons = import.meta.glob('../assets/svg/*.svg', {\n query: '?raw',\n import: 'default',\n eager: true,\n}) as Record<string, string>\n\n/** 首屏调用一次:同步装入 ph 子集,再注册离线集 + 本地 SVG(内核自带 + 消费方传入)。 */\nexport function setupIcons(extraIcons: Record<string, string> = {}): void {\n // 子集同步入库,首帧即可离线渲染静态图标,不必等异步预热,也不会命中外部 CDN。\n // 子集由 `npm run gen:icons` 从 src 里实际用到的名字 + 内核种子菜单的图标生成(scripts/gen-icon-subset.mjs)。\n addCollection(phSubset as IconifyJSON)\n setupSmartIcon({\n collections,\n localIcons: { ...kernelIcons, ...extraIcons },\n preloadPrefix: NO_PRELOAD,\n })\n}\n"],"names":["collections","m","NO_PRELOAD","kernelIcons","__vite_glob_0_0","setupIcons","extraIcons","addCollection","phSubset","setupSmartIcon"],"mappings":";;;;AAUA,MAAMA,IAAgC;AAAA,EACpC;AAAA,IACE,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,MAAM,OAAO,6BAA6B,EAAE,KAAK,CAAAC,MAAKA,EAAE,OAAsB;AAAA,EAAA;AAAA,EAExF;AAAA,IACE,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,MAAM,OAAO,iCAAiC,EAAE,KAAK,CAAAA,MAAKA,EAAE,OAAsB;AAAA,EAAA;AAAA,EAE5F;AAAA,IACE,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,MAAM,OAAO,6BAA6B,EAAE,KAAK,CAAAA,MAAKA,EAAE,OAAsB;AAAA,EAAA;AAAA,EAExF;AAAA,IACE,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ,MAAM,OAAO,qCAAqC,EAAE,KAAK,CAAAA,MAAKA,EAAE,OAAsB;AAAA,EAAA;AAElG,GAIMC,IAAa,YAGbC,IAAc,uBAAA,OAAA;AAAA,EAAA,0BAAAC;AAAA,CAAA;AAOb,SAASC,EAAWC,IAAqC,IAAU;AAGxE,EAAAC,EAAcC,CAAuB,GACrCC,EAAe;AAAA,IACb,aAAAT;AAAA,IACA,YAAY,EAAE,GAAGG,GAAa,GAAGG,EAAA;AAAA,IACjC,eAAeJ;AAAA,EAAA,CAChB;AACH;"}
|
package/dist/lib/markdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.js","sources":["../../src/lib/markdown.ts"],"sourcesContent":["// Markdown 渲染的全局安全 + 气隙自包含接线。\n//\n// 1) XSS:md-editor-v3 默认 `html:true`(markdown-it 原样放行内联 HTML)、`sanitize` 恒等空操作、预设插件链\n// **不含** XSS 过滤。通知作者(带权限即可,未必超管)存 `<img src=x onerror=…>`,任意查看者(含读通知的超管)\n// 打开即执行 → 偷 localStorage 里的 JWT
|
|
1
|
+
{"version":3,"file":"markdown.js","sources":["../../src/lib/markdown.ts"],"sourcesContent":["// Markdown 渲染的全局安全 + 气隙自包含接线。\n//\n// 1) XSS:md-editor-v3 默认 `html:true`(markdown-it 原样放行内联 HTML)、`sanitize` 恒等空操作、预设插件链\n// **不含** XSS 过滤。通知作者(带权限即可,未必超管)存 `<img src=x onerror=…>`,任意查看者(含读通知的超管)\n// 打开即执行 → 偷 localStorage 里的 JWT 达成账号接管。**「存纯 Markdown」不等于无 XSS 面**\n// (Markdown 天然放行 HTML),所以挂库自带 `XSSPlugin`(基于已随库打进来的 js-xss,零新依赖)。\n// 2) 气隙:md-editor-v3 挂载即从 unpkg 懒加载 highlight/katex/mermaid/prettier/echarts。前四个在组件上用\n// `no-*` 关掉;echarts 无 `no*` 旗标,只能给空 no-op instance —— 既断 CDN,又避开其默认 `parseOption` 用\n// `new Function` 对通知正文求值的隐患(通知用不到 echarts 代码块)。\nimport { config, XSSPlugin } from 'md-editor-v3'\nimport type { MarkdownItConfigPlugin } from 'md-editor-v3'\n\n/** 把 XSS 过滤插件追加到 markdown-it 预设插件链尾。抽成纯函数便于单测钉住「确实登记了」。 */\nexport function withXssPlugin(plugins: MarkdownItConfigPlugin[]): MarkdownItConfigPlugin[] {\n return [...plugins, { type: 'xss', plugin: XSSPlugin, options: {} }]\n}\n\nlet done = false\n/**\n * 幂等:全局登记 XSS 过滤 + echarts 空 instance(断 unpkg)。\n * 由 MarkdownEditor / MarkdownView 在 setup 首行调用 —— 放启动入口(createSmartAdmin)会把 md-editor-v3 拖进首屏 chunk。\n */\nexport function setupMarkdown(): void {\n if (done) return\n done = true\n config({\n markdownItPlugins: plugins => withXssPlugin(plugins),\n editorExtensions: { echarts: { instance: {} } },\n })\n}\n"],"names":["withXssPlugin","plugins","XSSPlugin","done","setupMarkdown","config"],"mappings":";AAaO,SAASA,EAAcC,GAA6D;AACzF,SAAO,CAAC,GAAGA,GAAS,EAAE,MAAM,OAAO,QAAQC,GAAW,SAAS,CAAA,GAAI;AACrE;AAEA,IAAIC,IAAO;AAKJ,SAASC,IAAsB;AACpC,EAAID,MACJA,IAAO,IACPE,EAAO;AAAA,IACL,mBAAmB,CAAAJ,MAAWD,EAAcC,CAAO;AAAA,IACnD,kBAAkB,EAAE,SAAS,EAAE,UAAU,CAAA,IAAG;AAAA,EAAE,CAC/C;AACH;"}
|
package/dist/lib/runtime.js
CHANGED
package/dist/locales/en-US.js
CHANGED
|
@@ -447,7 +447,7 @@ const e = {
|
|
|
447
447
|
passwordRequired: "Enter your current password",
|
|
448
448
|
confirm: "Verify and continue"
|
|
449
449
|
},
|
|
450
|
-
// Import wizard / export column picker
|
|
450
|
+
// Import wizard / export column picker
|
|
451
451
|
import: {
|
|
452
452
|
button: "Import",
|
|
453
453
|
wizardTitle: "Import users",
|