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

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 (90) hide show
  1. package/README.md +160 -38
  2. package/_Build/vue/components/Icon.vue +33 -0
  3. package/_Build/vue/components/Svg.vue +45 -0
  4. package/_Build/vue/components/basic/Button.vue +109 -0
  5. package/_Build/vue/components/basic/link.vue +64 -0
  6. package/_Build/vue/components/form/Cascader.vue +85 -0
  7. package/_Build/vue/components/form/Checkbox.vue +39 -0
  8. package/_Build/vue/components/form/CheckboxGroup.vue +91 -0
  9. package/_Build/vue/components/form/DatePicker.vue +116 -0
  10. package/_Build/vue/components/form/InputNumber.vue +89 -0
  11. package/_Build/vue/components/form/Select.vue +109 -0
  12. package/_Build/vue/components/form/Spinner.vue +5 -0
  13. package/_Build/vue/components/form/Switch.vue +63 -0
  14. package/_Build/vue/components/form/Upload.vue +101 -0
  15. package/_Build/vue/components/form/Wysiwyg.vue +127 -0
  16. package/_Build/vue/components/form/Wysiwyg2.vue +577 -0
  17. package/_Build/vue/components/form/basic.vue +106 -0
  18. package/_Build/vue/components/form/color.vue +22 -0
  19. package/_Build/vue/components/form/file.vue +89 -0
  20. package/_Build/vue/components/form/input.js +79 -0
  21. package/_Build/vue/components/form/input.vue +105 -0
  22. package/_Build/vue/components/layout/Alert.vue +38 -0
  23. package/_Build/vue/components/layout/Footer.vue +50 -0
  24. package/_Build/vue/components/layout/Header.vue +13 -0
  25. package/_Build/vue/components/layout/Loader.vue +59 -0
  26. package/_Build/vue/components/layout/Tooltip.vue +46 -0
  27. package/_Build/vue/components/layout/pageTitle.vue +18 -0
  28. package/_Build/vue/components/layout/sideBar.vue +25 -0
  29. package/_Build/vue/components/navigation/Breadcrumbs.vue +37 -0
  30. package/_Build/vue/components/navigation/BreadcrumbsItem.vue +19 -0
  31. package/_Build/vue/components/navigation/Menu.vue +14 -0
  32. package/_Build/vue/components/navigation/MenuItem.vue +20 -0
  33. package/_Build/vue/components/navigation/MenuItemGroup.vue +20 -0
  34. package/_Build/vue/components/navigation/SubMenu.vue +20 -0
  35. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/Upload/upload.vue +259 -0
  36. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/create.vue +62 -0
  37. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/edit.vue +98 -0
  38. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/index.vue +90 -0
  39. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/partials/form.vue +181 -0
  40. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/show.vue +267 -0
  41. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/parent.vue +36 -0
  42. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/create.vue +113 -0
  43. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/edit.vue +101 -0
  44. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/index.vue +112 -0
  45. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/partials/form.vue +174 -0
  46. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/show.vue +123 -0
  47. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/parent.vue +36 -0
  48. package/_Build/vue/modules/AuthModule/components/AuthModal.vue +105 -0
  49. package/_Build/vue/modules/AuthModule/components/Chip.vue +70 -0
  50. package/_Build/vue/modules/AuthModule/components/Chips.vue +26 -0
  51. package/_Build/vue/modules/AuthModule/components/FormRole.vue +117 -0
  52. package/_Build/vue/modules/AuthModule/components/VBreadcrumbs.vue +33 -0
  53. package/_Build/vue/modules/AuthModule/components/VFormFooter.vue +52 -0
  54. package/_Build/vue/modules/AuthModule/components/VPageHeader.vue +38 -0
  55. package/_Build/vue/modules/AuthModule/components/VPasswordValidation.vue +106 -0
  56. package/_Build/vue/modules/AuthModule/components/VRoleLegend.vue +43 -0
  57. package/_Build/vue/modules/AuthModule/components/VTable.vue +136 -0
  58. package/_Build/vue/modules/AuthModule/components/VTableSorter.vue +252 -0
  59. package/_Build/vue/modules/AuthModule/js/FakeAPI.js +78 -0
  60. package/_Build/vue/modules/AuthModule/js/axios.js +81 -0
  61. package/_Build/vue/modules/AuthModule/js/router.js +295 -0
  62. package/_Build/vue/modules/AuthModule/js/store.js +62 -0
  63. package/_Build/vue/modules/AuthModule/routes/account-exists.vue +33 -0
  64. package/_Build/vue/modules/AuthModule/routes/change-password.vue +163 -0
  65. package/_Build/vue/modules/AuthModule/routes/container.vue +34 -0
  66. package/_Build/vue/modules/AuthModule/routes/expired-reset.vue +78 -0
  67. package/_Build/vue/modules/AuthModule/routes/expired-verification.vue +101 -0
  68. package/_Build/vue/modules/AuthModule/routes/force-reset.vue +147 -0
  69. package/_Build/vue/modules/AuthModule/routes/forgot.vue +91 -0
  70. package/_Build/vue/modules/AuthModule/routes/login.vue +139 -0
  71. package/_Build/vue/modules/AuthModule/routes/logincallback.vue +39 -0
  72. package/_Build/vue/modules/AuthModule/routes/loginheadless.vue +21 -0
  73. package/_Build/vue/modules/AuthModule/routes/loginsso.vue +132 -0
  74. package/_Build/vue/modules/AuthModule/routes/logout.vue +19 -0
  75. package/_Build/vue/modules/AuthModule/routes/logoutheadless.vue +25 -0
  76. package/_Build/vue/modules/AuthModule/routes/register.vue +171 -0
  77. package/_Build/vue/modules/AuthModule/routes/reset.vue +133 -0
  78. package/_Build/vue/modules/AuthModule/routes/success-forgot.vue +120 -0
  79. package/_Build/vue/modules/AuthModule/routes/success-reset.vue +35 -0
  80. package/_Build/vue/modules/AuthModule/routes/success-verify.vue +30 -0
  81. package/_Build/vue/modules/AuthModule/routes/verify.vue +110 -0
  82. package/_base.scss +0 -1
  83. package/_defaults.scss +2 -13
  84. package/_variables.scss +9 -4
  85. package/{modules/_AuthModule.scss → components/_auth.scss} +19 -68
  86. package/package.json +3 -8
  87. package/vendor.scss +0 -1
  88. package/components/_input.scss +0 -0
  89. package/modules/_AuthVariables.scss +0 -7
  90. /package/{modules → components}/_modal.scss +0 -0
