@fishawack/lab-velocity 2.0.0-beta.5 → 2.0.0-beta.51
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.
- package/README.md +467 -36
- package/_Build/js/libs/build-id.js +14 -0
- package/_Build/js/libs/filters.js +36 -0
- package/_Build/js/libs/globals.js +7 -0
- package/_Build/js/libs/router.js +22 -0
- package/_Build/js/libs/routes.js +29 -0
- package/_Build/js/libs/store.js +21 -0
- package/_Build/js/libs/utility.js +161 -0
- package/_Build/vue/components/basic/Button.vue +1 -1
- package/_Build/vue/components/form/Avatar.vue +90 -0
- package/_Build/vue/components/form/Checkbox.vue +10 -0
- package/_Build/vue/components/form/InputNumber.vue +1 -1
- package/_Build/vue/components/form/Select.vue +223 -33
- package/_Build/vue/components/form/Spinner.vue +5 -0
- package/_Build/vue/components/layout/Alert.vue +5 -5
- package/_Build/vue/components/layout/Audit.vue +143 -0
- package/_Build/vue/{modules/AuthModule/components/VBreadcrumbs.vue → components/layout/Breadcrumbs.vue} +4 -4
- package/_Build/vue/{modules/AuthModule/components → components/layout}/Chips.vue +2 -2
- package/_Build/vue/components/layout/Footer.vue +11 -10
- package/_Build/vue/{modules/AuthModule/components/VFormFooter.vue → components/layout/FormFooter.vue} +13 -7
- package/_Build/vue/{modules/AuthModule/components → components/layout}/FormRole.vue +10 -8
- package/_Build/vue/components/layout/Layout.vue +94 -0
- package/_Build/vue/components/layout/Navigation.vue +77 -0
- package/_Build/vue/{modules/AuthModule/components/VPageHeader.vue → components/layout/PageHeader.vue} +14 -8
- package/_Build/vue/components/layout/SideBar.vue +26 -0
- package/_Build/vue/{modules/AuthModule/components/VTable.vue → components/layout/Table.vue} +37 -16
- package/_Build/vue/{modules/AuthModule/components/VTableSorter.vue → components/layout/TableSorter.vue} +108 -52
- package/_Build/vue/components/layout/TokenDisplay.vue +52 -0
- package/_Build/vue/components/layout/pageTitle.vue +1 -1
- package/_Build/vue/components/navigation/MenuItem.vue +7 -2
- package/_Build/vue/components/navigation/MenuItemGroup.vue +7 -2
- package/_Build/vue/modules/AuthModule/js/axios.js +21 -1
- package/_Build/vue/modules/AuthModule/js/clear-cookies.js +33 -0
- package/_Build/vue/modules/AuthModule/js/guest-request.js +32 -0
- package/_Build/vue/modules/AuthModule/js/impersonation-banner.js +102 -0
- package/_Build/vue/modules/AuthModule/js/router.js +91 -114
- package/_Build/vue/modules/AuthModule/js/store.js +23 -6
- package/_Build/vue/modules/AuthModule/routes/PCompanies/columns.js +268 -0
- package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +213 -0
- package/_Build/vue/modules/AuthModule/routes/PIntegrations/columns.js +58 -0
- package/_Build/vue/modules/AuthModule/routes/PIntegrations/resource.js +79 -0
- package/_Build/vue/modules/AuthModule/routes/PTeams/columns.js +78 -0
- package/_Build/vue/modules/AuthModule/routes/PTeams/resource.js +251 -0
- package/_Build/vue/modules/AuthModule/routes/PUsers/SetPasswordAction.vue +51 -0
- package/_Build/vue/modules/AuthModule/routes/PUsers/SetPasswordDialog.vue +138 -0
- package/_Build/vue/modules/AuthModule/routes/PUsers/columns.js +349 -0
- package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +239 -0
- package/_Build/vue/modules/AuthModule/routes/account-exists.vue +2 -2
- package/_Build/vue/modules/AuthModule/routes/change-password.vue +28 -32
- package/_Build/vue/modules/AuthModule/routes/container.vue +2 -11
- package/_Build/vue/modules/AuthModule/routes/expired-reset.vue +4 -4
- package/_Build/vue/modules/AuthModule/routes/expired-verification.vue +10 -9
- package/_Build/vue/modules/AuthModule/routes/force-reset.vue +44 -58
- package/_Build/vue/modules/AuthModule/routes/forgot.vue +10 -5
- package/_Build/vue/modules/AuthModule/routes/login.vue +12 -19
- package/_Build/vue/modules/AuthModule/routes/logincallback.vue +1 -3
- package/_Build/vue/modules/AuthModule/routes/loginsso.vue +14 -10
- package/_Build/vue/modules/AuthModule/routes/logout.vue +14 -5
- package/_Build/vue/modules/AuthModule/routes/logoutheadless.vue +5 -3
- package/_Build/vue/modules/AuthModule/routes/register.vue +24 -28
- package/_Build/vue/modules/AuthModule/routes/reset.vue +20 -14
- package/_Build/vue/modules/AuthModule/routes/success-forgot.vue +14 -8
- package/_Build/vue/modules/AuthModule/routes/success-reset.vue +2 -2
- package/_Build/vue/modules/AuthModule/routes/success-verify.vue +1 -3
- package/_Build/vue/modules/AuthModule/routes/verify.vue +11 -14
- package/_Build/vue/modules/resource/Children/create.vue +81 -0
- package/_Build/vue/modules/resource/Children/edit.vue +106 -0
- package/_Build/vue/modules/resource/Children/index.vue +42 -0
- package/_Build/vue/modules/resource/Children/partials/form.vue +111 -0
- package/_Build/vue/modules/resource/Children/show.vue +166 -0
- package/_Build/vue/modules/resource/index.js +561 -0
- package/_Build/vue/modules/resource/parent.vue +63 -0
- package/_Build/vue/modules/resource/trashable.js +104 -0
- package/_base.scss +0 -1
- package/_defaults.scss +2 -13
- package/_variables.scss +9 -4
- package/{modules/_AuthModule.scss → components/_auth.scss} +19 -68
- package/components/_datepicker.scss +1 -0
- package/components/_descriptions.scss +2 -0
- package/components/_footer.scss +1 -0
- package/components/_form.scss +18 -0
- package/components/_header.scss +3 -27
- package/components/_layout.scss +56 -0
- package/components/_menu.scss +0 -5
- package/components/_sidebar.scss +12 -27
- package/components/_table.scss +3 -0
- package/components/_token-display.scss +41 -0
- package/general.scss +1 -0
- package/index.js +31 -1
- package/package.json +6 -4
- package/vendor.scss +0 -1
- package/_Build/vue/components/layout/sideBar.vue +0 -25
- package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/Upload/upload.vue +0 -251
- package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/create.vue +0 -62
- package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/edit.vue +0 -98
- package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/index.vue +0 -90
- package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/partials/form.vue +0 -173
- package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/Children/show.vue +0 -262
- package/_Build/vue/modules/AuthModule/adminRoutes/PCompanies/parent.vue +0 -36
- package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/create.vue +0 -112
- package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/edit.vue +0 -103
- package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/index.vue +0 -112
- package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/partials/form.vue +0 -169
- package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/Children/show.vue +0 -120
- package/_Build/vue/modules/AuthModule/adminRoutes/PUsers/parent.vue +0 -36
- package/components/_input.scss +0 -0
- package/modules/_AuthVariables.scss +0 -7
- /package/_Build/vue/{modules/AuthModule/components → components/layout}/AuthModal.vue +0 -0
- /package/_Build/vue/{modules/AuthModule/components → components/layout}/Chip.vue +0 -0
- /package/_Build/vue/{modules/AuthModule/components/VPasswordValidation.vue → components/layout/PasswordValidation.vue} +0 -0
- /package/_Build/vue/{modules/AuthModule/components/VRoleLegend.vue → components/layout/RoleLegend.vue} +0 -0
- /package/{modules → components}/_modal.scss +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-table
|
|
3
3
|
:data="$props.data"
|
|
4
|
-
:height="fixedHeight ? 762 :
|
|
4
|
+
:height="fixedHeight ? 762 : undefined"
|
|
5
|
+
:row-class-name="rowClassName"
|
|
5
6
|
style="width: 100%"
|
|
6
7
|
@sort-change="handleSort"
|
|
7
8
|
>
|
|
@@ -13,24 +14,25 @@
|
|
|
13
14
|
<el-table-column
|
|
14
15
|
:width="item.width ?? 'auto'"
|
|
15
16
|
:sortable="!!item.sortable ? 'custom' : false"
|
|
16
|
-
:label="
|
|
17
|
+
:label="
|
|
18
|
+
item.label ||
|
|
19
|
+
item.key[0].toUpperCase() + item.key.slice(1)
|
|
20
|
+
"
|
|
17
21
|
:prop="item.key"
|
|
18
22
|
:show-overflow-tooltip="true"
|
|
19
23
|
>
|
|
20
24
|
<!-- Support a custom render function -->
|
|
21
25
|
<template v-if="item.render" #default="scope">
|
|
22
|
-
{{ item.render(scope.row) }}
|
|
23
|
-
</template>
|
|
24
|
-
|
|
25
|
-
<!-- Support module passed (as a raw component or :is property) -->
|
|
26
|
-
<template v-else-if="item.component" #default="scope">
|
|
27
26
|
<component
|
|
28
27
|
:is="
|
|
29
|
-
item.
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
item.render(
|
|
29
|
+
{
|
|
30
|
+
model: scope.row,
|
|
31
|
+
...additionalInfo,
|
|
32
|
+
},
|
|
33
|
+
this,
|
|
34
|
+
)
|
|
32
35
|
"
|
|
33
|
-
v-bind="item.component.props(scope.row)"
|
|
34
36
|
/>
|
|
35
37
|
</template>
|
|
36
38
|
</el-table-column>
|
|
@@ -47,18 +49,18 @@
|
|
|
47
49
|
v-if="$props.displayShowAction"
|
|
48
50
|
:to="$props.targetAction($props.data[scope.$index])"
|
|
49
51
|
>
|
|
50
|
-
<
|
|
52
|
+
<VelButton size="small" type="primary">
|
|
51
53
|
{{ `View` }}
|
|
52
|
-
</
|
|
54
|
+
</VelButton>
|
|
53
55
|
</router-link>
|
|
54
56
|
<router-link
|
|
55
57
|
v-if="$props.displayEditAction"
|
|
56
58
|
class="ml"
|
|
57
59
|
:to="$props.editAction($props.data[scope.$index])"
|
|
58
60
|
>
|
|
59
|
-
<
|
|
61
|
+
<VelButton size="small">
|
|
60
62
|
{{ `Edit` }}
|
|
61
|
-
</
|
|
63
|
+
</VelButton>
|
|
62
64
|
</router-link>
|
|
63
65
|
</template>
|
|
64
66
|
</el-table-column>
|
|
@@ -67,9 +69,24 @@
|
|
|
67
69
|
</template>
|
|
68
70
|
|
|
69
71
|
<script>
|
|
72
|
+
import { ElTable, ElTableColumn } from "element-plus";
|
|
73
|
+
import VelButton from "../basic/Button.vue";
|
|
74
|
+
|
|
70
75
|
export default {
|
|
71
76
|
name: "VTable",
|
|
72
77
|
|
|
78
|
+
components: {
|
|
79
|
+
ElTable,
|
|
80
|
+
ElTableColumn,
|
|
81
|
+
VelButton,
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
inject: {
|
|
85
|
+
additionalInfo: {
|
|
86
|
+
default: () => ({}),
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
|
|
73
90
|
props: {
|
|
74
91
|
data: {
|
|
75
92
|
type: [Array, Object],
|
|
@@ -115,8 +132,12 @@ export default {
|
|
|
115
132
|
type: Boolean,
|
|
116
133
|
default: true,
|
|
117
134
|
},
|
|
135
|
+
rowClassName: {
|
|
136
|
+
type: [Function, String],
|
|
137
|
+
default: undefined,
|
|
138
|
+
},
|
|
118
139
|
},
|
|
119
|
-
emits: ["sort"],
|
|
140
|
+
emits: ["sort", "reload"],
|
|
120
141
|
|
|
121
142
|
methods: {
|
|
122
143
|
handleSort(data) {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</p>
|
|
14
14
|
</div>
|
|
15
15
|
<div class="flex justify-end items-end grid__2/3">
|
|
16
|
-
<
|
|
16
|
+
<VelBasic
|
|
17
17
|
v-if="jsonData.searchable"
|
|
18
18
|
ref="search"
|
|
19
19
|
v-model="search"
|
|
@@ -25,19 +25,23 @@
|
|
|
25
25
|
@update:model-value="handleSearch"
|
|
26
26
|
>
|
|
27
27
|
<template #prepend
|
|
28
|
-
><GIcon
|
|
28
|
+
><GIcon
|
|
29
|
+
embed
|
|
30
|
+
asis
|
|
31
|
+
name="icon-search"
|
|
32
|
+
class="icon--0.5"
|
|
29
33
|
/></template>
|
|
30
|
-
</
|
|
34
|
+
</VelBasic>
|
|
31
35
|
<slot v-if="displayActions" name="table-action">
|
|
32
|
-
<
|
|
33
|
-
v-if="
|
|
36
|
+
<VelButton
|
|
37
|
+
v-if="displayCreateAction"
|
|
34
38
|
size="large"
|
|
35
39
|
type="primary"
|
|
36
40
|
tag="a"
|
|
37
41
|
class="ml-2"
|
|
38
42
|
@click="
|
|
39
43
|
$router.push({
|
|
40
|
-
name: `${jsonData.
|
|
44
|
+
name: `${jsonData.slug}.create`,
|
|
41
45
|
})
|
|
42
46
|
"
|
|
43
47
|
>
|
|
@@ -45,40 +49,42 @@
|
|
|
45
49
|
name="icon-plus"
|
|
46
50
|
embed
|
|
47
51
|
asis
|
|
48
|
-
class="fill-0 mr-0.5"
|
|
52
|
+
class="fill-0 icon--0.5 mr-0.5"
|
|
49
53
|
/>
|
|
50
54
|
Create new {{ jsonData.label }}
|
|
51
|
-
</
|
|
55
|
+
</VelButton>
|
|
52
56
|
</slot>
|
|
53
57
|
</div>
|
|
54
58
|
</slot>
|
|
55
59
|
</div>
|
|
56
60
|
<div class="bg-0 p-0.5 box-shadow-1 border-r-4">
|
|
57
|
-
<
|
|
61
|
+
<VelTable
|
|
58
62
|
:data="table_data"
|
|
59
63
|
:structure="jsonData.tableStructure"
|
|
60
64
|
:label="jsonData.label"
|
|
61
65
|
:over-write-id="jsonData.overWriteId"
|
|
62
66
|
:fixed-height="fixedHeight"
|
|
67
|
+
:row-class-name="jsonData.rowClassName"
|
|
63
68
|
:target-action="
|
|
64
69
|
(item) => ({
|
|
65
|
-
name: `${jsonData.
|
|
66
|
-
params: {
|
|
70
|
+
name: `${jsonData.slug}.show`,
|
|
71
|
+
params: { [idKey]: item.id },
|
|
67
72
|
})
|
|
68
73
|
"
|
|
69
74
|
:edit-action="
|
|
70
75
|
(item) => ({
|
|
71
|
-
name: `${jsonData.
|
|
72
|
-
params: {
|
|
76
|
+
name: `${jsonData.slug}.edit`,
|
|
77
|
+
params: { [idKey]: item.id },
|
|
73
78
|
})
|
|
74
79
|
"
|
|
75
80
|
:display-actions="displayActions"
|
|
76
81
|
:display-show-action="displayShowAction"
|
|
77
82
|
:display-edit-action="displayEditAction"
|
|
78
83
|
@sort="handleSort"
|
|
84
|
+
@reload="reload"
|
|
79
85
|
>
|
|
80
86
|
<slot name="table-content"></slot>
|
|
81
|
-
</
|
|
87
|
+
</VelTable>
|
|
82
88
|
|
|
83
89
|
<div class="flex justify-center items-center py-2">
|
|
84
90
|
<el-pagination
|
|
@@ -93,36 +99,42 @@
|
|
|
93
99
|
</div>
|
|
94
100
|
</div>
|
|
95
101
|
<div v-else class="absolute transform-center text-center">
|
|
96
|
-
<
|
|
97
|
-
<p v-text="`Loading...`" />
|
|
102
|
+
<VelSpinner />
|
|
98
103
|
</div>
|
|
99
104
|
</template>
|
|
100
105
|
|
|
101
106
|
<script>
|
|
107
|
+
import axios from "axios";
|
|
108
|
+
import { debounce } from "lodash";
|
|
109
|
+
import { ElPagination } from "element-plus";
|
|
110
|
+
import VelButton from "../basic/Button.vue";
|
|
111
|
+
import VelBasic from "../form/basic.vue";
|
|
112
|
+
import VelSpinner from "../form/Spinner.vue";
|
|
113
|
+
|
|
102
114
|
export default {
|
|
103
|
-
name: "
|
|
115
|
+
name: "TableSorter",
|
|
104
116
|
|
|
105
117
|
components: {
|
|
106
|
-
|
|
118
|
+
VelTable: require("./Table.vue").default,
|
|
119
|
+
VelButton,
|
|
120
|
+
VelBasic,
|
|
121
|
+
ElPagination,
|
|
122
|
+
VelSpinner,
|
|
107
123
|
},
|
|
108
124
|
|
|
109
125
|
props: {
|
|
110
126
|
jsonData: {
|
|
111
127
|
required: true,
|
|
112
|
-
type:
|
|
128
|
+
type: Object,
|
|
113
129
|
},
|
|
114
130
|
fixedHeight: {
|
|
115
131
|
default: true,
|
|
116
132
|
type: Boolean,
|
|
117
133
|
},
|
|
118
|
-
|
|
119
|
-
required: true,
|
|
120
|
-
type: String,
|
|
121
|
-
},
|
|
122
|
-
defaults: {
|
|
134
|
+
apiParams: {
|
|
123
135
|
required: false,
|
|
124
|
-
type:
|
|
125
|
-
default:
|
|
136
|
+
type: Object,
|
|
137
|
+
default: () => ({}),
|
|
126
138
|
},
|
|
127
139
|
displayActions: {
|
|
128
140
|
type: Boolean,
|
|
@@ -132,44 +144,79 @@ export default {
|
|
|
132
144
|
type: Boolean,
|
|
133
145
|
default: true,
|
|
134
146
|
},
|
|
147
|
+
displayCreateAction: {
|
|
148
|
+
type: Boolean,
|
|
149
|
+
default: true,
|
|
150
|
+
},
|
|
135
151
|
displayEditAction: {
|
|
136
152
|
type: Boolean,
|
|
137
153
|
default: true,
|
|
138
154
|
},
|
|
155
|
+
idKey: {
|
|
156
|
+
type: String,
|
|
157
|
+
default: "id",
|
|
158
|
+
},
|
|
139
159
|
},
|
|
140
160
|
|
|
141
161
|
data() {
|
|
142
162
|
return {
|
|
143
163
|
search: null,
|
|
144
164
|
sort: "-id",
|
|
145
|
-
query:
|
|
165
|
+
query: {},
|
|
146
166
|
table_data: [],
|
|
147
167
|
table_meta: null,
|
|
168
|
+
_abortController: null,
|
|
148
169
|
};
|
|
149
170
|
},
|
|
150
171
|
|
|
172
|
+
created() {
|
|
173
|
+
this.debouncedSearch = debounce(this._executeSearch, 300);
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
beforeUnmount() {
|
|
177
|
+
this.debouncedSearch.cancel();
|
|
178
|
+
this._abortController?.abort();
|
|
179
|
+
},
|
|
180
|
+
|
|
151
181
|
mounted() {
|
|
152
182
|
this.sort = this.jsonData.defaultSort || "-id";
|
|
153
183
|
this.fetchData({ page: 1 }).then((data) => {
|
|
154
|
-
|
|
155
|
-
|
|
184
|
+
if (data) {
|
|
185
|
+
this.table_data = data.data;
|
|
186
|
+
this.table_meta = data.meta;
|
|
156
187
|
|
|
157
|
-
|
|
188
|
+
this.table_curr_page = this.table_meta.current_page;
|
|
189
|
+
}
|
|
158
190
|
});
|
|
159
191
|
},
|
|
160
192
|
|
|
161
193
|
methods: {
|
|
194
|
+
reload() {
|
|
195
|
+
this.fetchData({ page: this.table_meta.current_page }).then(
|
|
196
|
+
(data) => {
|
|
197
|
+
if (data) {
|
|
198
|
+
this.table_data = data.data;
|
|
199
|
+
this.table_meta = data.meta;
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
);
|
|
203
|
+
},
|
|
162
204
|
handleSearch(data) {
|
|
163
205
|
if (data === null || data.length < 3) {
|
|
164
|
-
this.query =
|
|
206
|
+
this.query = {};
|
|
165
207
|
} else {
|
|
166
|
-
this.query =
|
|
167
|
-
`filter[${this.$refs.search.$el.dataset.key}]
|
|
168
|
-
|
|
208
|
+
this.query = {
|
|
209
|
+
[`filter[${this.$refs.search.$el.dataset.key}]`]: data,
|
|
210
|
+
};
|
|
169
211
|
}
|
|
212
|
+
this.debouncedSearch();
|
|
213
|
+
},
|
|
214
|
+
_executeSearch() {
|
|
170
215
|
this.fetchData({}).then((data) => {
|
|
171
|
-
|
|
172
|
-
|
|
216
|
+
if (data) {
|
|
217
|
+
this.table_data = data.data;
|
|
218
|
+
this.table_meta = data.meta;
|
|
219
|
+
}
|
|
173
220
|
});
|
|
174
221
|
},
|
|
175
222
|
handleSort(data) {
|
|
@@ -180,24 +227,31 @@ export default {
|
|
|
180
227
|
data.order === "ascending" ? data.prop : "-" + data.prop;
|
|
181
228
|
}
|
|
182
229
|
this.fetchData({}).then((data) => {
|
|
183
|
-
|
|
184
|
-
|
|
230
|
+
if (data) {
|
|
231
|
+
this.table_data = data.data;
|
|
232
|
+
this.table_meta = data.meta;
|
|
233
|
+
}
|
|
185
234
|
});
|
|
186
235
|
},
|
|
187
236
|
|
|
188
237
|
fetchData: function ({ page = "1" }) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
238
|
+
this._abortController?.abort();
|
|
239
|
+
this._abortController = new AbortController();
|
|
240
|
+
|
|
241
|
+
return axios
|
|
242
|
+
.get(`${this.$props.jsonData.api}`, {
|
|
243
|
+
params: {
|
|
244
|
+
sort: this.sort,
|
|
245
|
+
page: page,
|
|
246
|
+
...this.query,
|
|
247
|
+
...this.apiParams,
|
|
248
|
+
},
|
|
249
|
+
signal: this._abortController.signal,
|
|
250
|
+
})
|
|
251
|
+
.then((res) => res.data)
|
|
252
|
+
.catch((err) => {
|
|
253
|
+
if (!axios.isCancel(err)) console.log(err);
|
|
254
|
+
});
|
|
201
255
|
},
|
|
202
256
|
|
|
203
257
|
getStatusLabel(status) {
|
|
@@ -213,8 +267,10 @@ export default {
|
|
|
213
267
|
|
|
214
268
|
handleCurrentPageChange(val) {
|
|
215
269
|
this.fetchData({ page: val }).then((data) => {
|
|
216
|
-
|
|
217
|
-
|
|
270
|
+
if (data) {
|
|
271
|
+
this.table_data = data.data;
|
|
272
|
+
this.table_meta = data.meta;
|
|
273
|
+
}
|
|
218
274
|
});
|
|
219
275
|
},
|
|
220
276
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-dialog
|
|
3
|
+
:model-value="true"
|
|
4
|
+
title="Token Created"
|
|
5
|
+
width="560px"
|
|
6
|
+
class="token-display"
|
|
7
|
+
:close-on-click-modal="false"
|
|
8
|
+
:close-on-press-escape="false"
|
|
9
|
+
:show-close="false"
|
|
10
|
+
>
|
|
11
|
+
<p class="token-display__warning">
|
|
12
|
+
<strong>The token below will not be shown again.</strong> Ensure
|
|
13
|
+
you've taken a copy before closing this window.
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<div class="token-display__block">
|
|
17
|
+
<div class="token-display__header">
|
|
18
|
+
<span class="token-display__label">Bearer Token</span>
|
|
19
|
+
<el-button size="small" plain @click="copy">
|
|
20
|
+
{{ copied ? "Copied ✓" : "Copy" }}
|
|
21
|
+
</el-button>
|
|
22
|
+
</div>
|
|
23
|
+
<pre class="token-display__value">{{ token }}</pre>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<template #footer>
|
|
27
|
+
<el-button type="primary" @click="$emit('close')">Done</el-button>
|
|
28
|
+
</template>
|
|
29
|
+
</el-dialog>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script setup>
|
|
33
|
+
import { ref } from "vue";
|
|
34
|
+
import { ElDialog, ElButton } from "element-plus";
|
|
35
|
+
|
|
36
|
+
const props = defineProps({
|
|
37
|
+
token: {
|
|
38
|
+
type: String,
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
defineEmits(["close"]);
|
|
44
|
+
|
|
45
|
+
const copied = ref(false);
|
|
46
|
+
|
|
47
|
+
async function copy() {
|
|
48
|
+
await navigator.clipboard.writeText(props.token);
|
|
49
|
+
copied.value = true;
|
|
50
|
+
setTimeout(() => (copied.value = false), 2000);
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-menu-item
|
|
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:
|
|
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
|
|
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:
|
|
18
|
+
props: {
|
|
19
|
+
index: {
|
|
20
|
+
type: [String, Number],
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
19
24
|
};
|
|
20
25
|
</script>
|
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
|
+
import debounce from "lodash/debounce";
|
|
3
|
+
|
|
4
|
+
import { ElNotification } from "element-plus";
|
|
5
|
+
|
|
6
|
+
const displayErrorNotification = debounce(async function errors(e) {
|
|
7
|
+
if (e.response && !e.response.data.errors) {
|
|
8
|
+
ElNotification.error({
|
|
9
|
+
title: "Error",
|
|
10
|
+
message:
|
|
11
|
+
e.response.data.message ||
|
|
12
|
+
`${e.response.status}: ${
|
|
13
|
+
e.response.statusText || "Please try again later!"
|
|
14
|
+
}`,
|
|
15
|
+
duration: 10000,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}, 250);
|
|
2
19
|
|
|
3
20
|
function setAxiosDefaults(baseUrl, router) {
|
|
4
21
|
axios.defaults.baseURL = baseUrl;
|
|
@@ -12,7 +29,8 @@ function setAxiosDefaults(baseUrl, router) {
|
|
|
12
29
|
axios.interceptors.response.use(null, (error) => {
|
|
13
30
|
if (error.response) {
|
|
14
31
|
if (
|
|
15
|
-
error.response.status === 401
|
|
32
|
+
(error.response.status === 401 ||
|
|
33
|
+
error.response.status === 419) &&
|
|
16
34
|
router.currentRoute.value.name !== "auth.logout"
|
|
17
35
|
) {
|
|
18
36
|
router.push({
|
|
@@ -25,6 +43,8 @@ function setAxiosDefaults(baseUrl, router) {
|
|
|
25
43
|
}
|
|
26
44
|
}
|
|
27
45
|
|
|
46
|
+
displayErrorNotification(error);
|
|
47
|
+
|
|
28
48
|
return Promise.reject(error);
|
|
29
49
|
});
|
|
30
50
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clears all client-accessible cookies on both the current hostname
|
|
3
|
+
* and the apex domain, with path=/ to match cookies set with a path.
|
|
4
|
+
*
|
|
5
|
+
* e.g. for 360.avalerehealth.com this clears cookies on:
|
|
6
|
+
* - 360.avalerehealth.com
|
|
7
|
+
* - .360.avalerehealth.com
|
|
8
|
+
* - .avalerehealth.com
|
|
9
|
+
* - (no domain — browser default)
|
|
10
|
+
*/
|
|
11
|
+
export default function clearCookies() {
|
|
12
|
+
const hostname = location.hostname;
|
|
13
|
+
const parts = hostname.split(".");
|
|
14
|
+
const domains = [hostname];
|
|
15
|
+
|
|
16
|
+
// Build domain variants: .360.avalerehealth.com, .avalerehealth.com
|
|
17
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
18
|
+
domains.push("." + parts.slice(i).join("."));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
document.cookie.split(";").forEach((cookie) => {
|
|
22
|
+
const name = cookie.split("=")[0].trim();
|
|
23
|
+
if (!name) return;
|
|
24
|
+
|
|
25
|
+
// Clear with no domain (browser default)
|
|
26
|
+
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
|
|
27
|
+
|
|
28
|
+
// Clear on each domain variant
|
|
29
|
+
domains.forEach((domain) => {
|
|
30
|
+
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;domain=${domain}`;
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Wraps a form POST to a guest-only route with automatic logged-in detection.
|
|
6
|
+
*
|
|
7
|
+
* If the server redirects to /hydrate/logged-in (because a stale session
|
|
8
|
+
* exists), the helper dispatches a logout, fetches a fresh CSRF cookie,
|
|
9
|
+
* and retries the original request once.
|
|
10
|
+
*
|
|
11
|
+
* @param {object} options
|
|
12
|
+
* @param {object} options.form - form-backend-validation Form instance
|
|
13
|
+
* @param {string} options.url - endpoint to POST to
|
|
14
|
+
* @param {string} [options.method] - HTTP method (default: "post")
|
|
15
|
+
* @param {import('vuex').Store} options.store - Vuex store (for dispatch("logout"))
|
|
16
|
+
* @returns {Promise<object>} resolved response data
|
|
17
|
+
*/
|
|
18
|
+
export async function guestRequest({ form, url, method = "post", store }) {
|
|
19
|
+
const res = await form[method](url);
|
|
20
|
+
|
|
21
|
+
if (res && res["logged-in"]) {
|
|
22
|
+
try {
|
|
23
|
+
await store.dispatch("logout");
|
|
24
|
+
} catch (_) {}
|
|
25
|
+
|
|
26
|
+
await axios.get("/sanctum/csrf-cookie");
|
|
27
|
+
|
|
28
|
+
return await form[method](url);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return res;
|
|
32
|
+
}
|