Skip to content

Commit f387a2d

Browse files
committed
progress: import adminforth from '@/adminforth' instead of window.adminforth
1 parent a1d4405 commit f387a2d

File tree

13 files changed

+222
-163
lines changed

13 files changed

+222
-163
lines changed

Changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [v1.5.9] - next
99

10+
### Changed
11+
12+
- now you should use import adminforth from '@/adminforth' instead of window.adminforth. It has type hints and is more reliable
13+
14+
1015
## [v1.5.8]
1116

1217
### Added

adminforth/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

adminforth/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "adminforth",
3-
"version": "1.5.8",
3+
"version": "1.5.9-next.1",
44
"description": "OpenSource Vue3 powered forth-generation admin panel",
55
"main": "dist/index.js",
66
"module": "dist/index.js",

adminforth/spa/src/App.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,17 +250,18 @@ import { createHead } from 'unhead'
250250
import { loadFile } from '@/utils';
251251
import Toast from './components/Toast.vue';
252252
import {useToastStore} from '@/stores/toast';
253-
import { FrontendAPI } from '@/composables/useStores';
254253
import { getCustomComponent } from '@/utils';
255254
import type { AdminForthConfigMenuItem, AnnouncementBadgeResponse } from './types/Common';
256255
import { Tooltip } from '@/afcl';
256+
import { initFrontedAPI } from '@/adminforth';
257+
import adminforth from '@/adminforth';
257258
258259
259260
const coreStore = useCoreStore();
260261
const toastStore = useToastStore();
261262
const userStore = useUserStore();
262-
const frontendApi = new FrontendAPI();
263-
frontendApi.init();
263+
264+
initFrontedAPI()
264265
265266
createHead()
266267
const sideBarOpen = ref(false);
@@ -371,7 +372,7 @@ watch(dropdownUserButton, (dropdownUserButton) => {
371372
document.querySelector('#dropdown-user') as HTMLElement,
372373
document.querySelector('[data-dropdown-toggle="dropdown-user"]') as HTMLElement,
373374
);
374-
window.adminforth.closeUserMenuDropdown = () => {
375+
adminforth.closeUserMenuDropdown = () => {
375376
dd.hide();
376377
}
377378
}
@@ -396,7 +397,7 @@ onMounted(async () => {
396397
await initRouter();
397398
handleCustomLayout();
398399
399-
window.adminforth.menu.refreshMenuBadges = async () => {
400+
adminforth.menu.refreshMenuBadges = async () => {
400401
await coreStore.fetchMenuBadges();
401402
}
402403
})

adminforth/spa/src/adminforth.ts

Lines changed: 159 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,160 @@
1-
import type { FrontendAPIInterface } from "./types/FrontendAPI";
1+
import type { FilterParams, FrontendAPIInterface } from "./types/FrontendAPI";
2+
import type { FrontendAPIInterface, ConfirmParams, AlertParams, } from '@/types/FrontendAPI';
3+
import type { AdminForthFilterOperators, AdminForthResourceColumn } from '@/types/Common';
4+
import { useToastStore } from '@/stores/toast';
5+
import { useModalStore } from '@/stores/modal';
6+
import { useCoreStore } from '@/stores/core';
7+
import { useFiltersStore } from '@/stores/filters';
8+
import router from '@/router'
29

3-
export default window.adminforth as FrontendAPIInterface;
10+
11+
12+
declare global {
13+
interface Window {
14+
adminforth: FrontendAPIInterface;
15+
}
16+
}
17+
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+
}
50+
}
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' }
64+
},
65+
closeThreeDotsDropdown: async () => {
66+
console.log('closeThreeDotsDropdown')
67+
return { error: 'Not implemented' }
68+
},
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+
}
76+
}
77+
78+
confirm(params: ConfirmParams): Promise<void> {
79+
return new Promise((resolve, reject) => {
80+
this.modalStore.setModalContent({
81+
content: params.message,
82+
acceptText: params.yes || 'Yes',
83+
cancelText: params.no || 'Cancel'
84+
})
85+
this.modalStore.onAcceptFunction = resolve
86+
this.modalStore.onCancelFunction = reject
87+
this.modalStore.togleModal()
88+
})
89+
}
90+
91+
alert(params: AlertParams): void {
92+
this.toastStore.addToast({
93+
message: params.message,
94+
messageHtml: params.messageHtml,
95+
variant: params.variant,
96+
timeout: params.timeout
97+
})
98+
}
99+
100+
listFilterValidation(filter: FilterParams): boolean {
101+
if(router.currentRoute.value.meta.type !== 'list'){
102+
throw new Error(`Cannot use ${this.setListFilter.name} filter on a list page`)
103+
} else {
104+
console.log(this.coreStore.resourceColumnsWithFilters,'core store')
105+
const filterField = this.coreStore.resourceColumnsWithFilters.find((col: AdminForthResourceColumn) => col.name === filter.field)
106+
if(!filterField){
107+
throw new Error(`Field ${filter.field} is not available for filtering`)
108+
}
109+
110+
}
111+
return true
112+
}
113+
114+
setListFilter(filter: FilterParams): void {
115+
if(this.listFilterValidation(filter)){
116+
if(this.filtersStore.filters.some((f) => {return f.field === filter.field && f.operator === filter.operator})){
117+
throw new Error(`Filter ${filter.field} with operator ${filter.operator} already exists`)
118+
} else {
119+
this.filtersStore.setFilter(filter)
120+
}
121+
}
122+
}
123+
124+
clearListFilters(): void {
125+
this.filtersStore.clearFilters()
126+
}
127+
128+
updateListFilter(filter: FilterParams): void {
129+
if(this.listFilterValidation(filter)){
130+
const index = this.filtersStore.filters.findIndex((f: FilterParams) => f.field === filter.field)
131+
if(index === -1) {
132+
this.filtersStore.setFilter(filter)
133+
} else {
134+
const filters = [...this.filtersStore.filters];
135+
if (filter.value === undefined) {
136+
filters.splice(index, 1);
137+
} else {
138+
filters[index] = filter;
139+
}
140+
this.filtersStore.setFilters(filters);
141+
}
142+
}
143+
}
144+
145+
}
146+
147+
const frontendAPI: FrontendAPIInterface = new FrontendAPI();
148+
window.adminforth = frontendAPI;
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();
157+
}
158+
159+
160+
export default frontendAPI;

