@fishawack/lab-velocity 2.0.0-beta.11 → 2.0.0-beta.13

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 (57) hide show
  1. package/README.md +148 -6
  2. package/_Build/vue/components/layout/Alert.vue +5 -5
  3. package/_Build/vue/{modules/AuthModule/components/VBreadcrumbs.vue → components/layout/Breadcrumbs.vue} +4 -4
  4. package/_Build/vue/{modules/AuthModule/components → components/layout}/Chips.vue +2 -2
  5. package/_Build/vue/components/layout/Footer.vue +11 -10
  6. package/_Build/vue/{modules/AuthModule/components/VFormFooter.vue → components/layout/FormFooter.vue} +2 -2
  7. package/_Build/vue/{modules/AuthModule/components → components/layout}/FormRole.vue +7 -7
  8. package/_Build/vue/components/layout/Layout.vue +74 -0
  9. package/_Build/vue/components/layout/Navigation.vue +77 -0
  10. package/_Build/vue/{modules/AuthModule/components/VPageHeader.vue → components/layout/PageHeader.vue} +7 -2
  11. package/_Build/vue/components/layout/SideBar.vue +26 -0
  12. package/_Build/vue/{modules/AuthModule/components/VTable.vue → components/layout/Table.vue} +6 -15
  13. package/_Build/vue/{modules/AuthModule/components/VTableSorter.vue → components/layout/TableSorter.vue} +15 -17
  14. package/_Build/vue/components/layout/pageTitle.vue +1 -1
  15. package/_Build/vue/components/navigation/MenuItem.vue +7 -2
  16. package/_Build/vue/components/navigation/MenuItemGroup.vue +7 -2
  17. package/_Build/vue/modules/AuthModule/js/router.js +21 -89
  18. package/_Build/vue/modules/AuthModule/js/store.js +13 -4
  19. package/_Build/vue/modules/AuthModule/{adminRoutes/PCompanies/Children/partials → routes/PCompanies}/form.vue +15 -8
  20. package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +180 -0
  21. package/_Build/vue/modules/AuthModule/{adminRoutes/PUsers/Children/partials → routes/PUsers}/form.vue +15 -8
  22. package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +214 -0
  23. package/_Build/vue/modules/AuthModule/routes/change-password.vue +9 -8
  24. package/_Build/vue/modules/AuthModule/routes/container.vue +2 -11
  25. package/_Build/vue/modules/AuthModule/routes/force-reset.vue +9 -8
  26. package/_Build/vue/modules/AuthModule/routes/register.vue +9 -8
  27. package/_Build/vue/modules/AuthModule/routes/reset.vue +9 -8
  28. package/_Build/vue/modules/resource/Children/create.vue +76 -0
  29. package/_Build/vue/modules/resource/Children/edit.vue +109 -0
  30. package/_Build/vue/modules/resource/Children/index.vue +51 -0
  31. package/_Build/vue/modules/resource/Children/partials/form.vue +53 -0
  32. package/_Build/vue/modules/resource/Children/show.vue +145 -0
  33. package/_Build/vue/modules/resource/index.js +112 -0
  34. package/_Build/vue/modules/resource/parent.vue +41 -0
  35. package/components/_descriptions.scss +2 -0
  36. package/components/_footer.scss +1 -0
  37. package/components/_header.scss +3 -27
  38. package/components/_layout.scss +56 -0
  39. package/components/_sidebar.scss +12 -27
  40. package/index.js +7 -1
  41. package/package.json +3 -2
  42. package/_Build/vue/components/layout/sideBar.vue +0 -25
  43. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/Upload/upload.vue +0 -259
  44. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/create.vue +0 -62
  45. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/edit.vue +0 -98
  46. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/index.vue +0 -90
  47. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/show.vue +0 -267
  48. package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/parent.vue +0 -36
  49. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/create.vue +0 -113
  50. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/edit.vue +0 -101
  51. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/index.vue +0 -112
  52. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/show.vue +0 -123
  53. package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/parent.vue +0 -36
  54. /package/_Build/vue/{modules/AuthModule/components → components/layout}/AuthModal.vue +0 -0
  55. /package/_Build/vue/{modules/AuthModule/components → components/layout}/Chip.vue +0 -0
  56. /package/_Build/vue/{modules/AuthModule/components/VPasswordValidation.vue → components/layout/PasswordValidation.vue} +0 -0
  57. /package/_Build/vue/{modules/AuthModule/components/VRoleLegend.vue → components/layout/RoleLegend.vue} +0 -0
