@fishawack/lab-velocity 2.0.0-beta.4 → 2.0.0-beta.41

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 (110) hide show
  1. package/README.md +441 -37
  2. package/_Build/vue/components/basic/Button.vue +1 -1
  3. package/_Build/vue/components/form/Checkbox.vue +10 -0
  4. package/_Build/vue/components/form/Select.vue +223 -33
  5. package/_Build/vue/components/form/Spinner.vue +5 -0
  6. package/_Build/vue/components/layout/Alert.vue +5 -5
  7. package/_Build/vue/components/layout/Audit.vue +75 -0
  8. package/_Build/vue/{modules/AuthModule/components/VBreadcrumbs.vue → components/layout/Breadcrumbs.vue} +4 -4
  9. package/_Build/vue/{modules/AuthModule/components → components/layout}/Chips.vue +2 -2
  10. package/_Build/vue/components/layout/Footer.vue +11 -10
  11. package/_Build/vue/{modules/AuthModule/components/VFormFooter.vue → components/layout/FormFooter.vue} +13 -7
  12. package/_Build/vue/{modules/AuthModule/components → components/layout}/FormRole.vue +10 -8
  13. package/_Build/vue/components/layout/Layout.vue +76 -0
  14. package/_Build/vue/components/layout/Navigation.vue +77 -0
  15. package/_Build/vue/{modules/AuthModule/components/VPageHeader.vue → components/layout/PageHeader.vue} +7 -2
  16. package/_Build/vue/components/layout/SideBar.vue +26 -0
  17. package/_Build/vue/{modules/AuthModule/components/VTable.vue → components/layout/Table.vue} +32 -16
  18. package/_Build/vue/{modules/AuthModule/components/VTableSorter.vue → components/layout/TableSorter.vue} +68 -43
  19. package/_Build/vue/components/layout/pageTitle.vue +1 -1
  20. package/_Build/vue/components/navigation/MenuItem.vue +7 -2
  21. package/_Build/vue/components/navigation/MenuItemGroup.vue +7 -2
  22. package/_Build/vue/modules/AuthModule/js/axios.js +19 -0
  23. package/_Build/vue/modules/AuthModule/js/router.js +24 -89
  24. package/_Build/vue/modules/AuthModule/js/store.js +15 -6
  25. package/_Build/vue/modules/AuthModule/routes/PCompanies/columns.js +268 -0
  26. package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +213 -0
  27. package/_Build/vue/modules/AuthModule/routes/PTeams/resource.js +334 -0
  28. package/_Build/vue/modules/AuthModule/routes/PUsers/columns.js +349 -0
  29. package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +203 -0
  30. package/_Build/vue/modules/AuthModule/routes/account-exists.vue +2 -2
  31. package/_Build/vue/modules/AuthModule/routes/change-password.vue +23 -24
  32. package/_Build/vue/modules/AuthModule/routes/container.vue +2 -11
  33. package/_Build/vue/modules/AuthModule/routes/expired-reset.vue +4 -4
  34. package/_Build/vue/modules/AuthModule/routes/expired-verification.vue +9 -8
  35. package/_Build/vue/modules/AuthModule/routes/force-reset.vue +39 -50
  36. package/_Build/vue/modules/AuthModule/routes/forgot.vue +4 -4
  37. package/_Build/vue/modules/AuthModule/routes/login.vue +7 -11
  38. package/_Build/vue/modules/AuthModule/routes/logincallback.vue +1 -3
  39. package/_Build/vue/modules/AuthModule/routes/loginsso.vue +7 -9
  40. package/_Build/vue/modules/AuthModule/routes/logout.vue +1 -3
  41. package/_Build/vue/modules/AuthModule/routes/logoutheadless.vue +1 -3
  42. package/_Build/vue/modules/AuthModule/routes/register.vue +19 -21
  43. package/_Build/vue/modules/AuthModule/routes/reset.vue +14 -13
  44. package/_Build/vue/modules/AuthModule/routes/success-forgot.vue +8 -7
  45. package/_Build/vue/modules/AuthModule/routes/success-reset.vue +2 -2
  46. package/_Build/vue/modules/AuthModule/routes/success-verify.vue +1 -3
  47. package/_Build/vue/modules/AuthModule/routes/verify.vue +11 -14
  48. package/_Build/vue/modules/resource/Children/create.vue +81 -0
  49. package/_Build/vue/modules/resource/Children/edit.vue +106 -0
  50. package/_Build/vue/modules/resource/Children/index.vue +42 -0
  51. package/_Build/vue/modules/resource/Children/partials/form.vue +61 -0
  52. package/_Build/vue/modules/resource/Children/show.vue +144 -0
  53. package/_Build/vue/modules/resource/index.js +545 -0
  54. package/_Build/vue/modules/resource/parent.vue +63 -0
  55. package/_base.scss +0 -1
  56. package/_defaults.scss +2 -13
  57. package/_variables.scss +9 -4
  58. package/components/_alert.scss +5 -0
  59. package/components/_auth.scss +163 -0
  60. package/components/_basic.scss +55 -0
  61. package/components/_breadcrumbs.scss +39 -0
  62. package/components/_button.scss +304 -0
  63. package/components/_cascader.scss +12 -0
  64. package/components/_checkbox.scss +41 -0
  65. package/components/_chip.scss +24 -0
  66. package/components/_collapse.scss +24 -0
  67. package/components/_datepicker.scss +53 -0
  68. package/components/_descriptions.scss +2 -0
  69. package/components/_footer.scss +47 -0
  70. package/components/_form.scss +24 -0
  71. package/components/_header.scss +30 -0
  72. package/components/_icon.scss +25 -0
  73. package/components/_inputNumber.scss +22 -0
  74. package/components/_layout.scss +56 -0
  75. package/components/_link.scss +44 -0
  76. package/components/_loader.scss +43 -0
  77. package/components/_menu.scss +112 -0
  78. package/components/_modal.scss +24 -0
  79. package/components/_pageTitle.scss +8 -0
  80. package/components/_permissionLegend.scss +18 -0
  81. package/components/_select.scss +29 -0
  82. package/components/_sidebar.scss +41 -0
  83. package/components/_switch.scss +14 -0
  84. package/components/_table.scss +20 -0
  85. package/components/_tooltip.scss +4 -0
  86. package/components/_typography.scss +162 -0
  87. package/components/_upload.scss +15 -0
  88. package/components/_wysiwyg.scss +7 -0
  89. package/components/_wysiwyg2.scss +142 -0
  90. package/index.js +16 -1
  91. package/package.json +5 -3
  92. package/vendor.scss +0 -1
  93. package/_Build/vue/components/layout/sideBar.vue +0 -25
  94. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/Upload/upload.vue +0 -251
  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 -173
  99. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/show.vue +0 -262
  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 -169
  105. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/show.vue +0 -120
  106. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/parent.vue +0 -36
  107. /package/_Build/vue/{modules/AuthModule/components → components/layout}/AuthModal.vue +0 -0
  108. /package/_Build/vue/{modules/AuthModule/components → components/layout}/Chip.vue +0 -0
  109. /package/_Build/vue/{modules/AuthModule/components/VPasswordValidation.vue → components/layout/PasswordValidation.vue} +0 -0
  110. /package/_Build/vue/{modules/AuthModule/components/VRoleLegend.vue → components/layout/RoleLegend.vue} +0 -0
