adminforth 1.5.6-next.8 → 1.5.6
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/adapters/completion-adapter-open-ai-chat-gpt/index.d.ts +11 -0
- package/dist/adapters/completion-adapter-open-ai-chat-gpt/index.d.ts.map +1 -0
- package/dist/adapters/completion-adapter-open-ai-chat-gpt/index.js +36 -0
- package/dist/adapters/completion-adapter-open-ai-chat-gpt/index.js.map +1 -0
- package/dist/adapters/completion-adapter-open-ai-chat-gpt/types.d.ts +23 -0
- package/dist/adapters/completion-adapter-open-ai-chat-gpt/types.d.ts.map +1 -0
- package/dist/adapters/completion-adapter-open-ai-chat-gpt/types.js +2 -0
- package/dist/adapters/completion-adapter-open-ai-chat-gpt/types.js.map +1 -0
- package/dist/adapters/email-adapter-aws-ses/index.d.ts +11 -0
- package/dist/adapters/email-adapter-aws-ses/index.d.ts.map +1 -0
- package/dist/adapters/email-adapter-aws-ses/index.js +64 -0
- package/dist/adapters/email-adapter-aws-ses/index.js.map +1 -0
- package/dist/adapters/email-adapter-aws-ses/types.d.ts +14 -0
- package/dist/adapters/email-adapter-aws-ses/types.d.ts.map +1 -0
- package/dist/adapters/email-adapter-aws-ses/types.js +2 -0
- package/dist/adapters/email-adapter-aws-ses/types.js.map +1 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -10
- package/dist/index.js.map +1 -1
- package/dist/modules/restApi.d.ts +1 -1
- package/dist/modules/restApi.d.ts.map +1 -1
- package/dist/modules/restApi.js.map +1 -1
- package/dist/spa/package-lock.json +65 -0
- package/dist/spa/package.json +1 -0
- package/dist/spa/src/components/GroupsTable.vue +16 -7
- package/dist/spa/src/components/ResourceForm.vue +15 -6
- package/dist/spa/src/components/ShowTable.vue +66 -0
- package/dist/spa/src/main.ts +5 -1
- package/dist/spa/src/types/Adapters.ts +17 -0
- package/dist/spa/src/types/Back.ts +1 -2
- package/dist/spa/src/types/Common.ts +14 -2
- package/dist/spa/src/views/LoginView.vue +8 -9
- package/dist/spa/src/views/ShowView.vue +62 -50
- package/dist/spa/tailwind.config.js +3 -1
- package/dist/spa/vite.config.ts +15 -1
- package/dist/types/Adapters.d.ts +10 -0
- package/dist/types/Adapters.d.ts.map +1 -0
- package/dist/types/Adapters.js +2 -0
- package/dist/types/Adapters.js.map +1 -0
- package/dist/types/Back.d.ts +1 -1
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Back.js.map +1 -1
- package/dist/types/Common.d.ts +14 -2
- package/dist/types/Common.d.ts.map +1 -1
- package/dist/types/Common.js.map +1 -1
- package/package.json +1 -1
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"uuid": "^10.0.0",
|
|
23
23
|
"vue": "^3.5.12",
|
|
24
24
|
"vue-diff": "^1.2.4",
|
|
25
|
+
"vue-i18n": "^10.0.5",
|
|
25
26
|
"vue-router": "^4.3.0",
|
|
26
27
|
"vue-slider-component": "^4.1.0-beta.7"
|
|
27
28
|
},
|
|
@@ -618,6 +619,50 @@
|
|
|
618
619
|
"vue": "^3.0.0"
|
|
619
620
|
}
|
|
620
621
|
},
|
|
622
|
+
"node_modules/@intlify/core-base": {
|
|
623
|
+
"version": "10.0.5",
|
|
624
|
+
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-10.0.5.tgz",
|
|
625
|
+
"integrity": "sha512-F3snDTQs0MdvnnyzTDTVkOYVAZOE/MHwRvF7mn7Jw1yuih4NrFYLNYIymGlLmq4HU2iIdzYsZ7f47bOcwY73XQ==",
|
|
626
|
+
"license": "MIT",
|
|
627
|
+
"dependencies": {
|
|
628
|
+
"@intlify/message-compiler": "10.0.5",
|
|
629
|
+
"@intlify/shared": "10.0.5"
|
|
630
|
+
},
|
|
631
|
+
"engines": {
|
|
632
|
+
"node": ">= 16"
|
|
633
|
+
},
|
|
634
|
+
"funding": {
|
|
635
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
"node_modules/@intlify/message-compiler": {
|
|
639
|
+
"version": "10.0.5",
|
|
640
|
+
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-10.0.5.tgz",
|
|
641
|
+
"integrity": "sha512-6GT1BJ852gZ0gItNZN2krX5QAmea+cmdjMvsWohArAZ3GmHdnNANEcF9JjPXAMRtQ6Ux5E269ymamg/+WU6tQA==",
|
|
642
|
+
"license": "MIT",
|
|
643
|
+
"dependencies": {
|
|
644
|
+
"@intlify/shared": "10.0.5",
|
|
645
|
+
"source-map-js": "^1.0.2"
|
|
646
|
+
},
|
|
647
|
+
"engines": {
|
|
648
|
+
"node": ">= 16"
|
|
649
|
+
},
|
|
650
|
+
"funding": {
|
|
651
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
"node_modules/@intlify/shared": {
|
|
655
|
+
"version": "10.0.5",
|
|
656
|
+
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-10.0.5.tgz",
|
|
657
|
+
"integrity": "sha512-bmsP4L2HqBF6i6uaMqJMcFBONVjKt+siGluRq4Ca4C0q7W2eMaVZr8iCgF9dKbcVXutftkC7D6z2SaSMmLiDyA==",
|
|
658
|
+
"license": "MIT",
|
|
659
|
+
"engines": {
|
|
660
|
+
"node": ">= 16"
|
|
661
|
+
},
|
|
662
|
+
"funding": {
|
|
663
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
664
|
+
}
|
|
665
|
+
},
|
|
621
666
|
"node_modules/@isaacs/cliui": {
|
|
622
667
|
"version": "8.0.2",
|
|
623
668
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
|
@@ -4560,6 +4605,26 @@
|
|
|
4560
4605
|
"eslint": ">=6.0.0"
|
|
4561
4606
|
}
|
|
4562
4607
|
},
|
|
4608
|
+
"node_modules/vue-i18n": {
|
|
4609
|
+
"version": "10.0.5",
|
|
4610
|
+
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-10.0.5.tgz",
|
|
4611
|
+
"integrity": "sha512-9/gmDlCblz3i8ypu/afiIc/SUIfTTE1mr0mZhb9pk70xo2csHAM9mp2gdQ3KD2O0AM3Hz/5ypb+FycTj/lHlPQ==",
|
|
4612
|
+
"license": "MIT",
|
|
4613
|
+
"dependencies": {
|
|
4614
|
+
"@intlify/core-base": "10.0.5",
|
|
4615
|
+
"@intlify/shared": "10.0.5",
|
|
4616
|
+
"@vue/devtools-api": "^6.5.0"
|
|
4617
|
+
},
|
|
4618
|
+
"engines": {
|
|
4619
|
+
"node": ">= 16"
|
|
4620
|
+
},
|
|
4621
|
+
"funding": {
|
|
4622
|
+
"url": "https://github.com/sponsors/kazupon"
|
|
4623
|
+
},
|
|
4624
|
+
"peerDependencies": {
|
|
4625
|
+
"vue": "^3.0.0"
|
|
4626
|
+
}
|
|
4627
|
+
},
|
|
4563
4628
|
"node_modules/vue-router": {
|
|
4564
4629
|
"version": "4.3.2",
|
|
4565
4630
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.2.tgz",
|
package/dist/spa/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="shadow-resourseFormShadow dark:shadow-darkResourseFormShadow dark:shadow-2xl">
|
|
2
|
+
<div class="rounded-lg shadow-resourseFormShadow dark:shadow-darkResourseFormShadow dark:shadow-2xl">
|
|
3
3
|
<div v-if="group.groupName" class="text-md font-semibold px-6 py-3 flex flex-1 items-center dark:border-gray-600 text-gray-700 bg-lightFormHeading dark:bg-gray-700 dark:text-gray-400 rounded-t-lg">
|
|
4
4
|
{{ group.groupName }}
|
|
5
5
|
</div>
|
|
6
6
|
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
7
7
|
<thead class="text-xs text-gray-700 uppercase dark:text-gray-400 bg-lightFormHeading dark:bg-gray-700 block md:table-row-group ">
|
|
8
8
|
<tr>
|
|
9
|
-
<th scope="col" class="px-6 py-3 hidden md:w-52 md:table-cell">
|
|
9
|
+
<th scope="col" :class="{'rounded-tl-lg': !group.groupName}" class="px-6 py-3 hidden md:w-52 md:table-cell">
|
|
10
10
|
Field
|
|
11
11
|
</th>
|
|
12
|
-
<th scope="col" class="px-6 py-3 hidden md:table-cell">
|
|
12
|
+
<th scope="col" :class="{'rounded-tr-lg': !group.groupName}" class="px-6 py-3 hidden md:table-cell">
|
|
13
13
|
Value
|
|
14
14
|
</th>
|
|
15
15
|
</tr>
|
|
@@ -37,8 +37,6 @@
|
|
|
37
37
|
</template>
|
|
38
38
|
</Tooltip>
|
|
39
39
|
</span>
|
|
40
|
-
|
|
41
|
-
|
|
42
40
|
</td>
|
|
43
41
|
<td class="px-6 py-4 whitespace-pre-wrap relative block md:table-cell rounded-br-lg "
|
|
44
42
|
:class="{'rounded-br-lg': i === group.columns.length - 1}">
|
|
@@ -73,7 +71,7 @@
|
|
|
73
71
|
<Select
|
|
74
72
|
class="w-full"
|
|
75
73
|
v-else-if="column.type === 'boolean'"
|
|
76
|
-
:options="
|
|
74
|
+
:options="getBooleanOptions(column)"
|
|
77
75
|
:modelValue="currentValues[column.name]"
|
|
78
76
|
@update:modelValue="setCurrentValue(column.name, $event)"
|
|
79
77
|
></Select>
|
|
@@ -167,9 +165,20 @@
|
|
|
167
165
|
unmasked: any,
|
|
168
166
|
columnError: (column: any) => string,
|
|
169
167
|
setCurrentValue: (columnName: string, value: any) => void,
|
|
170
|
-
columnOptions:
|
|
168
|
+
columnOptions: any,
|
|
171
169
|
}>();
|
|
172
170
|
|
|
171
|
+
const getBooleanOptions = (column: any) => {
|
|
172
|
+
const options: Array<{ label: string; value: boolean | null }> = [
|
|
173
|
+
{ label: 'Yes', value: true },
|
|
174
|
+
{ label: 'No', value: false },
|
|
175
|
+
];
|
|
176
|
+
if (!column.required[props.mode]) {
|
|
177
|
+
options.push({ label: 'Unset', value: null });
|
|
178
|
+
}
|
|
179
|
+
return options;
|
|
180
|
+
};
|
|
181
|
+
|
|
173
182
|
const emit = defineEmits(['update:customComponentsInValidity', 'update:customComponentsEmptiness']);
|
|
174
183
|
|
|
175
184
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="rounded-default">
|
|
3
3
|
<form autocomplete="off" @submit.prevent>
|
|
4
|
-
<div v-if="!
|
|
4
|
+
<div v-if="!groups || groups.length === 0">
|
|
5
5
|
<GroupsTable
|
|
6
6
|
:source="source"
|
|
7
7
|
:group="{groupName: '', columns: editableColumns}"
|
|
@@ -178,7 +178,6 @@ const setCurrentValue = (key, value) => {
|
|
|
178
178
|
};
|
|
179
179
|
|
|
180
180
|
onMounted(() => {
|
|
181
|
-
|
|
182
181
|
currentValues.value = Object.assign({}, props.record);
|
|
183
182
|
// json values should transform to string
|
|
184
183
|
props.resource.columns.forEach((column) => {
|
|
@@ -220,19 +219,29 @@ const isValid = computed(() => {
|
|
|
220
219
|
});
|
|
221
220
|
|
|
222
221
|
|
|
223
|
-
const groups =
|
|
222
|
+
const groups = computed(() => {
|
|
223
|
+
let fieldGroupType;
|
|
224
|
+
if (mode.value === 'edit' && coreStore.resource.options?.editFieldGroups !== undefined) {
|
|
225
|
+
fieldGroupType = coreStore.resource.options.editFieldGroups;
|
|
226
|
+
} else if (mode.value === 'create' && coreStore.resource.options?.createFieldGroups !== undefined) {
|
|
227
|
+
fieldGroupType = coreStore.resource.options.createFieldGroups;
|
|
228
|
+
} else {
|
|
229
|
+
fieldGroupType = coreStore.resource.options?.fieldGroups;
|
|
230
|
+
}
|
|
231
|
+
return fieldGroupType ?? [];
|
|
232
|
+
});
|
|
224
233
|
|
|
225
234
|
const groupedColumns = computed(() => {
|
|
226
|
-
if (!groups || groups.length === 0) return [];
|
|
235
|
+
if (!groups.value || groups.value.length === 0) return [];
|
|
227
236
|
|
|
228
|
-
return groups.map(group => ({
|
|
237
|
+
return groups.value.map(group => ({
|
|
229
238
|
...group,
|
|
230
239
|
columns: props.resource.columns.filter(col => group.columns.includes(col.name) && editableColumns.value.includes(col))
|
|
231
240
|
}));
|
|
232
241
|
});
|
|
233
242
|
|
|
234
243
|
const getOtherColumns = () => {
|
|
235
|
-
if (!groups || groups.length === 0) return;
|
|
244
|
+
if (!groups.value || groups.value.length === 0) return;
|
|
236
245
|
|
|
237
246
|
const groupedColumnNames = new Set(groupedColumns.value.flatMap(group => group.columns.map(col => col.name)));
|
|
238
247
|
return editableColumns.value.filter(col => !groupedColumnNames.has(col.name));
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="overflow-x-auto rounded-default shadow-resourseFormShadow dark:shadow-darkResourseFormShadow">
|
|
3
|
+
<div v-if="groupName" class="text-md font-semibold px-6 py-3 flex flex-1 items-center dark:border-gray-600 text-gray-700 bg-lightFormHeading dark:bg-gray-700 dark:text-gray-400 rounded-t-lg">
|
|
4
|
+
{{ groupName }}
|
|
5
|
+
</div>
|
|
6
|
+
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 table-fixed mb-4">
|
|
7
|
+
<thead class="text-gray-700 dark:text-gray-400 bg-lightFormHeading dark:bg-gray-700 block md:table-row-group">
|
|
8
|
+
<tr>
|
|
9
|
+
<th scope="col" class="px-6 py-3 text-xs uppercase hidden md:w-52 md:table-cell">
|
|
10
|
+
Field
|
|
11
|
+
</th>
|
|
12
|
+
<th scope="col" class="px-6 py-3 text-xs uppercase hidden md:table-cell">
|
|
13
|
+
Value
|
|
14
|
+
</th>
|
|
15
|
+
</tr>
|
|
16
|
+
</thead>
|
|
17
|
+
<tbody>
|
|
18
|
+
<tr
|
|
19
|
+
v-for="column in columns"
|
|
20
|
+
:key="column.name"
|
|
21
|
+
class="bg-lightForm bg-darkForm odd:dark:bg-gray-900 even:dark:bg-gray-800 dark:border-gray-700 block md:table-row"
|
|
22
|
+
>
|
|
23
|
+
<td class="px-6 py-4 relative block md:table-cell font-bold md:font-normal pb-0 md:pb-4">
|
|
24
|
+
{{ column.label }}
|
|
25
|
+
</td>
|
|
26
|
+
<td class="px-6 py-4 whitespace-pre-wrap" :data-af-column="column.name">
|
|
27
|
+
<component
|
|
28
|
+
v-if="column?.components?.show"
|
|
29
|
+
:is="getCustomComponent(column?.components?.show)"
|
|
30
|
+
:resource="resource"
|
|
31
|
+
:meta="column.components.show.meta"
|
|
32
|
+
:column="column"
|
|
33
|
+
:record="record"
|
|
34
|
+
/>
|
|
35
|
+
<ValueRenderer
|
|
36
|
+
v-else
|
|
37
|
+
:column="column"
|
|
38
|
+
:record="record"
|
|
39
|
+
/>
|
|
40
|
+
</td>
|
|
41
|
+
</tr>
|
|
42
|
+
</tbody>
|
|
43
|
+
</table>
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<script setup lang="ts">
|
|
48
|
+
import { defineProps } from 'vue';
|
|
49
|
+
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
50
|
+
import { getCustomComponent } from '@/utils';
|
|
51
|
+
|
|
52
|
+
defineProps<{
|
|
53
|
+
columns: Array<{
|
|
54
|
+
name: string;
|
|
55
|
+
label: string;
|
|
56
|
+
components?: {
|
|
57
|
+
show?: {
|
|
58
|
+
meta: Record<string, any>;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}>;
|
|
62
|
+
groupName?: string | null;
|
|
63
|
+
resource: Record<string, any>;
|
|
64
|
+
record: Record<string, any>;
|
|
65
|
+
}>();
|
|
66
|
+
</script>
|
package/dist/spa/src/main.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createApp } from 'vue'
|
|
2
|
+
import { createI18n } from 'vue-i18n'
|
|
2
3
|
import { createPinia } from 'pinia'
|
|
3
4
|
/* IMPORTANT:ADMINFORTH IMPORTS */
|
|
4
5
|
|
|
@@ -9,9 +10,12 @@ import router from './router'
|
|
|
9
10
|
export const app = createApp(App)
|
|
10
11
|
/* IMPORTANT:ADMINFORTH COMPONENT REGISTRATIONS */
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
const i18n = createI18n({
|
|
14
|
+
// something vue-i18n options here ...
|
|
15
|
+
})
|
|
13
16
|
app.use(createPinia())
|
|
14
17
|
app.use(router)
|
|
18
|
+
app.use(i18n)
|
|
15
19
|
|
|
16
20
|
/* IMPORTANT:ADMINFORTH CUSTOM USES */
|
|
17
21
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface EmailAdapter {
|
|
2
|
+
sendEmail(
|
|
3
|
+
from: string,
|
|
4
|
+
to: string,
|
|
5
|
+
text: string,
|
|
6
|
+
html: string,
|
|
7
|
+
subject: string
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CompletionAdapter {
|
|
12
|
+
complete(
|
|
13
|
+
content: string,
|
|
14
|
+
stop: string[],
|
|
15
|
+
maxTokens: number
|
|
16
|
+
): Promise<{ content: string; finishReason: string }>;
|
|
17
|
+
}
|
|
@@ -204,7 +204,6 @@ export interface IAdminForthDataSourceConnector {
|
|
|
204
204
|
*/
|
|
205
205
|
updateRecordOriginalValues({ resource, recordId, newValues }: { resource: AdminForthResource; recordId: string; newValues: any; }): Promise<void>;
|
|
206
206
|
|
|
207
|
-
|
|
208
207
|
/**
|
|
209
208
|
* Used to delete record in database.
|
|
210
209
|
*/
|
|
@@ -278,7 +277,7 @@ export interface IAdminForthRestAPI {
|
|
|
278
277
|
* @param toReturn - this is an object which will get status of login process. If at least one callback returns error or redirectTo, login process will be stopped (future callbacks will not be called).
|
|
279
278
|
* @param response - http response object
|
|
280
279
|
*/
|
|
281
|
-
processLoginCallbacks(adminUser: AdminUser, toReturn: { redirectTo?: string, allowedLogin: boolean, error?: string }, response: any): Promise<void>;
|
|
280
|
+
processLoginCallbacks(adminUser: AdminUser, toReturn: { redirectTo?: string, allowedLogin: boolean, error?: string }, response: any, extra: HttpExtra): Promise<void>;
|
|
282
281
|
}
|
|
283
282
|
|
|
284
283
|
export interface IAdminForth {
|
|
@@ -338,9 +338,21 @@ export interface AdminForthResourceInputCommon {
|
|
|
338
338
|
allowedActions?: AllowedActionsResolved,
|
|
339
339
|
|
|
340
340
|
/**
|
|
341
|
-
* Allows to make groups of columns in create
|
|
341
|
+
* Allows to make groups of columns in show, create and edit resource pages.
|
|
342
342
|
*/
|
|
343
|
-
|
|
343
|
+
fieldGroups?: {
|
|
344
|
+
groupName: string;
|
|
345
|
+
columns: string[];
|
|
346
|
+
}[];
|
|
347
|
+
createFieldGroups?: {
|
|
348
|
+
groupName: string;
|
|
349
|
+
columns: string[];
|
|
350
|
+
}[];
|
|
351
|
+
editFieldGroups?: {
|
|
352
|
+
groupName: string;
|
|
353
|
+
columns: string[];
|
|
354
|
+
}[];
|
|
355
|
+
showFieldGroups?: {
|
|
344
356
|
groupName: string;
|
|
345
357
|
columns: string[];
|
|
346
358
|
}[];
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
<!-- Modal header -->
|
|
32
32
|
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
|
|
33
33
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
|
|
34
|
-
Sign in to {{ coreStore.config?.brandName }}
|
|
34
|
+
{{ $t('Sign in to') }} {{ coreStore.config?.brandName }}
|
|
35
35
|
</h3>
|
|
36
36
|
</div>
|
|
37
37
|
<!-- Modal body -->
|
|
38
38
|
<div class="p-4 md:p-5">
|
|
39
39
|
<form class="space-y-4" @submit.prevent>
|
|
40
40
|
<div>
|
|
41
|
-
<label for="username" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your {{ coreStore.config?.usernameFieldName?.toLowerCase() }}</label>
|
|
41
|
+
<label for="username" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">{{ $t('Your') }} {{ coreStore.config?.usernameFieldName?.toLowerCase() }}</label>
|
|
42
42
|
<input
|
|
43
43
|
autocomplete="username"
|
|
44
44
|
type="username"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white" placeholder="name@company.com" required />
|
|
50
50
|
</div>
|
|
51
51
|
<div class="relative">
|
|
52
|
-
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your password</label>
|
|
52
|
+
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">{{ $t('Your password') }}</label>
|
|
53
53
|
<input
|
|
54
54
|
ref="passwordInput"
|
|
55
55
|
autocomplete="current-password"
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
:title="`Stay logged in for ${coreStore.config.rememberMeDays} days`"
|
|
67
67
|
>
|
|
68
68
|
<Checkbox v-model="rememberMeValue" class="mr-2">
|
|
69
|
-
Remember me
|
|
69
|
+
{{ $t('Remember me') }}
|
|
70
70
|
</Checkbox>
|
|
71
71
|
|
|
72
72
|
</div>
|
|
@@ -81,9 +81,9 @@
|
|
|
81
81
|
<svg class="flex-shrink-0 inline w-4 h-4 me-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
|
82
82
|
<path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/>
|
|
83
83
|
</svg>
|
|
84
|
-
<span class="sr-only">Info</span>
|
|
84
|
+
<span class="sr-only">{{ $t('Info') }}</span>
|
|
85
85
|
<div>
|
|
86
|
-
|
|
86
|
+
{{ error }}
|
|
87
87
|
</div>
|
|
88
88
|
</div>
|
|
89
89
|
|
|
@@ -93,11 +93,11 @@
|
|
|
93
93
|
<svg class="flex-shrink-0 inline w-4 h-4 me-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
|
94
94
|
<path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/>
|
|
95
95
|
</svg>
|
|
96
|
-
<span class="sr-only">Info</span>
|
|
96
|
+
<span class="sr-only">{{ $t('Info') }}</span>
|
|
97
97
|
<div v-html="coreStore.config?.loginPromptHTML"></div>
|
|
98
98
|
</div>
|
|
99
99
|
<Button @click="login" :loader="inProgress" :disabled="inProgress" class="w-full">
|
|
100
|
-
Login to your account
|
|
100
|
+
{{ $t('Login to your account') }}
|
|
101
101
|
</Button>
|
|
102
102
|
</form>
|
|
103
103
|
|
|
@@ -141,7 +141,6 @@ const backgroundPosition = computed(() => {
|
|
|
141
141
|
|
|
142
142
|
onMounted(async () => {
|
|
143
143
|
if (coreStore.config?.demoCredentials) {
|
|
144
|
-
console.log('Setting demo credentials');
|
|
145
144
|
const [username, password] = coreStore.config.demoCredentials.split(':');
|
|
146
145
|
usernameInput.value.value = username;
|
|
147
146
|
passwordInput.value.value = password;
|
|
@@ -57,55 +57,33 @@
|
|
|
57
57
|
</div>
|
|
58
58
|
<div
|
|
59
59
|
v-else-if="coreStore.record"
|
|
60
|
-
class="relative w-full
|
|
60
|
+
class="relative w-full flex flex-col gap-4"
|
|
61
61
|
>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<template v-else>
|
|
88
|
-
<td class="px-6 py-4 relative block md:table-cell font-bold md:font-normal pb-0 md:pb-4"> <!--align-top-->
|
|
89
|
-
{{ column.label }}
|
|
90
|
-
</td>
|
|
91
|
-
<td class="px-6 py-4 whitespace-pre-wrap" :data-af-column="column.name">
|
|
92
|
-
<component
|
|
93
|
-
v-if="column?.components?.show"
|
|
94
|
-
:is="getCustomComponent(column?.components?.show)"
|
|
95
|
-
:resource="coreStore.resource"
|
|
96
|
-
:meta="column.components.show.meta"
|
|
97
|
-
:column="column"
|
|
98
|
-
:record="coreStore.record"
|
|
99
|
-
/>
|
|
100
|
-
<ValueRenderer v-else
|
|
101
|
-
:column="column"
|
|
102
|
-
:record="coreStore.record"
|
|
103
|
-
/>
|
|
104
|
-
</td>
|
|
105
|
-
</template>
|
|
106
|
-
</tr>
|
|
107
|
-
</tbody>
|
|
108
|
-
</table>
|
|
62
|
+
<div v-if="!groups.length && allColumns.length">
|
|
63
|
+
<ShowTable
|
|
64
|
+
:columns="allColumns"
|
|
65
|
+
:resource="coreStore.resource"
|
|
66
|
+
:record="coreStore.record"
|
|
67
|
+
/>
|
|
68
|
+
</div>
|
|
69
|
+
<template v-else>
|
|
70
|
+
<template v-for="group in groups" :key="group.groupName">
|
|
71
|
+
<ShowTable
|
|
72
|
+
:columns="group.columns"
|
|
73
|
+
:groupName="group.groupName"
|
|
74
|
+
:resource="coreStore.resource"
|
|
75
|
+
:record="coreStore.record"
|
|
76
|
+
/>
|
|
77
|
+
</template>
|
|
78
|
+
<template v-if="otherColumns.length > 0">
|
|
79
|
+
<ShowTable
|
|
80
|
+
:columns="otherColumns"
|
|
81
|
+
groupName="Other Fields"
|
|
82
|
+
:resource="coreStore.resource"
|
|
83
|
+
:record="coreStore.record"
|
|
84
|
+
/>
|
|
85
|
+
</template>
|
|
86
|
+
</template>
|
|
109
87
|
</div>
|
|
110
88
|
|
|
111
89
|
<div v-else class="text-center text-gray-500 dark:text-gray-400 mt-10">
|
|
@@ -132,15 +110,15 @@
|
|
|
132
110
|
|
|
133
111
|
import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
134
112
|
|
|
135
|
-
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
136
113
|
import { useCoreStore } from '@/stores/core';
|
|
137
114
|
import { getCustomComponent, checkAcessByAllowedActions, initThreeDotsDropdown } from '@/utils';
|
|
138
115
|
import { IconPenSolid, IconTrashBinSolid, IconPlusOutline } from '@iconify-prerendered/vue-flowbite';
|
|
139
|
-
import { onMounted, ref } from 'vue';
|
|
116
|
+
import { onMounted, ref, computed } from 'vue';
|
|
140
117
|
import { useRoute,useRouter } from 'vue-router';
|
|
141
118
|
import {callAdminForthApi} from '@/utils';
|
|
142
119
|
import { showSuccesTost, showErrorTost } from '@/composables/useFrontendApi';
|
|
143
120
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
121
|
+
import ShowTable from '@/components/ShowTable.vue';
|
|
144
122
|
|
|
145
123
|
|
|
146
124
|
const route = useRoute();
|
|
@@ -164,6 +142,40 @@ onMounted(async () => {
|
|
|
164
142
|
loading.value = false;
|
|
165
143
|
});
|
|
166
144
|
|
|
145
|
+
const groups = computed(() => {
|
|
146
|
+
let fieldGroupType;
|
|
147
|
+
if (coreStore.resource.options?.showFieldGroups) {
|
|
148
|
+
fieldGroupType = coreStore.resource.options.showFieldGroups;
|
|
149
|
+
} else if (coreStore.resource.options?.showFieldGroups === null) {
|
|
150
|
+
fieldGroupType = [];
|
|
151
|
+
} else {
|
|
152
|
+
fieldGroupType = coreStore.resource.options?.fieldGroups;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const activeGroups = fieldGroupType ?? [];
|
|
156
|
+
|
|
157
|
+
return activeGroups.map(group => ({
|
|
158
|
+
...group,
|
|
159
|
+
columns: coreStore.resource.columns.filter(
|
|
160
|
+
col => group.columns.includes(col.name) && col.showIn.includes('show')
|
|
161
|
+
),
|
|
162
|
+
}));
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const allColumns = computed(() => {
|
|
166
|
+
return coreStore.resource.columns.filter(col => col.showIn.includes('show'));
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const otherColumns = computed(() => {
|
|
170
|
+
const groupedColumnNames = new Set(
|
|
171
|
+
groups.value.flatMap(group => group.columns.map(col => col.name))
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
return coreStore.resource.columns.filter(
|
|
175
|
+
col => !groupedColumnNames.has(col.name) && col.showIn.includes('show')
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
|
|
167
179
|
async function deleteRecord(row) {
|
|
168
180
|
const data = await window.adminforth.confirm({
|
|
169
181
|
message: 'Are you sure you want to delete this item?',
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
import flowbitePlugin from 'flowbite/plugin';
|
|
3
|
+
|
|
2
4
|
export default {
|
|
3
5
|
content: ["./src/**/*.{vue, js, ts, tsx}","./src/*.{vue, js, ts, tsx}", "./index.html", "./node_modules/flowbite/**/*.js"],
|
|
4
6
|
theme: {
|
|
@@ -9,7 +11,7 @@ export default {
|
|
|
9
11
|
|
|
10
12
|
darkMode: 'class',
|
|
11
13
|
plugins: [
|
|
12
|
-
|
|
14
|
+
flowbitePlugin({
|
|
13
15
|
charts: true,
|
|
14
16
|
}),
|
|
15
17
|
],
|
package/dist/spa/vite.config.ts
CHANGED
|
@@ -34,5 +34,19 @@ export default defineConfig({
|
|
|
34
34
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
|
35
35
|
'@@': fileURLToPath(new URL('./src/custom', import.meta.url)),
|
|
36
36
|
}
|
|
37
|
-
}
|
|
37
|
+
},
|
|
38
|
+
build: {
|
|
39
|
+
rollupOptions: {
|
|
40
|
+
output: {
|
|
41
|
+
manualChunks(id) {
|
|
42
|
+
// reduce the size of the vendor chunk
|
|
43
|
+
// to only include the package name
|
|
44
|
+
// helps to reduce consumption of memory
|
|
45
|
+
if (id.includes('node_modules')) {
|
|
46
|
+
return id.toString().split('node_modules/')[1].split('/')[0].toString();
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
38
52
|
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface EmailAdapter {
|
|
2
|
+
sendEmail(from: string, to: string, text: string, html: string, subject: string): any;
|
|
3
|
+
}
|
|
4
|
+
export interface CompletionAdapter {
|
|
5
|
+
complete(content: string, stop: string[], maxTokens: number): Promise<{
|
|
6
|
+
content: string;
|
|
7
|
+
finishReason: string;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=Adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Adapters.d.ts","sourceRoot":"","sources":["../../types/Adapters.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,OACf;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Adapters.js","sourceRoot":"","sources":["../../types/Adapters.ts"],"names":[],"mappings":""}
|
package/dist/types/Back.d.ts
CHANGED
|
@@ -266,7 +266,7 @@ export interface IAdminForthRestAPI {
|
|
|
266
266
|
redirectTo?: string;
|
|
267
267
|
allowedLogin: boolean;
|
|
268
268
|
error?: string;
|
|
269
|
-
}, response: any): Promise<void>;
|
|
269
|
+
}, response: any, extra: HttpExtra): Promise<void>;
|
|
270
270
|
}
|
|
271
271
|
export interface IAdminForth {
|
|
272
272
|
config: AdminForthConfig;
|