adminforth 2.17.0-next.30 → 2.17.0-next.32

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.
Files changed (39) hide show
  1. package/commands/createCustomComponent/templates/customCrud/afterBreadcrumbs.vue.hbs +4 -2
  2. package/commands/createCustomComponent/templates/customCrud/beforeActionButtons.vue.hbs +3 -2
  3. package/commands/createCustomComponent/templates/customCrud/beforeBreadcrumbs.vue.hbs +4 -2
  4. package/commands/createCustomComponent/templates/customCrud/bottom.vue.hbs +4 -2
  5. package/commands/createCustomComponent/templates/customCrud/threeDotsDropdownItems.vue.hbs +4 -2
  6. package/dist/index.d.ts +8 -4
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +9 -3
  9. package/dist/index.js.map +1 -1
  10. package/dist/modules/configValidator.d.ts.map +1 -1
  11. package/dist/modules/configValidator.js +3 -1
  12. package/dist/modules/configValidator.js.map +1 -1
  13. package/dist/modules/restApi.js +12 -12
  14. package/dist/modules/restApi.js.map +1 -1
  15. package/dist/spa/src/App.vue +6 -3
  16. package/dist/spa/src/adminforth.ts +9 -2
  17. package/dist/spa/src/afcl/Dropzone.vue +6 -4
  18. package/dist/spa/src/components/ResourceListTable.vue +4 -3
  19. package/dist/spa/src/components/ResourceListTableVirtual.vue +4 -3
  20. package/dist/spa/src/components/Sidebar.vue +4 -2
  21. package/dist/spa/src/components/ThreeDotsMenu.vue +6 -6
  22. package/dist/spa/src/composables/useFrontendApi.ts +8 -4
  23. package/dist/spa/src/renderers/CompactField.vue +3 -2
  24. package/dist/spa/src/renderers/CompactUUID.vue +3 -2
  25. package/dist/spa/src/stores/core.ts +3 -2
  26. package/dist/spa/src/types/Back.ts +12 -6
  27. package/dist/spa/src/types/FrontendAPI.ts +25 -10
  28. package/dist/spa/src/views/CreateView.vue +6 -6
  29. package/dist/spa/src/views/EditView.vue +6 -6
  30. package/dist/spa/src/views/ListView.vue +8 -8
  31. package/dist/spa/src/views/SettingsView.vue +3 -2
  32. package/dist/spa/src/views/ShowView.vue +7 -6
  33. package/dist/types/Back.d.ts +12 -1
  34. package/dist/types/Back.d.ts.map +1 -1
  35. package/dist/types/Back.js.map +1 -1
  36. package/dist/types/FrontendAPI.d.ts +32 -10
  37. package/dist/types/FrontendAPI.d.ts.map +1 -1
  38. package/dist/types/FrontendAPI.js.map +1 -1
  39. package/package.json +1 -1
@@ -196,7 +196,7 @@ import { getCustomComponent } from '@/utils';
196
196
  import Toast from './components/Toast.vue';
197
197
  import {useToastStore} from '@/stores/toast';
198
198
  import { initFrontedAPI } from '@/adminforth';
199
- import adminforth from '@/adminforth';
199
+ import { useAdminforth } from '@/adminforth';
200
200
  import UserMenuSettingsButton from './components/UserMenuSettingsButton.vue';
201
201
  import { Tooltip } from '@/afcl'
202
202
 
@@ -204,6 +204,9 @@ const coreStore = useCoreStore();
204
204
  const toastStore = useToastStore();
205
205
  const userStore = useUserStore();
206
206
 
207
+ const { menu } = useAdminforth();
208
+ let { closeUserMenuDropdown } = useAdminforth();
209
+
207
210
  initFrontedAPI()
208
211
 
209
212
  createHead()