@@ -3,8 +3,20 @@
3
3
  import { h } from "vue";
4
4
  import { RouterView } from "vue-router";
5
5
 
6
+ import { routes as resourceRoutes } from "../../resource/index.js";
7
+
8
+ import defaultUserResource from "../routes/PUsers/resource.js";
9
+ import defaultCompanyResource from "../routes/PCompanies/resource.js";
10
+ import defaultTeamResource from "../routes/PTeams/resource.js";
11
+
6
12
  // Admin routes export - minimal auth flow (headless login only)
7
- export function adminRoutes(node) {
13
+ export function adminRoutes(node, overrides = {}) {
14
+ const {
15
+ userResource = defaultUserResource,
16
+ companyResource = defaultCompanyResource,
17
+ teamResource = defaultTeamResource,
18
+ } = overrides;
19
+
8
20
  return [
9
21
  {
10
22
  path: "/auth",
@@ -39,94 +51,17 @@ export function adminRoutes(node) {
39
51
  },
40
52
  ],
41
53
  },
42
- {
43
- path: "/users",
44
- component: node
45
- ? ""
46
- : require("../adminRoutes/PUsers/parent.vue").default,
47
- children: [
48
- {
49
- path: "",
50
- component: node
51
- ? ""
52
- : require("../adminRoutes/PUsers/Children/index.vue")
53
- .default,
54
- name: "users.index",
55
- },
56
- {
57
- path: "create",
58
- component: node
59
- ? ""
60
- : require("../adminRoutes/PUsers/Children/create.vue")
61
- .default,
62
- name: "users.create",
63
- },
64
- {
65
- path: ":id",
66
- component: node
67
- ? ""
68
- : require("../adminRoutes/PUsers/Children/show.vue")
69
- .default,
70
- name: "users.show",
71
- },
72
- {
73
- path: ":id/edit",
74
- component: node
75
- ? ""
76
- : require("../adminRoutes/PUsers/Children/edit.vue")
77
- .default,
78
- name: "users.edit",
79
- },
80
- ],
81
- },
82
- {
83
- path: "/companies",
84
- component: node
85
- ? ""
86
- : require("../adminRoutes/PCompanies/parent.vue").default,
87
- children: [
88
- {
89
- path: "",
90
- component: node
91
- ? ""
92
- : require("../adminRoutes/PCompanies/Children/index.vue")
93
- .default,
94
- name: "companies.index",
95
- },
96
- {
97
- path: "create",
98
- component: node
99
- ? ""
100
- : require("../adminRoutes/PCompanies/Children/create.vue")
101
- .default,
102
- name: "companies.create",
103
- },
104
- {
105
- path: ":id",
106
- component: node
107
- ? ""
108
- : require("../adminRoutes/PCompanies/Children/show.vue")
109
- .default,
110
- name: "companies.show",
111
- },
112
- {
113
- path: ":id/edit",
114
- component: node
115
- ? ""
116
- : require("../adminRoutes/PCompanies/Children/edit.vue")
117
- .default,
118
- name: "companies.edit",
119
- },
120
- {
121
- path: ":id/upload",
122
- component: node
123
- ? ""
124
- : require("../adminRoutes/PCompanies/Children/Upload/upload.vue")
125
- .default,
126
- name: "companies.upload",
127
- },
128
- ],
129
- },
54
+ ...resourceRoutes(node, ...userResource),
55
+ ...resourceRoutes(node, ...companyResource, [
56
+ ...resourceRoutes(node, teamResource[0], {
57
+ ...teamResource[1],
58
+ routeName: "companies.teams",
59
+ }),
60
+ ]),
61
+ ...resourceRoutes(node, teamResource[0], {
62
+ ...teamResource[1],
63
+ routeName: "teams",
64
+ }),
130
65
  ];
131
66
  }
