@fishawack/lab-velocity 2.0.0-beta.6 → 2.0.0-beta.60

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 (111) hide show
  1. package/README.md +467 -36
  2. package/_Build/js/libs/build-id.js +14 -0
  3. package/_Build/js/libs/filters.js +36 -0
  4. package/_Build/js/libs/globals.js +7 -0
  5. package/_Build/js/libs/router.js +22 -0
  6. package/_Build/js/libs/routes.js +29 -0
  7. package/_Build/js/libs/store.js +21 -0
  8. package/_Build/js/libs/utility.js +161 -0
  9. package/_Build/vue/components/basic/Button.vue +1 -1
  10. package/_Build/vue/components/form/Avatar.vue +90 -0
  11. package/_Build/vue/components/form/Checkbox.vue +10 -0
  12. package/_Build/vue/components/form/InputNumber.vue +1 -1
  13. package/_Build/vue/components/form/Select.vue +221 -31
  14. package/_Build/vue/components/form/Wysiwyg2.vue +87 -2
  15. package/_Build/vue/components/form/wysiwyg2-video.js +41 -0
  16. package/_Build/vue/components/layout/Alert.vue +5 -5
  17. package/_Build/vue/components/layout/Audit.vue +158 -0
  18. package/_Build/vue/{modules/AuthModule/components/VBreadcrumbs.vue → components/layout/Breadcrumbs.vue} +4 -4
  19. package/_Build/vue/{modules/AuthModule/components → components/layout}/Chips.vue +2 -2
  20. package/_Build/vue/components/layout/Footer.vue +11 -10
  21. package/_Build/vue/{modules/AuthModule/components/VFormFooter.vue → components/layout/FormFooter.vue} +2 -2
  22. package/_Build/vue/{modules/AuthModule/components → components/layout}/FormRole.vue +8 -8
  23. package/_Build/vue/components/layout/Layout.vue +94 -0
  24. package/_Build/vue/components/layout/Navigation.vue +83 -0
  25. package/_Build/vue/{modules/AuthModule/components/VPageHeader.vue → components/layout/PageHeader.vue} +14 -8
  26. package/_Build/vue/components/layout/SideBar.vue +26 -0
  27. package/_Build/vue/{modules/AuthModule/components/VTable.vue → components/layout/Table.vue} +24 -12
  28. package/_Build/vue/{modules/AuthModule/components/VTableSorter.vue → components/layout/TableSorter.vue} +92 -48
  29. package/_Build/vue/components/layout/TokenDisplay.vue +52 -0
  30. package/_Build/vue/components/layout/pageTitle.vue +1 -1
  31. package/_Build/vue/components/navigation/Menu.vue +6 -1
  32. package/_Build/vue/components/navigation/MenuItem.vue +7 -2
  33. package/_Build/vue/components/navigation/MenuItemGroup.vue +7 -2
  34. package/_Build/vue/modules/AuthModule/js/axios.js +21 -1
  35. package/_Build/vue/modules/AuthModule/js/clear-cookies.js +34 -0
  36. package/_Build/vue/modules/AuthModule/js/guest-request.js +32 -0
  37. package/_Build/vue/modules/AuthModule/js/impersonation-banner.js +102 -0
  38. package/_Build/vue/modules/AuthModule/js/router.js +91 -114
  39. package/_Build/vue/modules/AuthModule/js/store.js +23 -6
  40. package/_Build/vue/modules/AuthModule/routes/PCompanies/columns.js +268 -0
  41. package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +213 -0
  42. package/_Build/vue/modules/AuthModule/routes/PIntegrations/columns.js +58 -0
  43. package/_Build/vue/modules/AuthModule/routes/PIntegrations/resource.js +79 -0
  44. package/_Build/vue/modules/AuthModule/routes/PTeams/columns.js +78 -0
  45. package/_Build/vue/modules/AuthModule/routes/PTeams/resource.js +251 -0
  46. package/_Build/vue/modules/AuthModule/routes/PUsers/SetPasswordAction.vue +51 -0
  47. package/_Build/vue/modules/AuthModule/routes/PUsers/SetPasswordDialog.vue +138 -0
  48. package/_Build/vue/modules/AuthModule/routes/PUsers/columns.js +349 -0
  49. package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +239 -0
  50. package/_Build/vue/modules/AuthModule/routes/account-exists.vue +2 -2
  51. package/_Build/vue/modules/AuthModule/routes/change-password.vue +28 -32
  52. package/_Build/vue/modules/AuthModule/routes/container.vue +2 -11
  53. package/_Build/vue/modules/AuthModule/routes/expired-reset.vue +4 -4
  54. package/_Build/vue/modules/AuthModule/routes/expired-verification.vue +10 -9
  55. package/_Build/vue/modules/AuthModule/routes/force-reset.vue +44 -58
  56. package/_Build/vue/modules/AuthModule/routes/forgot.vue +10 -5
  57. package/_Build/vue/modules/AuthModule/routes/login.vue +12 -19
  58. package/_Build/vue/modules/AuthModule/routes/logincallback.vue +1 -3
  59. package/_Build/vue/modules/AuthModule/routes/loginsso.vue +14 -10
  60. package/_Build/vue/modules/AuthModule/routes/logout.vue +14 -5
  61. package/_Build/vue/modules/AuthModule/routes/logoutheadless.vue +16 -5
  62. package/_Build/vue/modules/AuthModule/routes/register.vue +24 -28
  63. package/_Build/vue/modules/AuthModule/routes/reset.vue +20 -14
  64. package/_Build/vue/modules/AuthModule/routes/success-forgot.vue +14 -8
  65. package/_Build/vue/modules/AuthModule/routes/success-reset.vue +2 -2
  66. package/_Build/vue/modules/AuthModule/routes/success-verify.vue +1 -3
  67. package/_Build/vue/modules/AuthModule/routes/verify.vue +11 -14
  68. package/_Build/vue/modules/resource/Children/create.vue +99 -0
  69. package/_Build/vue/modules/resource/Children/edit.vue +124 -0
  70. package/_Build/vue/modules/resource/Children/index.vue +42 -0
  71. package/_Build/vue/modules/resource/Children/partials/form.vue +111 -0
  72. package/_Build/vue/modules/resource/Children/show.vue +170 -0
  73. package/_Build/vue/modules/resource/index.js +562 -0
  74. package/_Build/vue/modules/resource/parent.vue +63 -0
  75. package/_Build/vue/modules/resource/trashable.js +104 -0
  76. package/_base.scss +0 -1
  77. package/_defaults.scss +2 -2
  78. package/components/_auth.scss +19 -61
  79. package/components/_datepicker.scss +1 -0
  80. package/components/_descriptions.scss +2 -0
  81. package/components/_footer.scss +1 -0
  82. package/components/_form.scss +18 -0
  83. package/components/_header.scss +3 -27
  84. package/components/_layout.scss +56 -0
  85. package/components/_menu.scss +0 -5
  86. package/components/_sidebar.scss +12 -27
  87. package/components/_table.scss +3 -0
  88. package/components/_token-display.scss +41 -0
  89. package/components/_wysiwyg2.scss +10 -0
  90. package/general.scss +1 -0
  91. package/index.js +31 -1
  92. package/package.json +7 -4
  93. package/_Build/vue/components/layout/sideBar.vue +0 -25
  94. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/Upload/upload.vue +0 -259
  95. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/create.vue +0 -62
  96. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/edit.vue +0 -98
  97. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/index.vue +0 -90
  98. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/partials/form.vue +0 -181
  99. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/show.vue +0 -266
  100. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/parent.vue +0 -36
  101. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/create.vue +0 -112
  102. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/edit.vue +0 -103
  103. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/index.vue +0 -112
  104. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/partials/form.vue +0 -173
  105. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/show.vue +0 -123
  106. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/parent.vue +0 -36
  107. package/components/_input.scss +0 -0
  108. /package/_Build/vue/{modules/AuthModule/components → components/layout}/AuthModal.vue +0 -0
  109. /package/_Build/vue/{modules/AuthModule/components → components/layout}/Chip.vue +0 -0
  110. /package/_Build/vue/{modules/AuthModule/components/VPasswordValidation.vue → components/layout/PasswordValidation.vue} +0 -0
  111. /package/_Build/vue/{modules/AuthModule/components/VRoleLegend.vue → components/layout/RoleLegend.vue} +0 -0