@@ -6,7 +6,7 @@
6
6
 
7
7
  <script>
8
8
  export default {
9
- name: "VPageTitle",
9
+ name: "PageTitle",
10
10
 
11
11
  props: {
12
12
  title: {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <el-menu-item :index="index" class="vel-menu-item" v-bind="$props">
2
+ <el-menu-item class="vel-menu-item" v-bind="$props" :index="`${index}`">
3
3
  <template #title>
4
4
  <slot name="title" />
5
5
  </template>
@@ -15,6 +15,11 @@ export default {
15
15
  components: {
16
16
  ElMenuItem,
17
17
  },
18
- props: ["index"],
18
+ props: {
19
+ index: {
20
+ type: [String, Number],
21
+ required: true,
22
+ },
23
+ },
19
24
  };
20
25
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <el-sub-menu :index="index" v-bind="$props">
2
+ <el-sub-menu v-bind="$props" :index="`${index}`">
3
3
  <template #title>
4
4
  <slot name="title" />
5
5
  </template>
@@ -15,6 +15,11 @@ export default {
15
15
  components: {
16
16
  ElSubMenu,
17
17
  },
18
- props: ["index"],
18
+ props: {
19
+ index: {
20
+ type: [String, Number],
21
+ required: true,
22
+ },
23
+ },
19
24
  };
20
25
  </script>
@@ -1,10 +1,22 @@
1
1
  "use strict";
2
2
 
3
+ import { merge } from "lodash";
4
+
3
5
  import { h } from "vue";
4
6
  import { RouterView } from "vue-router";
5
7
 
8
+ import { routes as resourceRoutes } from "../../resource/index.js";
9
+
10
+ import userResource from "../routes/PUsers/resource.js";
11
+ import companyResource from "../routes/PCompanies/resource.js";
12
+
6
13
  // Admin routes export - minimal auth flow (headless login only)
7
- export function adminRoutes(node) {
14
+ export function adminRoutes(node, overrides = {}) {
15
+ const {
16
+ userResource: overrideUserResource = {},
17
+ companyResource: overrideCompanyResource = {},
18
+ } = overrides;
19
+
8
20
  return [
9
21
  {
10
22
  path: "/auth",
@@ -39,94 +51,14 @@ 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(
55
+ node,
56
+ ...merge(userResource, [undefined, overrideUserResource]),
57
+ ),
58
+ ...resourceRoutes(
59
+ node,
60
+ ...merge(companyResource, [undefined, overrideCompanyResource]),
61
+ ),
130
62
  ];
131
63
  }
132
64
 
@@ -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
 
@@ -66,14 +66,19 @@
66
66
  <VelButton @click="form.domains.push('')">
67
67
  Add Domain
68
68
 
69
- <GIcon name="icon-plus" embed asis class="fill-0 ml" />
69
+ <GIcon
70
+ name="icon-plus"
71
+ embed
72
+ asis
73
+ class="fill-0 icon--0.5 ml"
74
+ />
70
75
  </VelButton>
71
76
  </div>
72
77
 
73
78
  <hr class="my-5 hr-muted" />
74
79
 
75
80
  <template v-if="$store.getters.can('edit roles')">
76
- <FormRole :form="form" />
81
+ <VelFormRole :form="form" />
77
82
 
78
83
  <hr class="my-5 hr-muted" />
79
84
  </template>
@@ -127,22 +132,24 @@
127
132
  <hr class="my-3 hr-muted" />
128
133
  </template>
129
134
 
130
- <VFormFooter :form="form" />
135
+ <VelFormFooter :form="form" />
131
136
  </form>
132
137
  </template>
133
138
 
134
139
  <!-- eslint-disable vue/no-mutating-props -->
135
140
  <script>
136
141
  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";
142
+ import VelButton from "../../../../components/basic/Button.vue";
143
+ import VelSelect from "../../../../components/form/Select.vue";
144
+ import VelBasic from "../../../../components/form/basic.vue";
145
+ import VelFormRole from "../../../../components/layout/FormRole.vue";
146
+ import VelFormFooter from "../../../../components/layout/FormFooter.vue";
140
147
  import { ElInput } from "element-plus";
141
148
 
142
149
  export default {
143
150
  components: {
144
- VFormFooter: require("../../../../components/VFormFooter.vue").default,
145
- FormRole: require("../../../../components/FormRole.vue").default,
151
+ VelFormFooter,
152
+ VelFormRole,
146
153
  VelButton,
147
154
  VelSelect,
148
155
  VelBasic,
@@ -0,0 +1,180 @@
1
+ import VelFormRole from "../../../../components/layout/FormRole.vue";
2
+ import VelButton from "../../../../components/basic/Button.vue";
3
+ import Chip from "../../../../components/layout/Chip.vue";
4
+ import Chips from "../../../../components/layout/Chips.vue";
5
+ import VelTableSorter from "../../../../components/layout/TableSorter.vue";
6
+ import VelRoleLegend from "../../../../components/layout/RoleLegend.vue";
7
+ import component from "./form.vue";
8
+ import userResource from "../PUsers/resource.js";
9
+ import { meta } from "../../../resource/index.js";
10
+
11
+ import { ElNotification } from "element-plus";
12
+ import { h } from "vue";
13
+ import axios from "axios";
14
+
15
+ export default [
16
+ "companies",
17
+ {
18
+ defaults: "include=primary_contact",
19
+ singular: "company",
20
+ icon: "icon-cases",
21
+ form: {
22
+ component,
23
+ fields: ({ model }) => ({
24
+ name: model?.name || null,
25
+ primary_contact: model?.primary_contact?.id || null,
26
+ domains: model?.domains || [],
27
+ roles: model?.roles.map((val) => val.id) || [],
28
+ sso_client_id: model?.sso_client_id || undefined,
29
+ sso_tenant: model?.sso_tenant || undefined,
30
+ sso_client_secret: model?.sso_client_secret || undefined,
31
+ sso_type: model?.sso_type || undefined,
32
+ }),
33
+ },
34
+ table: {
35
+ structure: [
36
+ {
37
+ label: "Name",
38
+ key: "name",
39
+ sortable: true,
40
+ },
41
+ {
42
+ label: "Total users",
43
+ key: "user_count",
44
+ sortable: false,
45
+ width: "150",
46
+ },
47
+ {
48
+ label: "Role",
49
+ render: (row) =>
50
+ h(
51
+ row.roles.length === 1 ? Chip : Chips,
52
+ row.roles.length === 1
53
+ ? {
54
+ name: row.roles[0].name,
55
+ label: row.roles[0].label,
56
+ }
57
+ : { array: row.roles },
58
+ ),
59
+ },
60
+ ],
61
+ },
62
+ index: {
63
+ structure: [
64
+ {
65
+ render: ({ resource, $store }) =>
66
+ h(VelTableSorter, {
67
+ key: "PIndex",
68
+ "json-data": {
69
+ ...resource,
70
+ tableStructure: resource.table.structure,
71
+ },
72
+ defaults: resource.defaults,
73
+ "fixed-height": false,
74
+ "display-edit-action":
75
+ $store.getters.can("write companies"),
76
+ }),
77
+ },
78
+ {
79
+ render: () =>
80
+ h(VelRoleLegend, {
81
+ class: "mt-5",
82
+ }),
83
+ },
84
+ ],
85
+ },
86
+ show: {
87
+ actions: [
88
+ {
89
+ render: ({ model }) =>
90
+ model.primary_contact &&
91
+ h(
92
+ VelButton,
93
+ {
94
+ type: "primary",
95
+ async onClick() {
96
+ try {
97
+ const res = await axios.post(
98
+ `/api/companies/${model.id}/welcome`,
99
+ );
100
+ ElNotification({
101
+ title: "Success",
102
+ message: res.data.message,
103
+ type: "success",
104
+ });
105
+
106
+ model.primary_contact_contacted = true;
107
+ } catch (e) {
108
+ ElNotification({
109
+ title: "Warning",
110
+ message:
111
+ e.response?.data?.message ||
112
+ e.message,
113
+ type: "warning",
114
+ });
115
+ }
116
+ },
117
+ },
118
+ "Send welcome email",
119
+ ),
120
+ },
121
+ ],
122
+ structure: [
123
+ [
124
+ {
125
+ label: "Domains",
126
+ render: ({ model }) =>
127
+ h("span", model.domains.join(", ")),
128
+ },
129
+ {
130
+ label: "SSO Enabled",
131
+ key: "sso_enabled",
132
+ },
133
+ {
134
+ label: "Primary Contact",
135
+ render: ({ model }) =>
136
+ h("span", model.primary_contact?.name),
137
+ },
138
+ {
139
+ label: "Primary Contact Email",
140
+ render: ({ model }) =>
141
+ h("span", model.primary_contact?.email),
142
+ },
143
+ {
144
+ label: "Primary Contact Contacted",
145
+ render: ({ model }) =>
146
+ h("span", !!model.primary_contact_contacted),
147
+ },
148
+ {
149
+ label: "Total users",
150
+ key: "user_count",
151
+ },
152
+ ],
153
+ {
154
+ render: ({ model }) =>
155
+ h(VelFormRole, {
156
+ overrides: model.overrides_roles_and_permissions,
157
+ form: { roles: model.roles.map((d) => d.id) },
158
+ readonly: true,
159
+ }),
160
+ },
161
+ {
162
+ render: ({ model, $store }) => {
163
+ const resource = meta(...userResource);
164
+ return h(VelTableSorter, {
165
+ key: "PIndex",
166
+ "json-data": {
167
+ ...resource,
168
+ tableStructure: resource.table.structure,
169
+ },
170
+ defaults: `include=company&filter[company_id]=${model.id}`,
171
+ "fixed-height": false,
172
+ "display-edit-action":
173
+ $store.getters.can("write users"),
174
+ });
175
+ },
176
+ },
177
+ ],
178
+ },
179
+ },
180
+ ];
@@ -74,11 +74,16 @@
74
74
  >
75
75
  Reset roles
76
76
  </VelButton>
77
- <FormRole :form="form" />
77
+ <VelFormRole :form="form" />
78
78
  </template>
79
79
  <template v-else>
80
80
  <VelButton @click="enableRoles = true">
81
- <GIcon name="icon-plus" embed asis class="fill-0 mr" />
81
+ <GIcon
82
+ name="icon-plus"
83
+ embed
84
+ asis
85
+ class="fill-0 icon--0.5 mr"
86
+ />
82
87
  Override roles
83
88
  </VelButton>
84
89
  <p class="mt-2">
@@ -88,21 +93,23 @@
88
93
  <hr class="my-5 hr-muted" />
89
94
  </template>
90
95
 
91
- <VFormFooter :loading="form.processing" />
96
+ <VelFormFooter :loading="form.processing" />
92
97
  </form>
93
98
  </template>
94
99
 
95
100
  <script>
96
101
  import axios from "axios";
97
102
  import { debounce } from "lodash";
98
- import VelButton from "../../../../../../components/basic/Button.vue";
99
- import VelCheckbox from "../../../../../../components/form/Checkbox.vue";
100
- import VelBasic from "../../../../../../components/form/basic.vue";
103
+ import VelButton from "../../../../components/basic/Button.vue";
104
+ import VelCheckbox from "../../../../components/form/Checkbox.vue";
105
+ import VelBasic from "../../../../components/form/basic.vue";
106
+ import VelFormRole from "../../../../components/layout/FormRole.vue";
107
+ import VelFormFooter from "../../../../components/layout/FormFooter.vue";
101
108
 
102
109
  export default {
103
110
  components: {
104
- VFormFooter: require("../../../../components/VFormFooter.vue").default,
105
- FormRole: require("../../../../components/FormRole.vue").default,
111
+ VelFormFooter,
112
+ VelFormRole,
106
113
  VelCheckbox,
107
114
  VelButton,
108
115
  VelBasic,