@fishawack/lab-velocity 2.0.0-beta.1 → 2.0.0-beta.2

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 (112) hide show
  1. package/_Build/vue/components/Icon.vue +33 -0
  2. package/_Build/vue/components/Svg.vue +45 -0
  3. package/_Build/vue/components/basic/Button.vue +109 -0
  4. package/_Build/vue/components/basic/link.vue +64 -0
  5. package/_Build/vue/components/form/Cascader.vue +85 -0
  6. package/_Build/vue/components/form/Checkbox.vue +39 -0
  7. package/_Build/vue/components/form/CheckboxGroup.vue +91 -0
  8. package/_Build/vue/components/form/DatePicker.vue +116 -0
  9. package/_Build/vue/components/form/InputNumber.vue +89 -0
  10. package/_Build/vue/components/form/Select.vue +109 -0
  11. package/_Build/vue/components/form/Switch.vue +63 -0
  12. package/_Build/vue/components/form/Upload.vue +101 -0
  13. package/_Build/vue/components/form/Wysiwyg.vue +127 -0
  14. package/_Build/vue/components/form/Wysiwyg2.vue +577 -0
  15. package/_Build/vue/components/form/basic.vue +106 -0
  16. package/_Build/vue/components/form/color.vue +22 -0
  17. package/_Build/vue/components/form/file.vue +89 -0
  18. package/_Build/vue/components/form/input.js +79 -0
  19. package/_Build/vue/components/form/input.vue +105 -0
  20. package/_Build/vue/components/layout/Alert.vue +38 -0
  21. package/_Build/vue/components/layout/Footer.vue +50 -0
  22. package/_Build/vue/components/layout/Header.vue +13 -0
  23. package/_Build/vue/components/layout/Loader.vue +59 -0
  24. package/_Build/vue/components/layout/Tooltip.vue +46 -0
  25. package/_Build/vue/components/layout/pageTitle.vue +18 -0
  26. package/_Build/vue/components/layout/sideBar.vue +25 -0
  27. package/_Build/vue/components/navigation/Breadcrumbs.vue +37 -0
  28. package/_Build/vue/components/navigation/BreadcrumbsItem.vue +19 -0
  29. package/_Build/vue/components/navigation/Menu.vue +14 -0
  30. package/_Build/vue/components/navigation/MenuItem.vue +20 -0
  31. package/_Build/vue/components/navigation/MenuItemGroup.vue +20 -0
  32. package/_Build/vue/components/navigation/SubMenu.vue +20 -0
  33. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/Upload/upload.vue +251 -0
  34. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/create.vue +62 -0
  35. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/edit.vue +98 -0
  36. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/index.vue +90 -0
  37. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/partials/form.vue +173 -0
  38. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/show.vue +262 -0
  39. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/parent.vue +36 -0
  40. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/create.vue +112 -0
  41. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/edit.vue +103 -0
  42. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/index.vue +112 -0
  43. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/partials/form.vue +169 -0
  44. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/show.vue +120 -0
  45. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/parent.vue +36 -0
  46. package/_Build/vue/modules/AuthModule/components/AuthModal.vue +105 -0
  47. package/_Build/vue/modules/AuthModule/components/Chip.vue +70 -0
  48. package/_Build/vue/modules/AuthModule/components/Chips.vue +26 -0
  49. package/_Build/vue/modules/AuthModule/components/FormRole.vue +115 -0
  50. package/_Build/vue/modules/AuthModule/components/VBreadcrumbs.vue +32 -0
  51. package/_Build/vue/modules/AuthModule/components/VFormFooter.vue +46 -0
  52. package/_Build/vue/modules/AuthModule/components/VPageHeader.vue +38 -0
  53. package/_Build/vue/modules/AuthModule/components/VPasswordValidation.vue +106 -0
  54. package/_Build/vue/modules/AuthModule/components/VRoleLegend.vue +43 -0
  55. package/_Build/vue/modules/AuthModule/components/VTable.vue +127 -0
  56. package/_Build/vue/modules/AuthModule/components/VTableSorter.vue +240 -0
  57. package/_Build/vue/modules/AuthModule/js/FakeAPI.js +78 -0
  58. package/_Build/vue/modules/AuthModule/js/axios.js +62 -0
  59. package/_Build/vue/modules/AuthModule/js/router.js +295 -0
  60. package/_Build/vue/modules/AuthModule/js/store.js +62 -0
  61. package/_Build/vue/modules/AuthModule/routes/account-exists.vue +33 -0
  62. package/_Build/vue/modules/AuthModule/routes/change-password.vue +165 -0
  63. package/_Build/vue/modules/AuthModule/routes/container.vue +34 -0
  64. package/_Build/vue/modules/AuthModule/routes/expired-reset.vue +78 -0
  65. package/_Build/vue/modules/AuthModule/routes/expired-verification.vue +100 -0
  66. package/_Build/vue/modules/AuthModule/routes/force-reset.vue +152 -0
  67. package/_Build/vue/modules/AuthModule/routes/forgot.vue +91 -0
  68. package/_Build/vue/modules/AuthModule/routes/login.vue +143 -0
  69. package/_Build/vue/modules/AuthModule/routes/logincallback.vue +41 -0
  70. package/_Build/vue/modules/AuthModule/routes/loginheadless.vue +21 -0
  71. package/_Build/vue/modules/AuthModule/routes/loginsso.vue +134 -0
  72. package/_Build/vue/modules/AuthModule/routes/logout.vue +21 -0
  73. package/_Build/vue/modules/AuthModule/routes/logoutheadless.vue +27 -0
  74. package/_Build/vue/modules/AuthModule/routes/register.vue +174 -0
  75. package/_Build/vue/modules/AuthModule/routes/reset.vue +133 -0
  76. package/_Build/vue/modules/AuthModule/routes/success-forgot.vue +119 -0
  77. package/_Build/vue/modules/AuthModule/routes/success-reset.vue +35 -0
  78. package/_Build/vue/modules/AuthModule/routes/success-verify.vue +32 -0
  79. package/_Build/vue/modules/AuthModule/routes/verify.vue +113 -0
  80. package/package.json +3 -9
  81. package/components/_alert.scss +0 -5
  82. package/components/_basic.scss +0 -55
  83. package/components/_breadcrumbs.scss +0 -39
  84. package/components/_button.scss +0 -304
  85. package/components/_cascader.scss +0 -12
  86. package/components/_checkbox.scss +0 -41
  87. package/components/_chip.scss +0 -24
  88. package/components/_collapse.scss +0 -24
  89. package/components/_datepicker.scss +0 -52
  90. package/components/_footer.scss +0 -46
  91. package/components/_form.scss +0 -24
  92. package/components/_header.scss +0 -54
  93. package/components/_icon.scss +0 -25
  94. package/components/_input.scss +0 -0
  95. package/components/_inputNumber.scss +0 -22
  96. package/components/_link.scss +0 -44
  97. package/components/_loader.scss +0 -43
  98. package/components/_menu.scss +0 -112
  99. package/components/_pageTitle.scss +0 -8
  100. package/components/_permissionLegend.scss +0 -18
  101. package/components/_select.scss +0 -29
  102. package/components/_sidebar.scss +0 -56
  103. package/components/_switch.scss +0 -14
  104. package/components/_table.scss +0 -20
  105. package/components/_tooltip.scss +0 -4
  106. package/components/_typography.scss +0 -162
  107. package/components/_upload.scss +0 -15
  108. package/components/_wysiwyg.scss +0 -7
  109. package/components/_wysiwyg2.scss +0 -142
  110. package/modules/_AuthModule.scss +0 -212
  111. package/modules/_AuthVariables.scss +0 -7
  112. package/modules/_modal.scss +0 -24