@@ -417,6 +417,42 @@
417
417
  ></path>
418
418
  </svg>
419
419
  </button>
420
+ <button
421
+ v-if="media"
422
+ type="button"
423
+ @click="openMediaDialog('image')"
424
+ >
425
+ <svg viewBox="0 0 18 18">
426
+ <rect
427
+ class="ql-stroke"
428
+ height="10"
429
+ width="12"
430
+ x="3"
431
+ y="4"
432
+ ></rect>
433
+ <circle class="ql-fill" cx="6" cy="7" r="1"></circle>
434
+ <polyline
435
+ class="ql-even ql-stroke"
436
+ points="5 12 5 11 7 9 8 10 11 7 13 9 13 12 5 12"
437
+ ></polyline>
438
+ </svg>
439
+ </button>
440
+ <button
441
+ v-if="media"
442
+ type="button"
443
+ @click="openMediaDialog('video')"
444
+ >
445
+ <svg viewBox="0 0 18 18">
446
+ <rect
447
+ class="ql-stroke"
448
+ height="12"
449
+ width="12"
450
+ x="3"
451
+ y="3"
452
+ ></rect>
453
+ <path class="ql-fill" d="M7,7v4l4-2Z"></path>
454
+ </svg>
455
+ </button>
420
456
  </div>