adminforth/spa/src/components/ResourceListTable.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ import {
290290
import router from '@/router';
291291
import { Tooltip } from '@/afcl';
292292
import type { AdminForthResourceCommon } from '@/types/Common';
293+
import adminforth from '@/adminforth';
293294
294295
const coreStore = useCoreStore();
295296
@@ -458,7 +459,7 @@ async function onClick(e,row) {
458459
}
459460
460461
async function deleteRecord(row) {
461-
const data = await window.adminforth.confirm({
462+
const data = await adminforth.confirm({
462463
message: 'Are you sure you want to delete this item?',
463464
yes: 'Delete',
464465
no: 'Cancel',

adminforth/spa/src/composables/useFrontendApi.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1+
import adminforth from '@/adminforth';
2+
13
export function showSuccesTost(message: string) {
2-
window.adminforth.alert({ message, variant: 'success' });
4+
adminforth.alert({ message, variant: 'success' });
35
return message;
46
}
57

68
export function showWarningTost(message: string) {
7-
window.adminforth.alert({ message, variant: 'warning' });
9+
adminforth.alert({ message, variant: 'warning' });
810
return message;
911
}
1012

1113
export function showErrorTost(message: string, timeout?: number) {
12-
window.adminforth.alert({ message, variant: 'danger', timeout: timeout || 30});
14+
adminforth.alert({ message, variant: 'danger', timeout: timeout || 30});
1315
return message;
1416
}
1517

0 commit comments

Comments
 (0)