@@ -0,0 +1,169 @@
1
+ <!-- eslint-disable vue/no-mutating-props -->
2
+ <template>
3
+ <form class="" @submit.prevent="submit">
4
+ <template v-if="method !== 'patch'">
5
+ <el-basic
6
+ v-model="form.name"
7
+ name="name"
8
+ :error="form.errors"
9
+ type="text"
10
+ placeholder="Name"
11
+ label="Name"
12
+ />
13
+
14
+ <el-basic
15
+ v-model="form.email"
16
+ placeholder="Email"
17
+ label="Email"
18
+ type="text"
19
+ name="email"
20
+ :error="form.errors"
21
+ />
22
+
23
+ Company: <span v-text="company?.name" />
24
+
25
+ <hr class="my-3 hr-muted" />
26
+
27
+ <el-checkbox
28
+ v-model="form.notify_user"
29
+ name="notify_user"
30
+ :error="form.errors"
31
+ label="Send email to notify user of account and password"
32
+ />
33
+ <el-checkbox
34
+ v-model="form.force_password_change"
35
+ name="force_password_change"
36
+ :error="form.errors"
37
+ label="Force password change on first login"
38
+ />
39
+ <el-checkbox
40
+ v-model="form.set_password"
41
+ name="set_password"
42
+ :error="form.errors"
43
+ label="Auto generate password"
44
+ />
45
+ <template v-if="!form.set_password">
46
+ <el-basic
47
+ v-model="form.password"
48
+ name="password"
49
+ :error="form.errors"
50
+ type="password"
51
+ placeholder="Password"
52
+ label="Password"
53
+ />
54
+ <el-basic
55
+ v-model="form.password_confirmation"
56
+ name="password_confirmation"
57
+ :error="form.errors"
58
+ type="password"
59
+ placeholder="Password Confirmation"
60
+ label="Password Confirmation"
61
+ />
62
+ </template>
63
+
64
+ <hr class="my-5 hr-muted" />
65
+ </template>
66
+
67
+ <template v-if="$store.getters.can('edit roles')">
68
+ <template v-if="enableRoles">
69
+ <el-button
70
+ type="secondary"
71
+ @click="
72
+ form.roles = [];
73
+ enableRoles = false;
74
+ "
75
+ >
76
+ Reset roles
77
+ </el-button>
78
+ <FormRole :form="form" />
79
+ </template>
80
+ <template v-else>
81
+ <el-button @click="enableRoles = true">
82
+ <GIcon name="icon-plus" embed asis class="fill-0 mr" />
83
+ Override roles
84
+ </el-button>
85
+ <p class="mt-2">
86
+ Roles will be inherited from the company level.
87
+ </p>
88
+ </template>
89
+ <hr class="my-5 hr-muted" />
90
+ </template>
91
+
92
+ <VFormFooter :loading="form.processing" />
93
+ </form>
94
+ </template>
95
+
96
+ <script>
97
+ import axios from "axios";
98
+ import { debounce } from "lodash";
99
+
100
+ export default {
101
+ components: {
102
+ VFormFooter: require("../../../../components/VFormFooter.vue").default,
103
+ FormRole: require("../../../../components/FormRole.vue").default,
104
+ },
105
+ props: {
106
+ form: {
107
+ required: true,
108
+ type: Object,
109
+ },
110
+ submit: {
111
+ required: true,
112
+ type: Function,
113
+ },
114
+ method: {
115
+ required: true,
116
+ type: String,
117
+ },
118
+ },
119
+
120
+ data() {
121
+ return {
122
+ companies: null,
123
+ enableRoles: null,
124
+ company: null,
125
+ };
126
+ },
127
+
128
+ computed: {
129
+ domain() {
130
+ return this.form.email?.split("@")[1];
131
+ },
132
+ },
133
+
134
+ watch: {
135
+ "form.roles": {
136
+ handler(newVal) {
137
+ if (this.enableRoles === null) {
138
+ this.enableRoles = newVal.length > 0;
139
+ }
140
+ },
141
+ },
142
+ "form.email": debounce(function () {
143
+ if (this.domain) {
144
+ axios
145
+ .get("/api/companies", {
146
+ params: {
147
+ "filter[domains.domain]": this.domain,
148
+ },
149
+ })
150
+ .then((res) => {
151
+ this.company = res.data.data[0];
152
+ })
153
+ .catch((error) => {
154
+ console.error("Error fetching company:", error);
155
+ this.company = null;
156
+ });
157
+ } else {
158
+ this.company = null;
159
+ }
160
+ }, 500),
161
+ },
162
+
163
+ mounted() {
164
+ axios.getAll("/api/companies").then((res) => {
165
+ this.companies = res.data.data;
166
+ });
167
+ },
168
+ };
169
+ </script>
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <VBreadcrumbs
3
+ :items="addBreadcrumbs"
4
+ class="mb-8"
5
+ container-classes="m-0"
6
+ />
7
+
8
+ <div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
9
+ <div class="grid__1/1">
10
+ <template v-if="user">
11
+ <div class="bg-0 p-3 box-shadow-1 border-r-4 mb-6">
12
+ <VPageHeader
13
+ icon="icon-user"
14
+ :title="`${user.name} ${user.last_name ?? ''}`"
15
+ >
16
+ <el-button
17
+ v-if="$store.getters.can('write users')"
18
+ tag="a"
19
+ type="primary"
20
+ @click="
21
+ $router.push({
22
+ name: 'users.edit',
23
+ param: user.id,
24
+ })
25
+ "
26
+ >
27
+ <GIcon
28
+ class="fill-0 mr-0.5"
29
+ name="icon-edit"
30
+ embed
31
+ artboard
32
+ />
33
+ Edit user
34
+ </el-button>
35
+ </VPageHeader>
36
+
37
+ <hr class="my-3 hr-muted" />
38
+
39
+ <table>
40
+ <tbody>
41
+ <tr>
42
+ <td class="p">Email</td>
43
+ <td class="p">{{ user.email }}</td>
44
+ </tr>
45
+ <tr>
46
+ <td class="p">Company</td>
47
+ <td class="p">
48
+ <router-link
49
+ :to="{
50
+ name: 'companies.show',
51
+ params: { id: user.company.id },
52
+ }"
53
+ >
54
+ {{ user.company?.name }}
55
+ </router-link>
56
+ </td>
57
+ </tr>
58
+ </tbody>
59
+ </table>
60
+
61
+ <hr class="my-3 hr-muted" />
62
+
63
+ <FormRole
64
+ :overrides="user.overrides_roles_and_permissions"
65
+ :form="{ roles: user.roles.map((d) => d.id) }"
66
+ :readonly="true"
67
+ />
68
+ </div>
69
+ </template>
70
+
71
+ <div v-else class="absolute transform-center text-center">
72
+ <GSpinner class="fill-5" />
73
+ <p v-text="`Loading...`" />
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </template>
78
+
79
+ <script>
80
+ import axios from "axios";
81
+
82
+ export default {
83
+ name: "PShow",
84
+
85
+ components: {
86
+ VBreadcrumbs: require("../../../components/VBreadcrumbs.vue").default,
87
+ VPageHeader: require("../../../components/VPageHeader.vue").default,
88
+ FormRole: require("../../../components/FormRole.vue").default,
89
+ },
90
+
91
+ props: {
92
+ breadcrumbs: {
93
+ type: Array,
94
+ required: true,
95
+ },
96
+ },
97
+
98
+ data() {
99
+ return {
100
+ user: null,
101
+ addBreadcrumbs: [...this.$props.breadcrumbs],
102
+ };
103
+ },
104
+
105
+ mounted() {
106
+ axios
107
+ .get(`/api/users/${this.$route.params.id}?include=company`)
108
+ .then((res) => {
109
+ this.user = res.data.data;
110
+ this.addBreadcrumbs.push({
111
+ href: {
112
+ name: "users.show",
113
+ param: this.user.id,
114
+ },
115
+ text: this.user.name,
116
+ });
117
+ });
118
+ },
119
+ };
120
+ </script>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <PageTitle title="Users" />
3
+
4
+ <router-view :key="$route.path" :breadcrumbs="breadcrumbs" />
5
+ </template>
6
+
7
+ <script>
8
+ import { PageTitle } from "@fishawack/lab-velocity";
9
+
10
+ export default {
11
+ name: "PUsers",
12
+
13
+ components: {
14
+ PageTitle,
15
+ },
16
+
17
+ data() {
18
+ return {
19
+ breadcrumbs: [
20
+ {
21
+ href: {
22
+ name: "index",
23
+ },
24
+ text: "Home",
25
+ },
26
+ {
27
+ href: {
28
+ name: "users.index",
29
+ },
30
+ text: "Users",
31
+ },
32
+ ],
33
+ };
34
+ },
35
+ };
36
+ </script>
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <div :class="{ active: open }" class="modal modal--auth">
3
+ <div class="modal__container" v-on:click.self="close">
4
+ <div class="modal__box AuthModule__form" :class="boxCls">
5
+ <component
6
+ v-if="compName"
7
+ :is="compName"
8
+ v-bind="compProps"
9
+ @close="close"
10
+ />
11
+ </div>
12
+ </div>
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ "use strict";
18
+
19
+ export default {
20
+ name: "AuthModal",
21
+
22
+ data() {
23
+ return {
24
+ open: false,
25
+ compName: null,
26
+ compProps: null,
27
+ cb: null,
28
+ boxCls: null,
29
+ validComponents: {
30
+ "force-reset": "VForceReset",
31
+ "password-change": "VPasswordChange",
32
+ },
33
+ };
34
+ },
35
+
36
+ methods: {
37
+ reset() {
38
+ this.compName = null;
39
+ this.compProps = null;
40
+ this.boxCls = null;
41
+ this.cb = null;
42
+ },
43
+ close() {
44
+ if (this.compName === "VForceReset") {
45
+ if (!this.$store.state.auth.forcePasswordChange) {
46
+ this.open = false;
47
+ }
48
+ } else {
49
+ this.open = false;
50
+ }
51
+ },
52
+ },
53
+
54
+ created() {
55
+ this.$emitter.on("AuthModal", (comp) => {
56
+ this.compName = this.validComponents[comp.type];
57
+ this.open = comp;
58
+ });
59
+
60
+ window.addEventListener("keydown", (e) => {
61
+ if (e.key === "Escape") {
62
+ this.open = false;
63
+ }
64
+ });
65
+ },
66
+
67
+ watch: {
68
+ open(isOpen) {
69
+ this.$emitter.emit("toggleBackgroundScroll", isOpen);
70
+
71
+ if (this.cb) {
72
+ this.cb();
73
+ }
74
+
75
+ if (!isOpen) {
76
+ this.reset();
77
+ }
78
+ },
79
+ $route(to, from) {
80
+ if (from.fullPath !== to.fullPath) {
81
+ this.open = false;
82
+ }
83
+ },
84
+ "$store.state.auth.forcePasswordChange": {
85
+ async handler(forcePasswordChange) {
86
+ if (forcePasswordChange) {
87
+ this.compName = this.validComponents["force-reset"];
88
+ this.open = true;
89
+ }
90
+ },
91
+ },
92
+ },
93
+
94
+ components: {
95
+ VForceReset: require("../routes/force-reset.vue").default,
96
+ VPasswordChange: require("../routes/change-password.vue").default,
97
+ },
98
+ mounted() {
99
+ if (this.$store.state.auth.forcePasswordChange) {
100
+ this.compName = this.validComponents["force-reset"];
101
+ this.open = true;
102
+ }
103
+ },
104
+ };
105
+ </script>
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <span
3
+ class="chip"
4
+ :class="`chip--${name}`"
5
+ :style="{
6
+ color,
7
+ }"
8
+ >
9
+ {{ label }}
10
+ </span>
11
+ </template>
12
+
13
+ <script>
14
+ export default {
15
+ props: {
16
+ name: {
17
+ type: String,
18
+ default: "",
19
+ },
20
+ label: {
21
+ type: String,
22
+ default: "",
23
+ },
24
+ },
25
+
26
+ computed: {
27
+ color() {
28
+ return this.generateColorFromString(this.name);
29
+ },
30
+ },
31
+
32
+ methods: {
33
+ /**
34
+ * Generate a more visually appealing color with better saturation
35
+ */
36
+ generateColorFromString(str) {
37
+ let hash = 0;
38
+
39
+ // Create hash from string
40
+ for (let i = 0; i < str.length; i++) {
41
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
42
+ }
43
+
44
+ // Generate HSL values for better color distribution
45
+ const hue = Math.abs(hash % 360);
46
+ const saturation = 45 + (Math.abs(hash) % 30); // 45-75%
47
+ const lightness = 35 + (Math.abs(hash) % 25); // 35-60%
48
+
49
+ return this.hslToHex(hue, saturation, lightness);
50
+ },
51
+
52
+ /**
53
+ * Convert HSL to HEX
54
+ */
55
+ hslToHex(h, s, l) {
56
+ // eslint-disable-next-line no-param-reassign
57
+ l /= 100;
58
+ const a = (s * Math.min(l, 1 - l)) / 100;
59
+ const f = (n) => {
60
+ const k = (n + h / 30) % 12;
61
+ const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
62
+ return Math.round(255 * color)
63
+ .toString(16)
64
+ .padStart(2, "0");
65
+ };
66
+ return `#${f(0)}${f(8)}${f(4)}`;
67
+ },
68
+ },
69
+ };
70
+ </script>
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <div class="chips">
3
+ <template v-for="(item, index) in array" :key="item.name">
4
+ <Chip
5
+ class="chip--round"
6
+ :name="item.name"
7
+ :label="`${item.label}${index < array.length - 1 ? ',' : ''}`"
8
+ /><span v-if="index < array.length - 1">&nbsp;</span>
9
+ </template>
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ export default {
15
+ components: {
16
+ Chip: require("./Chip.vue").default,
17
+ },
18
+
19
+ props: {
20
+ array: {
21
+ type: Array,
22
+ default: () => [],
23
+ },
24
+ },
25
+ };
26
+ </script>
@@ -0,0 +1,115 @@
1
+ <!-- eslint-disable vue/no-mutating-props -->
2
+ <template>
3
+ <h2 class="font-primary">Access Control</h2>
4
+
5
+ <template v-if="readonly">
6
+ <p>Roles</p>
7
+ <div v-if="!overrides" class="my-2">
8
+ <Chip
9
+ class="mr mb inline-block"
10
+ name="inherited"
11
+ label="Inherited"
12
+ />
13
+ </div>
14
+ <ul v-else class="my-2 pl-0">
15
+ <li
16
+ v-for="role in form.roles"
17
+ :key="roles.find((d) => d.id === role)"
18
+ class="mr mb inline-block"
19
+ >
20
+ <Chip
21
+ :name="roles.find((d) => d.id === role)?.name"
22
+ :label="roles.find((d) => d.id === role)?.label"
23
+ />
24
+ </li>
25
+ </ul>
26
+ </template>
27
+ <el-select
28
+ v-else
29
+ v-model="form.roles"
30
+ class="mt-2"
31
+ placeholder="Select"
32
+ multiple
33
+ name="roles"
34
+ :error="form.errors"
35
+ label="Roles"
36
+ :options="
37
+ roles?.map(({ id, label }) => ({
38
+ label,
39
+ value: id,
40
+ }))
41
+ "
42
+ />
43
+
44
+ <template v-if="permissions.length && (overrides === null || overrides)">
45
+ <p>Permissions</p>
46
+ <ul class="mt-2 pl-0">
47
+ <li
48
+ v-for="(permission, index) in permissions"
49
+ :key="index"
50
+ class="mr mb inline-block"
51
+ >
52
+ <Chip :name="permission.name" :label="permission.label" />
53
+ </li>
54
+ </ul>
55
+ </template>
56
+
57
+ <VRoleLegend class="mt-2" />
58
+ </template>
59
+
60
+ <script>
61
+ import axios from "axios";
62
+
63
+ export default {
64
+ components: {
65
+ VRoleLegend: require("./VRoleLegend.vue").default,
66
+ Chip: require("./Chip.vue").default,
67
+ },
68
+
69
+ props: {
70
+ form: {
71
+ required: true,
72
+ type: Object,
73
+ },
74
+ readonly: {
75
+ type: Boolean,
76
+ default: false,
77
+ },
78
+ overrides: {
79
+ type: Boolean,
80
+ default: null,
81
+ },
82
+ },
83
+
84
+ data() {
85
+ return {
86
+ roles: [],
87
+ };
88
+ },
89
+
90
+ computed: {
91
+ permissions() {
92
+ const allPermissions = this.form.roles.reduce((acc, id) => {
93
+ return acc.concat(
94
+ this.roles.find((d) => d.id === id)?.permissions || [],
95
+ );
96
+ }, []);
97
+
98
+ // Remove duplicates based on permission id
99
+ return allPermissions
100
+ .filter((permission, index, self) => {
101
+ return (
102
+ index === self.findIndex((p) => p.id === permission.id)
103
+ );
104
+ })
105
+ .sort();
106
+ },
107
+ },
108
+
109
+ mounted() {
110
+ axios.getAll("/api/roles").then((res) => {
111
+ this.roles = res.data.data;
112
+ });
113
+ },
114
+ };
115
+ </script>
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <div class="py mobile:hidden">
3
+ <div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
4
+ <div class="grid__1/1">
5
+ <div class="flex items-center">
6
+ <breadcrumbs :crumbs="items" />
7
+ </div>
8
+ </div>
9
+ </div>
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import { Breadcrumbs } from "@fishawack/lab-velocity";
15
+ export default {
16
+ name: "VBreadcrumbs",
17
+ components: {
18
+ Breadcrumbs,
19
+ },
20
+
21
+ props: {
22
+ containerClasses: {
23
+ type: [String, Array, Object],
24
+ default: "",
25
+ },
26
+ items: {
27
+ type: Array,
28
+ required: true,
29
+ },
30
+ },
31
+ };
32
+ </script>