@@ -310,7 +313,7 @@ watch(dropdownUserButton, (dropdownUserButton) => {
310
313
  document.querySelector('#dropdown-user') as HTMLElement,
311
314
  document.querySelector('[data-dropdown-toggle="dropdown-user"]') as HTMLElement,
312
315
  );
313
- adminforth.closeUserMenuDropdown = () => {
316
+ closeUserMenuDropdown = () => {
314
317
  dd.hide();
315
318
  }
316
319
  }
@@ -329,7 +332,7 @@ onMounted(async () => {
329
332
  // before init flowbite we have to wait router initialized because it affects dom(our v-ifs) and fetch menu
330
333
  await initRouter();
331
334
 
332
- adminforth.menu.refreshMenuBadges = async () => {
335
+ menu.refreshMenuBadges = async () => {
333
336
  await coreStore.fetchMenuBadges();
334
337
  }
335
338
 
@@ -24,7 +24,7 @@ class FrontendAPI implements FrontendAPIInterface {
24
24
  public list: {
25
25
  refresh(): Promise<{ error? : string }>;
26
26
  silentRefresh(): Promise<{ error? : string }>;
27
- silentRefreshRow(): Promise<{ error? : string }>;
27
+ silentRefreshRow(pk: any): Promise<{ error? : string }>;
28
28
  closeThreeDotsDropdown(): Promise<{ error? : string }>;
29
29
  closeUserMenuDropdown: () => void;
30
30
  setFilter: (filter: FilterParams) => void;
@@ -228,7 +228,14 @@ export function useAdminforth() {
228
228
  const api = frontendAPI as FrontendAPI;
229
229
  return {
230
230
  registerSaveInterceptor: (handler: (ctx: { action: 'create'|'edit'; values: any; resource: any; }) => Promise<{ ok: boolean; error?: string | null; extra?: object; }>) => api.registerSaveInterceptor(handler),
231
- api,
231
+ alert: (params: AlertParams) => api.alert(params),
232
+ confirm: (params: ConfirmParams) => api.confirm(params),
233
+ list: api.list,
234
+ show: api.show,
235
+ menu: api.menu,
236
+ closeUserMenuDropdown: () => api.closeUserMenuDropdown(),
237
+ runSaveInterceptors: (params: { action: 'create'|'edit'; values: any; resource: any; resourceId: string; }) => api.runSaveInterceptors(params),
238
+ clearSaveInterceptors: (resourceId?: string) => api.clearSaveInterceptors(resourceId),
232
239
  };
233
240
  }
234
241
 
@@ -100,7 +100,9 @@ import { humanifySize } from '@/utils';
100
100
  import { ref, type Ref, computed } from 'vue';
101
101
  import { IconFileSolid } from '@iconify-prerendered/vue-flowbite';
102
102
  import { watch } from 'vue';
103
- import adminforth from '@/adminforth';
103
+ import { useAdminforth } from '@/adminforth';
104
+
105
+ const { alert } = useAdminforth();
104
106
 
105
107
  const props = defineProps<{
106
108
  extensions: string[],
@@ -175,7 +177,7 @@ function doEmit(filesIn: FileList) {
175
177
  );
176
178
 
177
179
  if (isDuplicate) {
178
- adminforth.alert({
180
+ alert({
179
181
  message: `The file "${file.name}" is already selected.`,
180
182
  variant: 'warning',
181
183
  });
@@ -183,14 +185,14 @@ function doEmit(filesIn: FileList) {
183
185
  }
184
186
 
185
187
  if (!allowedExtensions.includes(`.${extension}`)) {
186
- adminforth.alert({
188
+ alert({
187
189
  message: `Sorry, the file type .${extension} is not allowed. Please upload a file with one of the following extensions: ${allowedExtensions.join(', ')}`,
188
190
  variant: 'danger',
189
191
  });
190
192
  return;
191
193
  }
192
194
  if (size > maxSizeBytes) {
193
- adminforth.alert({
195
+ alert({
194
196
  message: `Sorry, the file size ${humanifySize(size)} exceeds the maximum allowed size of ${humanifySize(maxSizeBytes)}.`,
195
197
  variant: 'danger',
196
198
  });
@@ -340,13 +340,14 @@ import {
340
340
  import router from '@/router';
341
341
  import { Tooltip } from '@/afcl';
342
342
  import type { AdminForthResourceCommon, AdminForthResourceColumnInputCommon, AdminForthResourceColumnCommon, AdminForthComponentDeclaration } from '@/types/Common';
343
- import adminforth from '@/adminforth';
343
+ import { useAdminforth } from '@/adminforth';
344
344
  import Checkbox from '@/afcl/Checkbox.vue';
345
345
  import ListActionsThreeDots from '@/components/ListActionsThreeDots.vue';
346
346
  import CallActionWrapper from '@/components/CallActionWrapper.vue'
347
347
 
348
348
  const coreStore = useCoreStore();
349
349
  const { t } = useI18n();
350
+ const { alert, confirm } = useAdminforth();
350
351
  const props = defineProps<{
351
352
  page: number,
352
353
  resource: AdminForthResourceCommon | null,
@@ -543,7 +544,7 @@ async function onClick(e: any, row: any) {
543
544
  }
544
545
 
545
546
  async function deleteRecord(row: any) {
546
- const data = await adminforth.confirm({
547
+ const data = await confirm({
547
548
  message: t('Are you sure you want to delete this item?'),
548
549
  yes: t('Delete'),
549
550
  no: t('Cancel'),
@@ -609,7 +610,7 @@ async function startCustomAction(actionId: string, row: any, extraData: Record<s
609
610
  emits('update:records', true);
610
611
 
611
612
  if (data.successMessage) {
612
- adminforth.alert({
613
+ alert({
613
614
  message: data.successMessage,
614
615
  variant: 'success'
615
616
  });
@@ -364,13 +364,14 @@ import {
364
364
  import router from '@/router';
365
365
  import { Tooltip } from '@/afcl';
366
366
  import type { AdminForthResourceCommon, AdminForthResourceColumnCommon, AdminForthComponentDeclaration } from '@/types/Common';
367
- import adminforth from '@/adminforth';
367
+ import { useAdminforth } from '@/adminforth';
368
368
  import Checkbox from '@/afcl/Checkbox.vue';
369
369
  import ListActionsThreeDots from '@/components/ListActionsThreeDots.vue';
370
370
  import CallActionWrapper from '@/components/CallActionWrapper.vue'
371
371
 
372
372
  const coreStore = useCoreStore();
373
373
  const { t } = useI18n();
374
+ const { alert, confirm } = useAdminforth();
374
375
  const props = defineProps<{
375
376
  page: number,
376
377
  resource: AdminForthResourceCommon | null,
@@ -570,7 +571,7 @@ async function onClick(e: any,row: any) {
570
571
  }
571
572
 
572
573
  async function deleteRecord(row: any) {
573
- const data = await adminforth.confirm({
574
+ const data = await confirm({
574
575
  message: t('Are you sure you want to delete this item?'),
575
576
  yes: t('Delete'),
576
577
  no: t('Cancel'),
@@ -635,7 +636,7 @@ async function startCustomAction(actionId: string, row: any, extraData: Record<s
635
636
  emits('update:records', true);
636
637
 
637
638
  if (data.successMessage) {
638
- adminforth.alert({
639
+ alert({
639
640
  message: data.successMessage,
640
641
  variant: 'success'
641
642
  });
@@ -299,7 +299,9 @@ import { IconCloseSidebarSolid, IconOpenSidebarSolid } from '@iconify-prerendere
299
299
  import { getIcon, verySimpleHash, loadFile, getCustomComponent } from '@/utils';
300
300
  import { Tooltip } from '@/afcl';
301
301
  import type { AnnouncementBadgeResponse } from '@/types/Common';
302
- import adminforth from '@/adminforth';
302
+ import { useAdminforth } from '@/adminforth';
303
+
304
+ const { menu } = useAdminforth();
303
305
 
304
306
  interface Props {
305
307
  sideBarOpen: boolean;
@@ -424,7 +426,7 @@ function closeCTA() {
424
426
  nextTick( async() => {
425
427
  emit('loadMenu');
426
428
  await coreStore.fetchMenuBadges();
427
- adminforth.menu.refreshMenuBadges();
429
+ menu.refreshMenuBadges();
428
430
  })
429
431
  }
430
432
 
@@ -80,7 +80,7 @@
80
80
  <script setup lang="ts">
81
81
  import { getCustomComponent, getIcon } from '@/utils';
82
82
  import { useCoreStore } from '@/stores/core';
83
- import adminforth from '@/adminforth';
83
+ import { useAdminforth } from '@/adminforth';
84
84
  import { callAdminForthApi } from '@/utils';
85
85
  import { useRoute, useRouter } from 'vue-router';
86
86
  import CallActionWrapper from '@/components/CallActionWrapper.vue'
@@ -88,7 +88,7 @@ import { ref, type ComponentPublicInstance, onMounted, onUnmounted } from 'vue';
88
88
  import type { AdminForthBulkActionCommon, AdminForthComponentDeclarationFull } from '@/types/Common';
89
89
  import type { AdminForthActionInput } from '@/types/Back';
90
90
 
91
-
91
+ const { list, alert} = useAdminforth();
92
92
  const route = useRoute();
93
93
  const coreStore = useCoreStore();
94
94
  const router = useRouter();
@@ -119,7 +119,7 @@ function setComponentRef(el: ComponentPublicInstance | null, index: number) {
119
119
  }
120
120
 
121
121
  async function handleActionClick(action: AdminForthActionInput, payload: any) {
122
- adminforth.list.closeThreeDotsDropdown();
122
+ list.closeThreeDotsDropdown();
123
123
 
124
124
  const actionId = action.id;
125
125
  const data = await callAdminForthApi({
@@ -156,7 +156,7 @@ async function handleActionClick(action: AdminForthActionInput, payload: any) {
156
156
  });
157
157
 
158
158
  if (data.successMessage) {
159
- adminforth.alert({
159
+ alert({
160
160
  message: data.successMessage,
161
161
  variant: 'success'
162
162
  });
@@ -164,7 +164,7 @@ async function handleActionClick(action: AdminForthActionInput, payload: any) {
164
164
  }
165
165
 
166
166
  if (data?.error) {
167
- adminforth.alert({
167
+ alert({
168
168
  message: data.error,
169
169
  variant: 'danger'
170
170
  });
@@ -172,7 +172,7 @@ async function handleActionClick(action: AdminForthActionInput, payload: any) {
172
172
  }
173
173
 
174
174
  function startBulkAction(actionId: string) {
175
- adminforth.list.closeThreeDotsDropdown();
175
+ list.closeThreeDotsDropdown();
176
176
  emit('startBulkAction', actionId);
177
177
  showDropdown.value = false;
178
178
  }
@@ -1,17 +1,21 @@
1
- import adminforth from '@/adminforth';
1
+ import { useAdminforth } from '@/adminforth';
2
+
2
3
 
3
4
  export function showSuccesTost(message: string) {
4
- adminforth.alert({ message, variant: 'success' });
5
+ const { alert } = useAdminforth();
6
+ alert({ message, variant: 'success' });
5
7
  return message;
6
8
  }
7
9
 
8
10
  export function showWarningTost(message: string) {
9
- adminforth.alert({ message, variant: 'warning' });
11
+ const { alert } = useAdminforth();
12
+ alert({ message, variant: 'warning' });
10
13
  return message;
11
14
  }
12
15
 
13
16
  export function showErrorTost(message: string, timeout?: number) {
14
- adminforth.alert({ message, variant: 'danger', timeout: timeout || 30});
17
+ const { alert } = useAdminforth();
18
+ alert({ message, variant: 'danger', timeout: timeout || 30});
15
19
  return message;
16
20
  }
17
21
 
@@ -15,10 +15,11 @@
15
15
  import { computed, ref, onMounted, nextTick } from 'vue';
16
16
  import { IconFileCopyAltSolid } from '@iconify-prerendered/vue-flowbite';
17
17
  import Tooltip from '@/afcl/Tooltip.vue';
18
- import adminforth from '@/adminforth';
18
+ import { useAdminforth } from '@/adminforth';
19
19
  import { useI18n } from 'vue-i18n';
20
20
 
21
21
  const { t } = useI18n();
22
+ const { alert } = useAdminforth();
22
23
  const visualValue = computed(() => {
23
24
  // if lenght is more then 8, show only first 4 and last 4 characters, ... in the middle
24
25
  const val = props.record[props.column.name];
@@ -34,7 +35,7 @@ const id = ref();
34
35
 
35
36
  function copyToCB() {
36
37
  navigator.clipboard.writeText(props.record[props.column.name]);
37
- adminforth.alert({
38
+ alert({
38
39
  message: t('ID copied to clipboard'),
39
40
  variant: 'success',
40
41
  })
@@ -15,10 +15,11 @@
15
15
  import { computed, ref, onMounted, nextTick } from 'vue';
16
16
  import { IconFileCopyAltSolid } from '@iconify-prerendered/vue-flowbite';
17
17
  import Tooltip from '@/afcl/Tooltip.vue';
18
- import adminforth from '@/adminforth';
18
+ import { useAdminforth } from '@/adminforth';
19
19
  import { useI18n } from 'vue-i18n';
20
20
 
21
21
  const { t } = useI18n();
22
+ const { alert } = useAdminforth();
22
23
  const visualValue = computed(() => {
23
24
  // if lenght is more then 8, show only first 4 and last 4 characters, ... in the middle
24
25
  const val = props.record[props.column.name];
@@ -34,7 +35,7 @@ const id = ref();
34
35
 
35
36
  function copyToCB() {
36
37
  navigator.clipboard.writeText(props.record[props.column.name]);
37
- adminforth.alert({
38
+ alert({
38
39
  message: t('ID copied to clipboard'),
39
40
  variant: 'success',
40
41
  })
@@ -2,12 +2,13 @@ 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
+ import { useAdminforth } from '@/adminforth';
6
6
 
7
7
  import type { AdminForthResourceCommon, AdminForthResourceColumnCommon, GetBaseConfigResponse, ResourceVeryShort, AdminUser, UserData, AdminForthConfigMenuItem, AdminForthConfigForFrontend } from '@/types/Common';
8
8
  import type { Ref } from 'vue'
9
9
 
10
10
  export const useCoreStore = defineStore('core', () => {
11
+ const { alert } = useAdminforth();
11
12
  const resourceById: Ref<Record<string, ResourceVeryShort>> = ref({});
12
13
  const theme: Ref<'light'| 'dark'> = ref(window.localStorage.getItem('af__theme') as ('light'|'dark') || 'light');
13
14
 
@@ -157,7 +158,7 @@ export const useCoreStore = defineStore('core', () => {
157
158
  });
158
159
 
159
160
  if (respData.error) {
160
- adminforth.alert({
161
+ alert({
161
162
  message: respData.error,
162
163
  variant: 'danger',
163
164
  timeout: 30,
@@ -359,16 +359,16 @@ export interface IAdminForth {
359
359
  tr(msg: string, category: string, lang: string, params: any, pluralizationNumber?: number): Promise<string>;
360
360
 
361
361
  createResourceRecord(
362
- params: { resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
362
+ params: { resource: AdminForthResource, record: any, response: IAdminForthHttpResponse, adminUser: AdminUser, extra?: HttpExtra }
363
363
  ): Promise<{ error?: string, createdRecord?: any, newRecordId?: any }>;
364
364
 
365
365
  updateResourceRecord(
366
- params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra, updates?: never }
367
- | { resource: AdminForthResource, recordId: any, record?: never, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra, updates: any }
366
+ params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, response: IAdminForthHttpResponse, extra?: HttpExtra, updates?: never }
367
+ | { resource: AdminForthResource, recordId: any, record?: never, oldRecord: any, adminUser: AdminUser, response: IAdminForthHttpResponse, extra?: HttpExtra, updates: any }
368
368
  ): Promise<{ error?: string }>;
369
369
 
370
370
  deleteResourceRecord(
371
- params: { resource: AdminForthResource, recordId: string, adminUser: AdminUser, record: any, extra?: HttpExtra }
371
+ params: { resource: AdminForthResource, recordId: string, adminUser: AdminUser, record: any, response: IAdminForthHttpResponse, extra?: HttpExtra }
372
372
  ): Promise<{ error?: string }>;
373
373
 
374
374
  auth: IAdminForthAuth;
@@ -545,6 +545,7 @@ export type BeforeDeleteSaveFunction = (params: {
545
545
  adminUser: AdminUser,
546
546
  record: any,
547
547
  adminforth: IAdminForth,
548
+ response: IAdminForthHttpResponse,
548
549
  extra?: HttpExtra,
549
550
  }) => Promise<{ok: boolean, error?: string}>;
550
551
 
@@ -557,6 +558,7 @@ export type BeforeEditSaveFunction = (params: {
557
558
  record: any, // legacy, 'updates' should be used instead
558
559
  oldRecord: any,
559
560
  adminforth: IAdminForth,
561
+ response: IAdminForthHttpResponse,
560
562
  extra?: HttpExtra,
561
563
  }) => Promise<{ok: boolean, error?: string | null}>;
562
564
 
@@ -567,6 +569,7 @@ export type BeforeCreateSaveFunction = (params: {
567
569
  adminUser: AdminUser,
568
570
  record: any,
569
571
  adminforth: IAdminForth,
572
+ response: IAdminForthHttpResponse,
570
573
  extra?: HttpExtra,
571
574
  }) => Promise<{ok: boolean, error?: string | null, newRecordId?: string}>;
572
575
 
@@ -577,6 +580,7 @@ export type AfterCreateSaveFunction = (params: {
577
580
  record: any,
578
581
  adminforth: IAdminForth,
579
582
  recordWithVirtualColumns?: any,
583
+ response: IAdminForthHttpResponse,
580
584
  extra?: HttpExtra,
581
585
  }) => Promise<{ok: boolean, error?: string}>;
582
586
 
@@ -590,6 +594,7 @@ export type AfterDeleteSaveFunction = (params: {
590
594
  adminUser: AdminUser,
591
595
  record: any,
592
596
  adminforth: IAdminForth,
597
+ response: IAdminForthHttpResponse,
593
598
  extra?: HttpExtra,
594
599
  }) => Promise<{ok: boolean, error?: string}>;
595
600
 
@@ -602,6 +607,7 @@ export type AfterEditSaveFunction = (params: {
602
607
  record: any, // legacy, 'updates' should be used instead
603
608
  oldRecord: any,
604
609
  adminforth: IAdminForth,
610
+ response: IAdminForthHttpResponse,
605
611
  extra?: HttpExtra,
606
612
  }) => Promise<{ok: boolean, error?: string}>;
607
613
 
@@ -1543,8 +1549,8 @@ export interface AdminForthBulkAction extends AdminForthBulkActionCommon {
1543
1549
  * Callback which will be called on backend when user clicks on action button.
1544
1550
  * It should return Promise which will be resolved when action is done.
1545
1551
  */
1546
- action: ({ resource, selectedIds, adminUser, tr }: {
1547
- resource: AdminForthResource, selectedIds: Array<any>, adminUser: AdminUser, tr: (key: string, category?: string, params?: any) => string
1552
+ action: ({ resource, selectedIds, adminUser, response, tr }: {
1553
+ resource: AdminForthResource, selectedIds: Array<any>, adminUser: AdminUser, response: IAdminForthHttpResponse, tr: (key: string, category?: string, params?: any) => string
1548
1554
  }) => Promise<{ ok: boolean, error?: string, successMessage?: string }>,
1549
1555
 
1550
1556
  /**
@@ -10,9 +10,10 @@ export interface FrontendAPIInterface {
10
10
  * Example:
11
11
  *
12
12
  * ```ts
13
- * import adminforth from '@/adminforth'
13
+ *import { useAdminforth } from '@/adminforth';
14
14
  *
15
- * const isConfirmed = await adminforth.confirm({message: 'Are you sure?', yes: 'Yes', no: 'No'})
15
+ * const { confirm } = useAdminforth();
16
+ * const isConfirmed = await confirm({message: 'Are you sure?', yes: 'Yes', no: 'No'})
16
17
  * if (isConfirmed) {
17
18
  * your code...
18
19
  * }
@@ -31,9 +32,10 @@ export interface FrontendAPIInterface {
31
32
  * Example:
32
33
  *
33
34
  * ```ts
34
- * import adminforth from '@/adminforth'
35
+ * import { useAdminforth } from '@/adminforth';
36
+ * const { alert } = useAdminforth();
35
37
  *
36
- * adminforth.alert({message: 'Hello', variant: 'success'})
38
+ * alert({message: 'Hello', variant: 'success'})
37
39
  * ```
38
40
  *
39
41
  * @param params - The parameters of the alert
@@ -76,13 +78,14 @@ export interface FrontendAPIInterface {
76
78
  * Example:
77
79
  *
78
80
  * ```ts
79
- * import adminforth from '@/adminforth'
81
+ * import { useAdminforth } from '@/adminforth';
80
82
  *
83
+ * const { list } = useAdminforth();
81
84
  * // Regular filter (will show in badge if column.showIn.filter !== false)
82
- * adminforth.list.setFilter({field: 'name', operator: 'ilike', value: 'john'})
85
+ * list.setFilter({field: 'name', operator: 'ilike', value: 'john'})
83
86
  *
84
87
  * // Hidden filter (won't show in badge if column.showIn.filter === false)
85
- * adminforth.list.setFilter({field: 'internal_status', operator: 'eq', value: 'active'})
88
+ * list.setFilter({field: 'internal_status', operator: 'eq', value: 'active'})
86
89
  * ```
87
90
  *
88
91
  * Please note that you can set/update filter even for fields which have showIn.filter=false in resource configuration.
@@ -102,9 +105,9 @@ export interface FrontendAPIInterface {
102
105
  * Example:
103
106
  *
104
107
  * ```ts
105
- * import adminforth from '@/adminforth';
106
- *
107
- * adminforth.list.updateFilter({field: 'name', operator: 'ilike', value: 'john'})
108
+ * import { useAdminforth } from '@/adminforth';
109
+ * const { list } = useAdminforth();
110
+ * list.updateFilter({field: 'name', operator: 'ilike', value: 'john'})
108
111
  * ```
109
112
  *
110
113
  * @param filter - The filter to update
@@ -136,6 +139,18 @@ export interface FrontendAPIInterface {
136
139
  * Close the user menu dropdown
137
140
  */
138
141
  closeUserMenuDropdown(): void;
142
+
143
+ /**
144
+ * Run save interceptors for a specific resource or all resources if no resourceId is provided
145
+ */
146
+ runSaveInterceptors(params: { action: 'create'|'edit'; values: any; resource: any; resourceId: string; }): Promise<{ ok: boolean; error?: string | null; extra?: object; }>;
147
+
148
+ /**
149
+ * Clear save interceptors for a specific resource or all resources if no resourceId is provided
150
+ *
151
+ * @param resourceId - The resource ID to clear interceptors for
152
+ */
153
+ clearSaveInterceptors(resourceId?: string): void;
139
154
  }
140
155
 
141
156
  export type ConfirmParams = {
@@ -86,7 +86,7 @@ import { useRoute, useRouter } from 'vue-router';
86
86
  import { computed } from 'vue';
87
87
  import { showErrorTost } from '@/composables/useFrontendApi';
88
88
  import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
89
- import adminforth, { useAdminforth } from '@/adminforth';
89
+ import { useAdminforth } from '@/adminforth';
90
90
  import { useI18n } from 'vue-i18n';
91
91
  import { type AdminForthComponentDeclarationFull } from '@/types/Common.js';
92
92
  import type { AdminForthResourceColumn } from '@/types/Back';
@@ -103,7 +103,7 @@ const router = useRouter();
103
103
  const record = ref({});
104
104
 
105
105
  const coreStore = useCoreStore();
106
- const { api } = useAdminforth();
106
+ const { clearSaveInterceptors, runSaveInterceptors, alert } = useAdminforth();
107
107
 
108
108
  const { t } = useI18n();
109
109
 
@@ -119,7 +119,7 @@ async function onUpdateRecord(newRecord: any) {
119
119
  }
120
120
 
121
121
  onBeforeMount(() => {
122
- api.clearSaveInterceptors(route.params.resourceId as string);
122
+ clearSaveInterceptors(route.params.resourceId as string);
123
123
  });
124
124
 
125
125
  onMounted(async () => {
@@ -174,7 +174,7 @@ async function saveRecord() {
174
174
  const requiredColumns = coreStore.resource?.columns.filter(c => c.required?.create === true) || [];
175
175
  const requiredColumnsToSkip = requiredColumns.filter(c => checkShowIf(c, record.value, coreStore.resource?.columns || []) === false);
176
176
  saving.value = true;
177
- const interceptorsResult = await api.runSaveInterceptors({
177
+ const interceptorsResult = await runSaveInterceptors({
178
178
  action: 'create',
179
179
  values: record.value,
180
180
  resource: coreStore.resource,
@@ -212,7 +212,7 @@ async function saveRecord() {
212
212
  primaryKey: response.newRecordId
213
213
  }
214
214
  });
215
- adminforth.alert({
215
+ alert({
216
216
  message: t('Record created successfully!'),
217
217
  variant: 'success'
218
218
  });
@@ -228,7 +228,7 @@ function scrollToInvalidField() {
228
228
  }
229
229
  }
230
230
  const errorMessage = t('Failed to save. Please fix errors for the following fields:') + '<ul class="mt-2 list-disc list-inside">' + columnsWithErrors.map(c => `<li><strong>${c.column.label || c.column.name}</strong>: ${c.error}</li>`).join('') + '</ul>';
231
- adminforth.alert({
231
+ alert({
232
232
  messageHtml: errorMessage,
233
233
  variant: 'danger'
234
234
  });
@@ -80,14 +80,14 @@ import { computed, onMounted, onBeforeMount, ref, type Ref, nextTick, watch } fr
80
80
  import { useRoute, useRouter } from 'vue-router';
81
81
  import { showErrorTost } from '@/composables/useFrontendApi';
82
82
  import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
83
- import adminforth, { useAdminforth } from '@/adminforth';
83
+ import { useAdminforth } from '@/adminforth';
84
84
  import { useI18n } from 'vue-i18n';
85
85
  import { type AdminForthComponentDeclarationFull } from '@/types/Common.js';
86
86
  import type { AdminForthResourceColumn } from '@/types/Back';
87
87
 
88
88
  const { t } = useI18n();
89
89
  const coreStore = useCoreStore();
90
- const { api } = useAdminforth();
90
+ const { clearSaveInterceptors, runSaveInterceptors, alert } = useAdminforth();
91
91
 
92
92
  const isValid = ref(false);
93
93
  const validating = ref(false);
@@ -129,7 +129,7 @@ const editableRecord = computed(() => {
129
129
  })
130
130
 
131
131
  onBeforeMount(() => {
132
- api.clearSaveInterceptors(route.params.resourceId as string);
132
+ clearSaveInterceptors(route.params.resourceId as string);
133
133
  });
134
134
 
135
135
  onMounted(async () => {
@@ -164,7 +164,7 @@ async function saveRecord() {
164
164
  }
165
165
 
166
166
  saving.value = true;
167
- const interceptorsResult = await api.runSaveInterceptors({
167
+ const interceptorsResult = await runSaveInterceptors({
168
168
  action: 'edit',
169
169
  values: record.value,
170
170
  resource: coreStore.resource,
@@ -215,7 +215,7 @@ async function saveRecord() {
215
215
  if (resp.error && resp.error !== 'Operation aborted by hook') {
216
216
  showErrorTost(resp.error);
217
217
  } else {
218
- adminforth.alert({
218
+ alert({
219
219
  message: t('Record updated successfully'),
220
220
  variant: 'success',
221
221
  timeout: 400000
@@ -234,7 +234,7 @@ function scrollToInvalidField() {
234
234
  }
235
235
  }
236
236
  const errorMessage = t('Failed to save. Please fix errors for the following fields:') + '<ul class="mt-2 list-disc list-inside">' + columnsWithErrors.map(c => `<li><strong>${c.column.label || c.column.name}</strong>: ${c.error}</li>`).join('') + '</ul>';
237
- adminforth.alert({
237
+ alert({
238
238
  messageHtml: errorMessage,
239
239
  variant: 'danger'
240
240
  });
@@ -225,10 +225,10 @@ import {
225
225
  } from '@iconify-prerendered/vue-flowbite';
226
226
 
227
227
  import Filters from '@/components/Filters.vue';
228
- import adminforth from '@/adminforth';
228
+ import { useAdminforth } from '@/adminforth';
229
229
 
230
230
  const filtersShow = ref(false);
231
-
231
+ const { confirm, alert, list } = useAdminforth();
232
232
  const coreStore = useCoreStore();
233
233
  const filtersStore = useFiltersStore();
234
234
 
@@ -355,7 +355,7 @@ async function refreshExistingList(pk?: any) {
355
355
  async function startBulkAction(actionId: string) {
356
356
  const action = coreStore.resource?.options?.bulkActions?.find(a => a.id === actionId);
357
357
  if (action?.confirm) {
358
- const confirmed = await adminforth.confirm({
358
+ const confirmed = await confirm({
359
359
  message: action.confirm,
360
360
  });
361
361
  if (!confirmed) {
@@ -380,7 +380,7 @@ async function startBulkAction(actionId: string) {
380
380
  await getList();
381
381
 
382
382
  if (data.successMessage) {
383
- adminforth.alert({
383
+ alert({
384
384
  message: data.successMessage,
385
385
  variant: 'success'
386
386
  });
@@ -464,7 +464,7 @@ async function init() {
464
464
  clearAutoRefresher();
465
465
  if (coreStore.resource!.options?.listRowsAutoRefreshSeconds) {
466
466
  listAutorefresher = setInterval(async () => {
467
- await adminforth.list.silentRefresh();
467
+ await list.silentRefresh();
468
468
  }, coreStore.resource!.options.listRowsAutoRefreshSeconds * 1000);
469
469
  }
470
470
  }
@@ -474,7 +474,7 @@ watch([page, sort, () => filtersStore.filters], async () => {
474
474
  await getList();
475
475
  }, { deep: true });
476
476
 
477
- adminforth.list.refresh = async () => {
477
+ list.refresh = async () => {
478
478
  const result = await getList();
479
479
 
480
480
  if (!result) {
@@ -488,11 +488,11 @@ adminforth.list.refresh = async () => {
488
488
  return {};
489
489
  };
490
490
 
491
- adminforth.list.silentRefresh = async () => {
491
+ list.silentRefresh = async () => {
492
492
  return await refreshExistingList();
493
493
  }
494
494
 
495
- adminforth.list.silentRefreshRow = async (pk: any) => {
495
+ list.silentRefreshRow = async (pk: any) => {
496
496
  return await refreshExistingList(pk);
497
497
  }
498
498