adminforth 1.0.81 → 1.0.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +6 -0
- package/dist/modules/codeInjector.js +7 -0
- package/dist/spa/spa/src/App.vue +1 -1
- package/dist/spa/spa/src/components/ResourceForm.vue +5 -4
- package/dist/spa/spa/src/stores/core.ts +1 -0
- package/dist/spa/spa/src/utils.ts +12 -0
- package/dist/spa/spa/src/views/CreateView.vue +5 -1
- package/dist/spa/spa/src/views/EditView.vue +3 -1
- package/dist/spa/spa/src/views/ListView.vue +2 -1
- package/dist/spa/spa/src/views/ShowView.vue +47 -3
- package/documentation/docusaurus.config.ts +34 -26
- package/documentation/package.json +1 -1
- package/documentation/src/components/HomepageFeatures/index.tsx +13 -15
- package/documentation/src/pages/index.module.css +1 -0
- package/documentation/src/pages/index.tsx +2 -2
- package/documentation/static/img/css.png +0 -0
- package/documentation/static/img/db.png +0 -0
- package/documentation/static/img/db2.png +0 -0
- package/documentation/static/img/gen.sh +24 -0
- package/documentation/static/img/tail.png +0 -0
- package/documentation/static/img/tail.png:Zone.Identifier +0 -0
- package/documentation/static/img/vue.png +0 -0
- package/index.ts +6 -0
- package/modules/codeInjector.ts +7 -0
- package/package.json +2 -2
- package/spa/src/App.vue +1 -1
- package/spa/src/components/ResourceForm.vue +5 -4
- package/spa/src/stores/core.ts +1 -0
- package/spa/src/utils.ts +12 -0
- package/spa/src/views/CreateView.vue +5 -1
- package/spa/src/views/EditView.vue +3 -1
- package/spa/src/views/ListView.vue +2 -1
- package/spa/src/views/ShowView.vue +47 -3
- package/styles.js +52 -0
- package/types/AdminForthConfig.ts +240 -9
- package/documentation/static/img/undraw_docusaurus_mountain.svg +0 -171
- package/documentation/static/img/undraw_docusaurus_react.svg +0 -170
- package/documentation/static/img/undraw_docusaurus_tree.svg +0 -40
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
</BreadcrumbsWithButtons>
|
|
24
24
|
|
|
25
25
|
<SingleSkeletLoader v-if="loading"></SingleSkeletLoader>
|
|
26
|
+
|
|
26
27
|
|
|
27
28
|
<ResourceForm
|
|
28
29
|
v-else
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
>
|
|
36
37
|
</ResourceForm>
|
|
37
38
|
|
|
39
|
+
|
|
38
40
|
</div>
|
|
39
41
|
</template>
|
|
40
42
|
|
|
@@ -45,11 +47,12 @@ import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
|
45
47
|
import ResourceForm from '@/components/ResourceForm.vue';
|
|
46
48
|
import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
47
49
|
import { useCoreStore } from '@/stores/core';
|
|
48
|
-
import { callAdminForthApi, getCustomComponent } from '@/utils';
|
|
50
|
+
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions } from '@/utils';
|
|
49
51
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
50
52
|
import { onMounted, ref } from 'vue';
|
|
51
53
|
import { useRoute, useRouter } from 'vue-router';
|
|
52
54
|
|
|
55
|
+
|
|
53
56
|
const isValid = ref(false);
|
|
54
57
|
const validating = ref(false);
|
|
55
58
|
|
|
@@ -81,6 +84,7 @@ onMounted(async () => {
|
|
|
81
84
|
return acc;
|
|
82
85
|
}, {});
|
|
83
86
|
loading.value = false;
|
|
87
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'create');
|
|
84
88
|
});
|
|
85
89
|
|
|
86
90
|
async function saveRecord() {
|
|
@@ -41,7 +41,7 @@ import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
|
41
41
|
import ResourceForm from '@/components/ResourceForm.vue';
|
|
42
42
|
import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
43
43
|
import { useCoreStore } from '@/stores/core';
|
|
44
|
-
import { callAdminForthApi, getCustomComponent } from '@/utils';
|
|
44
|
+
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions } from '@/utils';
|
|
45
45
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
46
46
|
import { computed, onMounted, ref } from 'vue';
|
|
47
47
|
import { useRoute, useRouter } from 'vue-router';
|
|
@@ -79,6 +79,7 @@ const editableRecord = computed(() => {
|
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
onMounted(async () => {
|
|
82
|
+
|
|
82
83
|
loading.value = true;
|
|
83
84
|
|
|
84
85
|
await coreStore.fetchResourceFull({
|
|
@@ -88,6 +89,7 @@ onMounted(async () => {
|
|
|
88
89
|
resourceId: route.params.resourceId,
|
|
89
90
|
primaryKey: route.params.primaryKey,
|
|
90
91
|
});
|
|
92
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'edit');
|
|
91
93
|
|
|
92
94
|
editComponentsPerColumn = coreStore.resourceColumns.reduce((acc, column) => {
|
|
93
95
|
if (column.component?.edit) {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
</BreadcrumbsWithButtons>
|
|
66
66
|
|
|
67
67
|
<!-- table -->
|
|
68
|
-
<div class="relative overflow-x-auto shadow-list-table-shadow dark:shadow-black
|
|
68
|
+
<div class="relative overflow-x-auto shadow-list-table-shadow dark:shadow-black overflow-y-hidden rounded-default">
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
<!-- skelet loader -->
|
|
@@ -208,6 +208,7 @@
|
|
|
208
208
|
<td class=" items-center px-6 py-4">
|
|
209
209
|
<div class="flex">
|
|
210
210
|
<RouterLink
|
|
211
|
+
v-if="allowedActions.show"
|
|
211
212
|
:to="{ name: 'resource-show', params: { resourceId: $route.params.resourceId, primaryKey: row._primaryKeyValue } }"
|
|
212
213
|
class="font-medium text-blue-600 dark:text-blue-500 hover:underline"
|
|
213
214
|
:data-tooltip-target="`tooltip-show-${rowI}`"
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Edit
|
|
9
9
|
</RouterLink>
|
|
10
10
|
|
|
11
|
-
<button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="
|
|
11
|
+
<button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="showDeleteModal"
|
|
12
12
|
class="flex items-center py-1 px-3 mb-2 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"
|
|
13
13
|
>
|
|
14
14
|
<IconTrashBinSolid class="w-4 h-4" />
|
|
@@ -83,20 +83,26 @@ import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
|
83
83
|
|
|
84
84
|
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
85
85
|
import { useCoreStore } from '@/stores/core';
|
|
86
|
-
import {
|
|
86
|
+
import { useModalStore } from '@/stores/modal';
|
|
87
|
+
import { getCustomComponent,checkAcessByAllowedActions } from '@/utils';
|
|
87
88
|
import { IconPenSolid, IconTrashBinSolid } from '@iconify-prerendered/vue-flowbite';
|
|
88
89
|
import { onMounted, ref } from 'vue';
|
|
89
|
-
import { useRoute } from 'vue-router';
|
|
90
|
+
import { useRoute,useRouter } from 'vue-router';
|
|
91
|
+
import {callAdminForthApi} from '@/utils';
|
|
90
92
|
|
|
91
93
|
|
|
92
94
|
const item = ref(null);
|
|
93
95
|
const route = useRoute();
|
|
96
|
+
const router = useRouter();
|
|
94
97
|
const loading = ref(false);
|
|
95
98
|
let showComponentsPerColumn = {};
|
|
96
99
|
let showRowComponentsPerColumn = {};
|
|
97
100
|
|
|
101
|
+
console.log(route.params,'showWiev');
|
|
102
|
+
|
|
98
103
|
|
|
99
104
|
const coreStore = useCoreStore();
|
|
105
|
+
const modalStore = useModalStore();
|
|
100
106
|
|
|
101
107
|
onMounted(async () => {
|
|
102
108
|
loading.value = true;
|
|
@@ -107,6 +113,8 @@ onMounted(async () => {
|
|
|
107
113
|
resourceId: route.params.resourceId,
|
|
108
114
|
primaryKey: route.params.primaryKey,
|
|
109
115
|
});
|
|
116
|
+
checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'show');
|
|
117
|
+
|
|
110
118
|
showComponentsPerColumn = coreStore.resourceColumns.reduce((acc, column) => {
|
|
111
119
|
if (column.component?.show) {
|
|
112
120
|
acc[column.name] = getCustomComponent(column.component.show);
|
|
@@ -123,4 +131,40 @@ onMounted(async () => {
|
|
|
123
131
|
loading.value = false;
|
|
124
132
|
});
|
|
125
133
|
|
|
134
|
+
function showDeleteModal(row) {
|
|
135
|
+
if (!coreStore.config?.deleteConfirmation) {
|
|
136
|
+
return deleteRecord(row);
|
|
137
|
+
}
|
|
138
|
+
modalStore.setModalContent({
|
|
139
|
+
content: 'Are you sure you want to delete this item?',
|
|
140
|
+
acceptText: 'Delete',
|
|
141
|
+
cancelText: 'Cancel',
|
|
142
|
+
});
|
|
143
|
+
modalStore.setOnAcceptFunction(() => {
|
|
144
|
+
return deleteRecord(row)
|
|
145
|
+
})
|
|
146
|
+
modalStore.togleModal();
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function deleteRecord(row) {
|
|
152
|
+
try{
|
|
153
|
+
await callAdminForthApi({
|
|
154
|
+
path: '/delete_record',
|
|
155
|
+
method: 'POST',
|
|
156
|
+
body: {
|
|
157
|
+
resourceId: route.params.resourceId,
|
|
158
|
+
primaryKey: route.params.primaryKey,
|
|
159
|
+
recordId: route.params.primaryKey
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
router.push({ name: 'resource-list', params: { resourceId: route.params.resourceId } });
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.log(error);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
modalStore.resetmodalState()
|
|
168
|
+
}
|
|
169
|
+
|
|
126
170
|
</script>
|
package/styles.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const styles = () => `
|
|
2
|
+
|
|
3
|
+
"colors": {
|
|
4
|
+
"html-bg": "#FFFFFF", // Changed to white
|
|
5
|
+
"header-bg": "#EDEDED", // Light grey
|
|
6
|
+
"header-bg-hover": "#D3D3D3", // Light grey hover
|
|
7
|
+
"header-text": "#333333", // Dark grey text
|
|
8
|
+
"header-text-hover": "#333333", // Dark grey text hover
|
|
9
|
+
"header-icons": "#333333", // Dark grey icons
|
|
10
|
+
"header-icons-hover": "#333333", // Dark grey icons hover
|
|
11
|
+
"header-logo-color": "#333333", // Dark grey logo
|
|
12
|
+
"header-border-color": "#CCCCCC", // Light grey border
|
|
13
|
+
|
|
14
|
+
"nav-menu-bg": "#F5F5F5", // Very light grey
|
|
15
|
+
"nav-menu-bg-hover": "#E0E0E0", // Light grey hover
|
|
16
|
+
"nav-menu-bg-active": "#CCCCCC", // Light grey active
|
|
17
|
+
"nav-menu-hover": "#E0E0E0", // Light grey hover
|
|
18
|
+
"nav-menu-active": "#CCCCCC", // Light grey active
|
|
19
|
+
"nav-menu-active-text": "#333333", // Dark grey active text
|
|
20
|
+
"nav-menu-text": "#333333", // Dark grey text
|
|
21
|
+
"nav-menu-text-hover": "#333333", // Dark grey text hover
|
|
22
|
+
"nav-menu-text-active": "#333333", // Dark grey text active
|
|
23
|
+
"nav-menu-devider": "#E0E0E0", // Light grey divider
|
|
24
|
+
"nav-menu-icons": "#333333", // Dark grey icons
|
|
25
|
+
"nav-menu-heading": "#333333", // Dark grey heading
|
|
26
|
+
|
|
27
|
+
"list-view-bg": "#FFFFFF", // White background
|
|
28
|
+
"list-view-table-bg": "#FFFFFF", // White table background
|
|
29
|
+
"list-view-table-heading": "#F5F5F5", // Very light grey heading
|
|
30
|
+
"list-view-table-heading-text": "#333333", // Dark grey heading text
|
|
31
|
+
"list-view-table-text": "#333333", // Dark grey text
|
|
32
|
+
"list-view-table-row-hover": "#F0F0F0", // Very light grey row hover
|
|
33
|
+
"list-view-bread-crumbs-text": "#666666", // Medium grey bread crumbs
|
|
34
|
+
"list-view-border-color": "#DDDDDD", // Light grey border
|
|
35
|
+
|
|
36
|
+
"form-view-bg": "#FFFFFF", // White form background
|
|
37
|
+
"form-view-border-color": "#F5F5F5", // Very light grey border
|
|
38
|
+
"form-view-heading": "#EDEDED" // Dark grey heading
|
|
39
|
+
},
|
|
40
|
+
"boxShadow": {
|
|
41
|
+
"custom-light": "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow
|
|
42
|
+
"header-shadow": "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow
|
|
43
|
+
"list-table-shadow": "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow
|
|
44
|
+
"resourse-form-shadow": "0 4px 8px rgba(0, 0, 0, 0.1)" // Lighter shadow
|
|
45
|
+
},
|
|
46
|
+
"fontSize": {
|
|
47
|
+
"header-text-size": "1rem"
|
|
48
|
+
},
|
|
49
|
+
"borderRadius": {
|
|
50
|
+
"default": "2px"
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
@@ -46,6 +46,7 @@ export type AdminForthResourceColumn = {
|
|
|
46
46
|
showIn?: Array<string>,
|
|
47
47
|
fillOnCreate?: Function,
|
|
48
48
|
isUnique?: boolean,
|
|
49
|
+
validation?: Array<ValidationObject>,
|
|
49
50
|
virtual?: boolean,
|
|
50
51
|
allowMinMaxQuery?: boolean,
|
|
51
52
|
component?: AdminForthResourceColumnComponent
|
|
@@ -62,13 +63,59 @@ export type AdminForthResourceColumn = {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
export type AdminForthResource = {
|
|
66
|
+
/**
|
|
67
|
+
* Unique identifier of resource. By default it equals to table name in database.
|
|
68
|
+
* If you wish you can explicitly set it to any string.
|
|
69
|
+
* We added to support cases when 2 datasources have tables with the same name.
|
|
70
|
+
*/
|
|
65
71
|
resourceId: string,
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Label for resource which will be displayed in the admin panel.
|
|
75
|
+
* By default it equals to table name in database.
|
|
76
|
+
*/
|
|
66
77
|
label?: string,
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Table name in database which will be used to fetch data from. Might be case sensitive.
|
|
81
|
+
*/
|
|
67
82
|
table: string,
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* ID of datasource which will be used to fetch data from.
|
|
86
|
+
*/
|
|
68
87
|
dataSource: string,
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Array of columns which will be displayed in the admin panel.
|
|
91
|
+
* Each column has its own configuration.
|
|
92
|
+
*/
|
|
69
93
|
columns: Array<AdminForthResourceColumn>,
|
|
70
|
-
|
|
94
|
+
|
|
95
|
+
dataSourceColumns?: Array<AdminForthResourceColumn>, // TODO, mark as private
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Hook which allow you to modify item label
|
|
99
|
+
*
|
|
100
|
+
* Example:
|
|
101
|
+
*
|
|
102
|
+
* ```ts
|
|
103
|
+
* itemLabel: (item) => `${item.name} - ${item.id}`,
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
*/
|
|
71
107
|
itemLabel?: Function,
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Hook which allow you to modify item title
|
|
111
|
+
*
|
|
112
|
+
* Example:
|
|
113
|
+
*
|
|
114
|
+
* ```ts
|
|
115
|
+
* itemTitle: (item) => `${item.name} - ${item.id}`,
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
*/
|
|
72
119
|
plugins?: Array<AdminForthPluginType>,
|
|
73
120
|
hooks?: {
|
|
74
121
|
show?: {
|
|
@@ -109,37 +156,193 @@ export type AdminForthDataSource = {
|
|
|
109
156
|
id: string,
|
|
110
157
|
url: string,
|
|
111
158
|
}
|
|
112
|
-
|
|
113
|
-
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Main configuration object for AdminForth
|
|
162
|
+
*/
|
|
163
|
+
export type AdminForthConfig = {
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Root user should be used to login to the admin panel first time.
|
|
167
|
+
* Then you should create User for yourself using AdminForth (so it will be persisted in DB),
|
|
168
|
+
* and then disable this option as it is less secure
|
|
169
|
+
*/
|
|
114
170
|
rootUser?: {
|
|
171
|
+
/**
|
|
172
|
+
* Username for root user
|
|
173
|
+
*/
|
|
115
174
|
username: string,
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Password for root user
|
|
178
|
+
*/
|
|
116
179
|
password: string,
|
|
117
180
|
},
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Authorization module configuration
|
|
184
|
+
*/
|
|
118
185
|
auth?: {
|
|
186
|
+
/**
|
|
187
|
+
* Resource ID for user resource.
|
|
188
|
+
* Resource is a table in database where users will be stored and fetched from. Resources and their ids are defined in resources section of the config.
|
|
189
|
+
* In other words this setting is a reference to a table in database where users will be fetched from on login.
|
|
190
|
+
*/
|
|
119
191
|
resourceId: string,
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Field name (column name) in user resource which will be used as username for searching user in database during login.
|
|
195
|
+
* Can be e.g. 'email' or 'username'
|
|
196
|
+
*/
|
|
120
197
|
usernameField: string,
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Field name (column name) in user resource which will be used to get hash of password.
|
|
201
|
+
* Can be e.g. 'passwordHash'
|
|
202
|
+
*/
|
|
121
203
|
passwordHashField: string,
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* File path to custom background image for login page
|
|
207
|
+
* Example:
|
|
208
|
+
* Place file `login-background.jpg` to `./custom` folder and set this option:
|
|
209
|
+
*
|
|
210
|
+
* ```ts
|
|
211
|
+
* loginBackgroundImage: '@@/login-background.jpg',
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
122
214
|
loginBackgroundImage?: string,
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Optionally if your users table has a field(column) with full name, you can set it here.
|
|
218
|
+
* This field will be used to display user name in the top right corner of the admin panel.
|
|
219
|
+
*/
|
|
123
220
|
userFullNameField?: string,
|
|
124
221
|
},
|
|
222
|
+
/**
|
|
223
|
+
* Array of resources which will be displayed in the admin panel.
|
|
224
|
+
* Resource represents one table or collection in database.
|
|
225
|
+
* Each resource has its own configuration.
|
|
226
|
+
*/
|
|
125
227
|
resources: Array<AdminForthResource>,
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Array of left sidebar menu items which will be displayed in the admin panel.
|
|
231
|
+
* Menu items can be links to resources or custom pages.
|
|
232
|
+
* Menu items can be grouped.
|
|
233
|
+
*
|
|
234
|
+
*/
|
|
126
235
|
menu: Array<AdminForthConfigMenuItem>,
|
|
127
|
-
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* If you want use custom DataSource which is not supported by AdminForth yet, you can define it's class here
|
|
239
|
+
*
|
|
240
|
+
*/
|
|
241
|
+
databaseConnectors?: any, // TODO Define interface for database connector
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* List of data sources which will be used to fetch data for resources.
|
|
245
|
+
* Datasource is one database connection
|
|
246
|
+
*
|
|
247
|
+
*/
|
|
128
248
|
dataSources: Array<DataSource>,
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Settings which allow you to customize AdminForth
|
|
252
|
+
*
|
|
253
|
+
*/
|
|
129
254
|
customization?: {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
255
|
+
/**
|
|
256
|
+
* Your app name
|
|
257
|
+
*/
|
|
133
258
|
brandName?: string,
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Path to your app logo
|
|
262
|
+
*
|
|
263
|
+
* Example:
|
|
264
|
+
* Place file `logo.svg` to `./custom` folder and set this option:
|
|
265
|
+
*
|
|
266
|
+
* ```ts
|
|
267
|
+
* brandLogo: '@@/logo.svg',
|
|
268
|
+
* ```
|
|
269
|
+
*
|
|
270
|
+
*/
|
|
271
|
+
brandLogo?: string,
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* DayJS format string for all dates in the app
|
|
275
|
+
*/
|
|
134
276
|
datesFormat?: string,
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* HTML title tag value, defaults to brandName
|
|
280
|
+
*/
|
|
135
281
|
title?: string,
|
|
136
|
-
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Placeholder for empty fields in lists and show views, by default empty string ''
|
|
285
|
+
*/
|
|
137
286
|
emptyFieldPlaceholder?: {
|
|
138
287
|
show?: string,
|
|
139
288
|
list?: string,
|
|
140
289
|
|
|
141
290
|
} | string,
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Relative or absolute path to custom components directory
|
|
294
|
+
* By default equals `./custom`.
|
|
295
|
+
*
|
|
296
|
+
* Custom .vue files, images, and any other assets placed in this directory can be accessed in AdminForth components and configs with `@@/`.
|
|
297
|
+
*
|
|
298
|
+
* For example if file path is `./custom/comp/my.vue`, you can use it in AdminForth config like this:
|
|
299
|
+
*
|
|
300
|
+
* ```ts
|
|
301
|
+
* component: {
|
|
302
|
+
* show: '@@/comp/my.vue',
|
|
303
|
+
* }
|
|
304
|
+
*
|
|
305
|
+
*/
|
|
306
|
+
customComponentsDir?: string,
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Path to custom .ts file which allows to inject custom Vue uses in SPA or add custom imports.
|
|
310
|
+
*
|
|
311
|
+
* Example: Create file: `./custom/vue-uses.ts` with next content:
|
|
312
|
+
*
|
|
313
|
+
* ```ts
|
|
314
|
+
* import HighchartsVue from 'highcharts-vue';
|
|
315
|
+
* // import '@@/custom.scss'; // here is how you can import custom styles
|
|
316
|
+
*
|
|
317
|
+
* export default function (app) {
|
|
318
|
+
* app.use(HighchartsVue);
|
|
319
|
+
* }
|
|
320
|
+
* ```
|
|
321
|
+
*
|
|
322
|
+
* Install HighCharts:
|
|
323
|
+
*
|
|
324
|
+
* ```bash
|
|
325
|
+
* npm install highcharts highcharts-vue
|
|
326
|
+
* ```
|
|
327
|
+
*
|
|
328
|
+
* And specify vueUsesFile in AdminForth config:
|
|
329
|
+
*
|
|
330
|
+
* ```ts
|
|
331
|
+
* vueUsesFile: '@@/vue-uses.ts',
|
|
332
|
+
* ```
|
|
333
|
+
*
|
|
334
|
+
*/
|
|
335
|
+
vueUsesFile?: string,
|
|
142
336
|
},
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* If you want to Serve AdminForth from a subdirectory, e.g. on example.com/backoffice, you can specify it like:
|
|
340
|
+
*
|
|
341
|
+
* ```ts
|
|
342
|
+
* baseUrl: '/backoffice',
|
|
343
|
+
* ```
|
|
344
|
+
*
|
|
345
|
+
*/
|
|
143
346
|
baseUrl?: string,
|
|
144
347
|
|
|
145
348
|
deleteConfirmation?: boolean,
|
|
@@ -152,15 +355,43 @@ export type AllowedActions = {
|
|
|
152
355
|
edit?: boolean,
|
|
153
356
|
show?: boolean,
|
|
154
357
|
delete?: boolean,
|
|
155
|
-
|
|
358
|
+
}
|
|
156
359
|
|
|
157
360
|
export type ValidationObject = {
|
|
361
|
+
/**
|
|
362
|
+
* Should be pure string (not RegExp string)
|
|
363
|
+
*
|
|
364
|
+
* Example:
|
|
365
|
+
*
|
|
366
|
+
* ```ts
|
|
367
|
+
* // regex for email
|
|
368
|
+
* regExp: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
|
|
369
|
+
* ```
|
|
370
|
+
*
|
|
371
|
+
*/
|
|
158
372
|
regExp: string,
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Error message shown to user if validation fails
|
|
376
|
+
*
|
|
377
|
+
* Example: "Invalid email format"
|
|
378
|
+
*/
|
|
159
379
|
message: string,
|
|
160
380
|
}
|
|
161
381
|
|
|
162
382
|
export type DataSource = {
|
|
383
|
+
/**
|
|
384
|
+
* ID of datasource which you will use in resources to specify from which database to fetch data from
|
|
385
|
+
*/
|
|
163
386
|
id: string,
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* URL to database. Examples:
|
|
390
|
+
*
|
|
391
|
+
* - MongoDB: `mongodb://<user>:<password>@<host>:<port>/<database>`
|
|
392
|
+
* - PostgreSQL: `postgresql://<user>:<password>@<host>:<port>/<database>`
|
|
393
|
+
* - SQLite: `sqlite://<path>`
|
|
394
|
+
*/
|
|
164
395
|
url: string,
|
|
165
396
|
}
|
|
166
397
|
|