@fishawack/lab-velocity 2.0.0-beta.10 → 2.0.0-beta.12

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 (50) hide show
  1. package/README.md +31 -6
  2. package/_Build/vue/components/layout/Alert.vue +5 -5
  3. package/_Build/vue/{modules/AuthModule/components/VBreadcrumbs.vue → components/layout/Breadcrumbs.vue} +4 -4
  4. package/_Build/vue/{modules/AuthModule/components → components/layout}/Chips.vue +2 -2
  5. package/_Build/vue/components/layout/Footer.vue +11 -10
  6. package/_Build/vue/{modules/AuthModule/components/VFormFooter.vue → components/layout/FormFooter.vue} +2 -2
  7. package/_Build/vue/{modules/AuthModule/components → components/layout}/FormRole.vue +7 -7
  8. package/_Build/vue/components/layout/Layout.vue +74 -0
  9. package/_Build/vue/components/layout/Navigation.vue +77 -0
  10. package/_Build/vue/{modules/AuthModule/components/VPageHeader.vue → components/layout/PageHeader.vue} +7 -2
  11. package/_Build/vue/components/layout/SideBar.vue +26 -0
  12. package/_Build/vue/{modules/AuthModule/components/VTable.vue → components/layout/Table.vue} +6 -15
  13. package/_Build/vue/{modules/AuthModule/components/VTableSorter.vue → components/layout/TableSorter.vue} +15 -17
  14. package/_Build/vue/components/layout/pageTitle.vue +1 -1
  15. package/_Build/vue/components/navigation/MenuItem.vue +7 -2
  16. package/_Build/vue/components/navigation/MenuItemGroup.vue +7 -2
  17. package/_Build/vue/modules/AuthModule/js/router.js +21 -89
  18. package/_Build/vue/modules/AuthModule/js/store.js +13 -4
  19. package/_Build/vue/modules/AuthModule/{adminRoutes/PCompanies/Children/partials → routes/PCompanies}/form.vue +15 -8
  20. package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +180 -0
  21. package/_Build/vue/modules/AuthModule/{adminRoutes/PUsers/Children/partials → routes/PUsers}/form.vue +15 -8
  22. package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +214 -0
  23. package/_Build/vue/modules/AuthModule/routes/change-password.vue +9 -8
  24. package/_Build/vue/modules/AuthModule/routes/container.vue +2 -11
  25. package/_Build/vue/modules/AuthModule/routes/force-reset.vue +9 -8
  26. package/_Build/vue/modules/AuthModule/routes/register.vue +9 -8
  27. package/_Build/vue/modules/AuthModule/routes/reset.vue +9 -8
  28. package/components/_descriptions.scss +2 -0
  29. package/components/_footer.scss +1 -0
  30. package/components/_header.scss +3 -27
  31. package/components/_layout.scss +56 -0
  32. package/components/_sidebar.scss +12 -27
  33. package/index.js +7 -1
  34. package/package.json +1 -1
  35. package/_Build/vue/components/layout/sideBar.vue +0 -25
  36. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/Upload/upload.vue +0 -259
  37. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/create.vue +0 -62
  38. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/edit.vue +0 -98
  39. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/index.vue +0 -90
  40. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/show.vue +0 -267
  41. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/parent.vue +0 -36
  42. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/create.vue +0 -113
  43. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/edit.vue +0 -101
  44. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/index.vue +0 -112
  45. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/show.vue +0 -123
  46. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/parent.vue +0 -36
  47. /package/_Build/vue/{modules/AuthModule/components → components/layout}/AuthModal.vue +0 -0
  48. /package/_Build/vue/{modules/AuthModule/components → components/layout}/Chip.vue +0 -0
  49. /package/_Build/vue/{modules/AuthModule/components/VPasswordValidation.vue → components/layout/PasswordValidation.vue} +0 -0
  50. /package/_Build/vue/{modules/AuthModule/components/VRoleLegend.vue → components/layout/RoleLegend.vue} +0 -0
