diff --git a/code/fms/fms-vue/package.json b/code/fms/fms-vue/package.json index f2200374..8fc56f81 100644 --- a/code/fms/fms-vue/package.json +++ b/code/fms/fms-vue/package.json @@ -20,6 +20,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "embla-carousel-vue": "^8.6.0", + "nprogress": "^0.2.0", "pinia": "^4.0.2", "reka-ui": "^2.10.1", "tailwind-merge": "^3.6.0", diff --git a/code/fms/fms-vue/pnpm-lock.yaml b/code/fms/fms-vue/pnpm-lock.yaml index 7f398731..012cf6b5 100644 --- a/code/fms/fms-vue/pnpm-lock.yaml +++ b/code/fms/fms-vue/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: embla-carousel-vue: specifier: ^8.6.0 version: 8.6.0(vue@3.5.41(typescript@6.0.3)) + nprogress: + specifier: ^0.2.0 + version: 0.2.0 pinia: specifier: ^4.0.2 version: 4.0.2(@vue/devtools-api@8.2.1)(typescript@6.0.3)(vue@3.5.41(typescript@6.0.3)) @@ -152,8 +155,12 @@ packages: '@internationalized/number@3.6.7': resolution: {integrity: sha512-3ji1fcrT+FPAK86UqEhB/psHixYo6niWPJtt7+qRaYFynt/BaJG8GhAPimtWUpEiVSTq8ZM8L5psMxGquiB/Vg==} - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.12': + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} '@jridgewell/remapping@2.3.5': resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} @@ -162,6 +169,19 @@ packages: resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.10': + resolution: {integrity: sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==} + + '@jridgewell/sourcemap-codec@1.4.14': + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} @@ -703,8 +723,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + agent-base@6.0.0: + resolution: {integrity: sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==} engines: {node: '>= 6.0.0'} alien-signals@3.2.1: @@ -714,6 +734,10 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} + ast-kit@2.1.2: + resolution: {integrity: sha512-cl76xfBQM6pztbrFWRnxbrDm9EOqDr1BF6+qQnnDZG2Co2LjyUktkN9GTJfBAfdae+DbT2nJf2nCGAdDDN7W2g==} + engines: {node: '>=20.18.0'} + ast-kit@2.2.0: resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} engines: {node: '>=20.19.0'} @@ -728,8 +752,11 @@ packages: axios@1.19.0: resolution: {integrity: sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==} - birpc@2.9.0: - resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + birpc@2.3.0: + resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==} + + birpc@2.6.1: + resolution: {integrity: sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==} call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} @@ -1075,9 +1102,9 @@ packages: resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} engines: {node: '>=14'} - magic-string-ast@1.0.3: - resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} - engines: {node: '>=20.19.0'} + magic-string-ast@1.0.2: + resolution: {integrity: sha512-8ngQgLhcT0t3YBdn9CGkZqCYlvwW9pm7aWJwd7AxseVWf1RU8ZHCQvG1mt3N5vvUme+pXTcHB8G/7fE666U8Vw==} + engines: {node: '>=20.18.0'} magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -1111,12 +1138,15 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-addon-api@7.0.0: + resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} nostics@1.2.0: resolution: {integrity: sha512-FGqEfhQjrvo1lL8KFifdTQiNwwQHJxC1jtYE1Rc54qF/jxONUNL+kC9gS1krX8Q65PgrQ5fCqH/I4NhWBvdSqg==} + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} @@ -1254,8 +1284,8 @@ packages: tw-animate-css@1.4.0: resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + type-fest@4.8.3: + resolution: {integrity: sha512-//BaTm14Q/gHBn09xlnKNqfI8t6bmdzx2DXYfPBNofN0WUybCEUDcbCWcTa0oF09lzLjZgPphXAsvRiMK0V6Bw==} engines: {node: '>=16'} typescript@6.0.3: @@ -1436,7 +1466,7 @@ snapshots: dependencies: '@babel/parser': 8.0.4 '@babel/types': 8.0.4 - '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.31 '@types/jsesc': 2.5.1 jsesc: 3.1.0 @@ -1495,24 +1525,38 @@ snapshots: dependencies: '@swc/helpers': 0.5.23 - '@jridgewell/gen-mapping@0.3.13': + '@jridgewell/gen-mapping@0.3.12': dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.10 '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: - '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.10': {} + + '@jridgewell/sourcemap-codec@1.4.14': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.4.14 '@lucide/vue@1.30.0(vue@3.5.41(typescript@6.0.3))': dependencies: @@ -1617,7 +1661,7 @@ snapshots: dependencies: detect-libc: 2.1.2 is-glob: 4.0.3 - node-addon-api: 7.1.1 + node-addon-api: 7.0.0 picomatch: 4.0.5 optionalDependencies: '@parcel/watcher-android-arm64': 2.6.0 @@ -1767,7 +1811,7 @@ snapshots: '@vee-validate/zod@4.15.1(vue@3.5.41(typescript@6.0.3))(zod@3.25.76)': dependencies: - type-fest: 4.41.0 + type-fest: 4.8.3 vee-validate: 4.15.1(vue@3.5.41(typescript@6.0.3)) zod: 3.25.76 transitivePeerDependencies: @@ -1794,9 +1838,9 @@ snapshots: '@vue-macros/common@3.1.4(vue@3.5.41(typescript@6.0.3))': dependencies: '@vue/compiler-sfc': 3.5.41 - ast-kit: 2.2.0 + ast-kit: 2.1.2 local-pkg: 1.2.1 - magic-string-ast: 1.0.3 + magic-string-ast: 1.0.2 unplugin-utils: 0.3.2 optionalDependencies: vue: 3.5.41(typescript@6.0.3) @@ -1842,7 +1886,7 @@ snapshots: '@vue/devtools-kit@7.7.10': dependencies: '@vue/devtools-shared': 7.7.10 - birpc: 2.9.0 + birpc: 2.3.0 hookable: 5.5.3 mitt: 3.0.1 perfect-debounce: 1.0.0 @@ -1852,7 +1896,7 @@ snapshots: '@vue/devtools-kit@8.2.1': dependencies: '@vue/devtools-shared': 8.2.1 - birpc: 2.9.0 + birpc: 2.6.1 hookable: 5.5.3 perfect-debounce: 2.1.0 @@ -1933,7 +1977,7 @@ snapshots: acorn@8.18.0: {} - agent-base@6.0.2: + agent-base@6.0.0: dependencies: debug: 4.4.3 transitivePeerDependencies: @@ -1945,6 +1989,11 @@ snapshots: dependencies: tslib: 2.8.1 + ast-kit@2.1.2: + dependencies: + '@babel/parser': 7.29.8 + pathe: 2.0.3 + ast-kit@2.2.0: dependencies: '@babel/parser': 7.29.8 @@ -1968,7 +2017,9 @@ snapshots: - debug - supports-color - birpc@2.9.0: {} + birpc@2.3.0: {} + + birpc@2.6.1: {} call-bind-apply-helpers@1.0.2: dependencies: @@ -2108,7 +2159,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: - agent-base: 6.0.2 + agent-base: 6.0.0 debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -2235,7 +2286,7 @@ snapshots: pkg-types: 2.3.1 quansync: 0.2.11 - magic-string-ast@1.0.3: + magic-string-ast@1.0.2: dependencies: magic-string: 0.30.21 @@ -2266,11 +2317,13 @@ snapshots: nanoid@3.3.18: {} - node-addon-api@7.1.1: + node-addon-api@7.0.0: optional: true nostics@1.2.0: {} + nprogress@0.2.0: {} + ohash@2.0.11: {} oxfmt@0.58.0: @@ -2420,7 +2473,7 @@ snapshots: tw-animate-css@1.4.0: {} - type-fest@4.41.0: {} + type-fest@4.8.3: {} typescript@6.0.3: {} @@ -2445,7 +2498,7 @@ snapshots: vee-validate@4.15.1(vue@3.5.41(typescript@6.0.3)): dependencies: '@vue/devtools-api': 7.7.10 - type-fest: 4.41.0 + type-fest: 4.8.3 vue: 3.5.41(typescript@6.0.3) vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(sass@1.102.0)(yaml@2.9.0): diff --git a/code/fms/fms-vue/src/App.vue b/code/fms/fms-vue/src/App.vue index c0482986..be8ca044 100644 --- a/code/fms/fms-vue/src/App.vue +++ b/code/fms/fms-vue/src/App.vue @@ -1,6 +1,8 @@ diff --git a/code/fms/fms-vue/src/components/FmsAutoComplete.vue b/code/fms/fms-vue/src/components/FmsAutoComplete.vue new file mode 100644 index 00000000..6909dc35 --- /dev/null +++ b/code/fms/fms-vue/src/components/FmsAutoComplete.vue @@ -0,0 +1,224 @@ + + + diff --git a/code/fms/fms-vue/src/components/FmsSelect.vue b/code/fms/fms-vue/src/components/FmsSelect.vue new file mode 100644 index 00000000..d28214c5 --- /dev/null +++ b/code/fms/fms-vue/src/components/FmsSelect.vue @@ -0,0 +1,251 @@ + + + diff --git a/code/fms/fms-vue/src/components/new-york-v4/blocks/login-02/components/LoginForm.vue b/code/fms/fms-vue/src/components/new-york-v4/blocks/login-02/components/LoginForm.vue deleted file mode 100644 index 4eb246d2..00000000 --- a/code/fms/fms-vue/src/components/new-york-v4/blocks/login-02/components/LoginForm.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - diff --git a/code/fms/fms-vue/src/components/new-york-v4/blocks/login-05/components/LoginForm.vue b/code/fms/fms-vue/src/components/new-york-v4/blocks/login-05/components/LoginForm.vue deleted file mode 100644 index fb25284d..00000000 --- a/code/fms/fms-vue/src/components/new-york-v4/blocks/login-05/components/LoginForm.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - diff --git a/code/fms/fms-vue/src/components/ui/form/Form.vue b/code/fms/fms-vue/src/components/ui/form/Form.vue new file mode 100644 index 00000000..72405c0a --- /dev/null +++ b/code/fms/fms-vue/src/components/ui/form/Form.vue @@ -0,0 +1,32 @@ + + + diff --git a/code/fms/fms-vue/src/components/ui/form/FormField.vue b/code/fms/fms-vue/src/components/ui/form/FormField.vue new file mode 100644 index 00000000..84846b8c --- /dev/null +++ b/code/fms/fms-vue/src/components/ui/form/FormField.vue @@ -0,0 +1,9 @@ + + + diff --git a/code/fms/fms-vue/src/components/ui/form/index.ts b/code/fms/fms-vue/src/components/ui/form/index.ts index 1eb05f11..8587eb5f 100644 --- a/code/fms/fms-vue/src/components/ui/form/index.ts +++ b/code/fms/fms-vue/src/components/ui/form/index.ts @@ -1,7 +1,8 @@ +export { default as Form } from "./Form.vue" +export { default as FormField } from "./FormField.vue" export { default as FormControl } from "./FormControl.vue" export { default as FormDescription } from "./FormDescription.vue" export { default as FormItem } from "./FormItem.vue" export { default as FormLabel } from "./FormLabel.vue" export { default as FormMessage } from "./FormMessage.vue" export { FORM_ITEM_INJECTION_KEY } from "./injectionKeys" -export { Form, Field as FormField, FieldArray as FormFieldArray } from "vee-validate" diff --git a/code/fms/fms-vue/src/composables/useLookupOptions.ts b/code/fms/fms-vue/src/composables/useLookupOptions.ts new file mode 100644 index 00000000..12720a06 --- /dev/null +++ b/code/fms/fms-vue/src/composables/useLookupOptions.ts @@ -0,0 +1,174 @@ +import { ref, watch } from "vue"; +import { useDebounceFn } from "@vueuse/core"; +import { pageDataApi } from "@/services/api"; + +export interface LookupOptionsConfig { + /** 后端表名/视图名(必填) */ + viewName: string; + /** 显示文本字段名,默认 "b_name" */ + labelKey?: string; + /** 取值字段名,默认 "b_id" */ + valueKey?: string; + /** 额外的固定查询条件 */ + searchCondition?: string; + /** 排序规则 */ + orderBy?: string; + /** 需要返回的字段列表 */ + searchColumns?: string[]; + /** 每页加载数量,默认 20 */ + pageSize?: number; + /** 搜索防抖延迟(ms),默认 300 */ + searchDelay?: number; +} + +export function useLookupOptions(config: LookupOptionsConfig) { + const { + viewName, + labelKey = "b_name", + valueKey = "b_id", + searchCondition = "", + orderBy = "", + searchColumns = [], + pageSize = 20, + searchDelay = 300, + } = config; + + const rows = ref[]>([]); + const loading = ref(false); + const total = ref(0); + const keyword = ref(""); + // Keep the unfiltered first page available while a later open is refreshing. + const defaultRows = ref[]>([]); + const defaultTotal = ref(0); + + let requestVersion = 0; + let currentPage = 1; + + function buildSearchCondition() { + const k = keyword.value.trim(); + if (!k) return searchCondition; + const escaped = k.replaceAll("'", "''"); + const like = `${labelKey} LIKE '%${escaped}%'`; + return searchCondition ? `${searchCondition} AND ${like}` : like; + } + + async function load(reset = false, preserveRows = false) { + if (reset) { + currentPage = 1; + if (!preserveRows) { + rows.value = []; + total.value = 0; + } + } + + const version = ++requestVersion; + loading.value = true; + const requestedKeyword = keyword.value.trim(); + + try { + const condition = buildSearchCondition(); + const result = await pageDataApi({ + viewName, + orderBy: orderBy || `${labelKey} ASC`, + searchColumns, + searchCondition: condition, + pageNo: currentPage, + pageSize, + }); + + if (version !== requestVersion) return; + + const data = result.data; + if (reset) { + rows.value = data.rows; + } else { + rows.value.push(...data.rows); + } + total.value = data.total; + + if (!requestedKeyword) { + defaultRows.value = [...rows.value]; + defaultTotal.value = total.value; + } + } finally { + if (version === requestVersion) { + loading.value = false; + } + } + } + + /** + * 搜索:防抖后重置并加载首页 + */ + const search = useDebounceFn((q: string) => { + keyword.value = q; + load(true); + }, searchDelay); + + /** + * 立即搜索(focus/打开时使用,不防抖) + */ + function immediate(q: string) { + keyword.value = q; + if (!q && defaultRows.value.length) { + rows.value = [...defaultRows.value]; + total.value = defaultTotal.value; + load(true, true); + return; + } + load(true); + } + + /** + * 打开下拉:若尚无数据则首页加载 + */ + function open() { + if (!rows.value.length) { + load(true); + } + } + + /** + * 滚动触底时加载下一页 + */ + function loadMore() { + if (loading.value) return; + if (rows.value.length >= total.value) return; + currentPage++; + load(false); + } + + /** + * 重置:清空数据、关键词、分页 + */ + function reset(clearCache = false) { + requestVersion++; + rows.value = []; + total.value = 0; + keyword.value = ""; + currentPage = 1; + loading.value = false; + if (clearCache) { + defaultRows.value = []; + defaultTotal.value = 0; + } + } + + // 关键 props 变化时自动重置 + watch( + () => [viewName, labelKey, valueKey, orderBy, searchCondition, searchColumns], + () => reset(true), + ); + + return { + rows, + loading, + total, + keyword, + search, + immediate, + open, + loadMore, + reset, + }; +} diff --git a/code/fms/fms-vue/src/layouts/DefaultLayout.vue b/code/fms/fms-vue/src/layouts/DefaultLayout.vue index 774cbaba..e68f753f 100644 --- a/code/fms/fms-vue/src/layouts/DefaultLayout.vue +++ b/code/fms/fms-vue/src/layouts/DefaultLayout.vue @@ -1,5 +1,5 @@ \ No newline at end of file + diff --git a/code/fms/fms-vue/src/layouts/components/AppSidebar.vue b/code/fms/fms-vue/src/layouts/components/AppSidebar.vue index c0599366..9b6a5266 100644 --- a/code/fms/fms-vue/src/layouts/components/AppSidebar.vue +++ b/code/fms/fms-vue/src/layouts/components/AppSidebar.vue @@ -1,11 +1,15 @@