adminforth 2.4.0-next.14 → 2.4.0-next.140
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/commands/callTsProxy.js +14 -4
- package/commands/cli.js +12 -4
- package/commands/createApp/templates/custom/tsconfig.json.hbs +2 -3
- package/commands/createApp/templates/index.ts.hbs +10 -2
- package/commands/createApp/templates/package.json.hbs +1 -1
- package/commands/createApp/utils.js +27 -2
- package/commands/createCustomComponent/configLoader.js +3 -0
- package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
- package/dist/dataConnectors/baseConnector.js +46 -15
- package/dist/dataConnectors/baseConnector.js.map +1 -1
- package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
- package/dist/dataConnectors/clickhouse.js +15 -0
- package/dist/dataConnectors/clickhouse.js.map +1 -1
- package/dist/dataConnectors/mongo.d.ts.map +1 -1
- package/dist/dataConnectors/mongo.js +44 -15
- package/dist/dataConnectors/mongo.js.map +1 -1
- package/dist/dataConnectors/mysql.d.ts.map +1 -1
- package/dist/dataConnectors/mysql.js +11 -0
- package/dist/dataConnectors/mysql.js.map +1 -1
- package/dist/dataConnectors/postgres.d.ts.map +1 -1
- package/dist/dataConnectors/postgres.js +11 -0
- package/dist/dataConnectors/postgres.js.map +1 -1
- package/dist/dataConnectors/sqlite.d.ts.map +1 -1
- package/dist/dataConnectors/sqlite.js +11 -0
- package/dist/dataConnectors/sqlite.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -9
- package/dist/index.js.map +1 -1
- package/dist/modules/codeInjector.d.ts.map +1 -1
- package/dist/modules/codeInjector.js +22 -5
- package/dist/modules/codeInjector.js.map +1 -1
- package/dist/modules/configValidator.d.ts.map +1 -1
- package/dist/modules/configValidator.js +53 -2
- package/dist/modules/configValidator.js.map +1 -1
- package/dist/modules/restApi.d.ts.map +1 -1
- package/dist/modules/restApi.js +147 -25
- package/dist/modules/restApi.js.map +1 -1
- package/dist/modules/styles.d.ts +457 -13
- package/dist/modules/styles.d.ts.map +1 -1
- package/dist/modules/styles.js +513 -31
- package/dist/modules/styles.js.map +1 -1
- package/dist/modules/utils.d.ts +1 -0
- package/dist/modules/utils.d.ts.map +1 -1
- package/dist/modules/utils.js +9 -0
- package/dist/modules/utils.js.map +1 -1
- package/dist/spa/index.html +1 -1
- package/dist/spa/src/App.vue +33 -15
- package/dist/spa/src/adminforth.ts +15 -6
- package/dist/spa/src/afcl/BarChart.vue +2 -2
- package/dist/spa/src/afcl/Button.vue +6 -6
- package/dist/spa/src/afcl/Checkbox.vue +21 -13
- package/dist/spa/src/afcl/CountryFlag.vue +4 -1
- package/dist/spa/src/{components/CustomDatePicker.vue → afcl/DatePicker.vue} +95 -9
- package/dist/spa/src/afcl/Dialog.vue +44 -27
- package/dist/spa/src/afcl/Dropzone.vue +12 -12
- package/dist/spa/src/afcl/Input.vue +6 -6
- package/dist/spa/src/afcl/JsonViewer.vue +25 -0
- package/dist/spa/src/afcl/Link.vue +1 -1
- package/dist/spa/src/afcl/LinkButton.vue +2 -2
- package/dist/spa/src/afcl/PieChart.vue +5 -5
- package/dist/spa/src/afcl/ProgressBar.vue +7 -7
- package/dist/spa/src/afcl/Select.vue +68 -34
- package/dist/spa/src/afcl/Skeleton.vue +6 -6
- package/dist/spa/src/afcl/Table.vue +199 -71
- package/dist/spa/src/afcl/Textarea.vue +31 -0
- package/dist/spa/src/afcl/Toggle.vue +32 -0
- package/dist/spa/src/afcl/Tooltip.vue +2 -3
- package/dist/spa/src/afcl/VerticalTabs.vue +3 -3
- package/dist/spa/src/afcl/index.ts +4 -3
- package/dist/spa/src/components/AcceptModal.vue +7 -7
- package/dist/spa/src/components/Breadcrumbs.vue +5 -5
- package/dist/spa/src/components/ColumnValueInput.vue +37 -18
- package/dist/spa/src/components/ColumnValueInputWrapper.vue +4 -3
- package/dist/spa/src/components/CustomDateRangePicker.vue +9 -8
- package/dist/spa/src/components/CustomRangePicker.vue +37 -8
- package/dist/spa/src/components/ErrorMessage.vue +21 -0
- package/dist/spa/src/components/Filters.vue +83 -37
- package/dist/spa/src/components/GroupsTable.vue +9 -8
- package/dist/spa/src/components/MenuLink.vue +3 -3
- package/dist/spa/src/components/ResourceForm.vue +94 -51
- package/dist/spa/src/components/ResourceListTable.vue +78 -80
- package/dist/spa/src/components/ResourceListTableVirtual.vue +70 -72
- package/dist/spa/src/components/ShowTable.vue +17 -12
- package/dist/spa/src/components/SingleSkeletLoader.vue +6 -6
- package/dist/spa/src/components/SkeleteLoader.vue +3 -3
- package/dist/spa/src/components/ThreeDotsMenu.vue +73 -14
- package/dist/spa/src/components/Toast.vue +2 -7
- package/dist/spa/src/components/ValueRenderer.vue +43 -16
- package/dist/spa/src/controls/BoolToggle.vue +34 -0
- package/dist/spa/src/i18n.ts +1 -1
- package/dist/spa/src/shims-vue.d.ts +5 -0
- package/dist/spa/src/spa_types/core.ts +8 -1
- package/dist/spa/src/stores/core.ts +1 -1
- package/dist/spa/src/stores/modal.ts +6 -1
- package/dist/spa/src/types/Back.ts +107 -21
- package/dist/spa/src/types/Common.ts +44 -31
- package/dist/spa/src/types/FrontendAPI.ts +8 -0
- package/dist/spa/src/types/adapters/CompletionAdapter.ts +25 -0
- package/dist/spa/src/types/adapters/EmailAdapter.ts +27 -0
- package/dist/spa/src/types/adapters/ImageGenerationAdapter.ts +50 -0
- package/dist/spa/src/types/adapters/ImageVisionAdapter.ts +30 -0
- package/dist/spa/src/types/adapters/OAuth2Adapter.ts +34 -0
- package/dist/spa/src/types/adapters/StorageAdapter.ts +73 -0
- package/dist/spa/src/types/adapters/index.ts +6 -0
- package/dist/spa/src/utils.ts +217 -7
- package/dist/spa/src/views/CreateView.vue +18 -19
- package/dist/spa/src/views/EditView.vue +25 -19
- package/dist/spa/src/views/ListView.vue +117 -79
- package/dist/spa/src/views/LoginView.vue +36 -44
- package/dist/spa/src/views/ResourceParent.vue +1 -1
- package/dist/spa/src/views/ShowView.vue +59 -39
- package/dist/spa/src/websocket.ts +6 -1
- package/dist/spa/tsconfig.app.json +1 -1
- package/dist/spa/vite.config.ts +45 -2
- package/dist/types/Back.d.ts +75 -14
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Back.js +15 -0
- package/dist/types/Back.js.map +1 -1
- package/dist/types/Common.d.ts +37 -28
- package/dist/types/Common.d.ts.map +1 -1
- package/dist/types/Common.js.map +1 -1
- package/dist/types/FrontendAPI.d.ts +7 -0
- package/dist/types/FrontendAPI.d.ts.map +1 -1
- package/dist/types/FrontendAPI.js.map +1 -1
- package/dist/types/adapters/CompletionAdapter.d.ts +20 -0
- package/dist/types/adapters/CompletionAdapter.d.ts.map +1 -0
- package/dist/types/adapters/CompletionAdapter.js +2 -0
- package/dist/types/adapters/CompletionAdapter.js.map +1 -0
- package/dist/types/adapters/EmailAdapter.d.ts +20 -0
- package/dist/types/adapters/EmailAdapter.d.ts.map +1 -0
- package/dist/types/adapters/EmailAdapter.js +2 -0
- package/dist/types/adapters/EmailAdapter.js.map +1 -0
- package/dist/types/adapters/ImageGenerationAdapter.d.ts +37 -0
- package/dist/types/adapters/ImageGenerationAdapter.d.ts.map +1 -0
- package/dist/types/adapters/ImageGenerationAdapter.js +2 -0
- package/dist/types/adapters/ImageGenerationAdapter.js.map +1 -0
- package/dist/types/adapters/ImageVisionAdapter.d.ts +25 -0
- package/dist/types/adapters/ImageVisionAdapter.d.ts.map +1 -0
- package/dist/types/adapters/ImageVisionAdapter.js +2 -0
- package/dist/types/adapters/ImageVisionAdapter.js.map +1 -0
- package/dist/types/adapters/OAuth2Adapter.d.ts +32 -0
- package/dist/types/adapters/OAuth2Adapter.d.ts.map +1 -0
- package/dist/types/adapters/OAuth2Adapter.js +2 -0
- package/dist/types/adapters/OAuth2Adapter.js.map +1 -0
- package/dist/types/adapters/StorageAdapter.d.ts +63 -0
- package/dist/types/adapters/StorageAdapter.d.ts.map +1 -0
- package/dist/types/adapters/StorageAdapter.js +2 -0
- package/dist/types/adapters/StorageAdapter.js.map +1 -0
- package/dist/types/adapters/index.d.ts +7 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/index.js +2 -0
- package/dist/types/adapters/index.js.map +1 -0
- package/package.json +9 -2
- package/dist/spa/src/types/Adapters.ts +0 -213
- package/dist/types/Adapters.d.ts +0 -168
- package/dist/types/Adapters.d.ts.map +0 -1
- package/dist/types/Adapters.js +0 -2
- package/dist/types/Adapters.js.map +0 -1
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
<div class="flex items-center w-full p-4
|
|
4
|
+
<div class="flex items-center w-full p-4 rounded-lg shadow-lg dark:text-darkToastText dark:bg-darkToastBackground bg-lightToastBackground text-lightToastText"
|
|
5
5
|
role="alert"
|
|
6
|
-
:class="
|
|
7
|
-
{
|
|
8
|
-
'danger': 'bg-red-100',
|
|
9
|
-
}[toast.variant]
|
|
10
|
-
"
|
|
11
6
|
>
|
|
12
7
|
<div v-if="toast.variant == 'info'" class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-lightPrimary dark:text-darkPrimary bg-lightPrimaryOpacity rounded-lg dark:bg-blue-800 dark:text-blue-200">
|
|
13
8
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 20">
|
|
@@ -36,7 +31,7 @@
|
|
|
36
31
|
|
|
37
32
|
<div class="ms-3 text-sm font-normal max-w-xs pr-2" v-if="toast.messageHtml" v-html="toast.messageHtml"></div>
|
|
38
33
|
<div class="ms-3 text-sm font-normal max-w-xs pr-2" v-else>{{toast.message}}</div>
|
|
39
|
-
<button @click="closeToast" type="button" class="ms-auto -mx-1.5 -my-1.5 bg-
|
|
34
|
+
<button @click="closeToast" type="button" class="ms-auto -mx-1.5 -my-1.5 bg-lightToastCloseIconBackground text-lightToastCloseIcon hover:text-lightToastCloseIconHover rounded-lg focus:ring-2 focus:ring-lightToastCloseIconFocusRing p-1.5 hover:bg-lightToastCloseIconBackgroundHover inline-flex items-center justify-center h-8 w-8 dark:text-darkToastCloseIcon dark:hover:text-darkToastCloseIconHover dark:bg-darkToastCloseIconBackground dark:hover:bg-darkToastCloseIconBackgroundHover dark:focus:ring-darkToastCloseIconFocusRing" >
|
|
40
35
|
<svg class="w-3 h-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
41
36
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
42
37
|
</svg>
|
|
@@ -12,13 +12,40 @@
|
|
|
12
12
|
>
|
|
13
13
|
<RouterLink
|
|
14
14
|
class="font-medium text-lightSidebarText dark:text-darkSidebarText hover:brightness-110 whitespace-nowrap"
|
|
15
|
-
:to="{
|
|
15
|
+
:to="{
|
|
16
|
+
name: 'resource-show',
|
|
17
|
+
params: {
|
|
18
|
+
primaryKey: foreignResource.pk,
|
|
19
|
+
resourceId: column.foreignResource
|
|
20
|
+
? (
|
|
21
|
+
column.foreignResource.resourceId
|
|
22
|
+
|| column.foreignResource.polymorphicResources?.find(
|
|
23
|
+
(pr: any) => pr.whenValue === record[column.foreignResource?.polymorphicOn!]
|
|
24
|
+
)?.resourceId
|
|
25
|
+
)
|
|
26
|
+
: undefined
|
|
27
|
+
}
|
|
28
|
+
}"
|
|
16
29
|
>
|
|
17
30
|
{{ foreignResource.label }}
|
|
18
31
|
</RouterLink>
|
|
19
32
|
</span>
|
|
20
33
|
<RouterLink v-else-if="record[column.name]" class="font-medium text-lightPrimary dark:text-darkPrimary hover:brightness-110 whitespace-nowrap"
|
|
21
|
-
|
|
34
|
+
:to="{
|
|
35
|
+
name: 'resource-show',
|
|
36
|
+
params: {
|
|
37
|
+
primaryKey: record[column.name].pk,
|
|
38
|
+
resourceId: column.foreignResource
|
|
39
|
+
? (
|
|
40
|
+
column.foreignResource.resourceId
|
|
41
|
+
|| column.foreignResource.polymorphicResources?.find(
|
|
42
|
+
(pr: any) => pr.whenValue === record[column.foreignResource?.polymorphicOn!]
|
|
43
|
+
)?.resourceId
|
|
44
|
+
)
|
|
45
|
+
: undefined
|
|
46
|
+
}
|
|
47
|
+
}"
|
|
48
|
+
>
|
|
22
49
|
{{ record[column.name].label }}
|
|
23
50
|
</RouterLink>
|
|
24
51
|
<div v-else>
|
|
@@ -27,8 +54,8 @@
|
|
|
27
54
|
</span>
|
|
28
55
|
|
|
29
56
|
<span v-else-if="column.type === 'boolean'">
|
|
30
|
-
<span v-if="record[column.name] === true" class="bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">{{ $t('Yes') }}</span>
|
|
31
|
-
<span v-else-if="record[column.name] === false" class="bg-red-100 whitespace-nowrap text-red-
|
|
57
|
+
<span v-if="record[column.name] === true" class="af-true-value-icon bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">{{ $t('Yes') }}</span>
|
|
58
|
+
<span v-else-if="record[column.name] === false" class="af-false-value-icon bg-red-100 whitespace-nowrap text-red-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400">{{ $t('No') }}</span>
|
|
32
59
|
<span v-else class="bg-gray-100 whitespace-nowrap text-gray-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-gray-400 border border-gray-400">{{ $t('Unset') }}</span>
|
|
33
60
|
</span>
|
|
34
61
|
<span
|
|
@@ -38,14 +65,14 @@
|
|
|
38
65
|
<template v-for="(arrayItem, arrayItemIndex) in record[column.name]">
|
|
39
66
|
<span
|
|
40
67
|
v-if="column.isArray.itemType === 'boolean' && arrayItem"
|
|
41
|
-
:key="`${column.name}-${arrayItemIndex}`"
|
|
42
|
-
class="bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">
|
|
68
|
+
:key="`${column.name}-${arrayItemIndex}-true`"
|
|
69
|
+
class="af-true-value-icon bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">
|
|
43
70
|
{{ $t('Yes') }}
|
|
44
71
|
</span>
|
|
45
72
|
<span
|
|
46
73
|
v-else-if="column.isArray.itemType === 'boolean'"
|
|
47
|
-
:key="`${column.name}-${arrayItemIndex}`"
|
|
48
|
-
class="bg-red-100 whitespace-nowrap text-red-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400">
|
|
74
|
+
:key="`${column.name}-${arrayItemIndex}-false`"
|
|
75
|
+
class="af-false-value-icon bg-red-100 whitespace-nowrap text-red-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400">
|
|
49
76
|
{{ $t('No') }}
|
|
50
77
|
</span>
|
|
51
78
|
<span
|
|
@@ -53,30 +80,30 @@
|
|
|
53
80
|
:key="`${column.name}-${arrayItemIndex}`"
|
|
54
81
|
class="rounded-md m-0.5 bg-lightAnnouncementBG dark:bg-darkAnnouncementBG text-lightAnnouncementText dark:text-darkAnnouncementText py-0.5 px-2.5 text-sm"
|
|
55
82
|
>
|
|
56
|
-
{{ checkEmptyValues(getArrayItemDisplayValue(arrayItem, column), route.meta.type) }}
|
|
83
|
+
{{ checkEmptyValues(getArrayItemDisplayValue(arrayItem, column), route.meta.type as "show" | "list") }}
|
|
57
84
|
</span>
|
|
58
85
|
</template>
|
|
59
86
|
</span>
|
|
60
87
|
<span v-else-if="column.enum">
|
|
61
|
-
{{ checkEmptyValues(column.enum.find(e => e.value === record[column.name])?.label || record[column.name], route.meta.type) }}
|
|
88
|
+
{{ checkEmptyValues(column.enum.find(e => e.value === record[column.name])?.label || record[column.name], route.meta.type as "show" | "list") }}
|
|
62
89
|
</span>
|
|
63
90
|
<span v-else-if="column.type === 'datetime'" class="whitespace-nowrap">
|
|
64
|
-
{{ checkEmptyValues(formatDateTime(record[column.name]), route.meta.type) }}
|
|
91
|
+
{{ checkEmptyValues(formatDateTime(record[column.name]), route.meta.type as "show" | "list") }}
|
|
65
92
|
</span>
|
|
66
93
|
<span v-else-if="column.type === 'date'" class="whitespace-nowrap">
|
|
67
|
-
{{ checkEmptyValues(formatDate(record[column.name]), route.meta.type) }}
|
|
94
|
+
{{ checkEmptyValues(formatDate(record[column.name]), route.meta.type as "show" | "list") }}
|
|
68
95
|
</span>
|
|
69
96
|
<span v-else-if="column.type === 'time'" class="whitespace-nowrap">
|
|
70
|
-
{{ checkEmptyValues(formatTime(record[column.name]), route.meta.type) }}
|
|
97
|
+
{{ checkEmptyValues(formatTime(record[column.name]), route.meta.type as "show" | "list") }}
|
|
71
98
|
</span>
|
|
72
99
|
<span v-else-if="column.type === 'decimal'">
|
|
73
|
-
{{ checkEmptyValues(record[column.name] && parseFloat(record[column.name]), route.meta.type) }}
|
|
100
|
+
{{ checkEmptyValues(record[column.name] && parseFloat(record[column.name]), route.meta.type as "show" | "list") }}
|
|
74
101
|
</span>
|
|
75
102
|
<span v-else-if="column.type === 'json'">
|
|
76
103
|
<JsonViewer class="min-w-[6rem]" :value="record[column.name]" :expandDepth="column.extra?.jsonCollapsedLevel" copyable sort :theme="coreStore.theme"/>
|
|
77
104
|
</span>
|
|
78
105
|
<span v-else>
|
|
79
|
-
{{ checkEmptyValues(record[column.name],route.meta.type) }}
|
|
106
|
+
{{ checkEmptyValues(record[column.name], route.meta.type as "show" | "list") }}
|
|
80
107
|
</span>
|
|
81
108
|
</div>
|
|
82
109
|
</template>
|
|
@@ -122,7 +149,7 @@ function formatTime(time: string) {
|
|
|
122
149
|
return dayjs(`0000-00-00 ${time}`).format(coreStore.config?.timeFormat || 'HH:mm:ss');
|
|
123
150
|
}
|
|
124
151
|
|
|
125
|
-
function getArrayItemDisplayValue(value, column) {
|
|
152
|
+
function getArrayItemDisplayValue(value: any, column: AdminForthResourceColumnCommon) {
|
|
126
153
|
if (column.isArray?.itemType === 'datetime') {
|
|
127
154
|
return formatDateTime(value);
|
|
128
155
|
} else if (column.isArray?.itemType === 'date') {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Toggle
|
|
3
|
+
:disabled="readonly"
|
|
4
|
+
@update:modelValue="$emit('update:value', $event)"
|
|
5
|
+
:modelValue="valueFromRecord"
|
|
6
|
+
>
|
|
7
|
+
<p>{{text}}</p>
|
|
8
|
+
</Toggle>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import Toggle from '@/afcl/Toggle.vue';
|
|
13
|
+
import type {
|
|
14
|
+
AdminForthResourceColumnCommon,
|
|
15
|
+
AdminForthResourceCommon,
|
|
16
|
+
AdminUser,
|
|
17
|
+
} from "@/types/Common";
|
|
18
|
+
|
|
19
|
+
const props = defineProps<{
|
|
20
|
+
value: boolean,
|
|
21
|
+
text: string,
|
|
22
|
+
column: AdminForthResourceColumnCommon,
|
|
23
|
+
record: any,
|
|
24
|
+
meta: any,
|
|
25
|
+
resource: AdminForthResourceCommon,
|
|
26
|
+
adminUser: AdminUser,
|
|
27
|
+
readonly: boolean
|
|
28
|
+
}>();
|
|
29
|
+
console.log(JSON.stringify(props));
|
|
30
|
+
console.log("Current mode:", props.meta?.mode)
|
|
31
|
+
defineEmits(['update:value']);
|
|
32
|
+
const valueFromRecord = props.record[props.column.name]
|
|
33
|
+
const editReadOnly = props.column.editReadonly;
|
|
34
|
+
</script>
|
package/dist/spa/src/i18n.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createApp } from 'vue';
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
// taken from here https://vue-i18n.intlify.dev/guide/essentials/pluralization.html#custom-pluralization
|
|
6
|
-
function slavicPluralRule(choice, choicesLength, orgRule) {
|
|
6
|
+
function slavicPluralRule(choice: number, choicesLength: number, orgRule: any) {
|
|
7
7
|
if (choice === 0) {
|
|
8
8
|
return 0
|
|
9
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AdminForthResource, AdminForthResourceColumn } from '../types/
|
|
1
|
+
import type { AdminForthResource, AdminForthResourceColumn } from '../types/Back.js';
|
|
2
2
|
|
|
3
3
|
export type resourceById = {
|
|
4
4
|
[key: string]: AdminForthResource;
|
|
@@ -21,6 +21,7 @@ export type ResourceColumns = {
|
|
|
21
21
|
|
|
22
22
|
export type CoreConfig = {
|
|
23
23
|
brandName: string,
|
|
24
|
+
singleTheme?: 'light' | 'dark',
|
|
24
25
|
brandLogo: string,
|
|
25
26
|
title: string,
|
|
26
27
|
datesFormat: string,
|
|
@@ -33,12 +34,18 @@ export type CoreConfig = {
|
|
|
33
34
|
passwordHashField: string,
|
|
34
35
|
loginBackgroundImage: string,
|
|
35
36
|
loginBackgroundPosition: string,
|
|
37
|
+
removeBackgroundBlendMode: boolean,
|
|
36
38
|
userFullnameField: string,
|
|
37
39
|
},
|
|
38
40
|
emptyFieldPlaceholder?: {
|
|
39
41
|
show?: string,
|
|
40
42
|
list?: string,
|
|
41
43
|
} | string,
|
|
44
|
+
|
|
45
|
+
customHeadItems?: {
|
|
46
|
+
tagName: string;
|
|
47
|
+
attributes: { [key: string]: string | boolean };
|
|
48
|
+
}[],
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
|
|
@@ -29,7 +29,12 @@ export const useModalStore = defineStore('modal', () => {
|
|
|
29
29
|
onCancelFunction.value = func;
|
|
30
30
|
}
|
|
31
31
|
function setModalContent(content: ModalContentType) {
|
|
32
|
-
modalContent.value =
|
|
32
|
+
modalContent.value = {
|
|
33
|
+
title: content.title || 'title',
|
|
34
|
+
content: content.content || 'content',
|
|
35
|
+
acceptText: content.acceptText || 'acceptText',
|
|
36
|
+
cancelText: content.cancelText || 'cancelText',
|
|
37
|
+
};
|
|
33
38
|
}
|
|
34
39
|
function resetmodalState() {
|
|
35
40
|
isOpened.value = false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Express } from 'express';
|
|
1
|
+
import type { Express, Request } from 'express';
|
|
2
2
|
import type { Writable } from 'stream';
|
|
3
3
|
|
|
4
4
|
import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections, AllowedActionsEnum,
|
|
@@ -8,12 +8,12 @@ import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections,
|
|
|
8
8
|
type AdminForthBulkActionCommon,
|
|
9
9
|
type AdminForthForeignResourceCommon,
|
|
10
10
|
type AdminForthResourceColumnCommon,
|
|
11
|
-
AdminForthResourceInputCommon,
|
|
12
|
-
AdminForthComponentDeclarationFull,
|
|
13
|
-
AdminForthConfigMenuItem,
|
|
14
|
-
AnnouncementBadgeResponse,
|
|
11
|
+
type AdminForthResourceInputCommon,
|
|
12
|
+
type AdminForthComponentDeclarationFull,
|
|
13
|
+
type AdminForthConfigMenuItem,
|
|
14
|
+
type AnnouncementBadgeResponse,
|
|
15
15
|
AdminForthResourcePages,
|
|
16
|
-
AdminForthResourceColumnInputCommon,
|
|
16
|
+
type AdminForthResourceColumnInputCommon,
|
|
17
17
|
} from './Common.js';
|
|
18
18
|
|
|
19
19
|
export interface ICodeInjector {
|
|
@@ -92,19 +92,36 @@ export interface IExpressHttpServer extends IHttpServer {
|
|
|
92
92
|
* Adds adminUser to request object if user is authorized. Drops request with 401 status if user is not authorized.
|
|
93
93
|
* @param callable : Function which will be called if user is authorized.
|
|
94
94
|
*
|
|
95
|
-
* Example:
|
|
96
95
|
*
|
|
96
|
+
* @example
|
|
97
97
|
* ```ts
|
|
98
|
-
* expressApp.get('/myApi', authorize((req, res) =>
|
|
98
|
+
* expressApp.get('/myApi', authorize((req, res) => {
|
|
99
99
|
* console.log('User is authorized', req.adminUser);
|
|
100
|
-
* res.json(
|
|
101
|
-
*
|
|
102
|
-
*
|
|
100
|
+
* res.json({ message: 'Hello World' });
|
|
101
|
+
* }));
|
|
102
|
+
* ```
|
|
103
103
|
*
|
|
104
|
-
*/
|
|
104
|
+
*/
|
|
105
105
|
authorize(callable: Function): void;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
export interface ITranslateFunction {
|
|
109
|
+
(
|
|
110
|
+
msg: string,
|
|
111
|
+
category: string,
|
|
112
|
+
params: any,
|
|
113
|
+
pluralizationNumber?: number
|
|
114
|
+
): Promise<string>;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Omit <Request, 'param'> is used to remove 'param' method from Request type for correct docs generation
|
|
118
|
+
export interface IAdminUserExpressRequest extends Omit<Request, 'protocol' | 'param' | 'unshift'> {
|
|
119
|
+
adminUser: AdminUser;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface ITranslateExpressRequest extends Omit<Request, 'protocol' | 'param' | 'unshift'> {
|
|
123
|
+
tr: ITranslateFunction;
|
|
124
|
+
}
|
|
108
125
|
|
|
109
126
|
export interface IAdminForthSingleFilter {
|
|
110
127
|
field?: string;
|
|
@@ -113,7 +130,9 @@ export interface IAdminForthSingleFilter {
|
|
|
113
130
|
| AdminForthFilterOperators.LTE | AdminForthFilterOperators.LIKE | AdminForthFilterOperators.ILIKE
|
|
114
131
|
| AdminForthFilterOperators.IN | AdminForthFilterOperators.NIN;
|
|
115
132
|
value?: any;
|
|
133
|
+
rightField?: string;
|
|
116
134
|
insecureRawSQL?: string;
|
|
135
|
+
insecureRawNoSQL?: any;
|
|
117
136
|
}
|
|
118
137
|
export interface IAdminForthAndOrFilter {
|
|
119
138
|
operator: AdminForthFilterOperators.AND | AdminForthFilterOperators.OR;
|
|
@@ -336,7 +355,7 @@ export interface IAdminForth {
|
|
|
336
355
|
|
|
337
356
|
createResourceRecord(
|
|
338
357
|
params: { resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
|
|
339
|
-
): Promise<{ error?: string, createdRecord?: any }>;
|
|
358
|
+
): Promise<{ error?: string, createdRecord?: any, newRecordId?: any }>;
|
|
340
359
|
|
|
341
360
|
updateResourceRecord(
|
|
342
361
|
params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
|
|
@@ -474,7 +493,7 @@ export type BeforeDataSourceRequestFunction = (params: {
|
|
|
474
493
|
requestUrl: string,
|
|
475
494
|
},
|
|
476
495
|
adminforth: IAdminForth,
|
|
477
|
-
}) => Promise<{ok: boolean, error?: string}>;
|
|
496
|
+
}) => Promise<{ok: boolean, error?: string, newRecordId?: string}>;
|
|
478
497
|
|
|
479
498
|
/**
|
|
480
499
|
* Modify response to change how data is returned after fetching from database.
|
|
@@ -525,7 +544,7 @@ export type BeforeEditSaveFunction = (params: {
|
|
|
525
544
|
oldRecord: any,
|
|
526
545
|
adminforth: IAdminForth,
|
|
527
546
|
extra?: HttpExtra,
|
|
528
|
-
}) => Promise<{ok: boolean, error?: string}>;
|
|
547
|
+
}) => Promise<{ok: boolean, error?: string | null}>;
|
|
529
548
|
|
|
530
549
|
|
|
531
550
|
|
|
@@ -535,7 +554,7 @@ export type BeforeCreateSaveFunction = (params: {
|
|
|
535
554
|
record: any,
|
|
536
555
|
adminforth: IAdminForth,
|
|
537
556
|
extra?: HttpExtra,
|
|
538
|
-
}) => Promise<{ok: boolean, error?: string}>;
|
|
557
|
+
}) => Promise<{ok: boolean, error?: string | null, newRecordId?: string}>;
|
|
539
558
|
|
|
540
559
|
export type AfterCreateSaveFunction = (params: {
|
|
541
560
|
resource: AdminForthResource,
|
|
@@ -619,12 +638,23 @@ interface AdminForthInputConfigCustomization {
|
|
|
619
638
|
*/
|
|
620
639
|
brandName?: string,
|
|
621
640
|
|
|
641
|
+
/**
|
|
642
|
+
* Whether to use single theme for the app
|
|
643
|
+
*/
|
|
644
|
+
singleTheme?: 'light' | 'dark',
|
|
645
|
+
|
|
622
646
|
/**
|
|
623
647
|
* Whether to show brand name in sidebar
|
|
624
648
|
* default is true
|
|
625
649
|
*/
|
|
626
650
|
showBrandNameInSidebar?: boolean,
|
|
627
651
|
|
|
652
|
+
/**
|
|
653
|
+
* Whether to show brand logo in sidebar
|
|
654
|
+
* default is true
|
|
655
|
+
*/
|
|
656
|
+
showBrandLogoInSidebar?: boolean,
|
|
657
|
+
|
|
628
658
|
/**
|
|
629
659
|
* Path to your app logo
|
|
630
660
|
*
|
|
@@ -757,8 +787,19 @@ interface AdminForthInputConfigCustomization {
|
|
|
757
787
|
userMenu?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
758
788
|
header?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
759
789
|
sidebar?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
790
|
+
sidebarTop?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
760
791
|
everyPageBottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
761
792
|
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Allows adding custom elements (e.g., <link>, <script>, <meta>) to the <head> of the HTML document.
|
|
796
|
+
* Each item must include a tag name and a set of attributes.
|
|
797
|
+
*/
|
|
798
|
+
customHeadItems?: {
|
|
799
|
+
tagName: string;
|
|
800
|
+
attributes: Record<string, string | boolean>;
|
|
801
|
+
}[];
|
|
802
|
+
|
|
762
803
|
}
|
|
763
804
|
|
|
764
805
|
export interface AdminForthActionInput {
|
|
@@ -935,6 +976,13 @@ export interface AdminForthInputConfig {
|
|
|
935
976
|
*/
|
|
936
977
|
loginBackgroundPosition?: 'over' | '1/2' | '1/3' | '2/3' | '3/4' | '2/5' | '3/5',
|
|
937
978
|
|
|
979
|
+
/**
|
|
980
|
+
* If true, background blend mode will be removed from login background image when position is 'over'
|
|
981
|
+
*
|
|
982
|
+
* Default: false
|
|
983
|
+
*/
|
|
984
|
+
removeBackgroundBlendMode?: boolean,
|
|
985
|
+
|
|
938
986
|
/**
|
|
939
987
|
* Function or functions which will be called before user try to login.
|
|
940
988
|
* Each function will resive User object as an argument
|
|
@@ -956,7 +1004,7 @@ export interface AdminForthInputConfig {
|
|
|
956
1004
|
/**
|
|
957
1005
|
* Any prompt to show users on login. Supports HTML.
|
|
958
1006
|
*/
|
|
959
|
-
loginPromptHTML?: string
|
|
1007
|
+
loginPromptHTML?: string | (() => string | void | undefined | Promise<string | void | undefined>) | undefined
|
|
960
1008
|
|
|
961
1009
|
/**
|
|
962
1010
|
* Remember me days for "Remember Me" checkbox on login page.
|
|
@@ -1062,8 +1110,15 @@ export interface AdminForthConfigCustomization extends Omit<AdminForthInputConfi
|
|
|
1062
1110
|
userMenu: Array<AdminForthComponentDeclarationFull>,
|
|
1063
1111
|
header: Array<AdminForthComponentDeclarationFull>,
|
|
1064
1112
|
sidebar: Array<AdminForthComponentDeclarationFull>,
|
|
1113
|
+
sidebarTop: Array<AdminForthComponentDeclarationFull>,
|
|
1065
1114
|
everyPageBottom: Array<AdminForthComponentDeclarationFull>,
|
|
1066
1115
|
},
|
|
1116
|
+
|
|
1117
|
+
customHeadItems?: {
|
|
1118
|
+
tagName: string;
|
|
1119
|
+
attributes: Record<string, string | boolean>;
|
|
1120
|
+
}[];
|
|
1121
|
+
|
|
1067
1122
|
}
|
|
1068
1123
|
|
|
1069
1124
|
export interface AdminForthConfig extends Omit<AdminForthInputConfig, 'customization' | 'resources'> {
|
|
@@ -1111,6 +1166,21 @@ export class Filters {
|
|
|
1111
1166
|
static LIKE(field: string, value: any): IAdminForthSingleFilter {
|
|
1112
1167
|
return { field, operator: AdminForthFilterOperators.LIKE, value };
|
|
1113
1168
|
}
|
|
1169
|
+
static ILIKE(field: string, value: any): IAdminForthSingleFilter {
|
|
1170
|
+
return { field, operator: AdminForthFilterOperators.ILIKE, value };
|
|
1171
|
+
}
|
|
1172
|
+
static GT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
|
|
1173
|
+
return { field: leftField, operator: AdminForthFilterOperators.GT, rightField };
|
|
1174
|
+
}
|
|
1175
|
+
static GTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
|
|
1176
|
+
return { field: leftField, operator: AdminForthFilterOperators.GTE, rightField };
|
|
1177
|
+
}
|
|
1178
|
+
static LT_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
|
|
1179
|
+
return { field: leftField, operator: AdminForthFilterOperators.LT, rightField };
|
|
1180
|
+
}
|
|
1181
|
+
static LTE_FIELD(leftField: string, rightField: string): IAdminForthSingleFilter {
|
|
1182
|
+
return { field: leftField, operator: AdminForthFilterOperators.LTE, rightField };
|
|
1183
|
+
}
|
|
1114
1184
|
static AND(
|
|
1115
1185
|
...args: (IAdminForthSingleFilter | IAdminForthAndOrFilter | Array<IAdminForthSingleFilter | IAdminForthAndOrFilter>)[]
|
|
1116
1186
|
): IAdminForthAndOrFilter {
|
|
@@ -1318,9 +1388,13 @@ export interface AdminForthResource extends Omit<AdminForthResourceInput, 'optio
|
|
|
1318
1388
|
},
|
|
1319
1389
|
create?: {
|
|
1320
1390
|
/**
|
|
1391
|
+
* Should return `ok: true` to continue saving pipeline and allow creating record in database, and `ok: false` to interrupt pipeline and prevent record creation.
|
|
1392
|
+
* If you need to show error on UI, set `error: \<error message\>` in response.
|
|
1393
|
+
*
|
|
1321
1394
|
* Typical use-cases:
|
|
1322
|
-
* -
|
|
1323
|
-
* -
|
|
1395
|
+
* - Create record by custom code (return `{ ok: false, newRecordId: <id of created record from custom code> }`)
|
|
1396
|
+
* - Validate record before saving to database and interrupt execution if validation failed (return `{ ok: false, error: <validation error> }`), though `allowedActions.create` should be preferred in most cases
|
|
1397
|
+
* - fill-in adminUser as creator of record (set `record.<some field> = x; return \{ ok: true \}`)
|
|
1324
1398
|
* - Attach additional data to record before saving to database (mostly fillOnCreate should be used instead)
|
|
1325
1399
|
*/
|
|
1326
1400
|
beforeSave?: Array<BeforeCreateSaveFunction>,
|
|
@@ -1471,15 +1545,27 @@ export type ShowInInput = ShowInModernInput | ShowInLegacyInput;
|
|
|
1471
1545
|
export type ShowIn = {
|
|
1472
1546
|
[key in AdminForthResourcePages]: AllowedActionValue
|
|
1473
1547
|
}
|
|
1548
|
+
export type BackendOnlyInput =
|
|
1549
|
+
| boolean
|
|
1550
|
+
| ((p: {
|
|
1551
|
+
adminUser: AdminUser;
|
|
1552
|
+
resource: AdminForthResource;
|
|
1553
|
+
meta: any;
|
|
1554
|
+
source: ActionCheckSource;
|
|
1555
|
+
adminforth: IAdminForth;
|
|
1556
|
+
}) => boolean | Promise<boolean>);
|
|
1557
|
+
|
|
1474
1558
|
|
|
1475
|
-
export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn'> {
|
|
1559
|
+
export interface AdminForthResourceColumnInput extends Omit<AdminForthResourceColumnInputCommon, 'showIn' | 'backendOnly'> {
|
|
1476
1560
|
showIn?: ShowInInput,
|
|
1477
1561
|
foreignResource?: AdminForthForeignResource,
|
|
1562
|
+
backendOnly?: BackendOnlyInput;
|
|
1478
1563
|
}
|
|
1479
1564
|
|
|
1480
|
-
export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn'> {
|
|
1565
|
+
export interface AdminForthResourceColumn extends Omit<AdminForthResourceColumnCommon, 'showIn' | 'backendOnly'> {
|
|
1481
1566
|
showIn?: ShowIn,
|
|
1482
1567
|
foreignResource?: AdminForthForeignResource,
|
|
1568
|
+
backendOnly?: BackendOnlyInput;
|
|
1483
1569
|
}
|
|
1484
1570
|
|
|
1485
1571
|
export interface IWebSocketClient {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
/**
|
|
3
2
|
* Types that are common for both frontend side (SPA) and backend side (server).
|
|
4
3
|
*/
|
|
@@ -95,12 +94,9 @@ export interface AdminForthBulkActionCommon {
|
|
|
95
94
|
label: string,
|
|
96
95
|
|
|
97
96
|
/**
|
|
98
|
-
*
|
|
99
|
-
* * 'danger' - red button
|
|
100
|
-
* * 'success' - green button
|
|
101
|
-
* * 'active' - blue button
|
|
97
|
+
* Add custom class
|
|
102
98
|
**/
|
|
103
|
-
|
|
99
|
+
buttonCustomCssClass?: string;
|
|
104
100
|
|
|
105
101
|
/**
|
|
106
102
|
* Optional small badge for button which will be displayed in the list view
|
|
@@ -122,6 +118,10 @@ export interface AdminForthBulkActionCommon {
|
|
|
122
118
|
*/
|
|
123
119
|
successMessage?: string,
|
|
124
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Show in three dots dropdown menu in list view.
|
|
123
|
+
*/
|
|
124
|
+
showInThreeDotsDropdown?: boolean,
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
export interface AdminForthFieldComponents {
|
|
@@ -263,9 +263,17 @@ export interface AdminForthComponentDeclarationFull {
|
|
|
263
263
|
*/
|
|
264
264
|
meta?: any,
|
|
265
265
|
}
|
|
266
|
+
import { type AdminForthActionInput } from './Back.js'
|
|
267
|
+
export { type AdminForthActionInput } from './Back.js'
|
|
266
268
|
|
|
267
269
|
export type AdminForthComponentDeclaration = AdminForthComponentDeclarationFull | string;
|
|
268
270
|
|
|
271
|
+
export type FieldGroup = {
|
|
272
|
+
groupName: string;
|
|
273
|
+
columns: string[];
|
|
274
|
+
noTitle?: boolean;
|
|
275
|
+
};
|
|
276
|
+
|
|
269
277
|
/**
|
|
270
278
|
* Resource describes one table or collection in database.
|
|
271
279
|
* AdminForth generates set of pages for 'list', 'show', 'edit', 'create', 'filter' operations for each resource.
|
|
@@ -347,6 +355,11 @@ export interface AdminForthResourceInputCommon {
|
|
|
347
355
|
direction: AdminForthSortDirections | string,
|
|
348
356
|
}
|
|
349
357
|
|
|
358
|
+
/*
|
|
359
|
+
* Custom actions list. Actions available in show, edit and create views.
|
|
360
|
+
*/
|
|
361
|
+
actions?: AdminForthActionInput[],
|
|
362
|
+
|
|
350
363
|
/**
|
|
351
364
|
* Custom bulk actions list. Bulk actions available in list view when user selects multiple records by
|
|
352
365
|
* using checkboxes.
|
|
@@ -374,26 +387,10 @@ export interface AdminForthResourceInputCommon {
|
|
|
374
387
|
/**
|
|
375
388
|
* Allows to make groups of columns in show, create and edit resource pages.
|
|
376
389
|
*/
|
|
377
|
-
fieldGroups?:
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}[];
|
|
382
|
-
createFieldGroups?: {
|
|
383
|
-
groupName: string;
|
|
384
|
-
columns: string[];
|
|
385
|
-
noTitle?: boolean;
|
|
386
|
-
}[];
|
|
387
|
-
editFieldGroups?: {
|
|
388
|
-
groupName: string;
|
|
389
|
-
columns: string[];
|
|
390
|
-
noTitle?: boolean;
|
|
391
|
-
}[];
|
|
392
|
-
showFieldGroups?: {
|
|
393
|
-
groupName: string;
|
|
394
|
-
columns: string[];
|
|
395
|
-
noTitle?: boolean;
|
|
396
|
-
}[];
|
|
390
|
+
fieldGroups?: FieldGroup[];
|
|
391
|
+
createFieldGroups?: FieldGroup[];
|
|
392
|
+
editFieldGroups?: FieldGroup[];
|
|
393
|
+
showFieldGroups?: FieldGroup[];
|
|
397
394
|
|
|
398
395
|
/**
|
|
399
396
|
* Page size for list view
|
|
@@ -584,6 +581,8 @@ export interface AdminForthForeignResourceCommon {
|
|
|
584
581
|
polymorphicResources?: Array<AdminForthPolymorphicForeignResource>,
|
|
585
582
|
polymorphicOn?: string,
|
|
586
583
|
unsetLabel?: string,
|
|
584
|
+
searchableFields?: string | string[],
|
|
585
|
+
searchIsCaseSensitive?: boolean,
|
|
587
586
|
}
|
|
588
587
|
|
|
589
588
|
export type FillOnCreateFunction = (params: {
|
|
@@ -810,9 +809,6 @@ export interface AdminForthResourceColumnInputCommon {
|
|
|
810
809
|
*/
|
|
811
810
|
minLength?: number,
|
|
812
811
|
|
|
813
|
-
min?: number,
|
|
814
|
-
max?: number,
|
|
815
|
-
|
|
816
812
|
/**
|
|
817
813
|
* Minimum value that can be entered in this field.
|
|
818
814
|
*/
|
|
@@ -878,6 +874,15 @@ export interface AdminForthResourceColumnCommon extends AdminForthResourceColumn
|
|
|
878
874
|
|
|
879
875
|
editingNote?: { create?: string, edit?: string },
|
|
880
876
|
|
|
877
|
+
/**
|
|
878
|
+
* Minimal value stored in this field.
|
|
879
|
+
*/
|
|
880
|
+
min?: number,
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Maximum value stored in this field.
|
|
884
|
+
*/
|
|
885
|
+
max?: number,
|
|
881
886
|
}
|
|
882
887
|
|
|
883
888
|
export enum AdminForthMenuTypes {
|
|
@@ -1055,16 +1060,19 @@ export interface AdminForthConfigForFrontend {
|
|
|
1055
1060
|
usernameFieldName: string,
|
|
1056
1061
|
loginBackgroundImage: string,
|
|
1057
1062
|
loginBackgroundPosition: string,
|
|
1063
|
+
removeBackgroundBlendMode: boolean,
|
|
1058
1064
|
title?: string,
|
|
1059
1065
|
demoCredentials?: string,
|
|
1060
|
-
loginPromptHTML?: string
|
|
1066
|
+
loginPromptHTML?: string | (() => string | Promise<string> | void | Promise<void> | Promise<undefined>) | undefined
|
|
1061
1067
|
loginPageInjections: {
|
|
1062
1068
|
underInputs: Array<AdminForthComponentDeclaration>,
|
|
1063
1069
|
panelHeader: Array<AdminForthComponentDeclaration>,
|
|
1064
1070
|
},
|
|
1065
1071
|
rememberMeDays: number,
|
|
1066
1072
|
showBrandNameInSidebar: boolean,
|
|
1073
|
+
showBrandLogoInSidebar: boolean,
|
|
1067
1074
|
brandLogo?: string,
|
|
1075
|
+
singleTheme?: 'light' | 'dark',
|
|
1068
1076
|
datesFormat: string,
|
|
1069
1077
|
timeFormat: string,
|
|
1070
1078
|
auth: any,
|
|
@@ -1079,8 +1087,13 @@ export interface AdminForthConfigForFrontend {
|
|
|
1079
1087
|
userMenu: Array<AdminForthComponentDeclarationFull>,
|
|
1080
1088
|
header: Array<AdminForthComponentDeclarationFull>,
|
|
1081
1089
|
sidebar: Array<AdminForthComponentDeclarationFull>,
|
|
1090
|
+
sidebarTop: Array<AdminForthComponentDeclarationFull>,
|
|
1082
1091
|
everyPageBottom: Array<AdminForthComponentDeclarationFull>,
|
|
1083
|
-
}
|
|
1092
|
+
},
|
|
1093
|
+
customHeadItems?: {
|
|
1094
|
+
tagName: string;
|
|
1095
|
+
attributes: Record<string, string | boolean>;
|
|
1096
|
+
}[],
|
|
1084
1097
|
}
|
|
1085
1098
|
|
|
1086
1099
|
export interface GetBaseConfigResponse {
|