package/README.md CHANGED
@@ -155,6 +155,7 @@ There are two different set of sass imports for the admin and the frontend route
155
155
  @import "@fishawack/lab-ui/typography";
156
156
  @import "@fishawack/lab-ui/grid";
157
157
  @import "@fishawack/lab-ui/utilities";
158
+ @import "@fishawack/lab-ui/icon";
158
159
 
159
160
  // Lab velocity
160
161
  @import "@fishawack/lab-velocity/base";
@@ -170,6 +171,32 @@ There are two different set of sass imports for the admin and the frontend route
170
171
  @import "@fishawack/lab-velocity/components/loader";
171
172
  @import "@fishawack/lab-velocity/components/permissionLegend";
172
173
  @import "@fishawack/lab-velocity/components/chip";
174
+ @import "@fishawack/lab-velocity/components/header";
175
+ @import "@fishawack/lab-velocity/components/footer";
176
+ @import "@fishawack/lab-velocity/components/sidebar";
177
+ @import "@fishawack/lab-velocity/components/menu";
178
+ @import "@fishawack/lab-velocity/components/layout";
179
+ ```
180
+
181
+ Lastly for the admin layout & navigation import & apply the Layout component to the app.vue within your project.
182
+
183
+ ```vue
184
+ <template>
185
+ <main id="app">
186
+ <VelLayout>
187
+ <router-view />
188
+ </VelLayout>
189
+ </main>
190
+ </template>
191
+
192
+ <script>
193
+ import { Layout as VelLayout } from "@fishawack/lab-velocity";
194
+ export default {
195
+ components: {
196
+ VelLayout,
197
+ },
198
+ };
199
+ </script>
173
200
  ```
174
201
 
175
202
  ### Icons
@@ -186,11 +213,9 @@ Ensure Content has Velocity pulled in & copy out the svg folder contents into th
186
213
  ### ENV VARS (frontend)
187
214
 
188
215
  ```env
189
- # Required
190
- HYDRATE_LOGO=example-logo
191
-
192
216
  # Descriptions