132
67
 
@@ -7,6 +7,9 @@ const store = {
7
7
  intended: null,
8
8
  user: null,
9
9
  redirect: process.env.HYDRATE_REDIRECT ?? "index",
10
+ logo: process.env.HYDRATE_LOGO ?? "example-logo",
11
+ logoReverse:
12
+ process.env.HYDRATE_LOGO_REVERSE ?? process.env.HYDRATE_LOGO,
10
13
  contact:
11
14
  process.env.HYDRATE_CONTACT ?? "mailto:det@avalerehealth.com",
12
15
  };
@@ -15,12 +18,18 @@ const store = {
15
18
  getters: {
16
19
  authenticated: (state) => !!state.user,
17
20
  can: (state) => (permission) => {
18
- return state.user?.permissions
19
- .map(({ name }) => name)
20
- .includes(permission);
21
+ const arr = Array.isArray(permission) ? permission : [permission];
22
+ const userPermissions = state.user?.permissions.map(
23
+ ({ name }) => name,
24
+ );
25
+
26
+ return arr.every((name) => userPermissions?.includes(name));
21
27
  },
22
28
  hasRole: (state) => (role) => {
23
- return state.user?.roles.map(({ name }) => name).includes(role);
29
+ const arr = Array.isArray(role) ? role : [role];
30
+ const userRoles = state.user?.roles.map(({ name }) => name);
31
+
32
+ return arr.every((name) => userRoles?.includes(name));
24
33
  },
25
34
  },
26
35
 
@@ -38,7 +47,7 @@ const store = {
38
47
  },
39
48
 
40
49
  actions: {
41
- getUser({ commit }, { errors, query = "", params }) {
50
+ getUser({ commit }, { errors = console.log, query = "", params } = {}) {
42
51
  return axios
43
52
  .get(`/api/users/self${query}`, {
44
53
  params,
@@ -51,7 +60,7 @@ const store = {
51
60
  .catch(errors);
52
61
  },
53
62
 
54
- logout({ commit }, { errors }) {
63
+ logout({ commit }) {
55
64
  commit("setUser", null);
56
65
 
57
66
  return axios.post("/logout");
@@ -0,0 +1,268 @@
1
+ import { h, resolveComponent } from "vue";
2
+ import { ElInput } from "element-plus";
3
+
4
+ import VelBasic from "../../../../components/form/basic.vue";
5
+ import VelButton from "../../../../components/basic/Button.vue";
6
+ import VelSelect from "../../../../components/form/Select.vue";
7
+ import VelFormRole from "../../../../components/layout/FormRole.vue";
8
+ import Chip from "../../../../components/layout/Chip.vue";
9
+ import Chips from "../../../../components/layout/Chips.vue";
10
+
11
+ export default [
12
+ {
13
+ key: "name",
14
+ sortable: true,
15
+ },
16
+ {
17
+ key: "primary_contact",
18
+ label: "Primary Contact",
19
+ condition: {
20
+ table: false,
21
+ form: {
22
+ write: ({ method }) => method === "patch",
23
+ },
24
+ },
25
+ preparation: ({ form }) => form.primary_contact?.id,
26
+ render: {
27
+ read: ({ model }) => h("span", model.primary_contact?.name),
28
+ write: ({ $route }) =>
29
+ h(VelSelect, {
30
+ endpoint: `api/users`,
31
+ params: {
32
+ "filter[company_id]": $route.params.companiesId,
33
+ },
34
+ labelKey: "name",
35
+ filterable: true,
36
+ searchParam: "name",
37
+ }),
38
+ },
39
+ },
40
+ {
41
+ key: "primary_contact_email",
42
+ label: "Primary Contact Email",
43
+ condition: {
44
+ table: false,
45
+ form: false,
46
+ },
47
+ render: {
48
+ read: ({ model }) => h("span", model.primary_contact?.email),
49
+ },
50
+ },
51
+ {
52
+ key: "primary_contact_contacted",
53
+ label: "Primary Contact Contacted",
54
+ condition: {
55
+ table: false,
56
+ form: false,
57
+ },
58
+ render: {
59
+ read: ({ model }) =>
60
+ h("span", String(!!model.primary_contact_contacted)),
61
+ },
62
+ },
63
+ {
64
+ key: "domains",
65
+ condition: {
66
+ table: false,
67
+ },
68
+ initial: ({ model }) => model?.domains || [],
69
+ render: {
70
+ read: ({ model }) => h("span", model.domains.join(", ")),
71
+ write: ({ form }) =>
72
+ h("div", { class: "form__group vel-basic" }, [
73
+ h("p", { class: "my-0" }, [
74
+ "Domain/s ",
75
+ h("sup", { class: "color-status-red-100" }, "*"),
76
+ ]),
77
+ h(
78
+ "ul",
79
+ { class: "list-none pl-0 mt mb-2" },
80
+ form.domains.map((domain, index) =>
81
+ h("li", { key: index, class: "mb-0.5" }, [
82
+ h(
83
+ ElInput,
84
+ {
85
+ modelValue: form.domains[index],
86
+ "onUpdate:modelValue": (val) => {
87
+ form.domains[index] = val;
88
+ },
89
+ placeholder: "avalerehealth.com",
90
+ },
91
+ {
92
+ prepend: () => "@",
93
+ append: () =>
94
+ h(
95
+ VelButton,
96
+ {
97
+ type: "danger",
98
+ onClick: () =>
99
+ form.domains.splice(
100
+ index,
101
+ 1,
102
+ ),
103
+ },
104
+ () =>
105
+ h(
106
+ resolveComponent(
107
+ "GSvg",
108
+ ),
109
+ {
110
+ class: "vel-icon",
111
+ name: "icon-trash",
112
+ },
113
+ ),
114
+ ),
115
+ },
116
+ ),
117
+ form.errors?.has?.(`domains.${index}`) &&
118
+ h(
119
+ "small",
120
+ {
121
+ class: "form__error vel-basic__error",
122
+ },
123
+ form.errors.first(`domains.${index}`),
124
+ ),
125
+ ]),
126
+ ),
127
+ ),
128
+ h("div", [
129
+ h(
130
+ VelButton,
131
+ {
132
+ onClick: () => form.domains.push(""),
133
+ },
134
+ () => [
135
+ "Add Domain ",
136
+ h(resolveComponent("GIcon"), {
137
+ name: "icon-plus",
138
+ embed: true,
139
+ asis: true,
140
+ class: "fill-0 icon--0.5 ml",
141
+ }),
142
+ ],
143
+ ),
144
+ ]),
145
+ ]),
146
+ },
147
+ },
148
+ {
149
+ key: "seats",
150
+ label: "Available Seats",
151
+ type: "number",
152
+ min: 0,
153
+ condition: {
154
+ table: false,
155
+ },
156
+ },
157
+ {
158
+ key: "user_count",
159
+ label: "Total Users",
160
+ width: "150",
161
+ condition: {
162
+ form: false,
163
+ },
164
+ },
165
+ {
166
+ key: "sso_enabled",
167
+ label: "SSO Enabled",
168
+ condition: {
169
+ table: false,
170
+ form: false,
171
+ },
172
+ },
173
+ {
174
+ key: "roles",
175
+ label: "Role",
176
+ condition: {
177
+ description: false,
178
+ form: {
179
+ write: ({ $store }) => $store.getters.can("edit roles"),
180
+ },
181
+ },
182
+ initial: ({ model }) =>
183
+ model?.roles.map((val) => ({
184
+ label: val.label,
185
+ value: val.id,
186
+ })) || [],
187
+ preparation: ({ form }) =>
188
+ form.roles.map((d) => (typeof d === "object" ? d.value : d)),
189
+ render: {
190
+ read: ({ model }) =>
191
+ h(
192
+ model.roles.length === 1 ? Chip : Chips,
193
+ model.roles.length === 1
194
+ ? {
195
+ name: model.roles[0].name,
196
+ label: model.roles[0].label,
197
+ }
198
+ : { array: model.roles },
199
+ ),
200
+ write: ({ model, form }) =>
201
+ h(VelFormRole, {
202
+ overrides: model?.overrides_roles_and_permissions,
203
+ form,
204
+ }),
205
+ },
206
+ },
207
+ {
208
+ key: "sso_type",
209
+ label: "Provider",
210
+ condition: {
211
+ table: false,
212
+ description: false,
213
+ form: {
214
+ write: ({ $store }) => $store.getters.can("edit sso"),
215
+ },
216
+ },
217
+ initial: ({ model }) => model?.sso_type || undefined,
218
+ preparation: ({ form }) => form.sso_type?.value,
219
+ render: {
220
+ write: () =>
221
+ h(VelSelect, {
222
+ clearable: true,
223
+ class: "mt-2",
224
+ options: [
225
+ { value: "azure", label: "azure" },
226
+ { value: "google", label: "google" },
227
+ ],
228
+ }),
229
+ },
230
+ },
231
+ {
232
+ key: "sso_client_id",
233
+ label: "Key",
234
+ condition: {
235
+ table: false,
236
+ description: false,
237
+ form: {
238
+ write: ({ $store }) => $store.getters.can("edit sso"),
239
+ },
240
+ },
241
+ initial: ({ model }) => model?.sso_client_id || undefined,
242
+ },
243
+ {
244
+ key: "sso_tenant",
245
+ label: "Tenant",
246
+ condition: {
247
+ table: false,
248
+ description: false,
249
+ form: {
250
+ write: ({ $store }) => $store.getters.can("edit sso"),
251
+ },
252
+ },
253
+ initial: ({ model }) => model?.sso_tenant || undefined,
254
+ },
255
+ {
256
+ key: "sso_client_secret",
257
+ label: "Secret",
258
+ type: "password",
259
+ condition: {
260
+ table: false,
261
+ description: false,
262
+ form: {
263
+ write: ({ $store }) => $store.getters.can("edit sso"),
264
+ },
265
+ },
266
+ initial: ({ model }) => model?.sso_client_secret || undefined,
267
+ },
268
+ ];
@@ -0,0 +1,213 @@
1
+ import { merge } from "lodash";
2
+ import { h, resolveComponent } from "vue";
3
+ import axios from "axios";
4
+ import { ElNotification } from "element-plus";
5
+
6
+ import { columns, defaultResource, meta } from "../../../resource/index.js";
7
+ import companiesColumns from "./columns.js";
8
+
9
+ import VelFormRole from "../../../../components/layout/FormRole.vue";
10
+ import VelButton from "../../../../components/basic/Button.vue";
11
+ import VelTableSorter from "../../../../components/layout/TableSorter.vue";
12
+ import VelRoleLegend from "../../../../components/layout/RoleLegend.vue";
13
+
14
+ import userResource from "../PUsers/resource.js";
15
+ import teamResource from "../PTeams/resource.js";
16
+
17
+ export default [
18
+ "companies",
19
+ {
20
+ api: {
21
+ params: {
22
+ index: ({ $route }) => ({
23
+ "filter[withTrashed]": $route.query.trashed,
24
+ }),
25
+ show: () => ({
26
+ include: "primary_contact",
27
+ }),
28
+ },
29
+ },
30
+ permissions: {
31
+ create: ({ $store }) => $store.getters.can("write companies"),
32
+ edit: ({ $store }) => $store.getters.can("write companies"),
33
+ delete: ({ $store }) => $store.getters.can("delete companies"),
34
+ },
35
+ singular: "company",
36
+ icon: "icon-cases",
37
+ ...merge(columns(companiesColumns), {
38
+ index: {
39
+ layout: [
40
+ ...defaultResource.index.layout,
41
+ () =>
42
+ h(VelRoleLegend, {
43
+ class: "mt-5",
44
+ }),
45
+ ],
46
+ },
47
+ show: {
48
+ actions: [
49
+ ({ model }) =>
50
+ model.primary_contact &&
51
+ h(
52
+ VelButton,
53
+ {
54
+ type: "primary",
55
+ async onClick() {
56
+ try {
57
+ const res = await axios.post(
58
+ `/api/companies/${model.id}/welcome`,
59
+ );
60
+ ElNotification({
61
+ title: "Success",
62
+ message: res.data.message,
63
+ type: "success",
64
+ });
65
+
66
+ model.primary_contact_contacted = true;
67
+ } catch (e) {
68
+ ElNotification({
69
+ title: "Warning",
70
+ message:
71
+ e.response?.data?.message ||
72
+ e.message,
73
+ type: "warning",
74
+ });
75
+ }
76
+ },
77
+ },
78
+ "Send welcome email",
79
+ ),
80
+ ...defaultResource.show.actions,
81
+ ],
82
+ tabs: [
83
+ ...defaultResource.show.tabs,
84
+ ({ model }) => ({
85
+ label: "Access control",
86
+ component: h(VelFormRole, {
87
+ overrides: model.overrides_roles_and_permissions,
88
+ form: { roles: model.roles.map((d) => d.id) },
89
+ readonly: true,
90
+ }),
91
+ }),
92
+ ({ model, $store, $router, $route, ...rest }) => {
93
+ const resource = meta(...teamResource);
94
+
95
+ const props = {
96
+ model,
97
+ $store,
98
+ $router,
99
+ $route,
100
+ ...rest,
101
+ resource,
102
+ };
103
+
104
+ return {
105
+ label: "Teams",
106
+ component: h("div", [
107
+ h(
108
+ "div",
109
+ { class: "flex justify-end items-end" },
110
+ [
111
+ resource.permissions.create(props) &&
112
+ h(
113
+ VelButton,
114
+ {
115
+ tag: "a",
116
+ type: "primary",
117
+ size: "large",
118
+ onClick: () => {
119
+ $router.push({
120
+ name: `companies.${resource.routeName}.create`,
121
+ });
122
+ },
123
+ },
124
+ () => [
125
+ h(
126
+ resolveComponent(
127
+ "GIcon",
128
+ ),
129
+ {
130
+ class: "fill-0 mr-0.5 icon--0.5",
131
+ name: "icon-plus",
132
+ embed: true,
133
+ artboard: true,
134
+ },
135
+ ),
136
+ `Create ${resource.singular}`,
137
+ ],
138
+ ),
139
+ ],
140
+ ),
141
+ h(
142
+ VelTableSorter,
143
+ resource.index.structure(props),
144
+ ),
145
+ ]),
146
+ };
147
+ },
148
+ ({ model, $store, $router, $route, ...rest }) => {
149
+ const resource = meta(...userResource);
150
+
151
+ resource.api.params.index = ({ $route }) => ({
152
+ include: "company",
153
+ "filter[company_id]": $route.params.companiesId,
154
+ });
155
+
156
+ const props = {
157
+ model,
158
+ $store,
159
+ $router,
160
+ $route,
161
+ ...rest,
162
+ resource,
163
+ };
164
+
165
+ return {
166
+ label: "Users",
167
+ component: h("div", [
168
+ h(
169
+ "div",
170
+ { class: "flex justify-end items-end" },
171
+ [
172
+ resource.permissions.create(props) &&
173
+ h(
174
+ VelButton,
175
+ {
176
+ tag: "a",
177
+ type: "primary",
178
+ size: "large",
179
+ onClick: () => {
180
+ $router.push({
181
+ name: `${resource.slug}.create`,
182
+ });
183
+ },
184
+ },
185
+ () => [
186
+ h(
187
+ resolveComponent(
188
+ "GIcon",
189
+ ),
190
+ {
191
+ class: "fill-0 mr-0.5 icon--0.5",
192
+ name: "icon-plus",
193
+ embed: true,
194
+ artboard: true,
195
+ },
196
+ ),
197
+ `Create ${resource.singular}`,
198
+ ],
199
+ ),
200
+ ],
201
+ ),
202
+ h(
203
+ VelTableSorter,
204
+ resource.index.structure(props),
205
+ ),
206
+ ]),
207
+ };
208
+ },
209
+ ],
210
+ },
211
+ }),
212
+ },
213
+ ];