adminforth 1.2.41 → 1.2.43
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/dataConnectors/mongo.ts +1 -2
- package/dist/dataConnectors/mongo.js +1 -2
- package/dist/index.js +5 -0
- package/dist/spa/index.html +4 -4
- package/dist/spa/package-lock.json +206 -5
- package/dist/spa/package.json +8 -2
- package/dist/spa/public/assets/favicon.png +0 -0
- package/dist/spa/src/App.vue +171 -72
- package/dist/spa/src/assets/logo.svg +19 -1
- package/dist/spa/src/components/AcceptModal.vue +3 -10
- package/dist/spa/src/components/BreadcrumbsWithButtons.vue +1 -1
- package/dist/spa/src/components/CustomDatePicker.vue +19 -6
- package/dist/spa/src/components/CustomDateRangePicker.vue +14 -5
- package/dist/spa/src/components/CustomRangePicker.vue +148 -0
- package/dist/spa/src/components/Dropdown.vue +19 -5
- package/dist/spa/src/components/Filters.vue +91 -37
- package/dist/spa/src/components/MenuLink.vue +2 -2
- package/dist/spa/src/components/ResourceForm.vue +163 -103
- package/dist/spa/src/components/ResourceListTable.vue +419 -0
- package/dist/spa/src/components/Toast.vue +66 -0
- package/dist/spa/src/components/ValueRenderer.vue +22 -6
- package/dist/spa/src/composables/useFrontendApi.ts +26 -0
- package/dist/spa/src/composables/useStores.ts +113 -0
- package/dist/spa/src/main.ts +1 -1
- package/dist/spa/src/router/index.ts +30 -19
- package/dist/spa/src/spa_types/core.ts +51 -0
- package/dist/spa/src/stores/core.ts +65 -59
- package/dist/spa/src/stores/filters.ts +22 -0
- package/dist/spa/src/stores/modal.ts +13 -3
- package/dist/spa/src/stores/toast.ts +15 -0
- package/dist/spa/src/stores/user.ts +54 -0
- package/dist/spa/src/utils.ts +65 -8
- package/dist/spa/src/views/CreateView.vue +76 -16
- package/dist/spa/src/views/EditView.vue +76 -14
- package/dist/spa/src/views/ListView.vue +88 -360
- package/dist/spa/src/views/LoginView.vue +17 -5
- package/dist/spa/src/views/ResourceParent.vue +1 -1
- package/dist/spa/src/views/ShowView.vue +114 -19
- package/dist/spa/tailwind.config.js +5 -2
- package/dist/spa/vite.config.ts +6 -0
- package/index.ts +5 -0
- package/package.json +1 -1
- package/dist/spa/public/favicon.ico +0 -0
- package/dist/spa/spa/public/favicon.ico +0 -0
- package/dist/spa/spa/src/views/HomeView.vue +0 -8
- package/dist/spa/src/views/HomeView.vue +0 -8
- package/dist/types.js +0 -30
|
@@ -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,32 +31,55 @@
|
|
|
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"
|
|
53
|
+
:customComponentsPerColumn="createComponentsPerColumn"
|
|
34
54
|
>
|
|
35
55
|
</ResourceForm>
|
|
36
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
|
+
|
|
37
66
|
</div>
|
|
38
67
|
</template>
|
|
39
68
|
|
|
40
69
|
|
|
41
70
|
<script setup>
|
|
42
71
|
|
|
43
|
-
import { ref, computed, onMounted } from 'vue';
|
|
44
|
-
import { useRoute, useRouter } from 'vue-router';
|
|
45
|
-
import { useCoreStore } from '@/stores/core';
|
|
46
|
-
import { callAdminForthApi } from '@/utils';
|
|
47
|
-
import ResourceForm from '@/components/ResourceForm.vue';
|
|
48
72
|
import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
49
|
-
import
|
|
73
|
+
import ResourceForm from '@/components/ResourceForm.vue';
|
|
50
74
|
import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
75
|
+
import { useCoreStore } from '@/stores/core';
|
|
76
|
+
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions } from '@/utils';
|
|
77
|
+
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
78
|
+
import { onMounted, ref, watch } from 'vue';
|
|
79
|
+
import { useRoute, useRouter } from 'vue-router';
|
|
80
|
+
import { computed } from 'vue';
|
|
81
|
+
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
82
|
+
|
|
51
83
|
|
|
52
84
|
const isValid = ref(false);
|
|
53
85
|
const validating = ref(false);
|
|
@@ -59,9 +91,19 @@ const route = useRoute();
|
|
|
59
91
|
const router = useRouter();
|
|
60
92
|
|
|
61
93
|
const record = ref({});
|
|
94
|
+
let createComponentsPerColumn = {};
|
|
62
95
|
|
|
63
96
|
const coreStore = useCoreStore();
|
|
64
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
|
+
|
|
65
107
|
async function onUpdateRecord(newRecord) {
|
|
66
108
|
console.log('newRecord', newRecord);
|
|
67
109
|
record.value = newRecord;
|
|
@@ -69,10 +111,18 @@ async function onUpdateRecord(newRecord) {
|
|
|
69
111
|
|
|
70
112
|
onMounted(async () => {
|
|
71
113
|
loading.value = true;
|
|
72
|
-
|
|
114
|
+
record.value = initalValues.value;
|
|
115
|
+
await coreStore.fetchResourceFull({
|
|
73
116
|
resourceId: route.params.resourceId
|
|
74
117
|
});
|
|
118
|
+
createComponentsPerColumn = coreStore.resource.columns.reduce((acc, column) => {
|
|
119
|
+
if (column.components?.create) {
|
|
120
|
+
acc[column.name] = getCustomComponent(column.components.create);
|
|
121
|
+
}
|
|
122
|
+
return acc;
|
|
123
|
+
}, {});
|
|
75
124
|
loading.value = false;
|
|
125
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'create');
|
|
76
126
|
});
|
|
77
127
|
|
|
78
128
|
async function saveRecord() {
|
|
@@ -91,12 +141,22 @@ async function saveRecord() {
|
|
|
91
141
|
record: record.value,
|
|
92
142
|
},
|
|
93
143
|
});
|
|
144
|
+
if (response.error) {
|
|
145
|
+
showErrorTost(response.error);
|
|
146
|
+
|
|
147
|
+
}
|
|
94
148
|
saving.value = false;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
+
}
|
|
100
160
|
}
|
|
101
161
|
|
|
102
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,31 +27,53 @@
|
|
|
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
|
-
:record="
|
|
27
|
-
:
|
|
43
|
+
:record="editableRecord"
|
|
44
|
+
:resource="coreStore.resource"
|
|
45
|
+
:adminUser="coreStore.adminUser"
|
|
28
46
|
@update:record="onUpdateRecord"
|
|
29
47
|
@update:isValid="isValid = $event"
|
|
30
48
|
:validating="validating"
|
|
49
|
+
:customComponentsPerColumn="editComponentsPerColumn"
|
|
31
50
|
>
|
|
32
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
|
+
|
|
33
62
|
</div>
|
|
34
63
|
</template>
|
|
35
64
|
|
|
36
65
|
|
|
37
66
|
<script setup>
|
|
38
67
|
|
|
39
|
-
import { ref, computed, onMounted } from 'vue';
|
|
40
|
-
import { useRoute, useRouter } from 'vue-router';
|
|
41
|
-
import { useCoreStore } from '@/stores/core';
|
|
42
|
-
import ResourceForm from '@/components/ResourceForm.vue';
|
|
43
68
|
import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
44
|
-
import
|
|
69
|
+
import ResourceForm from '@/components/ResourceForm.vue';
|
|
45
70
|
import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
46
|
-
import {
|
|
71
|
+
import { useCoreStore } from '@/stores/core';
|
|
72
|
+
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions } from '@/utils';
|
|
73
|
+
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
74
|
+
import { computed, onMounted, ref } from 'vue';
|
|
75
|
+
import { useRoute, useRouter } from 'vue-router';
|
|
76
|
+
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
47
77
|
|
|
48
78
|
const coreStore = useCoreStore();
|
|
49
79
|
|
|
@@ -58,23 +88,44 @@ const loading = ref(false);
|
|
|
58
88
|
const saving = ref(false);
|
|
59
89
|
|
|
60
90
|
const record = ref({});
|
|
91
|
+
let editComponentsPerColumn = {};
|
|
61
92
|
|
|
62
93
|
async function onUpdateRecord(newRecord) {
|
|
63
94
|
record.value = newRecord;
|
|
64
95
|
}
|
|
65
96
|
|
|
97
|
+
const editableRecord = computed(() => {
|
|
98
|
+
const newRecord = { ...coreStore.record };
|
|
99
|
+
if (!coreStore.resource) {
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
coreStore.resource.columns.forEach(column => {
|
|
103
|
+
if (column.foreignResource) {
|
|
104
|
+
newRecord[column.name] = newRecord[column.name]?.pk
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return newRecord;
|
|
108
|
+
})
|
|
66
109
|
|
|
67
110
|
onMounted(async () => {
|
|
111
|
+
|
|
68
112
|
loading.value = true;
|
|
69
113
|
|
|
70
|
-
await coreStore.
|
|
114
|
+
await coreStore.fetchResourceFull({
|
|
71
115
|
resourceId: route.params.resourceId
|
|
72
116
|
});
|
|
73
117
|
await coreStore.fetchRecord({
|
|
74
118
|
resourceId: route.params.resourceId,
|
|
75
119
|
primaryKey: route.params.primaryKey,
|
|
76
120
|
});
|
|
77
|
-
|
|
121
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'edit');
|
|
122
|
+
|
|
123
|
+
editComponentsPerColumn = coreStore.resource.columns.reduce((acc, column) => {
|
|
124
|
+
if (column.components?.edit) {
|
|
125
|
+
acc[column.name] = getCustomComponent(column.components.edit);
|
|
126
|
+
}
|
|
127
|
+
return acc;
|
|
128
|
+
}, {});
|
|
78
129
|
loading.value = false;
|
|
79
130
|
});
|
|
80
131
|
|
|
@@ -87,15 +138,26 @@ async function saveRecord() {
|
|
|
87
138
|
}
|
|
88
139
|
|
|
89
140
|
saving.value = true;
|
|
90
|
-
|
|
141
|
+
|
|
142
|
+
const updates = {};
|
|
143
|
+
for (const key in record.value) {
|
|
144
|
+
if (record.value[key] !== coreStore.record[key]) {
|
|
145
|
+
updates[key] = record.value[key];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const resp = await callAdminForthApi({
|
|
91
150
|
method: 'POST',
|
|
92
151
|
path: `/update_record`,
|
|
93
152
|
body: {
|
|
94
153
|
resourceId: route.params.resourceId,
|
|
95
154
|
recordId: route.params.primaryKey,
|
|
96
|
-
record:
|
|
155
|
+
record: updates,
|
|
97
156
|
},
|
|
98
157
|
});
|
|
158
|
+
if (resp.error) {
|
|
159
|
+
showErrorTost(resp.error);
|
|
160
|
+
}
|
|
99
161
|
saving.value = false;
|
|
100
162
|
router.push({ name: 'resource-show', params: { resourceId: route.params.resourceId, primaryKey: coreStore.record[coreStore.primaryKey] } });
|
|
101
163
|
}
|