@fishawack/lab-velocity 2.0.0-beta.40 → 2.0.0-beta.42

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 (30) hide show
  1. package/README.md +4 -2
  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/form/Avatar.vue +86 -0
  10. package/_Build/vue/components/layout/Audit.vue +124 -56
  11. package/_Build/vue/components/layout/Layout.vue +19 -1
  12. package/_Build/vue/components/layout/TableSorter.vue +42 -12
  13. package/_Build/vue/modules/AuthModule/js/router.js +20 -36
  14. package/_Build/vue/modules/AuthModule/routes/PCompanies/columns.js +268 -0
  15. package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +173 -232
  16. package/_Build/vue/modules/AuthModule/routes/PIntegrations/resource.js +122 -0
  17. package/_Build/vue/modules/AuthModule/routes/PTeams/resource.js +1 -0
  18. package/_Build/vue/modules/AuthModule/routes/PUsers/columns.js +349 -0
  19. package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +142 -262
  20. package/_Build/vue/modules/resource/Children/create.vue +2 -2
  21. package/_Build/vue/modules/resource/Children/edit.vue +2 -2
  22. package/_Build/vue/modules/resource/Children/partials/form.vue +71 -21
  23. package/_Build/vue/modules/resource/Children/show.vue +24 -2
  24. package/_Build/vue/modules/resource/index.js +12 -4
  25. package/components/_form.scss +18 -0
  26. package/components/_menu.scss +0 -5
  27. package/index.js +16 -0
  28. package/package.json +3 -1
  29. package/_Build/vue/modules/AuthModule/routes/PCompanies/form.vue +0 -205
  30. package/_Build/vue/modules/AuthModule/routes/PUsers/form.vue +0 -193
@@ -1,17 +1,18 @@
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
+
1
9
  import VelFormRole from "../../../../components/layout/FormRole.vue";
2
10
  import VelButton from "../../../../components/basic/Button.vue";
3
- import Chip from "../../../../components/layout/Chip.vue";
4
- import Chips from "../../../../components/layout/Chips.vue";
5
11
  import VelTableSorter from "../../../../components/layout/TableSorter.vue";
6
12
  import VelRoleLegend from "../../../../components/layout/RoleLegend.vue";
7
- import component from "./form.vue";
13
+
8
14
  import userResource from "../PUsers/resource.js";
9
15
  import teamResource from "../PTeams/resource.js";
10
- import { defaultResource, meta } from "../../../resource/index.js";
11
-
12
- import { ElNotification } from "element-plus";
13
- import { h, resolveComponent } from "vue";
14
- import axios from "axios";
15
16
 
