adminforth 2.17.0-next.30 → 2.17.0-next.31

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.
@@ -13,11 +13,13 @@
13
13
  <script setup lang="ts">
14
14
  import { onMounted } from 'vue';
15
15
  import { useI18n } from 'vue-i18n';
16
- import adminforth from '@/adminforth';
16
+ import { useAdminforth } from '@/adminforth';
17
17
  import { AdminForthResourceCommon, AdminUser } from "@/types/Common";
18
18
 
19
19
  const { t } = useI18n();
20
20
 
21
+ const { alert } = useAdminforth();
22
+
21
23
  const props = defineProps<{
22
24
  record: any
23
25
  resource: AdminForthResourceCommon
@@ -30,7 +32,7 @@ onMounted(() => {
30
32
  });
31
33
 
32
34
  function handleClick() {
33
- adminforth.alert({
35
+ alert({
34
36
  message: t('Confirmed'),
35
37
  variant: 'success',
36
38
  });
@@ -13,9 +13,10 @@
13
13
  <script setup lang="ts">
14
14
  import { onMounted } from 'vue';
15
15
  import { useI18n } from 'vue-i18n';
16
- import adminforth from '@/adminforth';
16
+ import { useAdminforth } from '@/adminforth';
17
17
  import { AdminForthResourceCommon, AdminUser } from "@/types/Common";
18
18
 
19
+ const { alert } = useAdminforth();
19
20
  const { t } = useI18n();
20
21
 
21
22
  const props = defineProps<{
@@ -30,7 +31,7 @@ onMounted(() => {
30
31
  });
31
32
 
32
33
  function handleClick() {
33
- adminforth.alert({
34
+ alert({
34
35
  message: t('Confirmed'),
35
36
  variant: 'success',
36
37
  });
@@ -13,11 +13,13 @@
13
13
  <script setup lang="ts">
14
14
  import { onMounted } from 'vue';
15
15
  import { useI18n } from 'vue-i18n';
16
- import adminforth from '@/adminforth';
16
+ import { useAdminforth } from '@/adminforth';
17
17
  import { AdminForthResourceCommon, AdminUser } from "@/types/Common";
18
18
 
19
19
  const { t } = useI18n();
20
20
 
21
+ const { alert } = useAdminforth();
22
+
21
23
  const props = defineProps<{
22
24
  record: any
23
25
  resource: AdminForthResourceCommon
@@ -30,7 +32,7 @@ onMounted(() => {
30
32
  });
31
33
 
32
34
  function handleClick() {
33
- adminforth.alert({
35
+ alert({
34
36
  message: t('Confirmed'),
35
37
  variant: 'success',
36
38
  });
@@ -13,11 +13,13 @@
13
13
  <script setup lang="ts">
14
14
  import { onMounted } from 'vue';
15
15
  import { useI18n } from 'vue-i18n';
16
- import adminforth from '@/adminforth';
16
+ import { useAdminforth } from '@/adminforth';
17
17
  import { AdminForthResourceCommon, AdminUser } from "@/types/Common";
18
18
 
19
19
  const { t } = useI18n();
20
20
 
21
+ const { alert } = useAdminforth();
22
+
21
23
  const props = defineProps<{
22
24
  record: any
23
25
  resource: AdminForthResourceCommon
@@ -30,7 +32,7 @@ onMounted(() => {
30
32
  });
31
33
 
32
34
  function handleClick() {
33
- adminforth.alert({
35
+ alert({
34
36
  message: t('Confirmed'),
35
37
  variant: 'success',
36
38
  });
@@ -12,12 +12,14 @@
12
12
 
13
13
  <script setup lang="ts">
14
14
  import { useI18n } from 'vue-i18n';
15
- import adminforth from '@/adminforth';
15
+ import { useAdminforth} from '@/adminforth';
16
16
  import { onMounted } from 'vue';
17
17
  import { AdminForthResourceCommon, AdminUser } from "@/types/Common";
18
18
 
19
19
  const { t } = useI18n();
20
20
 
21
+ const { alert } = useAdminforth();
22
+
21
23
  const props = defineProps<{
22
24
  record: any
23
25
  resource: AdminForthResourceCommon
@@ -29,7 +31,7 @@ const menuItems = [
29
31
  {
30
32
  label: 'Show Success Alert',
31
33
  action: () => {
32
- adminforth.alert({
34
+ alert({
33
35
  message: t('Success Alert'),
34
36
  variant: 'success',
35
37
  });
@@ -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,
@@ -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
 
@@ -28,7 +28,7 @@ import { useRouter } from 'vue-router';
28
28
  import { useCoreStore } from '@/stores/core';
29
29
  import { getCustomComponent, getIcon } from '@/utils';
30
30
  import { Dropdown } from 'flowbite';
31
- import adminforth from '@/adminforth';
31
+ import { useAdminforth } from '@/adminforth';
32
32
  import { VerticalTabs } from '@/afcl'
33
33
  import { useRoute } from 'vue-router'
34
34
 
@@ -36,6 +36,7 @@ const route = useRoute()
36
36
  const coreStore = useCoreStore();
37
37
  const router = useRouter();
38
38
 
39
+ let { closeUserMenuDropdown } = useAdminforth();
39
40
  const routerIsReady = ref(false);
40
41
  const loginRedirectCheckIsReady = ref(false);
41
42
  const dropdownUserButton = ref<HTMLElement | null>(null);
@@ -58,7 +59,7 @@ watch(dropdownUserButton, (el) => {
58
59
  document.querySelector('#dropdown-user') as HTMLElement,
59
60
  document.querySelector('[data-dropdown-toggle="dropdown-user"]') as HTMLElement,
60
61
  );
61
- adminforth.closeUserMenuDropdown = () => dd.hide();
62
+ closeUserMenuDropdown = () => dd.hide();
62
63
  }
63
64
  });
64
65
 
@@ -144,16 +144,17 @@ import {callAdminForthApi} from '@/utils';
144
144
  import { showSuccesTost, showErrorTost } from '@/composables/useFrontendApi';
145
145
  import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
146
146
  import ShowTable from '@/components/ShowTable.vue';
147
- import adminforth from "@/adminforth";
147
+ import { useAdminforth } from '@/adminforth';
148
148
  import { useI18n } from 'vue-i18n';
149
149
  import { getIcon } from '@/utils';
150
- import { type AdminForthComponentDeclarationFull } from '@/types/Common.js';
150
+ import { type AdminForthComponentDeclarationFull, type AdminForthResourceColumnCommon, type FieldGroup } from '@/types/Common.js';
151
151
  import CallActionWrapper from '@/components/CallActionWrapper.vue'
152
152
 
153
153
  const route = useRoute();
154
154
  const router = useRouter();
155
155
  const loading = ref(true);
156
156
  const { t } = useI18n();
157
+ const { confirm, alert, show } = useAdminforth();
157
158
  const coreStore = useCoreStore();
158
159
 
159
160
  const actionLoadingStates = ref<Record<string, boolean>>({});
@@ -206,7 +207,7 @@ const allColumns = computed(() => {
206
207
 
207
208
  const otherColumns = computed(() => {
208
209
  const groupedColumnNames = new Set(
209
- groups.value.flatMap(group => group.columns.map((col: AdminForthResourceColumnCommon) => col.name))
210
+ groups.value.flatMap(group => group.columns?.map((col: AdminForthResourceColumnCommon) => col.name))
210
211
  );
211
212
 
212
213
  return coreStore.resource?.columns.filter(
@@ -215,7 +216,7 @@ const otherColumns = computed(() => {
215
216
  });
216
217
 
217
218
  async function deleteRecord() {
218
- const data = await adminforth.confirm({
219
+ const data = await confirm({
219
220
  message: t('Are you sure you want to delete this item?'),
220
221
  yes: t('Delete'),
221
222
  no: t('Cancel'),
@@ -282,7 +283,7 @@ async function startCustomAction(actionId: string, extra: any) {
282
283
  });
283
284
 
284
285
  if (data.successMessage) {
285
- adminforth.alert({
286
+ alert({
286
287
  message: data.successMessage,
287
288
  variant: 'success'
288
289
  });
@@ -294,7 +295,7 @@ async function startCustomAction(actionId: string, extra: any) {
294
295
  }
295
296
  }
296
297
 
297
- adminforth.show.refresh = () => {
298
+ show.refresh = () => {
298
299
  (async () => {
299
300
  try {
300
301
  loading.value = true;
@@ -8,9 +8,10 @@ export interface FrontendAPIInterface {
8
8
  * Example:
9
9
  *
10
10
  * ```ts
11
- * import adminforth from '@/adminforth'
11
+ *import { useAdminforth } from '@/adminforth';
12
12
  *
13
- * const isConfirmed = await adminforth.confirm({message: 'Are you sure?', yes: 'Yes', no: 'No'})
13
+ * const { confirm } = useAdminforth();
14
+ * const isConfirmed = await confirm({message: 'Are you sure?', yes: 'Yes', no: 'No'})
14
15
  * if (isConfirmed) {
15
16
  * your code...
16
17
  * }
@@ -28,9 +29,10 @@ export interface FrontendAPIInterface {
28
29
  * Example:
29
30
  *
30
31
  * ```ts
31
- * import adminforth from '@/adminforth'
32
+ * import { useAdminforth } from '@/adminforth';
33
+ * const { alert } = useAdminforth();
32
34
  *
33
- * adminforth.alert({message: 'Hello', variant: 'success'})
35
+ * alert({message: 'Hello', variant: 'success'})
34
36
  * ```
35
37
  *
36
38
  * @param params - The parameters of the alert
@@ -72,13 +74,14 @@ export interface FrontendAPIInterface {
72
74
  * Example:
73
75
  *
74
76
  * ```ts
75
- * import adminforth from '@/adminforth'
77
+ * import { useAdminforth } from '@/adminforth';
76
78
  *
79
+ * const { list } = useAdminforth();
77
80
  * // Regular filter (will show in badge if column.showIn.filter !== false)
78
- * adminforth.list.setFilter({field: 'name', operator: 'ilike', value: 'john'})
81
+ * list.setFilter({field: 'name', operator: 'ilike', value: 'john'})
79
82
  *
80
83
  * // Hidden filter (won't show in badge if column.showIn.filter === false)
81
- * adminforth.list.setFilter({field: 'internal_status', operator: 'eq', value: 'active'})
84
+ * list.setFilter({field: 'internal_status', operator: 'eq', value: 'active'})
82
85
  * ```
83
86
  *
84
87
  * Please note that you can set/update filter even for fields which have showIn.filter=false in resource configuration.
@@ -97,9 +100,9 @@ export interface FrontendAPIInterface {
97
100
  * Example:
98
101
  *
99
102
  * ```ts
100
- * import adminforth from '@/adminforth';
101
- *
102
- * adminforth.list.updateFilter({field: 'name', operator: 'ilike', value: 'john'})
103
+ * import { useAdminforth } from '@/adminforth';
104
+ * const { list } = useAdminforth();
105
+ * list.updateFilter({field: 'name', operator: 'ilike', value: 'john'})
103
106
  * ```
104
107
  *
105
108
  * @param filter - The filter to update
@@ -127,6 +130,25 @@ export interface FrontendAPIInterface {
127
130
  * Close the user menu dropdown
128
131
  */
129
132
  closeUserMenuDropdown(): void;
133
+ /**
134
+ * Run save interceptors for a specific resource or all resources if no resourceId is provided
135
+ */
136
+ runSaveInterceptors(params: {
137
+ action: 'create' | 'edit';
138
+ values: any;
139
+ resource: any;
140
+ resourceId: string;
141
+ }): Promise<{
142
+ ok: boolean;
143
+ error?: string | null;
144
+ extra?: object;
145
+ }>;
146
+ /**
147
+ * Clear save interceptors for a specific resource or all resources if no resourceId is provided
148
+ *
149
+ * @param resourceId - The resource ID to clear interceptors for
150
+ */
151
+ clearSaveInterceptors(resourceId?: string): void;
130
152
  }
131
153
  export type ConfirmParams = {
132
154
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"FrontendAPI.d.ts","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IAEjC;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjD;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,MAAM,EAAC,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAG3D,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;QAE/B;;;;;;;;;;;;;;;;;;;;;;;;WAwBG;QACH,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEtC;;;;;;;;;;;;;;;;WAgBG;QACH,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEzC;;WAEG;QACH,YAAY,IAAI,IAAI,CAAC;KACxB,CAAA;IAED,IAAI,EAAE;QACF;;;WAGG;QACH,OAAO,IAAI,IAAI,CAAC;KACnB,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;IAE/B;;OAEG;IACH,OAAO,CAAC,EAAE;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;CAE3C,CAAA;AAID,oBAAY,YAAY;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd"}
1
+ {"version":3,"file":"FrontendAPI.d.ts","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IAEjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjD;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,MAAM,EAAC,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAG3D,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;QAE/B;;;;;;;;;;;;;;;;;;;;;;;;;WAyBG;QACH,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEtC;;;;;;;;;;;;;;;;WAgBG;QACH,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEzC;;WAEG;QACH,YAAY,IAAI,IAAI,CAAC;KACxB,CAAA;IAED,IAAI,EAAE;QACF;;;WAGG;QACH,OAAO,IAAI,IAAI,CAAC;KACnB,CAAA;IAED,IAAI,EAAE;QACF;;WAEG;QACH,iBAAiB,IAAI,IAAI,CAAC;KAC7B,CAAA;IAED;;OAEG;IACH,qBAAqB,IAAI,IAAI,CAAC;IAE9B;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAC,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KAAE,CAAC,CAAC;IAE5K;;;;OAIG;IACH,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpD;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;IAE/B;;OAEG;IACH,OAAO,CAAC,EAAE;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;CAE3C,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":"AA2LA,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"}
1
+ {"version":3,"file":"FrontendAPI.js","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AA0MA,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "2.17.0-next.30",
3
+ "version": "2.17.0-next.31",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",