421
457
  <editor-content :editor="editor" />
422
458
  <el-dialog v-model="dialogVisible" title="URL" width="500">
@@ -431,6 +467,27 @@
431
467
  </div>
432
468
  </template>
433
469
  </el-dialog>
470
+ <el-dialog
471
+ v-model="mediaDialogVisible"
472
+ :title="mediaType === 'image' ? 'Insert Image' : 'Insert Video'"
473
+ width="500"
474
+ >
475
+ <label
476
+ >Enter
477
+ {{ mediaType === "image" ? "image" : "video" }} URL</label
478
+ >
479
+ <el-input v-model="mediaUrl" type="url" placeholder="https://" />
480
+ <template #footer>
481
+ <div class="dialog-footer">
482
+ <el-button @click="mediaDialogVisible = false"
483
+ >Cancel</el-button
484
+ >
485
+ <el-button type="primary" @click="insertMedia">
486
+ Insert
487
+ </el-button>
488
+ </div>
489
+ </template>
490
+ </el-dialog>
434
491
  </XInput>
435
492
  </template>
436
493
 
@@ -456,6 +513,8 @@ import TableRow from "@tiptap/extension-table-row";
456
513
  import Superscript from "@tiptap/extension-superscript";
457
514
  import Subscript from "@tiptap/extension-subscript";
458
515
  import Link from "@tiptap/extension-link";
516
+ import Image from "@tiptap/extension-image";
517
+ import Video from "./wysiwyg2-video.js";
459
518
 