@@ -0,0 +1,181 @@
1
+ <!-- eslint-disable vue/no-mutating-props -->
2
+ <template>
3
+ <form class="" @submit.prevent="submit">
4
+ <VelBasic
5
+ v-model="form.name"
6
+ name="name"
7
+ :error="form.errors"
8
+ type="text"
9
+ placeholder="Name"
10
+ label="Company name"
11
+ >
12
+ <template #label>
13
+ Company name <sup class="color-status-red-100">*</sup>
14
+ </template>
15
+ </VelBasic>
16
+
17
+ <VelSelect
18
+ v-if="method === 'patch'"
19
+ v-model="form.primary_contact"
20
+ name="primary_contact"
21
+ :error="form.errors"
22
+ placeholder="Primary Contact"
23
+ label="Primary Contact"
24
+ :options="
25
+ users?.map(({ name, id }) => ({
26
+ label: name,
27
+ value: id,
28
+ }))
29
+ "
30
+ />
31
+
32
+ <hr class="my-3 hr-muted" />
33
+
34
+ <p class="my-0">Domain/s <sup class="color-status-red-100">*</sup></p>
35
+
36
+ <ul class="list-none pl-0 mt mb-2">
37
+ <li
38
+ v-for="(path, index) in form.domains"
39
+ :key="index"
40
+ class="mb-0.5"
41
+ >
42
+ <el-input
43
+ v-model="form.domains[index]"
44
+ placeholder="avalerehealth.com"
45
+ >
46
+ <template #prepend>@</template>
47
+ <template #append>
48
+ <VelButton
49
+ type="danger"
50
+ @click="form.domains.splice(index, 1)"
51
+ >
52
+ <GSvg class="vel-icon" name="trash" />
53
+ </VelButton>
54
+ </template>
55
+ </el-input>
56
+
57
+ <small
58
+ v-if="form.errors && form.errors.has(`domains.${index}`)"
59
+ class="form__error vel-basic__error"
60
+ v-text="form.errors.first(`domains.${index}`)"
61
+ ></small>
62
+ </li>
63
+ </ul>
64
+
65
+ <div>
66
+ <VelButton @click="form.domains.push('')">
67
+ Add Domain
68
+
69
+ <GIcon name="icon-plus" embed asis class="fill-0 ml" />
70
+ </VelButton>
71
+ </div>
72
+
73
+ <hr class="my-5 hr-muted" />
74
+
75
+ <template v-if="$store.getters.can('edit roles')">
76
+ <FormRole :form="form" />
77
+
78
+ <hr class="my-5 hr-muted" />
79
+ </template>
80
+
81
+ <template v-if="$store.getters.can('edit sso')">
82
+ <h3 class="h3 mb-2">SSO Settings</h3>
83
+
84
+ <VelSelect
85
+ v-model="form.sso_type"
86
+ name="sso_type"
87
+ :error="form.errors"
88
+ placeholder="Please Select"
89
+ label="Provider"
90
+ clearable
91
+ :options="[
92
+ {
93
+ value: 'azure',
94
+ label: 'azure',
95
+ },
96
+ {
97
+ value: 'google',
98
+ label: 'google',
99
+ },
100
+ ]"
101
+ />
102
+ <VelBasic
103
+ v-model="form.sso_client_id"
104
+ name="sso_client_id"
105
+ :error="form.errors"
106
+ type="text"
107
+ placeholder="Key"
108
+ label="Key"
109
+ />
110
+ <VelBasic
111
+ v-model="form.sso_tenant"
112
+ name="sso_tenant"
113
+ :error="form.errors"
114
+ type="text"
115
+ placeholder="Tenant"
116
+ label="Tenant"
117
+ />
118
+ <VelBasic
119
+ v-model="form.sso_client_secret"
120
+ name="sso_client_secret"
121
+ :error="form.errors"
122
+ type="password"
123
+ placeholder="Secret"
124
+ label="Secret"
125
+ />
126
+
127
+ <hr class="my-3 hr-muted" />
128
+ </template>
129
+
130
+ <VFormFooter :form="form" />
131
+ </form>
132
+ </template>
133
+
134
+ <!-- eslint-disable vue/no-mutating-props -->
135
+ <script>
136
+ import axios from "axios";
137
+ import VelButton from "../../../../../../components/basic/Button.vue";
138
+ import VelSelect from "../../../../../../components/form/Select.vue";
139
+ import VelBasic from "../../../../../../components/form/basic.vue";
140
+ import { ElInput } from "element-plus";
141
+
142
+ export default {
143
+ components: {
144
+ VFormFooter: require("../../../../components/VFormFooter.vue").default,
145
+ FormRole: require("../../../../components/FormRole.vue").default,
146
+ VelButton,
147
+ VelSelect,
148
+ VelBasic,
149
+ ElInput,
150
+ },
151
+
152
+ props: {
153
+ form: {
154
+ required: true,
155
+ type: Object,
156
+ },
157
+ submit: {
158
+ required: true,
159
+ type: Function,
160
+ },
161
+ method: {
162
+ type: String,
163
+ default: "post",
164
+ },
165
+ },
166
+
167
+ data() {
168
+ return {
169
+ users: [],
170
+ };
171
+ },
172
+
173
+ mounted() {
174
+ axios
175
+ .getAll(`/api/users?filter[company_id]=${this.$route.params.id}`)
176
+ .then((res) => {
177
+ this.users = res.data.data;
178
+ });
179
+ },
180
+ };
181
+ </script>
@@ -0,0 +1,267 @@
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="company">
11
+ <div class="bg-0 p-3 box-shadow-1 border-r-4 mb-6">
12
+ <VPageHeader icon="icon-business" :title="company.name">
13
+ <!--
14
+ Temporarily disabled
15
+ <el-button tag="a" type="secondary" :href="`/companies/${company.id}/upload`">
16
+ <GIcon class="fill-1 mr-0.5" name="icon-plus" embed artboard /> Import users
17
+ </el-button>
18
+ <el-button tag="a" type="secondary" :href="`/api/companies/${company.id}/export`">
19
+ <GIcon class="fill-1 mr-0.5" name="icon-download" embed artboard /> Export users
20
+ </el-button>
21
+ Temporarily disabled
22
+ -->
23
+
24
+ <VelButton
25
+ v-if="company.primary_contact"
26
+ type="primary"
27
+ @click="sendWelcome"
28
+ >
29
+ Send welcome email
30
+ </VelButton>
31
+
32
+ <VelButton
33
+ v-if="$store.getters.can('write companies')"
34
+ tag="a"
35
+ type="primary"
36
+ @click="
37
+ $router.push({
38
+ name: 'companies.edit',
39
+ param: company.id,
40
+ })
41
+ "
42
+ >
43
+ <GIcon
44
+ class="fill-0 mr-0.5"
45
+ name="icon-edit"
46
+ embed
47
+ artboard
48
+ />
49
+ Edit company
50
+ </VelButton>
51
+ </VPageHeader>
52
+
53
+ <hr class="my-3 hr-muted" />
54
+
55
+ <table>
56
+ <tbody>
57
+ <tr>
58
+ <td class="p">Domains</td>
59
+ <td class="p">
60
+ {{ company.domains.join(", ") }}
61
+ </td>
62
+ </tr>
63
+ <tr>
64
+ <td class="p">SSO Enabled</td>
65
+ <td class="p">
66
+ {{ company.sso_enabled }}
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <td class="p">Primary Contact</td>
71
+ <td class="p">
72
+ {{ company.primary_contact?.name }}
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td class="p">Primary Contact Email</td>
77
+ <td class="p">
78
+ {{ company.primary_contact?.email }}
79
+ </td>
80
+ </tr>
81
+ <tr>
82
+ <td class="p">Primary Contact Contacted</td>
83
+ <td class="p">
84
+ {{ !!company.primary_contact_contacted }}
85
+ </td>
86
+ </tr>
87
+ <tr>
88
+ <td class="p">Total users</td>
89
+ <td class="p">
90
+ {{ company.user_count }}
91
+ </td>
92
+ </tr>
93
+ </tbody>
94
+ </table>
95
+
96
+ <hr class="my-3 hr-muted" />
97
+
98
+ <FormRole
99
+ :form="{ roles: company.roles.map((d) => d.id) }"
100
+ :readonly="true"
101
+ />
102
+ </div>
103
+
104
+ <VTableSorter
105
+ key="PShow"
106
+ api="users"
107
+ :json-data="jsonData"
108
+ :defaults="`filter[company_id]=${id}`"
109
+ :fixed-height="false"
110
+ >
111
+ <template #table-action>
112
+ <VelButton
113
+ type="primary"
114
+ tag="a"
115
+ class="ml-2"
116
+ @click="
117
+ $router.push({
118
+ name: `${jsonData.pageLink}.create`,
119
+ query: { company_id: id },
120
+ })
121
+ "
122
+ >
123
+ <GIcon
124
+ name="icon-plus"
125
+ embed
126
+ asis
127
+ class="fill-0 mr-0.5"
128
+ />
129
+ Create new {{ jsonData.label }}
130
+ </VelButton>
131
+ </template>
132
+ </VTableSorter>
133
+ </template>
134
+
135
+ <div v-else class="absolute transform-center text-center">
136
+ <VelSpinner class="fill-5" />
137
+ </div>
138
+ </div>
139
+ </div>
140
+ </template>
141
+
142
+ <script>
143
+ import axios from "axios";
144
+ import VelButton from "../../../../../components/basic/Button.vue";
145
+ import VelSpinner from "../../../../../components/form/Spinner.vue";
146
+ import { ElNotification } from "element-plus";
147
+
148
+ export default {
149
+ name: "PShow",
150
+
151
+ components: {
152
+ VBreadcrumbs: require("../../../components/VBreadcrumbs.vue").default,
153
+ VTableSorter: require("../../../components/VTableSorter.vue").default,
154
+ VPageHeader: require("../../../components/VPageHeader.vue").default,
155
+ FormRole: require("../../../components/FormRole.vue").default,
156
+ VelSpinner,
157
+ VelButton,
158
+ },
159
+ props: {
160
+ breadcrumbs: {
161
+ type: Array,
162
+ required: true,
163
+ },
164
+ },
165
+
166
+ data() {
167
+ return {
168
+ processing: false,
169
+ company: null,
170
+ id: null,
171
+ addBreadcrumbs: [...this.$props.breadcrumbs],
172
+ jsonData: {
173
+ label: "user",
174
+ multiLabel: "users",
175
+ pageLink: "users",
176
+ api: "/api/users",
177
+ searchable: {
178
+ label: "Search users",
179
+ value: "name",
180
+ },
181
+ tableStructure: [
182
+ {
183
+ label: "Name",
184
+ key: "name",
185
+ sortable: true,
186
+ },
187
+ {
188
+ label: "Email",
189
+ key: "email",
190
+ sortable: true,
191
+ },
192
+ {
193
+ label: "Role",
194
+ component: {
195
+ module: (row) => {
196
+ if (
197
+ !row.overrides_roles_and_permissions ||
198
+ row.roles.length === 1
199
+ )
200
+ return require("../../../components/Chip.vue")
201
+ .default;
202
+
203
+ return require("../../../components/Chips.vue")
204
+ .default;
205
+ },
206
+ props: (row) => {
207
+ if (!row.overrides_roles_and_permissions)
208
+ return {
209
+ name: "inherited",
210
+ label: "Inherited",
211
+ };
212
+
213
+ return row.roles.length === 1
214
+ ? {
215
+ name: row.roles[0].name,
216
+ label: row.roles[0].label,
217
+ }
218
+ : { array: row.roles };
219
+ },
220
+ },
221
+ },
222
+ ],
223
+ },
224
+ };
225
+ },
226
+
227
+ mounted() {
228
+ this.id = this.$route.params.id;
229
+
230
+ axios
231
+ .get(`/api/companies/${this.id}?include=primary_contact`)
232
+ .then((res) => {
233
+ this.company = res.data.data;
234
+ this.addBreadcrumbs.push({
235
+ href: {
236
+ name: "companies.show",
237
+ param: this.company.id,
238
+ },
239
+ text: this.company.name,
240
+ });
241
+ });
242
+ },
243
+
244
+ methods: {
245
+ async sendWelcome() {
246
+ try {
247
+ const res = await axios.post(
248
+ `/api/companies/${this.id}/welcome`,
249
+ );
250
+ ElNotification({
251
+ title: "Success",
252
+ message: res.data.message,
253
+ type: "success",
254
+ });
255
+
256
+ this.company.primary_contact_contacted = true;
257
+ } catch (e) {
258
+ ElNotification({
259
+ title: "Warning",
260
+ message: e.response?.data?.message || e.message,
261
+ type: "warning",
262
+ });
263
+ }
264
+ },
265
+ },
266
+ };
267
+ </script>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <PageTitle title="Companies" />
3
+
4
+ <router-view :key="$route.path" :breadcrumbs="breadcrumbs" />
5
+ </template>
6
+
7
+ <script>
8
+ import PageTitle from "../../../../components/layout/pageTitle.vue";
9
+
10
+ export default {
11
+ name: "PCompanies",
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: "companies.index",
29
+ },
30
+ text: "Companies",
31
+ },
32
+ ],
33
+ };
34
+ },
35
+ };
36
+ </script>
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <VBreadcrumbs :items="breadcrumbs" class="mb-8" container-classes="m-0" />
3
+
4
+ <div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
5
+ <div class="grid__1/1">
6
+ <div class="grid__1/1 mb-4">
7
+ <h2 class="h1">Create User</h2>
8
+ </div>
9
+ <div class="grid__1/2">
10
+ <XForm ref="form" :form="form" :submit="submit" />
11
+ </div>
12
+ </div>
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ import { ElMessageBox } from "element-plus";
18
+ import Form from "form-backend-validation";
19
+ import { ElNotification } from "element-plus";
20
+
21
+ export default {
22
+ name: "PCreate",
23
+
24
+ components: {
25
+ VBreadcrumbs: require("../../../components/VBreadcrumbs.vue").default,
26
+ XForm: require("./partials/form.vue").default,
27
+ },
28
+
29
+ props: {
30
+ breadcrumbs: {
31
+ type: Array,
32
+ required: true,
33
+ },
34
+ },
35
+
36
+ data() {
37
+ return {
38
+ form: new Form(
39
+ {
40
+ name: null,
41
+ email: null,
42
+ roles: [],
43
+ notify_user: true,
44
+ company_id: null,
45
+ force_password_change: true,
46
+ set_password: true,
47
+ password: null,
48
+ password_confirmation: null,
49
+ },
50
+ {
51
+ resetOnSuccess: false,
52
+ },
53
+ ),
54
+ };
55
+ },
56
+
57
+ methods: {
58
+ generatePassword(
59
+ length = 20,
60
+ characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$",
61
+ ) {
62
+ return Array.from(crypto.getRandomValues(new Uint32Array(length)))
63
+ .map((x) => characters[x % characters.length])
64
+ .join("");
65
+ },
66
+ async submit() {
67
+ try {
68
+ if (this.form.set_password) {
69
+ const password = this.generatePassword();
70
+ this.form.password = password;
71
+ this.form.password_confirmation = password;
72
+ }
73
+
74
+ let res = await this.form.post(`/api/users`);
75
+
76
+ if (!this.form.set_password) {
77
+ this.open(res.data.id);
78
+ } else {
79
+ ElNotification({
80
+ title: "Success",
81
+ message: "User created a notified of their new account",
82
+ type: "success",
83
+ });
84
+
85
+ this.$router.replace({
86
+ name: "users.show",
87
+ params: { id: res.data.id },
88
+ });
89
+ }
90
+ } catch (e) {
91
+ console.log(e);
92
+ }
93
+ },
94
+ open(id) {
95
+ ElMessageBox.alert(
96
+ `<p>The password below will not be shown again. Ensure you've taken a copy if you plan to send manually. <br><br><strong>Email</strong>: ${this.form.email}<br> <strong>Password</strong>: ${this.form.password}</p>`,
97
+ "User Created",
98
+ {
99
+ confirmButtonText: "Ok",
100
+ dangerouslyUseHTMLString: true,
101
+ },
102
+ )
103
+ .then(() => {
104
+ this.$router.replace({
105
+ name: "users.show",
106
+ params: { id },
107
+ });
108
+ })
109
+ .catch(() => {});
110
+ },
111
+ },
112
+ };
113
+ </script>
@@ -0,0 +1,101 @@
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
+ <div class="grid__1/1 mb-4">
11
+ <h2 class="h1">Edit User</h2>
12
+ </div>
13
+ <div class="grid__1/2">
14
+ <XForm
15
+ :id="id"
16
+ ref="form"
17
+ :form="form"
18
+ :submit="submit"
19
+ method="patch"
20
+ />
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </template>
25
+
26
+ <script>
27
+ import Form from "form-backend-validation";
28
+
29
+ export default {
30
+ name: "PEdit",
31
+
32
+ components: {
33
+ VBreadcrumbs: require("../../../components/VBreadcrumbs.vue").default,
34
+ XForm: require("./partials/form.vue").default,
35
+ },
36
+
37
+ props: {
38
+ breadcrumbs: {
39
+ type: Array,
40
+ required: true,
41
+ },
42
+ },
43
+
44
+ data() {
45
+ return {
46
+ id: null,
47
+ form: new Form({
48
+ name: null,
49
+ email: null,
50
+ company_id: null,
51
+ roles: [],
52
+ }),
53
+ addBreadcrumbs: [...this.$props.breadcrumbs],
54
+ };
55
+ },
56
+
57
+ async mounted() {
58
+ this.id = this.$route.params.id;
59
+ window.axios
60
+ .get(`/api/users/${this.id}?include=company`)
61
+ .then((res) => {
62
+ const user = res.data.data;
63
+ this.form.name = user.name;
64
+ this.form.email = user.email;
65
+ this.form.company_id = user.company_id;
66
+ this.form.roles = user.overrides_roles_and_permissions
67
+ ? user.roles.map((val) => {
68
+ return val.id;
69
+ })
70
+ : [];
71
+ this.addBreadcrumbs.push({
72
+ href: {
73
+ name: "users.show",
74
+ param: this.id,
75
+ },
76
+ text: user.name,
77
+ });
78
+ });
79
+ },
80
+
81
+ methods: {
82
+ async submit() {
83
+ try {
84
+ let res = await this.form.patch(`/api/users/${this.id}`);
85
+
86
+ // if changing ourselves, re-fetch user data
87
+ if (res.data.id === this.$store.state.auth.user.id) {
88
+ await this.$store.dispatch("getUser");
89
+ }
90
+
91
+ this.$router.replace({
92
+ name: "users.show",
93
+ params: { id: res.data.id },
94
+ });
95
+ } catch (e) {
96
+ console.log(e);
97
+ }
98
+ },
99
+ },
100
+ };
101
+ </script>