adminforth 1.5.4-next.9 → 1.5.4
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/auth.js +4 -4
- package/dist/auth.js.map +1 -1
- package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
- package/dist/dataConnectors/clickhouse.js +0 -1
- package/dist/dataConnectors/clickhouse.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -13
- package/dist/index.js.map +1 -1
- package/dist/modules/codeInjector.d.ts.map +1 -1
- package/dist/modules/codeInjector.js +7 -5
- package/dist/modules/codeInjector.js.map +1 -1
- package/dist/modules/configValidator.d.ts +11 -5
- package/dist/modules/configValidator.d.ts.map +1 -1
- package/dist/modules/configValidator.js +387 -379
- package/dist/modules/configValidator.js.map +1 -1
- package/dist/modules/restApi.d.ts.map +1 -1
- package/dist/modules/restApi.js +32 -13
- package/dist/modules/restApi.js.map +1 -1
- package/dist/modules/socketBroker.d.ts.map +1 -1
- package/dist/modules/socketBroker.js +0 -1
- package/dist/modules/socketBroker.js.map +1 -1
- package/dist/servers/express.d.ts.map +1 -1
- package/dist/servers/express.js +2 -3
- package/dist/servers/express.js.map +1 -1
- package/dist/spa/src/App.vue +8 -6
- package/dist/spa/src/afcl/Input.vue +1 -1
- package/dist/spa/src/afcl/Link.vue +9 -1
- package/dist/spa/src/afcl/LinkButton.vue +5 -3
- package/dist/spa/src/afcl/VerticalTabs.vue +1 -1
- package/dist/spa/src/components/AcceptModal.vue +1 -2
- package/dist/spa/src/components/ResourceListTable.vue +4 -3
- package/dist/spa/src/components/SkeleteLoader.vue +5 -10
- package/dist/spa/src/components/ValueRenderer.vue +13 -14
- package/dist/spa/src/spa_types/core.ts +2 -4
- package/dist/spa/src/stores/core.ts +15 -16
- package/dist/spa/src/stores/user.ts +0 -7
- package/dist/spa/src/types/Back.ts +310 -327
- package/dist/spa/src/types/Common.ts +220 -10
- package/dist/spa/src/types/FrontendAPI.ts +5 -4
- package/dist/spa/src/utils.ts +5 -1
- package/dist/spa/src/views/LoginView.vue +6 -1
- package/dist/spa/src/websocket.ts +3 -2
- package/dist/types/Back.d.ts +262 -287
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Back.js +1 -46
- package/dist/types/Back.js.map +1 -1
- package/dist/types/Common.d.ts +194 -9
- package/dist/types/Common.d.ts.map +1 -1
- package/dist/types/Common.js +47 -0
- package/dist/types/Common.js.map +1 -1
- package/dist/types/FrontendAPI.d.ts +4 -4
- package/dist/types/FrontendAPI.d.ts.map +1 -1
- package/dist/types/FrontendAPI.js.map +1 -1
- package/package.json +4 -4
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
<script setup lang="ts">
|
|
248
248
|
|
|
249
249
|
|
|
250
|
-
import { computed, onMounted, ref, watch } from 'vue';
|
|
250
|
+
import { computed, onMounted, ref, watch, type Ref } from 'vue';
|
|
251
251
|
import { callAdminForthApi } from '@/utils';
|
|
252
252
|
|
|
253
253
|
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
@@ -267,12 +267,13 @@ import {
|
|
|
267
267
|
} from '@iconify-prerendered/vue-flowbite';
|
|
268
268
|
import router from '@/router';
|
|
269
269
|
import { Tooltip } from '@/afcl';
|
|
270
|
+
import type { AdminForthResourceCommon } from '@/types/Common';
|
|
270
271
|
|
|
271
272
|
const coreStore = useCoreStore();
|
|
272
273
|
|
|
273
274
|
const props = defineProps<{
|
|
274
275
|
page: number,
|
|
275
|
-
resource:
|
|
276
|
+
resource: AdminForthResourceCommon,
|
|
276
277
|
rows: any[] | null,
|
|
277
278
|
totalRows: number,
|
|
278
279
|
pageSize: number,
|
|
@@ -291,7 +292,7 @@ const emits = defineEmits([
|
|
|
291
292
|
|
|
292
293
|
]);
|
|
293
294
|
|
|
294
|
-
const checkboxesInternal = ref([]);
|
|
295
|
+
const checkboxesInternal: Ref<any[]> = ref([]);
|
|
295
296
|
const page = ref(1);
|
|
296
297
|
const sort = ref([]);
|
|
297
298
|
|
|
@@ -8,16 +8,11 @@
|
|
|
8
8
|
</tr>
|
|
9
9
|
</template>
|
|
10
10
|
|
|
11
|
-
<script setup>
|
|
12
|
-
|
|
13
|
-
const props = defineProps({
|
|
14
|
-
columns: Number,
|
|
15
|
-
rows: Number
|
|
16
|
-
});
|
|
11
|
+
<script setup lang="ts">
|
|
17
12
|
|
|
13
|
+
const props = defineProps<{
|
|
14
|
+
columns: number;
|
|
15
|
+
rows: number;
|
|
16
|
+
}>();
|
|
18
17
|
|
|
19
18
|
</script>
|
|
20
|
-
|
|
21
|
-
<style lang="scss" scoped>
|
|
22
|
-
|
|
23
|
-
</style>
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
{{ checkEmptyValues(column.enum.find(e => e.value === record[column.name])?.label || record[column.name], route.meta.type) }}
|
|
19
19
|
</span>
|
|
20
20
|
<span v-else-if="column.type === 'datetime'" class="whitespace-nowrap">
|
|
21
|
-
{{ checkEmptyValues(formatDateTime(record[column.name]),route.meta.type) }}
|
|
21
|
+
{{ checkEmptyValues(formatDateTime(record[column.name]), route.meta.type) }}
|
|
22
22
|
</span>
|
|
23
23
|
<span v-else-if="column.type === 'date'" class="whitespace-nowrap">
|
|
24
|
-
{{ checkEmptyValues(formatDate(record[column.name]),route.meta.type) }}
|
|
24
|
+
{{ checkEmptyValues(formatDate(record[column.name]), route.meta.type) }}
|
|
25
25
|
</span>
|
|
26
26
|
<span v-else-if="column.type === 'time'" class="whitespace-nowrap">
|
|
27
|
-
{{ checkEmptyValues(formatTime(record[column.name]),route.meta.type) }}
|
|
27
|
+
{{ checkEmptyValues(formatTime(record[column.name]), route.meta.type) }}
|
|
28
28
|
</span>
|
|
29
29
|
<span v-else-if="column.type === 'richtext'">
|
|
30
30
|
<div v-html="protectAgainstXSS(record[column.name])" class="allow-lists"></div>
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
</template>
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
<script setup>
|
|
45
|
+
<script setup lang="ts">
|
|
46
46
|
|
|
47
47
|
import dayjs from 'dayjs';
|
|
48
48
|
import utc from 'dayjs/plugin/utc';
|
|
@@ -52,10 +52,9 @@ import { useRoute, useRouter } from 'vue-router';
|
|
|
52
52
|
import sanitizeHtml from 'sanitize-html';
|
|
53
53
|
import { JsonViewer } from "vue3-json-viewer";
|
|
54
54
|
import "vue3-json-viewer/dist/index.css";
|
|
55
|
-
|
|
55
|
+
import type { AdminForthResourceColumnCommon } from '@/types/Common';
|
|
56
56
|
|
|
57
57
|
import { useCoreStore } from '@/stores/core';
|
|
58
|
-
import { computed } from 'vue';
|
|
59
58
|
|
|
60
59
|
const coreStore = useCoreStore();
|
|
61
60
|
const route = useRoute();
|
|
@@ -64,13 +63,13 @@ const route = useRoute();
|
|
|
64
63
|
dayjs.extend(utc);
|
|
65
64
|
dayjs.extend(timezone);
|
|
66
65
|
|
|
67
|
-
const props = defineProps
|
|
68
|
-
column:
|
|
69
|
-
record:
|
|
70
|
-
});
|
|
66
|
+
const props = defineProps<{
|
|
67
|
+
column: AdminForthResourceColumnCommon,
|
|
68
|
+
record: any
|
|
69
|
+
}>();
|
|
71
70
|
|
|
72
71
|
|
|
73
|
-
function protectAgainstXSS(value) {
|
|
72
|
+
function protectAgainstXSS(value: string) {
|
|
74
73
|
return sanitizeHtml(value, {
|
|
75
74
|
allowedTags: [
|
|
76
75
|
"address", "article", "aside", "footer", "header", "h1", "h2", "h3", "h4",
|
|
@@ -89,17 +88,17 @@ function protectAgainstXSS(value) {
|
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
|
|
92
|
-
function formatDateTime(date) {
|
|
91
|
+
function formatDateTime(date: string) {
|
|
93
92
|
if (!date) return '';
|
|
94
93
|
return dayjs.utc(date).local().format(`${coreStore.config?.datesFormat} ${coreStore.config?.timeFormat}` || 'YYYY-MM-DD HH:mm:ss');
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
function formatDate(date) {
|
|
96
|
+
function formatDate(date: string) {
|
|
98
97
|
if (!date) return '';
|
|
99
98
|
return dayjs.utc(date).local().format(coreStore.config?.datesFormat || 'YYYY-MM-DD');
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
function formatTime(time) {
|
|
101
|
+
function formatTime(time: string) {
|
|
103
102
|
if (!time) return '';
|
|
104
103
|
return dayjs(`0000-00-00 ${time}`).format(coreStore.config?.timeFormat || 'HH:mm:ss');
|
|
105
104
|
}
|
|
@@ -27,7 +27,6 @@ export type CoreConfig = {
|
|
|
27
27
|
timeFormat: string,
|
|
28
28
|
usernameField: string,
|
|
29
29
|
usernameFieldName?: string,
|
|
30
|
-
deleteConfirmation?: boolean,
|
|
31
30
|
auth?: {
|
|
32
31
|
resourceId: string,
|
|
33
32
|
usernameField: string,
|
|
@@ -37,9 +36,8 @@ export type CoreConfig = {
|
|
|
37
36
|
userFullnameField: string,
|
|
38
37
|
},
|
|
39
38
|
emptyFieldPlaceholder?: {
|
|
40
|
-
show
|
|
41
|
-
list
|
|
42
|
-
|
|
39
|
+
show?: string,
|
|
40
|
+
list?: string,
|
|
43
41
|
} | string,
|
|
44
42
|
}
|
|
45
43
|
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { ref, computed } from 'vue'
|
|
2
2
|
import { defineStore } from 'pinia'
|
|
3
3
|
import { callAdminForthApi } from '@/utils';
|
|
4
|
-
import type { AdminForthResourceCommon, AdminForthResourceColumnCommon } from '@/types/Common';
|
|
4
|
+
import type { AdminForthResourceCommon, AdminForthResourceColumnCommon, GetBaseConfigResponse, ResourceVeryShort, AdminUser, UserData, AdminForthConfigMenuItem, AdminForthConfigForFrontend } from '@/types/Common';
|
|
5
5
|
import type { Ref } from 'vue'
|
|
6
|
-
import type { AdminForthConfigMenuItem } from '@/types/Back';
|
|
7
6
|
|
|
8
7
|
export const useCoreStore = defineStore('core', () => {
|
|
9
|
-
const resourceById: Ref<
|
|
8
|
+
const resourceById: Ref<Record<string, ResourceVeryShort>> = ref({});
|
|
10
9
|
const theme: Ref<'light'| 'dark'> = ref(window.localStorage.getItem('af__theme') as ('light'|'dark') || 'light');
|
|
11
10
|
|
|
12
|
-
const menu = ref([]);
|
|
13
|
-
const config = ref(
|
|
11
|
+
const menu: Ref<AdminForthConfigMenuItem[]> = ref([]);
|
|
12
|
+
const config: Ref<AdminForthConfigForFrontend | null> = ref(null);
|
|
14
13
|
const record: Ref<any | null> = ref({});
|
|
15
14
|
const resource: Ref<AdminForthResourceCommon | null> = ref(null);
|
|
16
|
-
const userData = ref(null);
|
|
15
|
+
const userData: Ref<UserData | null> = ref(null);
|
|
17
16
|
|
|
18
17
|
const resourceColumnsWithFilters = computed(() => {
|
|
19
18
|
if (!resource.value) {
|
|
@@ -23,9 +22,9 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
23
22
|
})
|
|
24
23
|
|
|
25
24
|
const resourceOptions: Ref<AdminForthResourceCommon['options'] | null> = ref(null);
|
|
26
|
-
const resourceColumnsError = ref('');
|
|
27
|
-
const resourceColumnsId = ref(null);
|
|
28
|
-
const adminUser = ref(null);
|
|
25
|
+
const resourceColumnsError: Ref<string> = ref('');
|
|
26
|
+
const resourceColumnsId: Ref<string | null> = ref(null);
|
|
27
|
+
const adminUser: Ref<null | AdminUser> = ref(null);
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
async function resetAdminUser() {
|
|
@@ -46,7 +45,7 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
async function fetchMenuAndResource() {
|
|
49
|
-
const resp = await callAdminForthApi({
|
|
48
|
+
const resp: GetBaseConfigResponse = await callAdminForthApi({
|
|
50
49
|
path: '/get_base_config',
|
|
51
50
|
method: 'GET',
|
|
52
51
|
});
|
|
@@ -54,7 +53,7 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
54
53
|
return
|
|
55
54
|
}
|
|
56
55
|
menu.value = resp.menu;
|
|
57
|
-
resourceById.value = resp.resources.reduce((acc:
|
|
56
|
+
resourceById.value = resp.resources.reduce((acc: Record<string, ResourceVeryShort>, resource: ResourceVeryShort) => {
|
|
58
57
|
acc[resource.resourceId] = resource;
|
|
59
58
|
return acc;
|
|
60
59
|
}, {});
|
|
@@ -100,7 +99,7 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
100
99
|
if (!resource.value) {
|
|
101
100
|
throw new Error('Columns not fetched yet');
|
|
102
101
|
}
|
|
103
|
-
const col = resource.value.columns.find((col:
|
|
102
|
+
const col = resource.value.columns.find((col: AdminForthResourceColumnCommon) => col.primaryKey);
|
|
104
103
|
if (!col) {
|
|
105
104
|
throw new Error(`Primary key not found in resource ${resourceId}`);
|
|
106
105
|
}
|
|
@@ -170,13 +169,13 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
170
169
|
|
|
171
170
|
|
|
172
171
|
const username = computed(() => {
|
|
173
|
-
const usernameField = config.value
|
|
174
|
-
return userData.value && userData.value[usernameField];
|
|
172
|
+
const usernameField = config.value?.usernameField;
|
|
173
|
+
return userData.value && usernameField && userData.value[usernameField];
|
|
175
174
|
});
|
|
176
175
|
|
|
177
176
|
const userFullname = computed(() => {
|
|
178
|
-
const userFullnameField = config.value
|
|
179
|
-
return userData.value && userData.value[userFullnameField];
|
|
177
|
+
const userFullnameField = config.value?.userFullnameField;
|
|
178
|
+
return userData.value && userFullnameField && userData.value[userFullnameField];
|
|
180
179
|
})
|
|
181
180
|
|
|
182
181
|
|
|
@@ -22,13 +22,6 @@ export const useUserStore = defineStore('user', () => {
|
|
|
22
22
|
async function finishLogin() {
|
|
23
23
|
const coreStore = useCoreStore();
|
|
24
24
|
authorize(); // TODO not sure we need this approach with localStorage
|
|
25
|
-
// print traceback to this place
|
|
26
|
-
try {
|
|
27
|
-
null.test();
|
|
28
|
-
} catch (e) {
|
|
29
|
-
console.log(e);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
25
|
reconnect();
|
|
33
26
|
await router.push('/');
|
|
34
27
|
await router.isReady();
|