460
519
  export default {
461
520
  mixins: [input],
@@ -476,6 +535,10 @@ export default {
476
535
  type: Boolean,
477
536
  default: false,
478
537
  },
538
+ media: {
539
+ type: Boolean,
540
+ default: false,
541
+ },
479
542
  baseClass: {
480
543
  type: String,
481
544
  default: "vel-wysiwyg",
@@ -488,6 +551,9 @@ export default {
488
551
  previousUrl: null,
489
552
  newUrl: null,
490
553
  dialogVisible: false,
554
+ mediaDialogVisible: false,
555
+ mediaUrl: null,
556
+ mediaType: null,
491
557
  }),
492
558
 
493
559
  watch: {
@@ -536,6 +602,22 @@ export default {
536
602
  .setLink({ href: url })
537
603
  .run();
538
604
  },
605
+ openMediaDialog(type) {
606
+ this.mediaType = type;
607
+ this.mediaUrl = null;
608
+ this.mediaDialogVisible = true;
609
+ },
610
+ insertMedia() {
611
+ this.mediaDialogVisible = false;
612
+ let url = this.mediaUrl;
613
+ if (!url) return;
614
+
615
+ if (this.mediaType === "image") {
616
+ this.editor.chain().focus().setImage({ src: url }).run();
617
+ } else {
618
+ this.editor.chain().focus().setVideo({ src: url }).run();
619
+ }
620
+ },
539
621
  },
540
622
 
541
623
  mounted() {
@@ -559,14 +641,17 @@ export default {
559
641
  TableCell,
560
642
  );
561
643
  }
644
+ if (this.$props.media) {
645
+ extensions.push(Image, Video);
646
+ }
562
647
 
563
648
  this.editor = new Editor({
564
649
  extensions: extensions,
565
650
  });
566
651
  this.setValue();
567
652
 
568
- this.editor.on("blur", ({ editor, event }) => {
569
- const value = editor.isEmpty ? "" : event.srcElement.innerHTML;
653
+ this.editor.on("update", ({ editor }) => {
654
+ const value = editor.isEmpty ? "" : editor.getHTML();
570
655
  if (this.hold !== value) {
571
656
  this.hold = value;
572
657
  this.$emit("update:modelValue", this.hold);
@@ -0,0 +1,41 @@
1
+ import { Node, mergeAttributes } from "@tiptap/core";
2
+
3
+ export default Node.create({
4
+ name: "video",
5
+ group: "block",
6
+ atom: true,
7
+
8
+ addAttributes() {
9
+ return {
10
+ src: { default: null },
11
+ controls: { default: true },
12
+ width: { default: "100%" },
13
+ };
14
+ },
15
+
16
+ parseHTML() {
17
+ return [{ tag: "video" }];
18
+ },
19
+
20
+ renderHTML({ HTMLAttributes }) {
21
+ return [
22
+ "video",
23
+ mergeAttributes(HTMLAttributes, {
24
+ controls: HTMLAttributes.controls ? "" : null,
25
+ }),
26
+ ];
27
+ },
28
+
29
+ addCommands() {
30
+ return {
31
+ setVideo:
32
+ (options) =>
33
+ ({ commands }) => {
34
+ return commands.insertContent({
35
+ type: this.name,
36
+ attrs: options,
37
+ });
38
+ },
39
+ };
40
+ },
41
+ });
@@ -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>
@@ -0,0 +1,158 @@
1
+ <template>
2
+ <div>
3
+ <el-table :data="audits" v-loading="loading">
4
+ <el-table-column label="Old" :fit="false">
5
+ <template #default="scope">
6
+ <template v-if="scope?.row?.event !== 'created'">
7
+ <p
8
+ :key="key"
9
+ v-for="{ key, value } in formatValues(
10
+ scope?.row?.old_values,
11
+ )"
12
+ class="truncate color-9"
13
+ >
14
+ <strong>{{ key }}</strong
15
+ ><br />{{ value }}
16
+ </p>
17
+ </template>
18
+ </template>
19
+ </el-table-column>
20
+
21
+ <el-table-column label="New" :fit="false">
22
+ <template #default="scope">
23
+ <template v-if="scope?.row?.event === 'created'">
24
+ <span class="color-13">Resource Created</span>
25
+ </template>
26
+ <template v-else>
27
+ <p
28
+ :key="key"
29
+ v-for="{ key, value } in formatValues(
30
+ scope?.row?.new_values,
31
+ )"
32
+ class="truncate"
33
+ >
34
+ <strong>{{ key }}</strong
35
+ ><br />{{ value }}
36
+ </p>
37
+ </template>
38
+ </template>
39
+ </el-table-column>
40
+
41
+ <el-table-column label="User" :fit="false">
42
+ <template #default="scope">
43
+ <span :title="scope?.row?.user?.email">
44
+ {{ scope?.row?.user?.name || scope?.row?.user?.email }}
45
+ </span>
46
+ </template>
47
+ </el-table-column>
48
+
49
+ <el-table-column label="Date" :fit="false">
50
+ <template #default="scope">
51
+ <span :title="dateFormat(scope?.row?.created_at)">
52
+ {{ calendarFormat(scope?.row?.created_at) }}
53
+ </span>
54
+ </template>
55
+ </el-table-column>
56
+ </el-table>
57
+
58
+ <el-pagination
59
+ v-if="meta.last_page > 1"
60
+ v-model:current-page="page"
61
+ layout="prev, pager, next"
62
+ :total="meta.total"
63
+ :page-size="meta.per_page"
64
+ class="mt-3 justify-center"
65
+ @update:current-page="fetchAudits"
66
+ />
67
+ </div>
68
+ </template>
69
+
70
+ <script>
71
+ import { ElTable, ElTableColumn, ElPagination } from "element-plus";
72
+ import {
73
+ ucfirst,
74
+ calendarFormat,
75
+ dateFormat,
76
+ } from "../../../js/libs/filters.js";
77
+ import axios from "axios";
78
+
79
+ export default {
80
+ components: {
81
+ ElTable,
82
+ ElTableColumn,
83
+ ElPagination,
84
+ },
85
+
86
+ props: {
87
+ auditableType: {
88
+ type: String,
89
+ required: true,
90
+ },
91
+ auditableId: {
92
+ type: [Number, String],
93
+ required: true,
94
+ },
95
+ },
96
+
97
+ data() {
98
+ return {
99
+ audits: [],
100
+ meta: {},
101
+ loading: false,
102
+ page: 1,
103
+ };
104
+ },
105
+
106
+ mounted() {
107
+ this.fetchAudits();
108
+ },
109
+
110
+ methods: {
111
+ ucfirst,
112
+ calendarFormat,
113
+ dateFormat,
114
+
115
+ formatKey(key) {
116
+ return key
117
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
118
+ .replace(/[-_]/g, " ")
119
+ .replace(/\b\w/g, (c) => c.toUpperCase());
120
+ },
121
+
122
+ formatValue(value) {
123
+ if (value === null || value === "") return "—";
124
+ return value;
125
+ },
126
+
127
+ formatValues(values) {
128
+ if (!values) return [];
129
+ return Object.entries(values)
130
+ .filter(([key, value]) => value !== undefined)
131
+ .map(([key, value]) => ({
132
+ key: this.formatKey(key),
133
+ value: this.formatValue(value),
134
+ }));
135
+ },
136
+
137
+ async fetchAudits() {
138
+ this.loading = true;
139
+ try {
140
+ const res = await axios.get("/api/audits", {
141
+ params: {
142
+ "filter[auditable_type]": this.auditableType,
143
+ "filter[auditable_id]": this.auditableId,
144
+ include: "user",
145
+ page: this.page,
146
+ },
147
+ });
148
+ this.audits = res.data.data;
149
+ this.meta = res.data.meta;
150
+ } catch (err) {
151
+ console.error("Failed to load audits", err);
152
+ } finally {
153
+ this.loading = false;
154
+ }
155
+ },
156
+ },
157
+ };
158
+ </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
 
@@ -91,7 +91,7 @@ export default {
91
91
 
92
92
  computed: {
93
93
  permissions() {
94
- const allPermissions = this.form.roles.reduce((acc, id) => {
94
+ const allPermissions = (this.form.roles || []).reduce((acc, id) => {
95
95
  return acc.concat(
96
96
  this.roles.find((d) => d.id === id)?.permissions || [],
97
97
  );
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <div class="vel-app">
3
+ <VelHeader class="justify-end-dive">
4
+ <router-link :to="{ name: 'index' }">
5
+ <GSvg
6
+ class="logo"
7
+ style="width: 180px"
8
+ embed
9
+ asis
10
+ :name="$store.state.auth.logo"
11
+ />
12
+ </router-link>
13
+ <template #links>
14
+ <div
15
+ v-if="$store.getters.authenticated"
16
+ class="flex items-center pr"
17
+ >
18
+ <GIcon
19
+ class="icon fill-1 icon--0.5 mr-0.5"
20
+ name="icon-account-circle"
21
+ embed
22
+ asis
23
+ />
24
+ <span>{{ $store?.state?.auth?.user?.name }}</span>
25
+ </div>
26
+ <div class="flex items-center px">
27
+ <router-link
28
+ v-if="$store.getters.authenticated"
29
+ :to="{ name: 'auth.logout' }"
30
+ class="vel-logout"
31
+ >Logout</router-link
32
+ >
33
+ <router-link
34
+ v-else
35
+ :to="{ name: 'auth.login' }"
36
+ class="vel-logout"
37
+ >Login</router-link
38
+ >
39
+ </div>
40
+ <VelButton
41
+ v-if="$root.spaUrl"
42
+ class="ml"
43
+ type="primary"
44
+ tag="a"
45
+ round
46
+ :href="`${$root.spaUrl}?authenticated=1`"
47
+ >
48
+ <span v-text="`Access ${$root.appName}`" />
49
+ </VelButton>
50
+ </template>
51
+ </VelHeader>
52
+ <div class="vel-content">
53
+ <VelSideBar>
54
+ <template #navigation>
55
+ <VelNavigation v-bind="$attrs" />
56
+ </template>
57
+ <template #expand>
58
+ <GIcon
59
+ class="icon icon--0.5"
60
+ name="icon-keyboard-tab"
61
+ embed
62
+ asis
63
+ />
64
+ </template>
65
+ </VelSideBar>
66
+ <main class="vel-main">
67
+ <div class="vel-main__inner">
68
+ <slot />
69
+ </div>
70
+ <VelFooter contact="mailTo:det@avalerehealth.com">
71
+ <GSvg
72
+ class="logo fill-0"
73
+ style="width: 180px"
74
+ embed
75
+ asis
76
+ :name="$store.state.auth.logo"
77
+ />
78
+ </VelFooter>
79
+ </main>
80
+ </div>
81
+ </div>
82
+ </template>
83
+
84
+ <script>
85
+ export default {
86
+ components: {
87
+ VelHeader: require("./Header.vue").default,
88
+ VelSideBar: require("./SideBar.vue").default,
89
+ VelFooter: require("./Footer.vue").default,
90
+ VelNavigation: require("./Navigation.vue").default,
91
+ VelButton: require("../basic/Button.vue").default,
92
+ },
93
+ };
94
+ </script>