adminforth 1.1.32 → 1.1.33
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 +9 -0
- package/dist/modules/codeInjector.js +19 -7
- package/dist/modules/styles.js +2 -2
- package/dist/spa/index.html +2 -2
- package/dist/spa/package-lock.json +17 -4
- package/dist/spa/package.json +2 -1
- package/dist/spa/src/App.vue +125 -45
- package/dist/spa/src/assets/logo.svg +19 -1
- package/dist/spa/src/components/AcceptModal.vue +2 -9
- package/dist/spa/src/components/BreadcrumbsWithButtons.vue +1 -1
- package/dist/spa/src/components/CustomDatePicker.vue +16 -3
- package/dist/spa/src/components/CustomDateRangePicker.vue +11 -2
- package/dist/spa/src/components/Dropdown.vue +6 -1
- package/dist/spa/src/components/Filters.vue +40 -19
- package/dist/spa/src/components/ResourceForm.vue +26 -24
- package/dist/spa/src/components/ValueRenderer.vue +14 -8
- package/dist/spa/src/main.ts +1 -1
- package/dist/spa/src/router/index.ts +30 -20
- package/dist/spa/src/stores/core.ts +48 -31
- package/dist/spa/src/stores/modal.ts +13 -3
- package/dist/spa/src/utils.ts +62 -7
- package/dist/spa/src/views/CreateView.vue +67 -15
- package/dist/spa/src/views/EditView.vue +45 -11
- package/dist/spa/src/views/ListView.vue +82 -366
- package/dist/spa/src/views/LoginView.vue +16 -4
- package/dist/spa/src/views/ShowView.vue +105 -21
- package/dist/spa/tailwind.config.js +1 -1
- package/dist/spa/vite.config.ts +6 -0
- package/index.ts +11 -0
- package/modules/codeInjector.ts +19 -1
- package/modules/styles.ts +2 -2
- package/package.json +1 -1
- package/spa/index.html +1 -1
- package/spa/src/App.vue +2 -3
- package/types/AdminForthConfig.ts +15 -0
- package/dist/plugins/AccessControl/index.js +0 -66
- package/dist/plugins/AccessControl/types.js +0 -1
- package/dist/spa/public/favicon.ico +0 -0
- package/dist/spa/spa/.eslintrc.cjs +0 -14
- package/dist/spa/spa/.vscode/extensions.json +0 -6
- package/dist/spa/spa/README.md +0 -39
- package/dist/spa/spa/env.d.ts +0 -1
- package/dist/spa/spa/index.html +0 -23
- package/dist/spa/spa/package-lock.json +0 -4359
- package/dist/spa/spa/package.json +0 -47
- package/dist/spa/spa/postcss.config.js +0 -6
- package/dist/spa/spa/public/favicon.ico +0 -0
- package/dist/spa/spa/src/App.vue +0 -272
- package/dist/spa/spa/src/assets/base.css +0 -0
- package/dist/spa/spa/src/assets/logo.svg +0 -19
- package/dist/spa/spa/src/components/AcceptModal.vue +0 -45
- package/dist/spa/spa/src/components/Breadcrumbs.vue +0 -40
- package/dist/spa/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
- package/dist/spa/spa/src/components/CustomDatePicker.vue +0 -174
- package/dist/spa/spa/src/components/CustomDateRangePicker.vue +0 -218
- package/dist/spa/spa/src/components/CustomRangePicker.vue +0 -148
- package/dist/spa/spa/src/components/Dropdown.vue +0 -168
- package/dist/spa/spa/src/components/Filters.vue +0 -211
- package/dist/spa/spa/src/components/HelloWorld.vue +0 -17
- package/dist/spa/spa/src/components/MenuLink.vue +0 -24
- package/dist/spa/spa/src/components/ResourceForm.vue +0 -265
- package/dist/spa/spa/src/components/SingleSkeletLoader.vue +0 -13
- package/dist/spa/spa/src/components/ValueRenderer.vue +0 -60
- package/dist/spa/spa/src/components/icons/IconCalendar.vue +0 -5
- package/dist/spa/spa/src/components/icons/IconCommunity.vue +0 -7
- package/dist/spa/spa/src/components/icons/IconDocumentation.vue +0 -7
- package/dist/spa/spa/src/components/icons/IconEcosystem.vue +0 -7
- package/dist/spa/spa/src/components/icons/IconSupport.vue +0 -7
- package/dist/spa/spa/src/components/icons/IconTime.vue +0 -5
- package/dist/spa/spa/src/components/icons/IconTooling.vue +0 -19
- package/dist/spa/spa/src/index.scss +0 -26
- package/dist/spa/spa/src/main.ts +0 -18
- package/dist/spa/spa/src/router/index.ts +0 -64
- package/dist/spa/spa/src/stores/core.ts +0 -144
- package/dist/spa/spa/src/stores/modal.ts +0 -48
- package/dist/spa/spa/src/utils.ts +0 -101
- package/dist/spa/spa/src/views/CreateView.vue +0 -163
- package/dist/spa/spa/src/views/EditView.vue +0 -165
- package/dist/spa/spa/src/views/ListView.vue +0 -257
- package/dist/spa/spa/src/views/LoginView.vue +0 -134
- package/dist/spa/spa/src/views/ResourceParent.vue +0 -18
- package/dist/spa/spa/src/views/ShowView.vue +0 -188
- package/dist/spa/spa/tailwind.config.js +0 -15
- package/dist/spa/spa/tsconfig.app.json +0 -14
- package/dist/spa/spa/tsconfig.json +0 -11
- package/dist/spa/spa/tsconfig.node.json +0 -19
- package/dist/spa/spa/vite.config.ts +0 -49
- package/dist/types.js +0 -30
- /package/dist/spa/{spa/public → public/assets}/favicon.png +0 -0
- /package/dist/spa/{spa/src → src}/components/ResourceListTable.vue +0 -0
- /package/dist/spa/{spa/src → src}/components/Toast.vue +0 -0
- /package/dist/spa/{spa/src → src}/composables/useFrontendApi.ts +0 -0
- /package/dist/spa/{spa/src → src}/composables/useStores.ts +0 -0
- /package/dist/spa/{spa/src → src}/spa_types/core.ts +0 -0
- /package/dist/spa/{spa/src → src}/stores/filters.ts +0 -0
- /package/dist/spa/{spa/src → src}/stores/toast.ts +0 -0
- /package/dist/spa/{spa/src → src}/stores/user.ts +0 -0
- /package/spa/public/{favicon.png → assets/favicon.png} +0 -0
package/dist/spa/src/utils.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { onMounted, ref, resolveComponent } from 'vue';
|
|
2
|
+
import type { CoreConfig } from './spa_types/core';
|
|
2
3
|
|
|
3
4
|
import router from "./router";
|
|
5
|
+
import { useRouter } from 'vue-router';
|
|
6
|
+
import { useCoreStore } from './stores/core';
|
|
7
|
+
import { useUserStore } from './stores/user';
|
|
4
8
|
|
|
5
9
|
export async function callApi({path, method, body=undefined} ) {
|
|
6
10
|
const options = {
|
|
@@ -13,14 +17,18 @@ export async function callApi({path, method, body=undefined} ) {
|
|
|
13
17
|
const fullPath = `${import.meta.env.VITE_ADMINFORTH_PUBLIC_PATH || ''}${path}`;
|
|
14
18
|
const r = await fetch(fullPath, options);
|
|
15
19
|
if (r.status == 401) {
|
|
16
|
-
|
|
17
|
-
router.push({name: 'login'});
|
|
20
|
+
useUserStore().unauthorize();
|
|
21
|
+
router.push({ name: 'login' });
|
|
18
22
|
return null;
|
|
19
|
-
}
|
|
23
|
+
}
|
|
20
24
|
return await r.json();
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
export async function callAdminForthApi({ path, method, body=undefined }
|
|
27
|
+
export async function callAdminForthApi({ path, method, body=undefined }: {
|
|
28
|
+
path: string,
|
|
29
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
|
30
|
+
body?: any
|
|
31
|
+
}) {
|
|
24
32
|
try {
|
|
25
33
|
return callApi({path: `/adminapi/v1${path}`, method, body} );
|
|
26
34
|
} catch (e) {
|
|
@@ -29,8 +37,8 @@ export async function callAdminForthApi({ path, method, body=undefined }) {
|
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
39
|
|
|
32
|
-
export function getCustomComponent(
|
|
33
|
-
const name =
|
|
40
|
+
export function getCustomComponent({ file, meta }: { file: string, meta: any }) {
|
|
41
|
+
const name = file.replace(/@/g, '').replace(/\./g, '').replace(/\//g, '');
|
|
34
42
|
console.log('resolving name', name);
|
|
35
43
|
return resolveComponent(name);
|
|
36
44
|
}
|
|
@@ -43,4 +51,51 @@ export function getIcon(icon: string) {
|
|
|
43
51
|
const [iconSet, iconName] = icon.split(':');
|
|
44
52
|
const compName = 'Icon' + iconName.split('-').map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join('');
|
|
45
53
|
return resolveComponent(compName);
|
|
46
|
-
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const loadFile = (file: string) => {
|
|
57
|
+
if (file.startsWith('http')) {
|
|
58
|
+
return file;
|
|
59
|
+
}
|
|
60
|
+
let path;
|
|
61
|
+
let baseUrl = '';
|
|
62
|
+
if (file.startsWith('@/')) {
|
|
63
|
+
path = file.replace('@/', '');
|
|
64
|
+
baseUrl = new URL(`./${path}`, import.meta.url).href;
|
|
65
|
+
} else if (file.startsWith('@@/')) {
|
|
66
|
+
path = file.replace('@@/', '');
|
|
67
|
+
baseUrl = new URL(`./custom/${path}`, import.meta.url).href;
|
|
68
|
+
} else {
|
|
69
|
+
baseUrl = new URL(`./${file}`, import.meta.url).href;
|
|
70
|
+
}
|
|
71
|
+
return baseUrl;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function checkEmptyValues(value: any, viewType:'show' | 'list' ) {
|
|
75
|
+
const config: CoreConfig | {} = useCoreStore().config;
|
|
76
|
+
let emptyFieldPlaceholder = '';
|
|
77
|
+
if (config.emptyFieldPlaceholder) {
|
|
78
|
+
if(typeof config.emptyFieldPlaceholder === 'string') {
|
|
79
|
+
emptyFieldPlaceholder = config.emptyFieldPlaceholder;
|
|
80
|
+
} else {
|
|
81
|
+
emptyFieldPlaceholder = config.emptyFieldPlaceholder?.[viewType] || '';
|
|
82
|
+
}
|
|
83
|
+
if (value === null || value === undefined || value === '') {
|
|
84
|
+
return emptyFieldPlaceholder;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function checkAcessByAllowedActions(allowedActions:any, action:any ) {
|
|
91
|
+
if (!allowedActions) {
|
|
92
|
+
console.warn('allowedActions not set');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if(allowedActions[action] === false) {
|
|
96
|
+
console.warn(`Action ${action} is not allowed`);
|
|
97
|
+
router.back();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative">
|
|
3
3
|
|
|
4
|
+
<component
|
|
5
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.create?.beforeBreadcrumbs || []"
|
|
6
|
+
:is="getCustomComponent(c)"
|
|
7
|
+
:meta="c.meta"
|
|
8
|
+
:record="coreStore.record"
|
|
9
|
+
:resource="coreStore.resource"
|
|
10
|
+
:adminUser="coreStore.adminUser"
|
|
11
|
+
/>
|
|
12
|
+
|
|
4
13
|
<BreadcrumbsWithButtons>
|
|
5
14
|
<!-- save and cancle -->
|
|
6
15
|
<button @click="$router.back()"
|
|
7
|
-
class="flex items-center py-1 px-3 me-2
|
|
16
|
+
class="flex items-center py-1 px-3 me-2 text-sm font-medium rounded-default 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"
|
|
8
17
|
>
|
|
9
18
|
Cancel
|
|
10
19
|
</button>
|
|
11
20
|
|
|
12
21
|
<button @click="saveRecord"
|
|
13
|
-
class="flex items-center py-1 px-3
|
|
22
|
+
class="flex items-center py-1 px-3 text-sm font-medium rounded-default text-red-600 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-red-500 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700 disabled:opacity-50"
|
|
14
23
|
:disabled="saving || (validating && !isValid)"
|
|
15
24
|
>
|
|
16
25
|
<svg v-if="saving" x
|
|
@@ -22,12 +31,22 @@
|
|
|
22
31
|
|
|
23
32
|
</BreadcrumbsWithButtons>
|
|
24
33
|
|
|
34
|
+
<component
|
|
35
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.create?.afterBreadcrumbs || []"
|
|
36
|
+
:is="getCustomComponent(c)"
|
|
37
|
+
:meta="c.meta"
|
|
38
|
+
:record="coreStore.record"
|
|
39
|
+
:resource="coreStore.resource"
|
|
40
|
+
:adminUser="coreStore.adminUser"
|
|
41
|
+
/>
|
|
42
|
+
|
|
25
43
|
<SingleSkeletLoader v-if="loading"></SingleSkeletLoader>
|
|
44
|
+
|
|
26
45
|
|
|
27
46
|
<ResourceForm
|
|
28
47
|
v-else
|
|
29
|
-
:record="
|
|
30
|
-
:
|
|
48
|
+
:record="record"
|
|
49
|
+
:resource="coreStore.resource"
|
|
31
50
|
@update:record="onUpdateRecord"
|
|
32
51
|
@update:isValid="isValid = $event"
|
|
33
52
|
:validating="validating"
|
|
@@ -35,6 +54,15 @@
|
|
|
35
54
|
>
|
|
36
55
|
</ResourceForm>
|
|
37
56
|
|
|
57
|
+
<component
|
|
58
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.create?.bottom || []"
|
|
59
|
+
:is="getCustomComponent(c)"
|
|
60
|
+
:meta="c.meta"
|
|
61
|
+
:record="coreStore.record"
|
|
62
|
+
:resource="coreStore.resource"
|
|
63
|
+
:adminUser="coreStore.adminUser"
|
|
64
|
+
/>
|
|
65
|
+
|
|
38
66
|
</div>
|
|
39
67
|
</template>
|
|
40
68
|
|
|
@@ -45,10 +73,13 @@ import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
|
45
73
|
import ResourceForm from '@/components/ResourceForm.vue';
|
|
46
74
|
import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
47
75
|
import { useCoreStore } from '@/stores/core';
|
|
48
|
-
import { callAdminForthApi, getCustomComponent } from '@/utils';
|
|
76
|
+
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions } from '@/utils';
|
|
49
77
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
50
|
-
import { onMounted, ref } from 'vue';
|
|
78
|
+
import { onMounted, ref, watch } from 'vue';
|
|
51
79
|
import { useRoute, useRouter } from 'vue-router';
|
|
80
|
+
import { computed } from 'vue';
|
|
81
|
+
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
82
|
+
|
|
52
83
|
|
|
53
84
|
const isValid = ref(false);
|
|
54
85
|
const validating = ref(false);
|
|
@@ -64,6 +95,15 @@ let createComponentsPerColumn = {};
|
|
|
64
95
|
|
|
65
96
|
const coreStore = useCoreStore();
|
|
66
97
|
|
|
98
|
+
const initalValues = computed(() => {
|
|
99
|
+
if (!route.query.values) {
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
return JSON.parse(decodeURIComponent(route.query.values));
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
67
107
|
async function onUpdateRecord(newRecord) {
|
|
68
108
|
console.log('newRecord', newRecord);
|
|
69
109
|
record.value = newRecord;
|
|
@@ -71,16 +111,18 @@ async function onUpdateRecord(newRecord) {
|
|
|
71
111
|
|
|
72
112
|
onMounted(async () => {
|
|
73
113
|
loading.value = true;
|
|
74
|
-
|
|
114
|
+
record.value = initalValues.value;
|
|
115
|
+
await coreStore.fetchResourceFull({
|
|
75
116
|
resourceId: route.params.resourceId
|
|
76
117
|
});
|
|
77
|
-
createComponentsPerColumn = coreStore.
|
|
78
|
-
if (column.
|
|
79
|
-
acc[column.name] = getCustomComponent(column.
|
|
118
|
+
createComponentsPerColumn = coreStore.resource.columns.reduce((acc, column) => {
|
|
119
|
+
if (column.components?.create) {
|
|
120
|
+
acc[column.name] = getCustomComponent(column.components.create);
|
|
80
121
|
}
|
|
81
122
|
return acc;
|
|
82
123
|
}, {});
|
|
83
124
|
loading.value = false;
|
|
125
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'create');
|
|
84
126
|
});
|
|
85
127
|
|
|
86
128
|
async function saveRecord() {
|
|
@@ -99,12 +141,22 @@ async function saveRecord() {
|
|
|
99
141
|
record: record.value,
|
|
100
142
|
},
|
|
101
143
|
});
|
|
144
|
+
if (response.error) {
|
|
145
|
+
showErrorTost(response.error);
|
|
146
|
+
|
|
147
|
+
}
|
|
102
148
|
saving.value = false;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
149
|
+
if (route.query.returnTo) {
|
|
150
|
+
router.push(route.query.returnTo);
|
|
151
|
+
} else {
|
|
152
|
+
router.push({
|
|
153
|
+
name: 'resource-show',
|
|
154
|
+
params: {
|
|
155
|
+
resourceId: route.params.resourceId,
|
|
156
|
+
primaryKey: response.newRecordId
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
108
160
|
}
|
|
109
161
|
|
|
110
162
|
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative">
|
|
3
|
+
<component
|
|
4
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.edit?.beforeBreadcrumbs || []"
|
|
5
|
+
:is="getCustomComponent(c)"
|
|
6
|
+
:meta="c.meta"
|
|
7
|
+
:record="editableRecord"
|
|
8
|
+
:resource="coreStore.resource"
|
|
9
|
+
:adminUser="coreStore.adminUser"
|
|
10
|
+
/>
|
|
3
11
|
|
|
4
12
|
<BreadcrumbsWithButtons>
|
|
5
13
|
<!-- save and cancle -->
|
|
6
14
|
<button @click="$router.back()"
|
|
7
|
-
class="flex items-center py-1 px-3 me-2
|
|
15
|
+
class="flex items-center py-1 px-3 me-2 text-sm font-medium text-gray-900 rounded-default 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"
|
|
8
16
|
>
|
|
9
17
|
Cancel
|
|
10
18
|
</button>
|
|
11
19
|
|
|
12
20
|
<button @click="saveRecord"
|
|
13
|
-
class="flex items-center py-1 px-3
|
|
21
|
+
class="flex items-center py-1 px-3 text-sm font-medium rounded-default text-red-600 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-red-500 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
|
|
14
22
|
:disabled="saving || (validating && !isValid)"
|
|
15
23
|
>
|
|
16
24
|
<IconFloppyDiskSolid class="w-4 h-4" />
|
|
@@ -19,18 +27,38 @@
|
|
|
19
27
|
|
|
20
28
|
</BreadcrumbsWithButtons>
|
|
21
29
|
|
|
30
|
+
<component
|
|
31
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.edit?.afterBreadcrumbs || []"
|
|
32
|
+
:is="getCustomComponent(c)"
|
|
33
|
+
:meta="c.meta"
|
|
34
|
+
:record="coreStore.record"
|
|
35
|
+
:resource="coreStore.resource"
|
|
36
|
+
:adminUser="coreStore.adminUser"
|
|
37
|
+
/>
|
|
38
|
+
|
|
22
39
|
<SingleSkeletLoader v-if="loading"></SingleSkeletLoader>
|
|
23
40
|
|
|
24
41
|
<ResourceForm
|
|
25
42
|
v-else
|
|
26
43
|
:record="editableRecord"
|
|
27
|
-
:
|
|
44
|
+
:resource="coreStore.resource"
|
|
45
|
+
:adminUser="coreStore.adminUser"
|
|
28
46
|
@update:record="onUpdateRecord"
|
|
29
47
|
@update:isValid="isValid = $event"
|
|
30
48
|
:validating="validating"
|
|
31
49
|
:customComponentsPerColumn="editComponentsPerColumn"
|
|
32
50
|
>
|
|
33
51
|
</ResourceForm>
|
|
52
|
+
|
|
53
|
+
<component
|
|
54
|
+
v-for="c in coreStore?.resourceOptions?.pageInjections?.edit?.bottom || []"
|
|
55
|
+
:is="getCustomComponent(c)"
|
|
56
|
+
:meta="c.meta"
|
|
57
|
+
:record="coreStore.record"
|
|
58
|
+
:resource="coreStore.resource"
|
|
59
|
+
:adminUser="coreStore.adminUser"
|
|
60
|
+
/>
|
|
61
|
+
|
|
34
62
|
</div>
|
|
35
63
|
</template>
|
|
36
64
|
|
|
@@ -41,10 +69,11 @@ import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
|
41
69
|
import ResourceForm from '@/components/ResourceForm.vue';
|
|
42
70
|
import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
43
71
|
import { useCoreStore } from '@/stores/core';
|
|
44
|
-
import { callAdminForthApi, getCustomComponent } from '@/utils';
|
|
72
|
+
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions } from '@/utils';
|
|
45
73
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
46
74
|
import { computed, onMounted, ref } from 'vue';
|
|
47
75
|
import { useRoute, useRouter } from 'vue-router';
|
|
76
|
+
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
48
77
|
|
|
49
78
|
const coreStore = useCoreStore();
|
|
50
79
|
|
|
@@ -67,10 +96,10 @@ async function onUpdateRecord(newRecord) {
|
|
|
67
96
|
|
|
68
97
|
const editableRecord = computed(() => {
|
|
69
98
|
const newRecord = { ...coreStore.record };
|
|
70
|
-
if (!coreStore.
|
|
99
|
+
if (!coreStore.resource) {
|
|
71
100
|
return {};
|
|
72
101
|
}
|
|
73
|
-
coreStore.
|
|
102
|
+
coreStore.resource.columns.forEach(column => {
|
|
74
103
|
if (column.foreignResource) {
|
|
75
104
|
newRecord[column.name] = newRecord[column.name]?.pk
|
|
76
105
|
}
|
|
@@ -79,19 +108,21 @@ const editableRecord = computed(() => {
|
|
|
79
108
|
})
|
|
80
109
|
|
|
81
110
|
onMounted(async () => {
|
|
111
|
+
|
|
82
112
|
loading.value = true;
|
|
83
113
|
|
|
84
|
-
await coreStore.
|
|
114
|
+
await coreStore.fetchResourceFull({
|
|
85
115
|
resourceId: route.params.resourceId
|
|
86
116
|
});
|
|
87
117
|
await coreStore.fetchRecord({
|
|
88
118
|
resourceId: route.params.resourceId,
|
|
89
119
|
primaryKey: route.params.primaryKey,
|
|
90
120
|
});
|
|
121
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'edit');
|
|
91
122
|
|
|
92
|
-
editComponentsPerColumn = coreStore.
|
|
93
|
-
if (column.
|
|
94
|
-
acc[column.name] = getCustomComponent(column.
|
|
123
|
+
editComponentsPerColumn = coreStore.resource.columns.reduce((acc, column) => {
|
|
124
|
+
if (column.components?.edit) {
|
|
125
|
+
acc[column.name] = getCustomComponent(column.components.edit);
|
|
95
126
|
}
|
|
96
127
|
return acc;
|
|
97
128
|
}, {});
|
|
@@ -115,7 +146,7 @@ async function saveRecord() {
|
|
|
115
146
|
}
|
|
116
147
|
}
|
|
117
148
|
|
|
118
|
-
await callAdminForthApi({
|
|
149
|
+
const resp = await callAdminForthApi({
|
|
119
150
|
method: 'POST',
|
|
120
151
|
path: `/update_record`,
|
|
121
152
|
body: {
|
|
@@ -124,6 +155,9 @@ async function saveRecord() {
|
|
|
124
155
|
record: updates,
|
|
125
156
|
},
|
|
126
157
|
});
|
|
158
|
+
if (resp.error) {
|
|
159
|
+
showErrorTost(resp.error);
|
|
160
|
+
}
|
|
127
161
|
saving.value = false;
|
|
128
162
|
router.push({ name: 'resource-show', params: { resourceId: route.params.resourceId, primaryKey: coreStore.record[coreStore.primaryKey] } });
|
|
129
163
|
}
|