16
17
  export default [
17
18
  "companies",
@@ -33,241 +34,181 @@ export default [
33
34
  },
34
35
  singular: "company",
35
36
  icon: "icon-cases",
36
- form: {
37
- component,
38
- fields: ({ model }) => ({
39
- name: model?.name || null,
40
- primary_contact: model?.primary_contact?.id || null,
41
- domains: model?.domains || [],
42
- seats: model?.seats != null ? model.seats : null,
43
- roles:
44
- model?.roles.map((val) => ({
45
- label: val.label,
46
- value: val.id,
47
- })) || [],
48
- sso_client_id: model?.sso_client_id || undefined,
49
- sso_tenant: model?.sso_tenant || undefined,
50
- sso_client_secret: model?.sso_client_secret || undefined,
51
- sso_type: model?.sso_type || undefined,
52
- }),
53
- preparation: (props) => {
54
- const data = props.form.data();
55
- data.roles = data.roles.map((d) => d.value);
56
- return data;
37
+ auditable: true,
38
+ ...merge(columns(companiesColumns), {
39
+ index: {
40
+ layout: [
41
+ ...defaultResource.index.layout,
42
+ () =>
43
+ h(VelRoleLegend, {
44
+ class: "mt-5",
45
+ }),
46
+ ],
57
47
  },
58
- },
59
- table: {
60
- structure: () => [
61
- {
62
- key: "name",
63
- sortable: true,
64
- },
65
- {
66
- key: "user_count",
67
- label: "Total users",
68
- width: "150",
69
- },
70
- {
71
- key: "role",
72
- render: ({ model }) =>
48
+ show: {
49
+ actions: [
50
+ ({ model }) =>
51
+ model.primary_contact &&
73
52
  h(
74
- model.roles.length === 1 ? Chip : Chips,
75
- model.roles.length === 1
76
- ? {
77
- name: model.roles[0].name,
78
- label: model.roles[0].label,
79
- }
80
- : { array: model.roles },
81
- ),
82
- },
83
- ],
84
- },
85
- description: {
86
- structure: () => [
87
- {
88
- key: "domains",
89
- render: ({ model }) => h("span", model.domains.join(", ")),
90
- },
91
- {
92
- key: "sso_enabled",
93
- label: "SSO Enabled",
94
- },
95
- {
96
- key: "primary_contact",
97
- label: "Primary Contact",
98
- render: ({ model }) =>
99
- h("span", model.primary_contact?.name),
100
- },
101
- {
102
- key: "primary_contact_email",
103
- label: "Primary Contact Email",
104
- render: ({ model }) =>
105
- h("span", model.primary_contact?.email),
106
- },
107
- {
108
- key: "primary_contact_contacted",
109
- label: "Primary Contact Contacted",
110
- render: ({ model }) =>
111
- h("span", !!model.primary_contact_contacted),
112
- },
113
- {
114
- label: "Total Users",
115
- key: "user_count",
116
- },
117
- {
118
- label: "Available Seats",
119
- key: "seats",
120
- },
121
- ],
122
- },
123
- index: {
124
- layout: [
125
- ...defaultResource.index.layout,
126
- () =>
127
- h(VelRoleLegend, {
128
- class: "mt-5",
129
- }),
130
- ],
131
- },
132
- show: {
133
- actions: [
134
- ({ model }) =>
135
- model.primary_contact &&
136
- h(
137
- VelButton,
138
- {
139
- type: "primary",
140
- async onClick() {
141
- try {
142
- const res = await axios.post(
143
- `/api/companies/${model.id}/welcome`,
144
- );
145
- ElNotification({
146
- title: "Success",
147
- message: res.data.message,
148
- type: "success",
149
- });
53
+ VelButton,
54
+ {
55
+ type: "primary",
56
+ async onClick() {
57
+ try {
58
+ const res = await axios.post(
59
+ `/api/companies/${model.id}/welcome`,
60
+ );
61
+ ElNotification({
62
+ title: "Success",
63
+ message: res.data.message,
64
+ type: "success",
65
+ });
150
66
 
151
- model.primary_contact_contacted = true;
152
- } catch (e) {
153
- ElNotification({
154
- title: "Warning",
155
- message:
156
- e.response?.data?.message ||
157
- e.message,
158
- type: "warning",
159
- });
160
- }
67
+ model.primary_contact_contacted = true;
68
+ } catch (e) {
69
+ ElNotification({
70
+ title: "Warning",
71
+ message:
72
+ e.response?.data?.message ||
73
+ e.message,
74
+ type: "warning",
75
+ });
76
+ }
77
+ },
161
78
  },
162
- },
163
- "Send welcome email",
164
- ),
165
- ...defaultResource.show.actions,
166
- ],
167
- tabs: [
168
- ...defaultResource.show.tabs,
169
- ({ model }) => ({
170
- label: "Access control",
171
- component: h(VelFormRole, {
172
- overrides: model.overrides_roles_and_permissions,
173
- form: { roles: model.roles.map((d) => d.id) },
174
- readonly: true,
79
+ "Send welcome email",
80
+ ),
81
+ ...defaultResource.show.actions,
82
+ ],
83
+ tabs: [
84
+ ...defaultResource.show.tabs,
85
+ ({ model }) => ({
86
+ label: "Access control",
87
+ component: h(VelFormRole, {
88
+ overrides: model.overrides_roles_and_permissions,
89
+ form: { roles: model.roles.map((d) => d.id) },
90
+ readonly: true,
91
+ }),
175
92
  }),
176
- }),
177
- ({ model, $store, $router, $route, ...rest }) => {
178
- const resource = meta(...teamResource);
93
+ ({ model, $store, $router, $route, ...rest }) => {
94
+ const resource = meta(...teamResource);
179
95
 
180
- const props = {
181
- model,
182
- $store,
183
- $router,
184
- $route,
185
- ...rest,
186
- resource,
187
- };
96
+ const props = {
97
+ model,
98
+ $store,
99
+ $router,
100
+ $route,
101
+ ...rest,
102
+ resource,
103
+ };
188
104
 
189
- return {
190
- label: "Teams",
191
- component: h("div", [
192
- h("div", { class: "flex justify-end items-end" }, [
193
- resource.permissions.create(props) &&
194
- h(
195
- VelButton,
196
- {
197
- tag: "a",
198
- type: "primary",
199
- size: "large",
200
- onClick: () => {
201
- $router.push({
202
- name: `companies.${resource.routeName}.create`,
203
- });
204
- },
205
- },
206
- () => [
207
- h(resolveComponent("GIcon"), {
208
- class: "fill-0 mr-0.5 icon--0.5",
209
- name: "icon-plus",
210
- embed: true,
211
- artboard: true,
212
- }),
213
- `Create ${resource.singular}`,
214
- ],
215
- ),
105
+ return {
106
+ label: "Teams",
107
+ component: h("div", [
108
+ h(
109
+ "div",
110
+ { class: "flex justify-end items-end" },
111
+ [
112
+ resource.permissions.create(props) &&
113
+ h(
114
+ VelButton,
115
+ {
116
+ tag: "a",
117
+ type: "primary",
118
+ size: "large",
119
+ onClick: () => {
120
+ $router.push({
121
+ name: `companies.${resource.routeName}.create`,
122
+ });
123
+ },
124
+ },
125
+ () => [
126
+ h(
127
+ resolveComponent(
128
+ "GIcon",
129
+ ),
130
+ {
131
+ class: "fill-0 mr-0.5 icon--0.5",
132
+ name: "icon-plus",
133
+ embed: true,
134
+ artboard: true,
135
+ },
136
+ ),
137
+ `Create ${resource.singular}`,
138
+ ],
139
+ ),
140
+ ],
141
+ ),
142
+ h(
143
+ VelTableSorter,
144
+ resource.index.structure(props),
145
+ ),
216
146
  ]),
217
- h(VelTableSorter, resource.index.structure(props)),
218
- ]),
219
- };
220
- },
221
- ({ model, $store, $router, $route, ...rest }) => {
222
- const resource = meta(...userResource);
147
+ };
148
+ },
149
+ ({ model, $store, $router, $route, ...rest }) => {
150
+ const resource = meta(...userResource);
223
151
 
224
- resource.api.params.index = ({ $route }) => ({
225
- include: "company",
226
- "filter[company_id]": $route.params.companiesId,
227
- });
152
+ resource.api.params.index = ({ $route }) => ({
153
+ include: "company",
154
+ "filter[company_id]": $route.params.companiesId,
155
+ });
228
156
 
229
- const props = {
230
- model,
231
- $store,
232
- $router,
233
- $route,
234
- ...rest,
235
- resource,
236
- };
157
+ const props = {
158
+ model,
159
+ $store,
160
+ $router,
161
+ $route,
162
+ ...rest,
163
+ resource,
164
+ };
237
165
 
238
- return {
239
- label: "Users",
240
- component: h("div", [
241
- h("div", { class: "flex justify-end items-end" }, [
242
- resource.permissions.create(props) &&
243
- h(
244
- VelButton,
245
- {
246
- tag: "a",
247
- type: "primary",
248
- size: "large",
249
- onClick: () => {
250
- $router.push({
251
- name: `${resource.slug}.create`,
252
- });
253
- },
254
- },
255
- () => [
256
- h(resolveComponent("GIcon"), {
257
- class: "fill-0 mr-0.5 icon--0.5",
258
- name: "icon-plus",
259
- embed: true,
260
- artboard: true,
261
- }),
262
- `Create ${resource.singular}`,
263
- ],
264
- ),
166
+ return {
167
+ label: "Users",
168
+ component: h("div", [
169
+ h(
170
+ "div",
171
+ { class: "flex justify-end items-end" },
172
+ [
173
+ resource.permissions.create(props) &&
174
+ h(
175
+ VelButton,
176
+ {
177
+ tag: "a",
178
+ type: "primary",
179
+ size: "large",
180
+ onClick: () => {
181
+ $router.push({
182
+ name: `${resource.slug}.create`,
183
+ });
184
+ },
185
+ },
186
+ () => [
187
+ h(
188
+ resolveComponent(
189
+ "GIcon",
190
+ ),
191
+ {
192
+ class: "fill-0 mr-0.5 icon--0.5",
193
+ name: "icon-plus",
194
+ embed: true,
195
+ artboard: true,
196
+ },
197
+ ),
198
+ `Create ${resource.singular}`,
199
+ ],
200
+ ),
201
+ ],
202
+ ),
203
+ h(
204
+ VelTableSorter,
205
+ resource.index.structure(props),
206
+ ),
265
207
  ]),
266
- h(VelTableSorter, resource.index.structure(props)),
267
- ]),
268
- };
269
- },
270
- ],
271
- },
208
+ };
209
+ },
210
+ ],
211
+ },
212
+ }),
272
213
  },
273
214
  ];
@@ -0,0 +1,122 @@
1
+ import { merge } from "lodash";
2
+ import { ElMessageBox } from "element-plus";
3
+ import { h } from "vue";
4
+
5
+ import { columns } from "../../../resource/index.js";
6
+ import VelSelect from "../../../../components/form/Select.vue";
7
+
8
+ export default [
9
+ "integrations",
10
+ {
11
+ icon: `icon-keyboard-tab`,
12
+ api: {
13
+ params: {
14
+ index: () => ({ include: "user,client,accessLogsCount" }),
15
+ show: () => ({ include: "user,client,accessLogsCount" }),
16
+ },
17
+ },
18
+ searchable: {
19
+ value: "name",
20
+ },
21
+ permissions: {
22
+ create: ({ $store }) => $store.getters.can("write integrations"),
23
+ edit: ({ $store }) => $store.getters.can("write integrations"),
24
+ delete: ({ $store }) => $store.getters.can("delete integrations"),
25
+ },
26
+ ...merge(
27
+ columns([
28
+ {
29
+ key: "name",
30
+ sortable: true,
31
+ },
32
+ {
33
+ key: "scopes",
34
+ endpoint: "api/scopes",
35
+ labelKey: "description",
36
+ filterable: true,
37
+ clearable: true,
38
+ multiple: true,
39
+ initial: () => [],
40
+ preparation: ({ form }) => form.scopes.map((d) => d.id),
41
+ render: {
42
+ read: ({ model }) =>
43
+ h("span", model.client?.scopes.join(", ")),
44
+ write: () => h(VelSelect),
45
+ },
46
+ condition: {
47
+ table: false,
48
+ },
49
+ },
50
+ {
51
+ key: "client_id",
52
+ label: "Client ID",
53
+ condition: {
54
+ form: false,
55
+ },
56
+ },
57
+ {
58
+ key: "user_id",
59
+ label: "Created by",
60
+ render: {
61
+ read: ({ model }) =>
62
+ h("span", model?.user?.name ?? "System"),
63
+ },
64
+ condition: {
65
+ form: false,
66
+ },
67
+ },
68
+ {
69
+ key: "access_logs_count",
70
+ label: "API Calls",
71
+ render: {
72
+ read: ({ model }) =>
73
+ h("span", model?.access_logs_count ?? 0),
74
+ },
75
+ condition: {
76
+ form: false,
77
+ },
78
+ },
79
+ ]),
80
+ {
81
+ form: {
82
+ submit: async (props) => {
83
+ const { form, resource, $router } = props;
84
+ const hold = JSON.parse(JSON.stringify(form.data()));
85
+ try {
86
+ form.populate(resource.form.preparation(props));
87
+ let res = await form.post(
88
+ `${resource.api.endpoint(props)}`,
89
+ );
90
+ ElMessageBox.alert(
91
+ `<p>The token below will not be shown again. Ensure you've taken a copy before closing this window.<br><br><strong>Token</strong>:</p><p><em>${res.data.token}</em></p>`,
92
+ "Token minted",
93
+ {
94
+ confirmButtonText: "Ok",
95
+ dangerouslyUseHTMLString: true,
96
+ },
97
+ )
98
+ .then(() => {
99
+ $router.replace({
100
+ name: `${resource.name}.show`,
101
+ params: {
102
+ integrationsId: res.data.id,
103
+ },
104
+ });
105
+ })
106
+ .catch(() => {});
107
+ } catch (e) {
108
+ console.log(e);
109
+ } finally {
110
+ if (
111
+ !form.successful ||
112
+ !form.__options.resetOnSuccess
113
+ ) {
114
+ form.populate(hold);
115
+ }
116
+ }
117
+ },
118
+ },
119
+ },
120
+ ),
121
+ },
122
+ ];
@@ -32,6 +32,7 @@ export default [
32
32
  }),
33
33
  },
34
34
  },
35
+ auditable: true,
35
36
  permissions: {
36
37
  create: ({ $store }) => $store.getters.can("write teams"),
37
38
  edit: ({ $store }) => $store.getters.can("write teams"),