adminforth 1.5.8 → 1.5.9-next.1
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/spa/src/App.vue +6 -5
- package/dist/spa/src/{composables/useStores.ts → adminforth.ts} +72 -45
- package/dist/spa/src/afcl/Dropzone.vue +4 -3
- package/dist/spa/src/components/ResourceListTable.vue +2 -1
- package/dist/spa/src/composables/useFrontendApi.ts +5 -3
- package/dist/spa/src/renderers/CompactField.vue +4 -3
- package/dist/spa/src/renderers/CompactUUID.vue +4 -3
- package/dist/spa/src/renderers/CountryFlag.vue +3 -1
- package/dist/spa/src/stores/core.ts +2 -1
- package/dist/spa/src/types/FrontendAPI.ts +32 -6
- package/dist/spa/src/utils.ts +3 -3
- package/dist/spa/src/views/CreateView.vue +3 -2
- package/dist/spa/src/views/EditView.vue +3 -3
- package/dist/spa/src/views/ListView.vue +7 -6
- package/dist/spa/src/views/ShowView.vue +3 -2
- package/dist/spa/tsconfig.json +1 -1
- package/dist/types/FrontendAPI.d.ts +29 -6
- package/dist/types/FrontendAPI.d.ts.map +1 -1
- package/dist/types/FrontendAPI.js.map +1 -1
- package/package.json +1 -1
package/dist/spa/src/App.vue
CHANGED
|
@@ -250,17 +250,18 @@ import { createHead } from 'unhead'
|
|
|
250
250
|
import { loadFile } from '@/utils';
|
|
251
251
|
import Toast from './components/Toast.vue';
|
|
252
252
|
import {useToastStore} from '@/stores/toast';
|
|
253
|
-
import { FrontendAPI } from '@/composables/useStores';
|
|
254
253
|
import { getCustomComponent } from '@/utils';
|
|
255
254
|
import type { AdminForthConfigMenuItem, AnnouncementBadgeResponse } from './types/Common';
|
|
256
255
|
import { Tooltip } from '@/afcl';
|
|
256
|
+
import { initFrontedAPI } from '@/adminforth';
|
|
257
|
+
import adminforth from '@/adminforth';
|
|
257
258
|
|
|
258
259
|
|
|
259
260
|
const coreStore = useCoreStore();
|
|
260
261
|
const toastStore = useToastStore();
|
|
261
262
|
const userStore = useUserStore();
|
|
262
|
-
|
|
263
|
-
|
|
263
|
+
|
|
264
|
+
initFrontedAPI()
|
|
264
265
|
|
|
265
266
|
createHead()
|
|
266
267
|
const sideBarOpen = ref(false);
|
|
@@ -371,7 +372,7 @@ watch(dropdownUserButton, (dropdownUserButton) => {
|
|
|
371
372
|
document.querySelector('#dropdown-user') as HTMLElement,
|
|
372
373
|
document.querySelector('[data-dropdown-toggle="dropdown-user"]') as HTMLElement,
|
|
373
374
|
);
|
|
374
|
-
|
|
375
|
+
adminforth.closeUserMenuDropdown = () => {
|
|
375
376
|
dd.hide();
|
|
376
377
|
}
|
|
377
378
|
}
|
|
@@ -396,7 +397,7 @@ onMounted(async () => {
|
|
|
396
397
|
await initRouter();
|
|
397
398
|
handleCustomLayout();
|
|
398
399
|
|
|
399
|
-
|
|
400
|
+
adminforth.menu.refreshMenuBadges = async () => {
|
|
400
401
|
await coreStore.fetchMenuBadges();
|
|
401
402
|
}
|
|
402
403
|
})
|
|
@@ -1,25 +1,13 @@
|
|
|
1
|
+
import type { FilterParams, FrontendAPIInterface } from "./types/FrontendAPI";
|
|
1
2
|
import type { FrontendAPIInterface, ConfirmParams, AlertParams, } from '@/types/FrontendAPI';
|
|
2
3
|
import type { AdminForthFilterOperators, AdminForthResourceColumn } from '@/types/Common';
|
|
3
|
-
import { useToastStore } from '
|
|
4
|
-
import { useModalStore } from '
|
|
4
|
+
import { useToastStore } from '@/stores/toast';
|
|
5
|
+
import { useModalStore } from '@/stores/modal';
|
|
5
6
|
import { useCoreStore } from '@/stores/core';
|
|
6
7
|
import { useFiltersStore } from '@/stores/filters';
|
|
7
8
|
import router from '@/router'
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Field of resource to filter
|
|
12
|
-
*/
|
|
13
|
-
field: string;
|
|
14
|
-
/**
|
|
15
|
-
* Operator of filter
|
|
16
|
-
*/
|
|
17
|
-
operator: AdminForthFilterOperators;
|
|
18
|
-
/**
|
|
19
|
-
* Value of filter
|
|
20
|
-
*/
|
|
21
|
-
value: string | number | boolean ;
|
|
22
|
-
}
|
|
10
|
+
|
|
23
11
|
|
|
24
12
|
declare global {
|
|
25
13
|
interface Window {
|
|
@@ -27,34 +15,64 @@ declare global {
|
|
|
27
15
|
}
|
|
28
16
|
}
|
|
29
17
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
18
|
+
class FrontendAPI implements FrontendAPIInterface {
|
|
19
|
+
public toastStore:any
|
|
20
|
+
public modalStore:any
|
|
21
|
+
public filtersStore:any
|
|
22
|
+
public coreStore:any
|
|
23
|
+
|
|
24
|
+
public list: {
|
|
25
|
+
refresh(): Promise<{ error? : string }>;
|
|
26
|
+
silentRefresh(): Promise<{ error? : string }>;
|
|
27
|
+
silentRefreshRow(): Promise<{ error? : string }>;
|
|
28
|
+
closeThreeDotsDropdown(): Promise<{ error? : string }>;
|
|
29
|
+
closeUserMenuDropdown: () => void;
|
|
30
|
+
setFilter: (filter: FilterParams) => void;
|
|
31
|
+
updateFilter: (filter: FilterParams) => void;
|
|
32
|
+
clearFilters: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public menu: {
|
|
36
|
+
refreshMenuBadges: () => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
closeUserMenuDropdown(): void {
|
|
40
|
+
console.log('closeUserMenuDropdown')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
constructor() {
|
|
45
|
+
|
|
46
|
+
this.menu = {
|
|
47
|
+
refreshMenuBadges: () => {
|
|
48
|
+
console.log('refreshMenuBadges')
|
|
49
|
+
}
|
|
38
50
|
}
|
|
39
|
-
|
|
40
|
-
this.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
clearFilters: () => this.clearListFilters.bind(this),
|
|
51
|
+
|
|
52
|
+
this.list = {
|
|
53
|
+
refresh: async () => {
|
|
54
|
+
console.log('refresh');
|
|
55
|
+
return { error: 'Not implemented' }
|
|
56
|
+
},
|
|
57
|
+
silentRefresh: async () => {
|
|
58
|
+
console.log('silentRefresh')
|
|
59
|
+
return { error: 'Not implemented' }
|
|
60
|
+
},
|
|
61
|
+
silentRefreshRow: async () => {
|
|
62
|
+
console.log('silentRefreshRow')
|
|
63
|
+
return { error: 'Not implemented' }
|
|
53
64
|
},
|
|
54
|
-
|
|
55
|
-
|
|
65
|
+
closeThreeDotsDropdown: async () => {
|
|
66
|
+
console.log('closeThreeDotsDropdown')
|
|
67
|
+
return { error: 'Not implemented' }
|
|
56
68
|
},
|
|
57
|
-
|
|
69
|
+
closeUserMenuDropdown: () => {
|
|
70
|
+
console.log('closeUserMenuDropdown')
|
|
71
|
+
},
|
|
72
|
+
setFilter: this.setListFilter.bind(this),
|
|
73
|
+
updateFilter: this.updateListFilter.bind(this),
|
|
74
|
+
clearFilters: this.clearListFilters.bind(this),
|
|
75
|
+
}
|
|
58
76
|
}
|
|
59
77
|
|
|
60
78
|
confirm(params: ConfirmParams): Promise<void> {
|
|
@@ -83,7 +101,6 @@ export class FrontendAPI {
|
|
|
83
101
|
if(router.currentRoute.value.meta.type !== 'list'){
|
|
84
102
|
throw new Error(`Cannot use ${this.setListFilter.name} filter on a list page`)
|
|
85
103
|
} else {
|
|
86
|
-
if(!this.coreStore) this.coreStore = useCoreStore()
|
|
87
104
|
console.log(this.coreStore.resourceColumnsWithFilters,'core store')
|
|
88
105
|
const filterField = this.coreStore.resourceColumnsWithFilters.find((col: AdminForthResourceColumn) => col.name === filter.field)
|
|
89
106
|
if(!filterField){
|
|
@@ -96,7 +113,6 @@ export class FrontendAPI {
|
|
|
96
113
|
|
|
97
114
|
setListFilter(filter: FilterParams): void {
|
|
98
115
|
if(this.listFilterValidation(filter)){
|
|
99
|
-
this.filtersStore = useFiltersStore()
|
|
100
116
|
if(this.filtersStore.filters.some((f) => {return f.field === filter.field && f.operator === filter.operator})){
|
|
101
117
|
throw new Error(`Filter ${filter.field} with operator ${filter.operator} already exists`)
|
|
102
118
|
} else {
|
|
@@ -106,13 +122,11 @@ export class FrontendAPI {
|
|
|
106
122
|
}
|
|
107
123
|
|
|
108
124
|
clearListFilters(): void {
|
|
109
|
-
this.filtersStore = useFiltersStore()
|
|
110
125
|
this.filtersStore.clearFilters()
|
|
111
126
|
}
|
|
112
127
|
|
|
113
128
|
updateListFilter(filter: FilterParams): void {
|
|
114
129
|
if(this.listFilterValidation(filter)){
|
|
115
|
-
this.filtersStore = useFiltersStore()
|
|
116
130
|
const index = this.filtersStore.filters.findIndex((f: FilterParams) => f.field === filter.field)
|
|
117
131
|
if(index === -1) {
|
|
118
132
|
this.filtersStore.setFilter(filter)
|
|
@@ -128,6 +142,19 @@ export class FrontendAPI {
|
|
|
128
142
|
}
|
|
129
143
|
}
|
|
130
144
|
|
|
145
|
+
}
|
|
131
146
|
|
|
147
|
+
const frontendAPI: FrontendAPIInterface = new FrontendAPI();
|
|
148
|
+
window.adminforth = frontendAPI;
|
|
132
149
|
|
|
150
|
+
export function initFrontedAPI() {
|
|
151
|
+
// force init
|
|
152
|
+
const api: FrontendAPI = frontendAPI as FrontendAPI;
|
|
153
|
+
api.toastStore = useToastStore();
|
|
154
|
+
api.modalStore = useModalStore();
|
|
155
|
+
api.coreStore = useCoreStore();
|
|
156
|
+
api.filtersStore = useFiltersStore();
|
|
133
157
|
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
export default frontendAPI;
|
|
@@ -48,9 +48,10 @@
|
|
|
48
48
|
|
|
49
49
|
<script setup lang="ts">
|
|
50
50
|
import { humanifySize } from '@/utils';
|
|
51
|
-
import { ref } from 'vue';
|
|
51
|
+
import { ref, type Ref } from 'vue';
|
|
52
52
|
import { IconFileSolid } from '@iconify-prerendered/vue-flowbite';
|
|
53
53
|
import { watch } from 'vue';
|
|
54
|
+
import adminforth from '@/adminforth';
|
|
54
55
|
|
|
55
56
|
const props = defineProps<{
|
|
56
57
|
extensions: string[],
|
|
@@ -93,14 +94,14 @@ function doEmit(filesIn: FileList) {
|
|
|
93
94
|
const size = file.size;
|
|
94
95
|
|
|
95
96
|
if (!allowedExtensions.includes(`.${extension}`)) {
|
|
96
|
-
|
|
97
|
+
adminforth.alert({
|
|
97
98
|
message: `Sorry, the file type .${extension} is not allowed. Please upload a file with one of the following extensions: ${allowedExtensions.join(', ')}`,
|
|
98
99
|
variant: 'danger',
|
|
99
100
|
});
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
103
|
if (size > maxSizeBytes) {
|
|
103
|
-
|
|
104
|
+
adminforth.alert({
|
|
104
105
|
message: `Sorry, the file size ${humanifySize(size)} exceeds the maximum allowed size of ${humanifySize(maxSizeBytes)}.`,
|
|
105
106
|
variant: 'danger',
|
|
106
107
|
});
|
|
@@ -290,6 +290,7 @@ import {
|
|
|
290
290
|
import router from '@/router';
|
|
291
291
|
import { Tooltip } from '@/afcl';
|
|
292
292
|
import type { AdminForthResourceCommon } from '@/types/Common';
|
|
293
|
+
import adminforth from '@/adminforth';
|
|
293
294
|
|
|
294
295
|
const coreStore = useCoreStore();
|
|
295
296
|
|
|
@@ -458,7 +459,7 @@ async function onClick(e,row) {
|
|
|
458
459
|
}
|
|
459
460
|
|
|
460
461
|
async function deleteRecord(row) {
|
|
461
|
-
const data = await
|
|
462
|
+
const data = await adminforth.confirm({
|
|
462
463
|
message: 'Are you sure you want to delete this item?',
|
|
463
464
|
yes: 'Delete',
|
|
464
465
|
no: 'Cancel',
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import adminforth from '@/adminforth';
|
|
2
|
+
|
|
1
3
|
export function showSuccesTost(message: string) {
|
|
2
|
-
|
|
4
|
+
adminforth.alert({ message, variant: 'success' });
|
|
3
5
|
return message;
|
|
4
6
|
}
|
|
5
7
|
|
|
6
8
|
export function showWarningTost(message: string) {
|
|
7
|
-
|
|
9
|
+
adminforth.alert({ message, variant: 'warning' });
|
|
8
10
|
return message;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export function showErrorTost(message: string, timeout?: number) {
|
|
12
|
-
|
|
14
|
+
adminforth.alert({ message, variant: 'danger', timeout: timeout || 30});
|
|
13
15
|
return message;
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
|
-
<script setup>
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
|
|
14
15
|
import { computed, ref, onMounted, nextTick } from 'vue';
|
|
15
16
|
import { IconFileCopyAltSolid } from '@iconify-prerendered/vue-flowbite';
|
|
16
17
|
import Tooltip from '@/afcl/Tooltip.vue';
|
|
17
|
-
|
|
18
|
+
import adminforth from '@/adminforth';
|
|
18
19
|
|
|
19
20
|
const visualValue = computed(() => {
|
|
20
21
|
// if lenght is more then 8, show only first 4 and last 4 characters, ... in the middle
|
|
@@ -31,7 +32,7 @@ const id = ref();
|
|
|
31
32
|
|
|
32
33
|
function copyToCB() {
|
|
33
34
|
navigator.clipboard.writeText(props.record[props.column.name]);
|
|
34
|
-
|
|
35
|
+
adminforth.alert({
|
|
35
36
|
message: 'ID copied to clipboard',
|
|
36
37
|
variant: 'success',
|
|
37
38
|
})
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
|
-
<script setup>
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
|
|
14
15
|
import { computed, ref, onMounted, nextTick } from 'vue';
|
|
15
16
|
import { IconFileCopyAltSolid } from '@iconify-prerendered/vue-flowbite';
|
|
16
17
|
import Tooltip from '@/afcl/Tooltip.vue';
|
|
17
|
-
|
|
18
|
+
import adminforth from '@/adminforth';
|
|
18
19
|
|
|
19
20
|
const visualValue = computed(() => {
|
|
20
21
|
// if lenght is more then 8, show only first 4 and last 4 characters, ... in the middle
|
|
@@ -31,7 +32,7 @@ const id = ref();
|
|
|
31
32
|
|
|
32
33
|
function copyToCB() {
|
|
33
34
|
navigator.clipboard.writeText(props.record[props.column.name]);
|
|
34
|
-
|
|
35
|
+
adminforth.alert({
|
|
35
36
|
message: 'ID copied to clipboard',
|
|
36
37
|
variant: 'success',
|
|
37
38
|
})
|
|
@@ -57,7 +57,9 @@ const countryName = computed(() => {
|
|
|
57
57
|
|
|
58
58
|
// border radius for background
|
|
59
59
|
border-radius: 2px;
|
|
60
|
-
box-shadow: inset -0.3px -0.3px 0.3px 0px rgba(0 0 0 / 0.2),
|
|
60
|
+
box-shadow: inset -0.3px -0.3px 0.3px 0px rgba(0 0 0 / 0.2),
|
|
61
|
+
inset 0.3px 0.3px 0.3px 0px rgba(255 255 255 / 0.2),
|
|
62
|
+
0px 0px 3px #00000030;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
</style>
|
|
@@ -2,6 +2,7 @@ import { ref, computed } from 'vue'
|
|
|
2
2
|
import { defineStore } from 'pinia'
|
|
3
3
|
import { callAdminForthApi } from '@/utils';
|
|
4
4
|
import websocket from '@/websocket';
|
|
5
|
+
import adminforth from '@/adminforth';
|
|
5
6
|
|
|
6
7
|
import type { AdminForthResourceCommon, AdminForthResourceColumnCommon, GetBaseConfigResponse, ResourceVeryShort, AdminUser, UserData, AdminForthConfigMenuItem, AdminForthConfigForFrontend } from '@/types/Common';
|
|
7
8
|
import type { Ref } from 'vue'
|
|
@@ -151,7 +152,7 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
151
152
|
});
|
|
152
153
|
|
|
153
154
|
if (respData.error) {
|
|
154
|
-
|
|
155
|
+
adminforth.alert({
|
|
155
156
|
message: respData.error,
|
|
156
157
|
variant: 'danger',
|
|
157
158
|
timeout: 30,
|
|
@@ -1,4 +1,22 @@
|
|
|
1
|
+
import type { AdminForthFilterOperators } from "./Common.js";
|
|
2
|
+
|
|
1
3
|
|
|
4
|
+
|
|
5
|
+
export type FilterParams = {
|
|
6
|
+
/**
|
|
7
|
+
* Field of resource to filter
|
|
8
|
+
*/
|
|
9
|
+
field: string;
|
|
10
|
+
/**
|
|
11
|
+
* Operator of filter
|
|
12
|
+
*/
|
|
13
|
+
operator: AdminForthFilterOperators;
|
|
14
|
+
/**
|
|
15
|
+
* Value of filter
|
|
16
|
+
*/
|
|
17
|
+
value: string | number | boolean ;
|
|
18
|
+
}
|
|
19
|
+
|
|
2
20
|
export interface FrontendAPIInterface {
|
|
3
21
|
|
|
4
22
|
/**
|
|
@@ -9,7 +27,9 @@ export interface FrontendAPIInterface {
|
|
|
9
27
|
* Example:
|
|
10
28
|
*
|
|
11
29
|
* ```ts
|
|
12
|
-
*
|
|
30
|
+
* import adminforth from '@/adminforth'
|
|
31
|
+
*
|
|
32
|
+
* const isConfirmed = await adminforth.confirm({message: 'Are you sure?', yes: 'Yes', no: 'No'})
|
|
13
33
|
* if (isConfirmed) {
|
|
14
34
|
* your code...
|
|
15
35
|
* }
|
|
@@ -28,7 +48,9 @@ export interface FrontendAPIInterface {
|
|
|
28
48
|
* Example:
|
|
29
49
|
*
|
|
30
50
|
* ```ts
|
|
31
|
-
*
|
|
51
|
+
* import adminforth from '@/adminforth'
|
|
52
|
+
*
|
|
53
|
+
* adminforth.alert({message: 'Hello', variant: 'success'})
|
|
32
54
|
* ```
|
|
33
55
|
*
|
|
34
56
|
* @param params - The parameters of the alert
|
|
@@ -69,12 +91,14 @@ export interface FrontendAPIInterface {
|
|
|
69
91
|
* Example:
|
|
70
92
|
*
|
|
71
93
|
* ```ts
|
|
72
|
-
*
|
|
94
|
+
* import adminforth from '@/adminforth'
|
|
95
|
+
*
|
|
96
|
+
* adminforth.list.setFilter({field: 'name', operator: 'ilike', value: 'john'})
|
|
73
97
|
* ```
|
|
74
98
|
*
|
|
75
99
|
* @param filter - The filter to set
|
|
76
100
|
*/
|
|
77
|
-
setFilter(filter:
|
|
101
|
+
setFilter(filter: FilterParams): void;
|
|
78
102
|
|
|
79
103
|
/**
|
|
80
104
|
* Update a filter in the list
|
|
@@ -82,12 +106,14 @@ export interface FrontendAPIInterface {
|
|
|
82
106
|
* Example:
|
|
83
107
|
*
|
|
84
108
|
* ```ts
|
|
85
|
-
*
|
|
109
|
+
* import adminforth from '@/adminforth';
|
|
110
|
+
*
|
|
111
|
+
* adminforth.list.updateFilter({field: 'name', operator: 'ilike', value: 'john'})
|
|
86
112
|
* ```
|
|
87
113
|
*
|
|
88
114
|
* @param filter - The filter to update
|
|
89
115
|
*/
|
|
90
|
-
updateFilter(filter:
|
|
116
|
+
updateFilter(filter: FilterParams): void;
|
|
91
117
|
|
|
92
118
|
/**
|
|
93
119
|
* Clear all filters from the list
|
package/dist/spa/src/utils.ts
CHANGED
|
@@ -5,7 +5,7 @@ import router from "./router";
|
|
|
5
5
|
import { useCoreStore } from './stores/core';
|
|
6
6
|
import { useUserStore } from './stores/user';
|
|
7
7
|
import { Dropdown } from 'flowbite';
|
|
8
|
-
|
|
8
|
+
import adminforth from './adminforth';
|
|
9
9
|
|
|
10
10
|
const LS_LANG_KEY = `afLanguage`;
|
|
11
11
|
|
|
@@ -31,7 +31,7 @@ export async function callApi({path, method, body=undefined}: {
|
|
|
31
31
|
}
|
|
32
32
|
return await r.json();
|
|
33
33
|
} catch(e){
|
|
34
|
-
|
|
34
|
+
adminforth.alert({variant:'danger', message: window.i18n?.global?.t('Something went wrong, please try again later'),})
|
|
35
35
|
console.error(`error in callApi ${path}`,e);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -118,7 +118,7 @@ export function initThreeDotsDropdown() {
|
|
|
118
118
|
threeDotsDropdown,
|
|
119
119
|
document.querySelector('[data-dropdown-toggle="listThreeDotsDropdown"]') as HTMLElement,
|
|
120
120
|
);
|
|
121
|
-
|
|
121
|
+
adminforth.list.closeThreeDotsDropdown = () => {
|
|
122
122
|
dd.hide();
|
|
123
123
|
}
|
|
124
124
|
}
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
</template>
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
<script setup>
|
|
75
|
+
<script setup lang="ts">
|
|
76
76
|
|
|
77
77
|
import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
78
78
|
import ResourceForm from '@/components/ResourceForm.vue';
|
|
@@ -85,6 +85,7 @@ import { useRoute, useRouter } from 'vue-router';
|
|
|
85
85
|
import { computed } from 'vue';
|
|
86
86
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
87
87
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
88
|
+
import adminforth from '@/adminforth';
|
|
88
89
|
|
|
89
90
|
|
|
90
91
|
const isValid = ref(false);
|
|
@@ -155,7 +156,7 @@ async function saveRecord() {
|
|
|
155
156
|
primaryKey: response.newRecordId
|
|
156
157
|
}
|
|
157
158
|
});
|
|
158
|
-
|
|
159
|
+
adminforth.alert({
|
|
159
160
|
message: 'Record created successfully',
|
|
160
161
|
variant: 'success'
|
|
161
162
|
});
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
</template>
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
<script setup>
|
|
71
|
+
<script setup lang="ts">
|
|
72
72
|
|
|
73
73
|
import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
74
74
|
import ResourceForm from '@/components/ResourceForm.vue';
|
|
@@ -80,7 +80,7 @@ import { computed, onMounted, ref } from 'vue';
|
|
|
80
80
|
import { useRoute, useRouter } from 'vue-router';
|
|
81
81
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
82
82
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
83
|
-
|
|
83
|
+
import adminforth from '@/adminforth';
|
|
84
84
|
|
|
85
85
|
const coreStore = useCoreStore();
|
|
86
86
|
|
|
@@ -158,7 +158,7 @@ async function saveRecord() {
|
|
|
158
158
|
if (resp.error) {
|
|
159
159
|
showErrorTost(resp.error);
|
|
160
160
|
} else {
|
|
161
|
-
|
|
161
|
+
adminforth.alert({
|
|
162
162
|
message: 'Record updated successfully',
|
|
163
163
|
variant: 'success',
|
|
164
164
|
timeout: 400000
|
|
@@ -147,6 +147,7 @@ import {
|
|
|
147
147
|
} from '@iconify-prerendered/vue-flowbite';
|
|
148
148
|
|
|
149
149
|
import Filters from '@/components/Filters.vue';
|
|
150
|
+
import adminforth from '@/adminforth';
|
|
150
151
|
|
|
151
152
|
const filtersShow = ref(false);
|
|
152
153
|
|
|
@@ -262,7 +263,7 @@ async function refreshExistingList(pk?: any) {
|
|
|
262
263
|
async function startBulkAction(actionId) {
|
|
263
264
|
const action = coreStore.resource.options.bulkActions.find(a => a.id === actionId);
|
|
264
265
|
if (action.confirm) {
|
|
265
|
-
const confirmed = await
|
|
266
|
+
const confirmed = await adminforth.confirm({
|
|
266
267
|
message: action.confirm,
|
|
267
268
|
});
|
|
268
269
|
if (!confirmed) {
|
|
@@ -287,7 +288,7 @@ async function startBulkAction(actionId) {
|
|
|
287
288
|
await getList();
|
|
288
289
|
|
|
289
290
|
if (data.successMessage) {
|
|
290
|
-
|
|
291
|
+
adminforth.alert({
|
|
291
292
|
message: data.successMessage,
|
|
292
293
|
variant: 'success'
|
|
293
294
|
});
|
|
@@ -367,7 +368,7 @@ async function init() {
|
|
|
367
368
|
}
|
|
368
369
|
if (coreStore.resource!.options?.listRowsAutoRefreshSeconds) {
|
|
369
370
|
listAutorefresher = setInterval(async () => {
|
|
370
|
-
await
|
|
371
|
+
await adminforth.list.silentRefresh();
|
|
371
372
|
}, coreStore.resource!.options.listRowsAutoRefreshSeconds * 1000);
|
|
372
373
|
}
|
|
373
374
|
}
|
|
@@ -377,15 +378,15 @@ watch([page, sort, () => filtersStore.filters], async () => {
|
|
|
377
378
|
await getList();
|
|
378
379
|
}, { deep: true });
|
|
379
380
|
|
|
380
|
-
|
|
381
|
+
adminforth.list.refresh = async () => {
|
|
381
382
|
return await getList();
|
|
382
383
|
}
|
|
383
384
|
|
|
384
|
-
|
|
385
|
+
adminforth.list.silentRefresh = async () => {
|
|
385
386
|
return await refreshExistingList();
|
|
386
387
|
}
|
|
387
388
|
|
|
388
|
-
|
|
389
|
+
adminforth.list.silentRefreshRow = async (pk: any) => {
|
|
389
390
|
return await refreshExistingList(pk);
|
|
390
391
|
}
|
|
391
392
|
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
</template>
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
<script setup>
|
|
109
|
+
<script setup lang="ts">
|
|
110
110
|
|
|
111
111
|
import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
|
|
112
112
|
|
|
@@ -119,6 +119,7 @@ import {callAdminForthApi} from '@/utils';
|
|
|
119
119
|
import { showSuccesTost, showErrorTost } from '@/composables/useFrontendApi';
|
|
120
120
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
121
121
|
import ShowTable from '@/components/ShowTable.vue';
|
|
122
|
+
import adminforth from "@/adminforth";
|
|
122
123
|
|
|
123
124
|
|
|
124
125
|
const route = useRoute();
|
|
@@ -177,7 +178,7 @@ const otherColumns = computed(() => {
|
|
|
177
178
|
});
|
|
178
179
|
|
|
179
180
|
async function deleteRecord(row) {
|
|
180
|
-
const data = await
|
|
181
|
+
const data = await adminforth.confirm({
|
|
181
182
|
message: 'Are you sure you want to delete this item?',
|
|
182
183
|
yes: 'Delete',
|
|
183
184
|
no: 'Cancel',
|
package/dist/spa/tsconfig.json
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
import type { AdminForthFilterOperators } from "./Common.js";
|
|
2
|
+
export type FilterParams = {
|
|
3
|
+
/**
|
|
4
|
+
* Field of resource to filter
|
|
5
|
+
*/
|
|
6
|
+
field: string;
|
|
7
|
+
/**
|
|
8
|
+
* Operator of filter
|
|
9
|
+
*/
|
|
10
|
+
operator: AdminForthFilterOperators;
|
|
11
|
+
/**
|
|
12
|
+
* Value of filter
|
|
13
|
+
*/
|
|
14
|
+
value: string | number | boolean;
|
|
15
|
+
};
|
|
1
16
|
export interface FrontendAPIInterface {
|
|
2
17
|
/**
|
|
3
18
|
* Show a confirmation dialog
|
|
@@ -7,7 +22,9 @@ export interface FrontendAPIInterface {
|
|
|
7
22
|
* Example:
|
|
8
23
|
*
|
|
9
24
|
* ```ts
|
|
10
|
-
*
|
|
25
|
+
* import adminforth from '@/adminforth'
|
|
26
|
+
*
|
|
27
|
+
* const isConfirmed = await adminforth.confirm({message: 'Are you sure?', yes: 'Yes', no: 'No'})
|
|
11
28
|
* if (isConfirmed) {
|
|
12
29
|
* your code...
|
|
13
30
|
* }
|
|
@@ -25,7 +42,9 @@ export interface FrontendAPIInterface {
|
|
|
25
42
|
* Example:
|
|
26
43
|
*
|
|
27
44
|
* ```ts
|
|
28
|
-
*
|
|
45
|
+
* import adminforth from '@/adminforth'
|
|
46
|
+
*
|
|
47
|
+
* adminforth.alert({message: 'Hello', variant: 'success'})
|
|
29
48
|
* ```
|
|
30
49
|
*
|
|
31
50
|
* @param params - The parameters of the alert
|
|
@@ -64,24 +83,28 @@ export interface FrontendAPIInterface {
|
|
|
64
83
|
* Example:
|
|
65
84
|
*
|
|
66
85
|
* ```ts
|
|
67
|
-
*
|
|
86
|
+
* import adminforth from '@/adminforth'
|
|
87
|
+
*
|
|
88
|
+
* adminforth.list.setFilter({field: 'name', operator: 'ilike', value: 'john'})
|
|
68
89
|
* ```
|
|
69
90
|
*
|
|
70
91
|
* @param filter - The filter to set
|
|
71
92
|
*/
|
|
72
|
-
setFilter(filter:
|
|
93
|
+
setFilter(filter: FilterParams): void;
|
|
73
94
|
/**
|
|
74
95
|
* Update a filter in the list
|
|
75
96
|
*
|
|
76
97
|
* Example:
|
|
77
98
|
*
|
|
78
99
|
* ```ts
|
|
79
|
-
*
|
|
100
|
+
* import adminforth from '@/adminforth';
|
|
101
|
+
*
|
|
102
|
+
* adminforth.list.updateFilter({field: 'name', operator: 'ilike', value: 'john'})
|
|
80
103
|
* ```
|
|
81
104
|
*
|
|
82
105
|
* @param filter - The filter to update
|
|
83
106
|
*/
|
|
84
|
-
updateFilter(filter:
|
|
107
|
+
updateFilter(filter: FilterParams): void;
|
|
85
108
|
/**
|
|
86
109
|
* Clear all filters from the list
|
|
87
110
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrontendAPI.d.ts","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FrontendAPI.d.ts","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAI7D,MAAM,MAAM,YAAY,GAAG;IACvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,yBAAyB,CAAC;IACpC;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAE;CACrC,CAAA;AAED,MAAM,WAAW,oBAAoB;IAEjC;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,MAAM,EAAC,aAAa,GAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,MAAM,EAAC,WAAW,GAAG,IAAI,CAAC;IAGhC,IAAI,EAAE;QAEF;;WAEG;QACH,OAAO,IAAI,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAExC;;;;WAIG;QACH,aAAa,IAAI,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAE9C;;WAEG;QACH,gBAAgB,CAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAEzD;;WAEG;QACH,sBAAsB,IAAI,IAAI,CAAC;QAG/B;;;;;;;;;;;;;;WAcG;QACH,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEtC;;;;;;;;;;;;WAYG;QACH,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEzC;;WAEG;QACH,YAAY,IAAI,IAAI,CAAC;KACxB,CAAA;IAED,IAAI,EAAE;QACF;;WAEG;QACH,iBAAiB,IAAI,IAAI,CAAC;KAC7B,CAAA;IAED;;OAEG;IACH,qBAAqB,IAAI,IAAI,CAAC;CACjC;AAED,MAAM,MAAM,aAAa,GAAG;IACxB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CAEf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,OAAO,YAAY,CAAC;IAEnD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;CAElC,CAAA;AAID,oBAAY,YAAY;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrontendAPI.js","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FrontendAPI.js","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AAkLA,MAAM,CAAN,IAAY,YAKT;AALH,WAAY,YAAY;IACpB,iCAAiB,CAAA;IACjB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,6BAAa,CAAA;AACf,CAAC,EALS,YAAY,KAAZ,YAAY,QAKrB"}
|