193
- HYDRATE_LOGO Name of svg logo to display on page
194
- HYDRATE_REDIRECT Default index if not configured
195
- HYDRATE_CONTACT Default mailto:EP@avalerehealth, Email for contact us button
217
+ HYDRATE_LOGO Name of primary logo (default: example-logo)
218
+ HYDRATE_LOGO_REVERSE Name of the logo when color scheme is reversed (default: to HYDRATE_LOGO value if not provided)
219
+ HYDRATE_REDIRECT Name of the route name to redirect to after login (default: index)
220
+ HYDRATE_CONTACT Email for contact us button (default: mailto:det@avalerehealth.com)
196
221
  ```
@@ -11,7 +11,11 @@
11
11
  <script>
12
12
  import { ElAlert } from "element-plus";
13
13
  export default {
14
- name: "VPageTitle",
14
+ name: "Alert",
15
+
16
+ components: {
17
+ ElAlert,
18
+ },
15
19
 
16
20
  props: {
17
21
  effect: {
@@ -30,9 +34,5 @@ export default {
30
34
  default: true,
31
35
  },
32
36
  },
33
-
34
- components: {
35
- ElAlert,
36
- },
37
37
  };
38
38
  </script>
@@ -3,7 +3,7 @@
3
3
  <div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
4
4
  <div class="grid__1/1">
5
5
  <div class="flex items-center">
6
- <breadcrumbs :crumbs="items" />
6
+ <VelBreadcrumbs :crumbs="items" />
7
7
  </div>
8
8
  </div>
9
9
  </div>
@@ -11,12 +11,12 @@
11
11
  </template>
12
12
 
13
13
  <script>
14
- import Breadcrumbs from "../../../components/navigation/Breadcrumbs.vue";
14
+ import VelBreadcrumbs from "../navigation/Breadcrumbs.vue";
15
15
 
16
16
  export default {
17
- name: "VBreadcrumbs",
17
+ name: "Breadcrumbs",
18
18
  components: {
19
- Breadcrumbs,
19
+ VelBreadcrumbs,
20
20
  },
21
21
 
22
22
  props: {
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="chips">
3
3
  <template v-for="(item, index) in array" :key="item.name">
4
- <Chip
4
+ <VelChip
5
5
  class="chip--round"
6
6
  :name="item.name"
7
7
  :label="`${item.label}${index < array.length - 1 ? ',' : ''}`"
@@ -13,7 +13,7 @@
13
13
  <script>
14
14
  export default {
15
15
  components: {
16
- Chip: require("./Chip.vue").default,
16
+ VelChip: require("./Chip.vue").default,
17
17
  },
18
18
 
19
19
  props: {
@@ -8,25 +8,25 @@
8
8
  <div class="vel-footer__bottom">
9
9
  <div class="vel-footer__bottom__links">
10
10
  <p class="color-0">&copy;2025 Avalere Health.</p>
11
- <el-link
11
+ <VelLink
12
12
  underline
13
13
  class="color-0 ml"
14
14
  href="https://avalerehealth.com/privacy-policy/"
15
15
  target="_blank"
16
- >Privacy Policy</el-link
16
+ >Privacy Policy</VelLink
17
17
  >
18
- <el-link
18
+ <VelLink
19
19
  underline
20
20
  class="color-0 ml"
21
21
  href="https://avalerehealth.com/corporate-policies/"
22
22
  target="_blank"
23
- >Corporate policies and compliance</el-link
23
+ >Corporate policies and compliance</VelLink
24
24
  >
25
25
  </div>
26
26
  <div class="vel-footer__bottom__end">
27
27
  <p class="color-0">Have a question?</p>
28
- <el-link underline class="color-0 ml" :href="contact"
29
- >Contact our Support Team</el-link
28
+ <VelLink underline class="color-0 ml" :href="contact"
29
+ >Contact our Support Team</VelLink
30
30
  >
31
31
  </div>
32
32
  </div>
@@ -34,17 +34,18 @@
34
34
  </template>
35
35
 
36
36
  <script>
37
- import elLink from "../basic/link.vue";
37
+ import VelLink from "../basic/link.vue";
38
38
 
39
39
  export default {
40
+ components: {
41
+ VelLink,
42
+ },
43
+
40
44
  props: {
41
45
  contact: {
42
46
  required: true,
43
47
  type: String,
44
48
  },
45
49
  },
46
- components: {
47
- elLink,
48
- },
49
50
  };
50
51
  </script>
@@ -24,10 +24,10 @@
24
24
  </template>
25
25
 
26
26
  <script>
27
- import VelButton from "../../../components/basic/Button.vue";
27
+ import VelButton from "../basic/Button.vue";
28
28
 
29
29
  export default {
30
- name: "VFormFooter",
30
+ name: "FormFooter",
31
31
 
32
32
  components: {
33
33
  VelButton,
@@ -5,7 +5,7 @@
5
5
  <template v-if="readonly">
6
6
  <p>Roles</p>
7
7
  <div v-if="!overrides" class="my-2">
8
- <Chip
8
+ <VelChip
9
9
  class="mr mb inline-block"
10
10
  name="inherited"
11
11
  label="Inherited"
@@ -17,7 +17,7 @@
17
17
  :key="roles.find((d) => d.id === role)"
18
18
  class="mr mb inline-block"
19
19
  >
20
- <Chip
20
+ <VelChip
21
21
  :name="roles.find((d) => d.id === role)?.name"
22
22
  :label="roles.find((d) => d.id === role)?.label"
23
23
  />
@@ -49,22 +49,22 @@
49
49
  :key="index"
50
50
  class="mr mb inline-block"
51
51
  >
52
- <Chip :name="permission.name" :label="permission.label" />
52
+ <VelChip :name="permission.name" :label="permission.label" />
53
53
  </li>
54
54
  </ul>
55
55
  </template>
56
56
 
57
- <VRoleLegend class="mt-2" />
57
+ <VelRoleLegend class="mt-2" />
58
58
  </template>
59
59
 
60
60
  <script>
61
61
  import axios from "axios";
62
- import VelSelect from "../../../components/form/Select.vue";
62
+ import VelSelect from "../form/Select.vue";
63
63
 
64
64
  export default {
65
65
  components: {
66
- VRoleLegend: require("./VRoleLegend.vue").default,
67
- Chip: require("./Chip.vue").default,
66
+ VelRoleLegend: require("./RoleLegend.vue").default,
67
+ VelChip: require("./Chip.vue").default,
68
68
  VelSelect,
69
69
  },
70
70
 
@@ -0,0 +1,74 @@
1
+ <template>
2
+ <div class="vel-app">
3
+ <VelHeader class="justify-end-dive">
4
+ <GSvg
5
+ class="logo"
6
+ style="width: 180px"
7
+ embed
8
+ asis
9
+ :name="$store.state.auth.logo"
10
+ />
11
+ <template #links>
12
+ <div class="flex items-center pr">
13
+ <GIcon
14
+ class="icon fill-1 icon--0.5 mr-0.5"
15
+ name="icon-account-circle"
16
+ embed
17
+ asis
18
+ />
19
+ <span>{{ $store?.state?.auth?.user?.name }}</span>
20
+ </div>
21
+ <VelButton
22
+ class="ml"
23
+ type="primary"
24
+ tag="a"
25
+ round
26
+ :href="`${$root.spaUrl}?authenticated=1`"
27
+ >
28
+ <span v-text="`Access ${$root.appName}`" />
29
+ </VelButton>
30
+ </template>
31
+ </VelHeader>
32
+ <div class="vel-content">
33
+ <VelSideBar>
34
+ <template #navigation>
35
+ <VelNavigation v-bind="$attrs" />
36
+ </template>
37
+ <template #expand>
38
+ <GIcon
39
+ class="icon icon--0.5"
40
+ name="icon-keyboard-tab"
41
+ embed
42
+ asis
43
+ />
44
+ </template>
45
+ </VelSideBar>
46
+ <main class="vel-main">
47
+ <div class="vel-main__inner">
48
+ <slot />
49
+ </div>
50
+ <VelFooter contact="mailTo:det@avalerehealth.com">
51
+ <GSvg
52
+ class="logo fill-0"
53
+ style="width: 180px"
54
+ embed
55
+ asis
56
+ :name="$store.state.auth.logo"
57
+ />
58
+ </VelFooter>
59
+ </main>
60
+ </div>
61
+ </div>
62
+ </template>
63
+
64
+ <script>
65
+ export default {
66
+ components: {
67
+ VelHeader: require("./Header.vue").default,
68
+ VelSideBar: require("./SideBar.vue").default,
69
+ VelFooter: require("./Footer.vue").default,
70
+ VelNavigation: require("./Navigation.vue").default,
71
+ VelButton: require("../basic/Button.vue").default,
72
+ },
73
+ };
74
+ </script>
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <VMenu>
3
+ <template v-for="(link, lkey) in links" :key="lkey">
4
+ <MenuItem v-if="!link.children" :index="lkey">
5
+ <router-link :to="link.href">
6
+ <GIcon
7
+ class="icon icon--0.5"
8
+ :name="link.icon"
9
+ asis
10
+ embed
11
+ />
12
+ <span>{{ link.title }}</span>
13
+ </router-link>
14
+ </MenuItem>
15
+ <SubMenu v-else :id="lkey" :index="lkey">
16
+ <template #title>
17
+ <GIcon
18
+ class="icon icon--0.5"
19
+ :name="link.icon"
20
+ asis
21
+ embed
22
+ />
23
+ <span>{{ link.title }}</span>
24
+ </template>
25
+ <MenuItem
26
+ v-for="(child, cindex) in link.children"
27
+ :key="cindex"
28
+ :index="lkey + '-1-' + cindex"
29
+ >
30
+ <router-link :to="child.href">
31
+ <span>{{ child.title }}</span>
32
+ </router-link>
33
+ </MenuItem>
34
+ </SubMenu>
35
+ </template>
36
+ </VMenu>
37
+ </template>
38
+
39
+ <script>
40
+ export default {
41
+ name: "Navigation",
42
+
43
+ components: {
44
+ VMenu: require("../navigation/Menu.vue").default,
45
+ MenuItem: require("../navigation/MenuItem.vue").default,
46
+ SubMenu: require("../navigation/SubMenu.vue").default,
47
+ },
48
+
49
+ props: {
50
+ links: {
51
+ type: Array,
52
+ default: () => [
53
+ {
54
+ title: "Home",
55
+ href: { name: "index" },
56
+ icon: "icon-home",
57
+ },
58
+ {
59
+ title: "Companies",
60
+ href: { name: "companies.index" },
61
+ icon: "icon-cases",
62
+ },
63
+ {
64
+ title: "Users",
65
+ href: { name: "users.index" },
66
+ icon: "icon-user",
67
+ },
68
+ {
69
+ title: "Utilities",
70
+ href: { name: "index" },
71
+ icon: "icon-utility",
72
+ },
73
+ ],
74
+ },
75
+ },
76
+ };
77
+ </script>
@@ -5,7 +5,12 @@
5
5
  <div
6
6
  class="p-1.5 mr-2 border-radius border border-solid border-muted flex items-center justify-center"
7
7
  >
8
- <GIcon class="icon--3 fill-1" :name="icon" embed artboard />
8
+ <GIcon
9
+ class="fill-1 icon--0.5"
10
+ :name="icon"
11
+ embed
12
+ artboard
13
+ />
9
14
  </div>
10
15
  </span>
11
16
 
@@ -22,7 +27,7 @@
22
27
 
23
28
  <script>
24
29
  export default {
25
- name: "VShowPageHeader",
30
+ name: "PageHeader",
26
31
 
27
32
  props: {
28
33
  icon: {
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <div class="vel-sidebar" :class="{ active: active }">
3
+ <div class="vel-sidebar__inner">
4
+ <div class="vel-sidebar__top">
5
+ <slot name="navigation" />
6
+ </div>
7
+ <div class="vel-sidebar__bottom">
8
+ <button class="vel-sidebar__button" @click="active = !active">
9
+ <slot name="expand"> > </slot>
10
+ </button>
11
+ </div>
12
+ </div>
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ export default {
18
+ name: "SideBar",
19
+
20
+ data() {
21
+ return {
22
+ active: true,
23
+ };
24
+ },
25
+ };
26
+ </script>
@@ -13,25 +13,16 @@
13
13
  <el-table-column
14
14
  :width="item.width ?? 'auto'"
15
15
  :sortable="!!item.sortable ? 'custom' : false"
16
- :label="item.label"
16
+ :label="
17
+ item.label ||
18
+ item.key[0].toUpperCase() + item.key.slice(1)
19
+ "
17
20
  :prop="item.key"
18
21
  :show-overflow-tooltip="true"
19
22
  >
20
23
  <!-- Support a custom render function -->
21
24
  <template v-if="item.render" #default="scope">
22
- {{ item.render(scope.row) }}
23
- </template>
24
-
25
- <!-- Support module passed (as a raw component or :is property) -->
26
- <template v-else-if="item.component" #default="scope">
27
- <component
28
- :is="
29
- item.component.is
30
- ? item.component.is(scope.row)
31
- : item.component.module(scope.row)
32
- "
33
- v-bind="item.component.props(scope.row)"
34
- />
25
+ <component :is="item.render(scope.row, this)" />
35
26
  </template>
36
27
  </el-table-column>
37
28
  </template>
@@ -68,7 +59,7 @@
68
59
 
69
60
  <script>
70
61
  import { ElTable, ElTableColumn } from "element-plus";
71
- import VelButton from "../../../components/basic/Button.vue";
62
+ import VelButton from "../basic/Button.vue";
72
63
 
73
64
  export default {
74
65
  name: "VTable",
@@ -25,7 +25,11 @@
25
25
  @update:model-value="handleSearch"
26
26
  >
27
27
  <template #prepend
28
- ><GIcon embed asis name="icon-search"
28
+ ><GIcon
29
+ embed
30
+ asis
31
+ name="icon-search"
32
+ class="icon--0.5"
29
33
  /></template>
30
34
  </VelBasic>
31
35
  <slot v-if="displayActions" name="table-action">
@@ -45,7 +49,7 @@
45
49
  name="icon-plus"
46
50
  embed
47
51
  asis
48
- class="fill-0 mr-0.5"
52
+ class="fill-0 icon--0.5 mr-0.5"
49
53
  />
50
54
  Create new {{ jsonData.label }}
51
55
  </VelButton>
@@ -54,7 +58,7 @@
54
58
  </slot>
55
59
  </div>
56
60
  <div class="bg-0 p-0.5 box-shadow-1 border-r-4">
57
- <VTable
61
+ <VelTable
58
62
  :data="table_data"
59
63
  :structure="jsonData.tableStructure"
60
64
  :label="jsonData.label"
@@ -78,7 +82,7 @@
78
82
  @sort="handleSort"
79
83
  >
80
84
  <slot name="table-content"></slot>
81
- </VTable>
85
+ </VelTable>
82
86
 
83
87
  <div class="flex justify-center items-center py-2">
84
88
  <el-pagination
@@ -100,15 +104,15 @@
100
104
  <script>
101
105
  import axios from "axios";
102
106
  import { ElPagination } from "element-plus";
103
- import VelButton from "../../../components/basic/Button.vue";
104
- import VelBasic from "../../../components/form/basic.vue";
105
- import VelSpinner from "../../../components/form/Spinner.vue";
107
+ import VelButton from "../basic/Button.vue";
108
+ import VelBasic from "../form/basic.vue";
109
+ import VelSpinner from "../form/Spinner.vue";
106
110
 
107
111
  export default {
108
- name: "VTableSorter",
112
+ name: "TableSorter",
109
113
 
110
114
  components: {
111
- VTable: require("./VTable.vue").default,
115
+ VelTable: require("./Table.vue").default,
112
116
  VelButton,
113
117
  VelBasic,
114
118
  ElPagination,
@@ -124,10 +128,6 @@ export default {
124
128
  default: true,
125
129
  type: Boolean,
126
130
  },
127
- api: {
128
- required: true,
129
- type: String,
130
- },
131
131
  defaults: {
132
132
  required: false,
133
133
  type: String,
@@ -205,10 +205,8 @@ export default {
205
205
  const query = mergedQuery.join("&");
206
206
 
207
207
  return axios
208
- .get(`/api/${this.$props.api}${query ? "?" + query : ""}`)
209
- .then((res) => {
210
- return res.data;
211
- })
208
+ .get(`${this.$props.jsonData.api}${query ? "?" + query : ""}`)
209
+ .then((res) => res.data)
212
210
  .catch(console.log);
213
211
  },
214
212
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  <script>
8
8
  export default {
9
- name: "VPageTitle",
9
+ name: "PageTitle",
10
10
 
11
11
  props: {
12
12
  title: {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <el-menu-item :index="index" class="vel-menu-item" v-bind="$props">
2
+ <el-menu-item class="vel-menu-item" v-bind="$props" :index="`${index}`">
3
3
  <template #title>
4
4
  <slot name="title" />
5
5
  </template>
@@ -15,6 +15,11 @@ export default {
15
15
  components: {
16
16
  ElMenuItem,
17
17
  },
18
- props: ["index"],
18
+ props: {
19
+ index: {
20
+ type: [String, Number],
21
+ required: true,
22
+ },
23
+ },
19
24
  };
20
25
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <el-sub-menu :index="index" v-bind="$props">
2
+ <el-sub-menu v-bind="$props" :index="`${index}`">
3
3
  <template #title>
4
4
  <slot name="title" />
5
5
  </template>
@@ -15,6 +15,11 @@ export default {
15
15
  components: {
16
16
  ElSubMenu,
17
17
  },
18
- props: ["index"],
18
+ props: {
19
+ index: {
20
+ type: [String, Number],
21
+ required: true,
22
+ },
23
+ },
19
24
  };
20
25
  </script>