adminforth 1.1.14 → 1.1.15
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/dist/index.js +15 -0
- package/dist/plugins/plugins/ForeignInlineListPlugin/custom/InlineList.vue +248 -0
- package/dist/spa/spa/src/router/index.ts +2 -2
- package/dist/spa/spa/src/stores/user.ts +22 -18
- package/dist/spa/spa/src/utils.ts +1 -1
- package/dist/spa/spa/src/views/LoginView.vue +4 -0
- package/index.ts +15 -0
- package/package.json +3 -2
- package/spa/src/router/index.ts +2 -2
- package/spa/src/stores/user.ts +22 -18
- package/spa/src/utils.ts +1 -1
- package/spa/src/views/LoginView.vue +4 -0
package/dist/index.js
CHANGED
|
@@ -158,6 +158,7 @@ class AdminForth {
|
|
|
158
158
|
res.columns = [];
|
|
159
159
|
}
|
|
160
160
|
res.columns.forEach((col) => {
|
|
161
|
+
var _b, _c, _d, _e;
|
|
161
162
|
col.label = col.label || guessLabelFromName(col.name);
|
|
162
163
|
//define default sortable
|
|
163
164
|
if (!Object.keys(col).includes('sortable')) {
|
|
@@ -192,6 +193,20 @@ class AdminForth {
|
|
|
192
193
|
errors.push(`Resource "${res.resourceId}" column "${col.name}" has invalid showIn value "${wrongShowIn}", allowed values are ${Object.keys(AdminForthResourcePages).join(', ')}`);
|
|
193
194
|
}
|
|
194
195
|
col.showIn = col.showIn || Object.values(AdminForthResourcePages);
|
|
196
|
+
if (col.foreignResource) {
|
|
197
|
+
const befHook = (_c = (_b = col.foreignResource.hooks) === null || _b === void 0 ? void 0 : _b.dropdownList) === null || _c === void 0 ? void 0 : _c.beforeDatasourceRequest;
|
|
198
|
+
if (befHook) {
|
|
199
|
+
if (!Array.isArray(befHook)) {
|
|
200
|
+
col.foreignResource.hooks.dropdownList.beforeDatasourceRequest = [befHook];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const aftHook = (_e = (_d = col.foreignResource.hooks) === null || _d === void 0 ? void 0 : _d.dropdownList) === null || _e === void 0 ? void 0 : _e.afterDatasourceResponse;
|
|
204
|
+
if (aftHook) {
|
|
205
|
+
if (!Array.isArray(aftHook)) {
|
|
206
|
+
col.foreignResource.hooks.dropdownList.afterDatasourceResponse = [aftHook];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
195
210
|
});
|
|
196
211
|
if (!res.options) {
|
|
197
212
|
res.options = { bulkActions: [], allowedActions: {} };
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Teleport to="body">
|
|
3
|
+
<!-- todo exclude foreign column-->
|
|
4
|
+
<Filters
|
|
5
|
+
v-if="listResource"
|
|
6
|
+
:columns="listResource.columns.filter((c) => c.name !== listResourceRefColumn.name)"
|
|
7
|
+
v-model:filters="filters"
|
|
8
|
+
:columnsMinMax="columnsMinMax"
|
|
9
|
+
:show="filtersShow"
|
|
10
|
+
@hide="filtersShow = false"
|
|
11
|
+
/>
|
|
12
|
+
</Teleport>
|
|
13
|
+
|
|
14
|
+
<td colspan="2">
|
|
15
|
+
<div class="flex items-center gap-1">
|
|
16
|
+
<h4 v-if="listResource"
|
|
17
|
+
class="px-6 py-4"
|
|
18
|
+
>{{ listResource.label }} inline records</h4>
|
|
19
|
+
|
|
20
|
+
<button
|
|
21
|
+
@click="()=>{checkboxes = []}"
|
|
22
|
+
v-if="checkboxes.length"
|
|
23
|
+
data-tooltip-target="tooltip-remove-all"
|
|
24
|
+
data-tooltip-placement="bottom"
|
|
25
|
+
class="flex gap-1 items-center py-1 px-3 me-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
|
|
26
|
+
>
|
|
27
|
+
<IconBanOutline class="w-5 h-5 "/>
|
|
28
|
+
<div id="tooltip-remove-all" role="tooltip"
|
|
29
|
+
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
|
|
30
|
+
Remove selection
|
|
31
|
+
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
32
|
+
</div>
|
|
33
|
+
</button>
|
|
34
|
+
|
|
35
|
+
<button
|
|
36
|
+
v-if="checkboxes.length"
|
|
37
|
+
v-for="(action,i) in listResource?.options?.bulkActions"
|
|
38
|
+
:key="action.id"
|
|
39
|
+
@click="startBulkAction(action.id)"
|
|
40
|
+
class="flex gap-1 items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
|
|
41
|
+
:class="{'bg-red-100 text-red-800 border-red-400 dark:bg-red-700 dark:text-red-400 dark:border-red-400':action.state==='danger', 'bg-green-100 text-green-800 border-green-400 dark:bg-green-700 dark:text-green-400 dark:border-green-400':action.state==='success',
|
|
42
|
+
'bg-blue-100 text-blue-800 border-blue-400 dark:bg-blue-700 dark:text-blue-400 dark:border-blue-400':action.state==='active',
|
|
43
|
+
}"
|
|
44
|
+
>
|
|
45
|
+
<component
|
|
46
|
+
v-if="action.icon"
|
|
47
|
+
:is="getIcon(action.icon)"
|
|
48
|
+
class="w-5 h-5 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"></component>
|
|
49
|
+
|
|
50
|
+
{{ `${action.label} (${checkboxes.length})` }}
|
|
51
|
+
</button>
|
|
52
|
+
|
|
53
|
+
<RouterLink v-if="listResource?.options?.allowedActions?.create"
|
|
54
|
+
:to="{
|
|
55
|
+
name: 'resource-create',
|
|
56
|
+
params: { resourceId: listResource.resourceId },
|
|
57
|
+
query: {
|
|
58
|
+
values: encodeURIComponent(JSON.stringify({[listResourceRefColumn.name]: props.record[selfPrimaryKeyColumn.name]})),
|
|
59
|
+
returnTo: $route.fullPath,
|
|
60
|
+
},
|
|
61
|
+
}"
|
|
62
|
+
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700 rounded-default"
|
|
63
|
+
>
|
|
64
|
+
<IconPlusOutline class="w-4 h-4 me-2"/>
|
|
65
|
+
Create
|
|
66
|
+
</RouterLink>
|
|
67
|
+
|
|
68
|
+
<button
|
|
69
|
+
class="flex gap-1 items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700 rounded-default"
|
|
70
|
+
@click="()=>{filtersShow = !filtersShow}"
|
|
71
|
+
>
|
|
72
|
+
<IconFilterOutline class="w-4 h-4 me-2"/>
|
|
73
|
+
Filter
|
|
74
|
+
<span
|
|
75
|
+
class="bg-red-100 text-red-800 text-xs font-medium px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400"
|
|
76
|
+
v-if="filters.length">
|
|
77
|
+
{{ filters.length }}
|
|
78
|
+
</span>
|
|
79
|
+
</button>
|
|
80
|
+
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<ResourceListTable
|
|
84
|
+
:resource="listResource"
|
|
85
|
+
:rows="rows"
|
|
86
|
+
@update:page="page = $event"
|
|
87
|
+
@update:sort="sort = $event"
|
|
88
|
+
@update:checkboxes="checkboxes = $event"
|
|
89
|
+
:pageSize="pageSize"
|
|
90
|
+
:totalRows="totalRows"
|
|
91
|
+
:checkboxes="checkboxes"
|
|
92
|
+
/>
|
|
93
|
+
|
|
94
|
+
</td>
|
|
95
|
+
</template>
|
|
96
|
+
|
|
97
|
+
<script setup>
|
|
98
|
+
import { callAdminForthApi } from '@/utils';
|
|
99
|
+
import { ref, onMounted, watch, computed } from 'vue';
|
|
100
|
+
import ResourceListTable from '@/components/ResourceListTable.vue';
|
|
101
|
+
import Filters from '@/components/Filters.vue';
|
|
102
|
+
import {
|
|
103
|
+
IconBanOutline,
|
|
104
|
+
IconFilterOutline,
|
|
105
|
+
IconPlusOutline,
|
|
106
|
+
} from '@iconify-prerendered/vue-flowbite';
|
|
107
|
+
|
|
108
|
+
import { getIcon } from '@/utils';
|
|
109
|
+
|
|
110
|
+
const props = defineProps(['column', 'record', 'meta', 'resource', 'adminUser']);
|
|
111
|
+
|
|
112
|
+
const listResource = ref(null);
|
|
113
|
+
const loading = ref(true);
|
|
114
|
+
|
|
115
|
+
const page = ref(1);
|
|
116
|
+
const sort = ref([]);
|
|
117
|
+
const checkboxes = ref([]);
|
|
118
|
+
const pageSize = computed(() => listResource.value?.options?.listPageSize || 10);
|
|
119
|
+
|
|
120
|
+
const rows = ref(null);
|
|
121
|
+
const totalRows = ref(0);
|
|
122
|
+
|
|
123
|
+
const filters = ref([]);
|
|
124
|
+
const filtersShow = ref(false);
|
|
125
|
+
const columnsMinMax = ref(null);
|
|
126
|
+
|
|
127
|
+
const listResourceRefColumn = computed(() => {
|
|
128
|
+
if (!listResource.value) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
return listResource.value.columns.find(c => c.foreignResource?.resourceId === props.resource.resourceId);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const selfPrimaryKeyColumn = computed(() => {
|
|
135
|
+
return props.resource.columns.find(c => c.primaryKey);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const endFilters = computed(() => {
|
|
139
|
+
if (!listResource.value) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
// get name of the column that is foreign key
|
|
143
|
+
const refColumn = listResourceRefColumn.value;
|
|
144
|
+
|
|
145
|
+
const primaryKeyColumn = selfPrimaryKeyColumn.value;
|
|
146
|
+
|
|
147
|
+
if (!refColumn) {
|
|
148
|
+
window.adminforth.alert({
|
|
149
|
+
message: `Column with foreignResource.resourceId which is equal to '${props.resource.resourceId}' not found in resource which is specified as foreighResourceId '${listResource.value.resourceId}'`,
|
|
150
|
+
variant: 'danger',
|
|
151
|
+
});
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
return [
|
|
155
|
+
...filters.value,
|
|
156
|
+
{
|
|
157
|
+
field: refColumn.name,
|
|
158
|
+
operator: 'eq',
|
|
159
|
+
value: props.record[primaryKeyColumn.name],
|
|
160
|
+
},
|
|
161
|
+
];
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
watch([page], async () => {
|
|
165
|
+
await getList();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
watch([sort], async () => {
|
|
169
|
+
await getList();
|
|
170
|
+
}, {deep: true});
|
|
171
|
+
|
|
172
|
+
watch([filters], async () => {
|
|
173
|
+
page.value = 1;
|
|
174
|
+
checkboxes.value = [];
|
|
175
|
+
await getList();
|
|
176
|
+
}, {deep: true});
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
async function startBulkAction(actionId) {
|
|
180
|
+
const data = await callAdminForthApi({
|
|
181
|
+
path: '/start_bulk_action',
|
|
182
|
+
method: 'POST',
|
|
183
|
+
body: {
|
|
184
|
+
resourceId: listResource.value.resourceId,
|
|
185
|
+
actionId: actionId,
|
|
186
|
+
recordIds: checkboxes.value
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
if (data?.status === 'success') {
|
|
190
|
+
checkboxes.value = [];
|
|
191
|
+
}
|
|
192
|
+
await getList();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function getList() {
|
|
196
|
+
rows.value = null;
|
|
197
|
+
console.log('getList', listResource.value)
|
|
198
|
+
const data = await callAdminForthApi({
|
|
199
|
+
path: '/get_resource_data',
|
|
200
|
+
method: 'POST',
|
|
201
|
+
body: {
|
|
202
|
+
source: 'list',
|
|
203
|
+
resourceId: listResource.value.resourceId,
|
|
204
|
+
limit: pageSize.value,
|
|
205
|
+
offset: (page.value - 1) * pageSize.value,
|
|
206
|
+
filters: endFilters.value,
|
|
207
|
+
sort: sort.value,
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
if (data.error) {
|
|
212
|
+
window.adminforth.alert({
|
|
213
|
+
message: data.error,
|
|
214
|
+
variant: 'danger',
|
|
215
|
+
timeout: 'unlimited',
|
|
216
|
+
});
|
|
217
|
+
rows.value = [];
|
|
218
|
+
totalRows.value = 0;
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
rows.value = data.data?.map(row => {
|
|
223
|
+
row._primaryKeyValue = row[listResource.value.columns.find(c => c.primaryKey).name];
|
|
224
|
+
return row;
|
|
225
|
+
});
|
|
226
|
+
totalRows.value = data.total;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
onMounted( async () => {
|
|
230
|
+
loading.value = true;
|
|
231
|
+
const foreighResourceId = props.meta.foreignResourceId;
|
|
232
|
+
listResource.value = (await callAdminForthApi({
|
|
233
|
+
path: `/plugin/${props.meta.pluginInstanceId}/get_resource`,
|
|
234
|
+
method: 'POST',
|
|
235
|
+
body: {},
|
|
236
|
+
})).resource;
|
|
237
|
+
columnsMinMax.value = await callAdminForthApi({
|
|
238
|
+
path: '/get_min_max_for_columns',
|
|
239
|
+
method: 'POST',
|
|
240
|
+
body: {
|
|
241
|
+
resourceId: foreighResourceId,
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
loading.value = false;
|
|
245
|
+
await getList();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
</script>
|
|
@@ -13,8 +13,8 @@ const router = createRouter({
|
|
|
13
13
|
meta: { title: 'login' },
|
|
14
14
|
beforeEnter: async (to, from, next) => {
|
|
15
15
|
const userStore = useUserStore()
|
|
16
|
-
if
|
|
17
|
-
next({
|
|
16
|
+
if(localStorage.getItem('isAuthorized') === 'true'){
|
|
17
|
+
next({name: 'home'})
|
|
18
18
|
} else {
|
|
19
19
|
next()
|
|
20
20
|
}
|
|
@@ -7,10 +7,12 @@ export const useUserStore = defineStore('user', () => {
|
|
|
7
7
|
|
|
8
8
|
function authorize() {
|
|
9
9
|
isAuthorized.value = true;
|
|
10
|
+
localStorage.setItem('isAuthorized', 'true');
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
function unauthorize() {
|
|
13
14
|
isAuthorized.value = false;
|
|
15
|
+
localStorage.setItem('isAuthorized', 'false');
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
async function logout() {
|
|
@@ -18,32 +20,34 @@ export const useUserStore = defineStore('user', () => {
|
|
|
18
20
|
path: '/logout',
|
|
19
21
|
method: 'POST',
|
|
20
22
|
});
|
|
23
|
+
unauthorize();
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
async function checkAuth( skipApiCall = false){
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
// async function checkAuth( skipApiCall = false){
|
|
27
|
+
// console.log('checkAuth', isAuthorized.value, skipApiCall)
|
|
28
|
+
// if(isAuthorized.value) {
|
|
29
|
+
// return true}
|
|
30
|
+
// else {
|
|
31
|
+
// if(skipApiCall) return false;
|
|
32
|
+
// const resp = await callAdminForthApi({
|
|
33
|
+
// path: '/check_auth',
|
|
34
|
+
// method: 'POST',
|
|
35
|
+
// });
|
|
36
|
+
// if (resp.status !== 401) {
|
|
37
|
+
// authorize();
|
|
38
|
+
// return true;
|
|
39
|
+
// }
|
|
40
|
+
// else {
|
|
41
|
+
// unauthorize();
|
|
42
|
+
// return false;}
|
|
43
|
+
// }
|
|
39
44
|
|
|
40
|
-
}
|
|
45
|
+
// }
|
|
41
46
|
|
|
42
47
|
return {
|
|
43
48
|
isAuthorized,
|
|
44
49
|
authorize,
|
|
45
50
|
unauthorize,
|
|
46
|
-
checkAuth,
|
|
47
51
|
logout
|
|
48
52
|
}
|
|
49
53
|
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
|
|
82
82
|
import { onMounted, ref, watchEffect } from 'vue';
|
|
83
83
|
import { useCoreStore } from '@/stores/core';
|
|
84
|
+
import { useUserStore } from '@/stores/user';
|
|
84
85
|
import { IconEyeSolid, IconEyeSlashSolid } from '@iconify-prerendered/vue-flowbite';
|
|
85
86
|
import { callAdminForthApi, loadFile } from '@/utils';
|
|
86
87
|
import { useRouter } from 'vue-router';
|
|
@@ -91,6 +92,8 @@ const router = useRouter();
|
|
|
91
92
|
const inProgress = ref(false);
|
|
92
93
|
|
|
93
94
|
const coreStore = useCoreStore();
|
|
95
|
+
const user = useUserStore();
|
|
96
|
+
|
|
94
97
|
|
|
95
98
|
const showPw = ref(false);
|
|
96
99
|
|
|
@@ -115,6 +118,7 @@ async function login() {
|
|
|
115
118
|
error.value = resp.error;
|
|
116
119
|
} else {
|
|
117
120
|
error.value = null;
|
|
121
|
+
user.authorize()
|
|
118
122
|
router.push('/');
|
|
119
123
|
await router.isReady();
|
|
120
124
|
await coreStore.fetchMenuAndResource();
|
package/index.ts
CHANGED
|
@@ -229,6 +229,21 @@ class AdminForth implements AdminForthClass {
|
|
|
229
229
|
errors.push(`Resource "${res.resourceId}" column "${col.name}" has invalid showIn value "${wrongShowIn}", allowed values are ${Object.keys(AdminForthResourcePages).join(', ')}`);
|
|
230
230
|
}
|
|
231
231
|
col.showIn = col.showIn || Object.values(AdminForthResourcePages);
|
|
232
|
+
|
|
233
|
+
if (col.foreignResource) {
|
|
234
|
+
const befHook = col.foreignResource.hooks?.dropdownList?.beforeDatasourceRequest;
|
|
235
|
+
if (befHook) {
|
|
236
|
+
if (!Array.isArray(befHook)) {
|
|
237
|
+
col.foreignResource.hooks.dropdownList.beforeDatasourceRequest = [befHook];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const aftHook = col.foreignResource.hooks?.dropdownList?.afterDatasourceResponse;
|
|
241
|
+
if (aftHook) {
|
|
242
|
+
if (!Array.isArray(aftHook)) {
|
|
243
|
+
col.foreignResource.hooks.dropdownList.afterDatasourceResponse = [aftHook];
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
232
247
|
})
|
|
233
248
|
|
|
234
249
|
if (!res.options) {
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adminforth",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"description": "OpenSource Vue3 powered forth-generation admin panel",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
9
|
"build": "tsc",
|
|
10
|
-
"
|
|
10
|
+
"prepareDist": "cp -r spa dist/spa && find plugins -type f ! -name '*.ts' -exec cp --parents {} dist/plugins \\;",
|
|
11
|
+
"rollout": "tsc && npm run prepareDist && npm version patch && npm publish && cd documentation && npm run build && npm run deploy",
|
|
11
12
|
"docs": "typedoc"
|
|
12
13
|
},
|
|
13
14
|
"author": "devforth.io",
|
package/spa/src/router/index.ts
CHANGED
|
@@ -13,8 +13,8 @@ const router = createRouter({
|
|
|
13
13
|
meta: { title: 'login' },
|
|
14
14
|
beforeEnter: async (to, from, next) => {
|
|
15
15
|
const userStore = useUserStore()
|
|
16
|
-
if
|
|
17
|
-
next({
|
|
16
|
+
if(localStorage.getItem('isAuthorized') === 'true'){
|
|
17
|
+
next({name: 'home'})
|
|
18
18
|
} else {
|
|
19
19
|
next()
|
|
20
20
|
}
|
package/spa/src/stores/user.ts
CHANGED
|
@@ -7,10 +7,12 @@ export const useUserStore = defineStore('user', () => {
|
|
|
7
7
|
|
|
8
8
|
function authorize() {
|
|
9
9
|
isAuthorized.value = true;
|
|
10
|
+
localStorage.setItem('isAuthorized', 'true');
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
function unauthorize() {
|
|
13
14
|
isAuthorized.value = false;
|
|
15
|
+
localStorage.setItem('isAuthorized', 'false');
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
async function logout() {
|
|
@@ -18,32 +20,34 @@ export const useUserStore = defineStore('user', () => {
|
|
|
18
20
|
path: '/logout',
|
|
19
21
|
method: 'POST',
|
|
20
22
|
});
|
|
23
|
+
unauthorize();
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
async function checkAuth( skipApiCall = false){
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
// async function checkAuth( skipApiCall = false){
|
|
27
|
+
// console.log('checkAuth', isAuthorized.value, skipApiCall)
|
|
28
|
+
// if(isAuthorized.value) {
|
|
29
|
+
// return true}
|
|
30
|
+
// else {
|
|
31
|
+
// if(skipApiCall) return false;
|
|
32
|
+
// const resp = await callAdminForthApi({
|
|
33
|
+
// path: '/check_auth',
|
|
34
|
+
// method: 'POST',
|
|
35
|
+
// });
|
|
36
|
+
// if (resp.status !== 401) {
|
|
37
|
+
// authorize();
|
|
38
|
+
// return true;
|
|
39
|
+
// }
|
|
40
|
+
// else {
|
|
41
|
+
// unauthorize();
|
|
42
|
+
// return false;}
|
|
43
|
+
// }
|
|
39
44
|
|
|
40
|
-
}
|
|
45
|
+
// }
|
|
41
46
|
|
|
42
47
|
return {
|
|
43
48
|
isAuthorized,
|
|
44
49
|
authorize,
|
|
45
50
|
unauthorize,
|
|
46
|
-
checkAuth,
|
|
47
51
|
logout
|
|
48
52
|
}
|
|
49
53
|
|
package/spa/src/utils.ts
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
|
|
82
82
|
import { onMounted, ref, watchEffect } from 'vue';
|
|
83
83
|
import { useCoreStore } from '@/stores/core';
|
|
84
|
+
import { useUserStore } from '@/stores/user';
|
|
84
85
|
import { IconEyeSolid, IconEyeSlashSolid } from '@iconify-prerendered/vue-flowbite';
|
|
85
86
|
import { callAdminForthApi, loadFile } from '@/utils';
|
|
86
87
|
import { useRouter } from 'vue-router';
|
|
@@ -91,6 +92,8 @@ const router = useRouter();
|
|
|
91
92
|
const inProgress = ref(false);
|
|
92
93
|
|
|
93
94
|
const coreStore = useCoreStore();
|
|
95
|
+
const user = useUserStore();
|
|
96
|
+
|
|
94
97
|
|
|
95
98
|
const showPw = ref(false);
|
|
96
99
|
|
|
@@ -115,6 +118,7 @@ async function login() {
|
|
|
115
118
|
error.value = resp.error;
|
|
116
119
|
} else {
|
|
117
120
|
error.value = null;
|
|
121
|
+
user.authorize()
|
|
118
122
|
router.push('/');
|
|
119
123
|
await router.isReady();
|
|
120
124
|
await coreStore.fetchMenuAndResource();
|