adminforth 2.17.0-next.9 → 2.17.0
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/commands/callTsProxy.js +2 -1
- package/commands/createApp/templates/adminuser.ts.hbs +2 -1
- package/commands/createApp/templates/index.ts.hbs +3 -2
- package/commands/createCustomComponent/main.js +0 -3
- package/commands/createCustomComponent/templates/customCrud/afterBreadcrumbs.vue.hbs +4 -2
- package/commands/createCustomComponent/templates/customCrud/beforeActionButtons.vue.hbs +3 -2
- package/commands/createCustomComponent/templates/customCrud/beforeBreadcrumbs.vue.hbs +4 -2
- package/commands/createCustomComponent/templates/customCrud/bottom.vue.hbs +4 -2
- package/commands/createCustomComponent/templates/customCrud/threeDotsDropdownItems.vue.hbs +4 -2
- package/commands/createPlugin/templates/index.ts.hbs +4 -0
- package/dist/auth.d.ts +2 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +17 -10
- package/dist/auth.js.map +1 -1
- package/dist/basePlugin.d.ts +1 -0
- package/dist/basePlugin.d.ts.map +1 -1
- package/dist/basePlugin.js +6 -2
- package/dist/basePlugin.js.map +1 -1
- package/dist/dataConnectors/baseConnector.d.ts +1 -0
- package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
- package/dist/dataConnectors/baseConnector.js +100 -14
- package/dist/dataConnectors/baseConnector.js.map +1 -1
- package/dist/dataConnectors/clickhouse.d.ts +2 -0
- package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
- package/dist/dataConnectors/clickhouse.js +15 -4
- package/dist/dataConnectors/clickhouse.js.map +1 -1
- package/dist/dataConnectors/mongo.d.ts +8 -1
- package/dist/dataConnectors/mongo.d.ts.map +1 -1
- package/dist/dataConnectors/mongo.js +72 -28
- package/dist/dataConnectors/mongo.js.map +1 -1
- package/dist/dataConnectors/mysql.d.ts +2 -0
- package/dist/dataConnectors/mysql.d.ts.map +1 -1
- package/dist/dataConnectors/mysql.js +22 -23
- package/dist/dataConnectors/mysql.js.map +1 -1
- package/dist/dataConnectors/postgres.d.ts +2 -0
- package/dist/dataConnectors/postgres.d.ts.map +1 -1
- package/dist/dataConnectors/postgres.js +23 -26
- package/dist/dataConnectors/postgres.js.map +1 -1
- package/dist/dataConnectors/sqlite.d.ts +2 -0
- package/dist/dataConnectors/sqlite.d.ts.map +1 -1
- package/dist/dataConnectors/sqlite.js +19 -19
- package/dist/dataConnectors/sqlite.js.map +1 -1
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +60 -54
- package/dist/index.js.map +1 -1
- package/dist/modules/codeInjector.d.ts.map +1 -1
- package/dist/modules/codeInjector.js +45 -63
- package/dist/modules/codeInjector.js.map +1 -1
- package/dist/modules/configValidator.d.ts.map +1 -1
- package/dist/modules/configValidator.js +14 -9
- package/dist/modules/configValidator.js.map +1 -1
- package/dist/modules/logger.d.ts +5 -0
- package/dist/modules/logger.d.ts.map +1 -0
- package/dist/modules/logger.js +16 -0
- package/dist/modules/logger.js.map +1 -0
- package/dist/modules/restApi.d.ts.map +1 -1
- package/dist/modules/restApi.js +21 -23
- package/dist/modules/restApi.js.map +1 -1
- package/dist/modules/socketBroker.d.ts.map +1 -1
- package/dist/modules/socketBroker.js +6 -5
- package/dist/modules/socketBroker.js.map +1 -1
- package/dist/modules/styles.js +1 -1
- package/dist/servers/express.d.ts.map +1 -1
- package/dist/servers/express.js +11 -11
- package/dist/servers/express.js.map +1 -1
- package/dist/spa/src/App.vue +6 -3
- package/dist/spa/src/adminforth.ts +60 -1
- package/dist/spa/src/afcl/DatePicker.vue +0 -1
- package/dist/spa/src/afcl/Dropzone.vue +6 -4
- package/dist/spa/src/afcl/Tooltip.vue +38 -4
- package/dist/spa/src/components/ColumnValueInput.vue +14 -1
- package/dist/spa/src/components/CustomDateRangePicker.vue +0 -2
- package/dist/spa/src/components/CustomRangePicker.vue +9 -6
- package/dist/spa/src/components/Filters.vue +4 -4
- package/dist/spa/src/components/ListActionsThreeDots.vue +235 -0
- package/dist/spa/src/components/ResourceForm.vue +4 -4
- package/dist/spa/src/components/ResourceListTable.vue +30 -16
- package/dist/spa/src/components/ResourceListTableVirtual.vue +34 -18
- package/dist/spa/src/components/Sidebar.vue +4 -2
- package/dist/spa/src/components/ThreeDotsMenu.vue +35 -20
- package/dist/spa/src/composables/useFrontendApi.ts +8 -4
- package/dist/spa/src/renderers/CompactField.vue +3 -2
- package/dist/spa/src/renderers/CompactUUID.vue +3 -2
- package/dist/spa/src/stores/core.ts +3 -2
- package/dist/spa/src/types/Back.ts +33 -10
- package/dist/spa/src/types/Common.ts +7 -14
- package/dist/spa/src/types/FrontendAPI.ts +25 -10
- package/dist/spa/src/views/CreateView.vue +23 -31
- package/dist/spa/src/views/EditView.vue +23 -31
- package/dist/spa/src/views/ListView.vue +20 -10
- package/dist/spa/src/views/SettingsView.vue +3 -2
- package/dist/spa/src/views/ShowView.vue +7 -6
- package/dist/types/Back.d.ts +26 -4
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Back.js +6 -0
- package/dist/types/Back.js.map +1 -1
- package/dist/types/Common.d.ts +8 -15
- package/dist/types/Common.d.ts.map +1 -1
- package/dist/types/Common.js +2 -0
- package/dist/types/Common.js.map +1 -1
- package/dist/types/FrontendAPI.d.ts +32 -10
- package/dist/types/FrontendAPI.d.ts.map +1 -1
- package/dist/types/FrontendAPI.js.map +1 -1
- package/package.json +4 -1
- package/commands/createCustomComponent/templates/customCrud/saveButton.vue.hbs +0 -28
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Express, Request } from 'express';
|
|
2
2
|
import type { Writable } from 'stream';
|
|
3
3
|
|
|
4
|
-
import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections, AllowedActionsEnum,
|
|
4
|
+
import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections, AllowedActionsEnum, AdminForthResourcePages,
|
|
5
5
|
type AdminForthComponentDeclaration,
|
|
6
6
|
type AdminForthResourceCommon,
|
|
7
7
|
type AdminUser, type AllowedActionsResolved,
|
|
@@ -12,7 +12,6 @@ import { ActionCheckSource, AdminForthFilterOperators, AdminForthSortDirections,
|
|
|
12
12
|
type AdminForthComponentDeclarationFull,
|
|
13
13
|
type AdminForthConfigMenuItem,
|
|
14
14
|
type AnnouncementBadgeResponse,
|
|
15
|
-
AdminForthResourcePages,
|
|
16
15
|
type AdminForthResourceColumnInputCommon,
|
|
17
16
|
} from './Common.js';
|
|
18
17
|
|
|
@@ -129,7 +128,7 @@ export interface IAdminForthSingleFilter {
|
|
|
129
128
|
operator?: AdminForthFilterOperators.EQ | AdminForthFilterOperators.NE
|
|
130
129
|
| AdminForthFilterOperators.GT | AdminForthFilterOperators.LT | AdminForthFilterOperators.GTE
|
|
131
130
|
| AdminForthFilterOperators.LTE | AdminForthFilterOperators.LIKE | AdminForthFilterOperators.ILIKE
|
|
132
|
-
| AdminForthFilterOperators.IN | AdminForthFilterOperators.NIN;
|
|
131
|
+
| AdminForthFilterOperators.IN | AdminForthFilterOperators.NIN | AdminForthFilterOperators.IS_EMPTY | AdminForthFilterOperators.IS_NOT_EMPTY;
|
|
133
132
|
value?: any;
|
|
134
133
|
rightField?: string;
|
|
135
134
|
insecureRawSQL?: string;
|
|
@@ -307,7 +306,7 @@ export interface IAdminForthAuth {
|
|
|
307
306
|
|
|
308
307
|
removeCustomCookie({response, name}: {response: any, name: string}): void;
|
|
309
308
|
|
|
310
|
-
setCustomCookie({response, payload}: {response: any, payload: {name: string, value: string, expiry
|
|
309
|
+
setCustomCookie({response, payload}: {response: any, payload: {name: string, value: string, expiry?: number, expirySeconds: number, httpOnly: boolean}}): void;
|
|
311
310
|
|
|
312
311
|
getCustomCookie({cookies, name}: {cookies: {key: string, value: string}[], name: string}): string | null;
|
|
313
312
|
|
|
@@ -360,16 +359,16 @@ export interface IAdminForth {
|
|
|
360
359
|
tr(msg: string, category: string, lang: string, params: any, pluralizationNumber?: number): Promise<string>;
|
|
361
360
|
|
|
362
361
|
createResourceRecord(
|
|
363
|
-
params: { resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
|
|
362
|
+
params: { resource: AdminForthResource, record: any, response: IAdminForthHttpResponse, adminUser: AdminUser, extra?: HttpExtra }
|
|
364
363
|
): Promise<{ error?: string, createdRecord?: any, newRecordId?: any }>;
|
|
365
364
|
|
|
366
365
|
updateResourceRecord(
|
|
367
|
-
params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra, updates?: never }
|
|
368
|
-
| { 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 }
|
|
369
368
|
): Promise<{ error?: string }>;
|
|
370
369
|
|
|
371
370
|
deleteResourceRecord(
|
|
372
|
-
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 }
|
|
373
372
|
): Promise<{ error?: string }>;
|
|
374
373
|
|
|
375
374
|
auth: IAdminForthAuth;
|
|
@@ -469,6 +468,13 @@ export interface IAdminForthPlugin {
|
|
|
469
468
|
instanceUniqueRepresentation(pluginOptions: any) : string;
|
|
470
469
|
|
|
471
470
|
|
|
471
|
+
/**
|
|
472
|
+
* If this method returns true, AdminForth will allow only one instance of plugin per whole app
|
|
473
|
+
* (only for case when we are creating copy of resource and activating plugins)
|
|
474
|
+
* If false, multiple instances of plugin can be installed on different resources.
|
|
475
|
+
*/
|
|
476
|
+
shouldHaveSingleInstancePerWholeApp?(): boolean;
|
|
477
|
+
|
|
472
478
|
/**
|
|
473
479
|
* Optional method which will be called after AdminForth discovers all resources and their columns.
|
|
474
480
|
* Can be used to validate types of columns, check if some columns are missing, etc.
|
|
@@ -539,6 +545,7 @@ export type BeforeDeleteSaveFunction = (params: {
|
|
|
539
545
|
adminUser: AdminUser,
|
|
540
546
|
record: any,
|
|
541
547
|
adminforth: IAdminForth,
|
|
548
|
+
response: IAdminForthHttpResponse,
|
|
542
549
|
extra?: HttpExtra,
|
|
543
550
|
}) => Promise<{ok: boolean, error?: string}>;
|
|
544
551
|
|
|
@@ -551,6 +558,7 @@ export type BeforeEditSaveFunction = (params: {
|
|
|
551
558
|
record: any, // legacy, 'updates' should be used instead
|
|
552
559
|
oldRecord: any,
|
|
553
560
|
adminforth: IAdminForth,
|
|
561
|
+
response: IAdminForthHttpResponse,
|
|
554
562
|
extra?: HttpExtra,
|
|
555
563
|
}) => Promise<{ok: boolean, error?: string | null}>;
|
|
556
564
|
|
|
@@ -561,6 +569,7 @@ export type BeforeCreateSaveFunction = (params: {
|
|
|
561
569
|
adminUser: AdminUser,
|
|
562
570
|
record: any,
|
|
563
571
|
adminforth: IAdminForth,
|
|
572
|
+
response: IAdminForthHttpResponse,
|
|
564
573
|
extra?: HttpExtra,
|
|
565
574
|
}) => Promise<{ok: boolean, error?: string | null, newRecordId?: string}>;
|
|
566
575
|
|
|
@@ -571,6 +580,7 @@ export type AfterCreateSaveFunction = (params: {
|
|
|
571
580
|
record: any,
|
|
572
581
|
adminforth: IAdminForth,
|
|
573
582
|
recordWithVirtualColumns?: any,
|
|
583
|
+
response: IAdminForthHttpResponse,
|
|
574
584
|
extra?: HttpExtra,
|
|
575
585
|
}) => Promise<{ok: boolean, error?: string}>;
|
|
576
586
|
|
|
@@ -584,6 +594,7 @@ export type AfterDeleteSaveFunction = (params: {
|
|
|
584
594
|
adminUser: AdminUser,
|
|
585
595
|
record: any,
|
|
586
596
|
adminforth: IAdminForth,
|
|
597
|
+
response: IAdminForthHttpResponse,
|
|
587
598
|
extra?: HttpExtra,
|
|
588
599
|
}) => Promise<{ok: boolean, error?: string}>;
|
|
589
600
|
|
|
@@ -596,6 +607,7 @@ export type AfterEditSaveFunction = (params: {
|
|
|
596
607
|
record: any, // legacy, 'updates' should be used instead
|
|
597
608
|
oldRecord: any,
|
|
598
609
|
adminforth: IAdminForth,
|
|
610
|
+
response: IAdminForthHttpResponse,
|
|
599
611
|
extra?: HttpExtra,
|
|
600
612
|
}) => Promise<{ok: boolean, error?: string}>;
|
|
601
613
|
|
|
@@ -848,6 +860,7 @@ export interface AdminForthActionInput {
|
|
|
848
860
|
name: string;
|
|
849
861
|
showIn?: {
|
|
850
862
|
list?: boolean,
|
|
863
|
+
listThreeDotsMenu?: boolean,
|
|
851
864
|
showButton?: boolean,
|
|
852
865
|
showThreeDotsMenu?: boolean,
|
|
853
866
|
};
|
|
@@ -861,6 +874,7 @@ export interface AdminForthActionInput {
|
|
|
861
874
|
resource: AdminForthResource;
|
|
862
875
|
recordId: string;
|
|
863
876
|
adminUser: AdminUser;
|
|
877
|
+
response: IAdminForthHttpResponse;
|
|
864
878
|
extra?: HttpExtra;
|
|
865
879
|
tr: Function;
|
|
866
880
|
}) => Promise<{
|
|
@@ -1282,6 +1296,14 @@ export class Filters {
|
|
|
1282
1296
|
subFilters,
|
|
1283
1297
|
};
|
|
1284
1298
|
}
|
|
1299
|
+
|
|
1300
|
+
static IS_EMPTY(field: string): IAdminForthSingleFilter {
|
|
1301
|
+
return { field, operator: AdminForthFilterOperators.IS_EMPTY, value: null };
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
static IS_NOT_EMPTY(field: string): IAdminForthSingleFilter {
|
|
1305
|
+
return { field, operator: AdminForthFilterOperators.IS_NOT_EMPTY, value: null };
|
|
1306
|
+
}
|
|
1285
1307
|
}
|
|
1286
1308
|
|
|
1287
1309
|
export type FDataSort = (field: string, direction: AdminForthSortDirections) => IAdminForthSort;
|
|
@@ -1358,6 +1380,7 @@ export type AllowedActions = {
|
|
|
1358
1380
|
*/
|
|
1359
1381
|
export interface ResourceOptionsInput extends Omit<NonNullable<AdminForthResourceInputCommon['options']>, 'allowedActions' | 'bulkActions'> {
|
|
1360
1382
|
|
|
1383
|
+
baseActionsAsQuickIcons?: ('show' | 'edit' | 'delete')[],
|
|
1361
1384
|
/**
|
|
1362
1385
|
* Custom bulk actions list. Bulk actions available in list view when user selects multiple records by
|
|
1363
1386
|
* using checkboxes.
|
|
@@ -1526,8 +1549,8 @@ export interface AdminForthBulkAction extends AdminForthBulkActionCommon {
|
|
|
1526
1549
|
* Callback which will be called on backend when user clicks on action button.
|
|
1527
1550
|
* It should return Promise which will be resolved when action is done.
|
|
1528
1551
|
*/
|
|
1529
|
-
action: ({ resource, selectedIds, adminUser, tr }: {
|
|
1530
|
-
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
|
|
1531
1554
|
}) => Promise<{ ok: boolean, error?: string, successMessage?: string }>,
|
|
1532
1555
|
|
|
1533
1556
|
/**
|
|
@@ -28,6 +28,8 @@ export enum AdminForthFilterOperators {
|
|
|
28
28
|
NIN = 'nin',
|
|
29
29
|
AND = 'and',
|
|
30
30
|
OR = 'or',
|
|
31
|
+
IS_EMPTY = 'isEmpty',
|
|
32
|
+
IS_NOT_EMPTY = 'isNotEmpty',
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
export type FilterParams = {
|
|
@@ -294,7 +296,7 @@ export interface AdminForthComponentDeclarationFull {
|
|
|
294
296
|
[key: string]: any,
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
|
-
import { type AdminForthActionInput } from './Back.js'
|
|
299
|
+
import { type AdminForthActionInput, type AdminForthResource } from './Back.js'
|
|
298
300
|
export { type AdminForthActionInput } from './Back.js'
|
|
299
301
|
|
|
300
302
|
export type AdminForthComponentDeclaration = AdminForthComponentDeclarationFull | string;
|
|
@@ -445,7 +447,7 @@ export interface AdminForthResourceInputCommon {
|
|
|
445
447
|
* If you wish to open page in new tab, add `target=_blank` get param to returned URL, example:
|
|
446
448
|
*
|
|
447
449
|
* ```ts
|
|
448
|
-
* listTableClickUrl: async (record, adminUser) => {
|
|
450
|
+
* listTableClickUrl: async (record, adminUser, resource) => {
|
|
449
451
|
* return `https://google.com/search?q=${record.name}&target=_blank`;
|
|
450
452
|
* }
|
|
451
453
|
* ```
|
|
@@ -455,7 +457,7 @@ export interface AdminForthResourceInputCommon {
|
|
|
455
457
|
* Example:
|
|
456
458
|
*
|
|
457
459
|
* ```ts
|
|
458
|
-
* listTableClickUrl: async (record, adminUser) => {
|
|
460
|
+
* listTableClickUrl: async (record, adminUser, resource) => {
|
|
459
461
|
* return null;
|
|
460
462
|
* }
|
|
461
463
|
* ```
|
|
@@ -464,7 +466,7 @@ export interface AdminForthResourceInputCommon {
|
|
|
464
466
|
* @param adminUser - user who clicked
|
|
465
467
|
* @returns
|
|
466
468
|
*/
|
|
467
|
-
listTableClickUrl?: (record: any, adminUser: AdminUser) => Promise<string | null>,
|
|
469
|
+
listTableClickUrl?: (record: any, adminUser: AdminUser, resource: AdminForthResource) => Promise<string | null>,
|
|
468
470
|
|
|
469
471
|
/**
|
|
470
472
|
* Whether to refresh existing list rows automatically every N seconds.
|
|
@@ -503,6 +505,7 @@ export interface AdminForthResourceInputCommon {
|
|
|
503
505
|
bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
504
506
|
threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
505
507
|
customActionIcons?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
508
|
+
customActionIconsThreeDotsMenuItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
506
509
|
tableBodyStart?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
507
510
|
tableRowReplace?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
508
511
|
},
|
|
@@ -529,11 +532,6 @@ export interface AdminForthResourceInputCommon {
|
|
|
529
532
|
afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
530
533
|
bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
531
534
|
threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
532
|
-
/**
|
|
533
|
-
* Custom Save button component for Edit page.
|
|
534
|
-
* Accepts props: [record, resource, adminUser, meta, saving, validating, isValid, disabled, saveRecord]
|
|
535
|
-
*/
|
|
536
|
-
saveButton?: AdminForthComponentDeclaration,
|
|
537
535
|
},
|
|
538
536
|
|
|
539
537
|
/**
|
|
@@ -546,11 +544,6 @@ export interface AdminForthResourceInputCommon {
|
|
|
546
544
|
afterBreadcrumbs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
547
545
|
bottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
548
546
|
threeDotsDropdownItems?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
|
|
549
|
-
/**
|
|
550
|
-
* Custom Save button component for Create page.
|
|
551
|
-
* Accepts props: [record, resource, adminUser, meta, saving, validating, isValid, disabled, saveRecord]
|
|
552
|
-
*/
|
|
553
|
-
saveButton?: AdminForthComponentDeclaration,
|
|
554
547
|
},
|
|
555
548
|
}
|
|
556
549
|
},
|
|
@@ -10,9 +10,10 @@ export interface FrontendAPIInterface {
|
|
|
10
10
|
* Example:
|
|
11
11
|
*
|
|
12
12
|
* ```ts
|
|
13
|
-
*
|
|
13
|
+
*import { useAdminforth } from '@/adminforth';
|
|
14
14
|
*
|
|
15
|
-
* const
|
|
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
|
|
35
|
+
* import { useAdminforth } from '@/adminforth';
|
|
36
|
+
* const { alert } = useAdminforth();
|
|
35
37
|
*
|
|
36
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
106
|
-
*
|
|
107
|
-
*
|
|
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 = {
|
|
@@ -17,25 +17,7 @@
|
|
|
17
17
|
>
|
|
18
18
|
{{ $t('Cancel') }}
|
|
19
19
|
</button>
|
|
20
|
-
|
|
21
|
-
<!-- Custom Save Button injection -->
|
|
22
|
-
<component
|
|
23
|
-
v-if="createSaveButtonInjection"
|
|
24
|
-
:is="getCustomComponent(createSaveButtonInjection)"
|
|
25
|
-
:meta="createSaveButtonInjection.meta"
|
|
26
|
-
:record="record"
|
|
27
|
-
:resource="coreStore.resource"
|
|
28
|
-
:adminUser="coreStore.adminUser"
|
|
29
|
-
:saving="saving"
|
|
30
|
-
:validating="validating"
|
|
31
|
-
:isValid="isValid"
|
|
32
|
-
:disabled="saving || (validating && !isValid)"
|
|
33
|
-
:saveRecord="saveRecord"
|
|
34
|
-
/>
|
|
35
|
-
|
|
36
|
-
<!-- Default Save Button fallback -->
|
|
37
20
|
<button
|
|
38
|
-
v-else
|
|
39
21
|
@click="() => saveRecord()"
|
|
40
22
|
class="af-save-button flex items-center py-1 px-3 text-sm font-medium rounded-default text-lightCreateViewSaveButtonText focus:outline-none bg-lightCreateViewButtonBackground rounded border border-lightCreateViewButtonBorder hover:bg-lightCreateViewButtonBackgroundHover hover:text-lightCreateViewSaveButtonTextHover focus:z-10 focus:ring-4 focus:ring-lightCreateViewButtonFocusRing dark:focus:ring-darkCreateViewButtonFocusRing dark:bg-darkCreateViewButtonBackground dark:text-darkCreateViewSaveButtonText dark:border-darkCreateViewButtonBorder dark:hover:text-darkCreateViewSaveButtonTextHover dark:hover:bg-darkCreateViewButtonBackgroundHover disabled:opacity-50 gap-1"
|
|
41
23
|
:disabled="saving || (validating && !isValid)"
|
|
@@ -99,12 +81,12 @@ import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
|
99
81
|
import { useCoreStore } from '@/stores/core';
|
|
100
82
|
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown, checkShowIf } from '@/utils';
|
|
101
83
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
102
|
-
import { onMounted, ref, watch, nextTick } from 'vue';
|
|
84
|
+
import { onMounted, onBeforeMount, ref, watch, nextTick } from 'vue';
|
|
103
85
|
import { useRoute, useRouter } from 'vue-router';
|
|
104
86
|
import { computed } from 'vue';
|
|
105
87
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
106
88
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
107
|
-
import
|
|
89
|
+
import { useAdminforth } from '@/adminforth';
|
|
108
90
|
import { useI18n } from 'vue-i18n';
|
|
109
91
|
import { type AdminForthComponentDeclarationFull } from '@/types/Common.js';
|
|
110
92
|
import type { AdminForthResourceColumn } from '@/types/Back';
|
|
@@ -121,18 +103,12 @@ const router = useRouter();
|
|
|
121
103
|
const record = ref({});
|
|
122
104
|
|
|
123
105
|
const coreStore = useCoreStore();
|
|
106
|
+
const { clearSaveInterceptors, runSaveInterceptors, alert } = useAdminforth();
|
|
124
107
|
|
|
125
108
|
const { t } = useI18n();
|
|
126
109
|
|
|
127
110
|
const resourceFormRef = ref<InstanceType<typeof ResourceForm> | null>(null);
|
|
128
111
|
|
|
129
|
-
const createSaveButtonInjection = computed<AdminForthComponentDeclarationFull | null>(() => {
|
|
130
|
-
const raw: any = coreStore.resourceOptions?.pageInjections?.create?.saveButton as any;
|
|
131
|
-
if (!raw) return null;
|
|
132
|
-
const item = Array.isArray(raw) ? raw[0] : raw;
|
|
133
|
-
return item as AdminForthComponentDeclarationFull;
|
|
134
|
-
});
|
|
135
|
-
|
|
136
112
|
const initialValues = ref({});
|
|
137
113
|
|
|
138
114
|
const readonlyColumns = ref([]);
|
|
@@ -142,6 +118,10 @@ async function onUpdateRecord(newRecord: any) {
|
|
|
142
118
|
record.value = newRecord;
|
|
143
119
|
}
|
|
144
120
|
|
|
121
|
+
onBeforeMount(() => {
|
|
122
|
+
clearSaveInterceptors(route.params.resourceId as string);
|
|
123
|
+
});
|
|
124
|
+
|
|
145
125
|
onMounted(async () => {
|
|
146
126
|
loading.value = true;
|
|
147
127
|
await coreStore.fetchResourceFull({
|
|
@@ -182,7 +162,7 @@ onMounted(async () => {
|
|
|
182
162
|
initThreeDotsDropdown();
|
|
183
163
|
});
|
|
184
164
|
|
|
185
|
-
async function saveRecord(
|
|
165
|
+
async function saveRecord() {
|
|
186
166
|
if (!isValid.value) {
|
|
187
167
|
validating.value = true;
|
|
188
168
|
await nextTick();
|
|
@@ -194,6 +174,18 @@ async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
|
194
174
|
const requiredColumns = coreStore.resource?.columns.filter(c => c.required?.create === true) || [];
|
|
195
175
|
const requiredColumnsToSkip = requiredColumns.filter(c => checkShowIf(c, record.value, coreStore.resource?.columns || []) === false);
|
|
196
176
|
saving.value = true;
|
|
177
|
+
const interceptorsResult = await runSaveInterceptors({
|
|
178
|
+
action: 'create',
|
|
179
|
+
values: record.value,
|
|
180
|
+
resource: coreStore.resource,
|
|
181
|
+
resourceId: route.params.resourceId as string,
|
|
182
|
+
});
|
|
183
|
+
if (!interceptorsResult.ok) {
|
|
184
|
+
saving.value = false;
|
|
185
|
+
if (interceptorsResult.error) showErrorTost(interceptorsResult.error);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const interceptorConfirmationResult = (interceptorsResult.extra as Record<string, any>)?.confirmationResult;
|
|
197
189
|
const response = await callAdminForthApi({
|
|
198
190
|
method: 'POST',
|
|
199
191
|
path: `/create_record`,
|
|
@@ -202,7 +194,7 @@ async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
|
202
194
|
record: record.value,
|
|
203
195
|
requiredColumnsToSkip,
|
|
204
196
|
meta: {
|
|
205
|
-
...(
|
|
197
|
+
...(interceptorConfirmationResult ? { confirmationResult: interceptorConfirmationResult } : {}),
|
|
206
198
|
},
|
|
207
199
|
},
|
|
208
200
|
});
|
|
@@ -220,7 +212,7 @@ async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
|
220
212
|
primaryKey: response.newRecordId
|
|
221
213
|
}
|
|
222
214
|
});
|
|
223
|
-
|
|
215
|
+
alert({
|
|
224
216
|
message: t('Record created successfully!'),
|
|
225
217
|
variant: 'success'
|
|
226
218
|
});
|
|
@@ -236,7 +228,7 @@ function scrollToInvalidField() {
|
|
|
236
228
|
}
|
|
237
229
|
}
|
|
238
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>';
|
|
239
|
-
|
|
231
|
+
alert({
|
|
240
232
|
messageHtml: errorMessage,
|
|
241
233
|
variant: 'danger'
|
|
242
234
|
});
|
|
@@ -16,25 +16,7 @@
|
|
|
16
16
|
>
|
|
17
17
|
{{ $t('Cancel') }}
|
|
18
18
|
</button>
|
|
19
|
-
|
|
20
|
-
<!-- Custom Save Button injection -->
|
|
21
|
-
<component
|
|
22
|
-
v-if="editSaveButtonInjection"
|
|
23
|
-
:is="getCustomComponent(editSaveButtonInjection)"
|
|
24
|
-
:meta="editSaveButtonInjection.meta"
|
|
25
|
-
:record="editableRecord"
|
|
26
|
-
:resource="coreStore.resource"
|
|
27
|
-
:adminUser="coreStore.adminUser"
|
|
28
|
-
:saving="saving"
|
|
29
|
-
:validating="validating"
|
|
30
|
-
:isValid="isValid"
|
|
31
|
-
:disabled="saving || (validating && !isValid)"
|
|
32
|
-
:saveRecord="saveRecord"
|
|
33
|
-
/>
|
|
34
|
-
|
|
35
|
-
<!-- Default Save Button fallback -->
|
|
36
19
|
<button
|
|
37
|
-
v-else
|
|
38
20
|
@click="() => saveRecord()"
|
|
39
21
|
class="flex items-center py-1 px-3 text-sm font-medium rounded-default text-lightEditViewSaveButtonText focus:outline-none bg-lightEditViewButtonBackground rounded border border-lightEditViewButtonBorder hover:bg-lightEditViewButtonBackgroundHover hover:text-lightEditViewSaveButtonTextHover focus:z-10 focus:ring-4 focus:ring-lightEditViewButtonFocusRing dark:focus:ring-darkEditViewButtonFocusRing dark:bg-darkEditViewButtonBackground dark:text-darkEditViewSaveButtonText dark:border-darkEditViewButtonBorder dark:hover:text-darkEditViewSaveButtonTextHover dark:hover:bg-darkEditViewButtonBackgroundHover disabled:opacity-50 gap-1"
|
|
40
22
|
:disabled="saving || (validating && !isValid)"
|
|
@@ -94,17 +76,18 @@ import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
|
94
76
|
import { useCoreStore } from '@/stores/core';
|
|
95
77
|
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown } from '@/utils';
|
|
96
78
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
97
|
-
import { computed, onMounted, ref, type Ref, nextTick, watch } from 'vue';
|
|
79
|
+
import { computed, onMounted, onBeforeMount, ref, type Ref, nextTick, watch } from 'vue';
|
|
98
80
|
import { useRoute, useRouter } from 'vue-router';
|
|
99
81
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
100
82
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
101
|
-
import
|
|
83
|
+
import { useAdminforth } from '@/adminforth';
|
|
102
84
|
import { useI18n } from 'vue-i18n';
|
|
103
85
|
import { type AdminForthComponentDeclarationFull } from '@/types/Common.js';
|
|
104
86
|
import type { AdminForthResourceColumn } from '@/types/Back';
|
|
105
87
|
|
|
106
88
|
const { t } = useI18n();
|
|
107
89
|
const coreStore = useCoreStore();
|
|
90
|
+
const { clearSaveInterceptors, runSaveInterceptors, alert } = useAdminforth();
|
|
108
91
|
|
|
109
92
|
const isValid = ref(false);
|
|
110
93
|
const validating = ref(false);
|
|
@@ -124,13 +107,6 @@ watch(record, (newVal) => {
|
|
|
124
107
|
|
|
125
108
|
const resourceFormRef = ref<InstanceType<typeof ResourceForm> | null>(null);
|
|
126
109
|
|
|
127
|
-
const editSaveButtonInjection = computed<AdminForthComponentDeclarationFull | null>(() => {
|
|
128
|
-
const raw: any = coreStore.resourceOptions?.pageInjections?.edit?.saveButton as any;
|
|
129
|
-
if (!raw) return null;
|
|
130
|
-
const item = Array.isArray(raw) ? raw[0] : raw;
|
|
131
|
-
return item as AdminForthComponentDeclarationFull;
|
|
132
|
-
});
|
|
133
|
-
|
|
134
110
|
async function onUpdateRecord(newRecord: Record<string, any>) {
|
|
135
111
|
record.value = newRecord;
|
|
136
112
|
}
|
|
@@ -152,6 +128,10 @@ const editableRecord = computed(() => {
|
|
|
152
128
|
return newRecord;
|
|
153
129
|
})
|
|
154
130
|
|
|
131
|
+
onBeforeMount(() => {
|
|
132
|
+
clearSaveInterceptors(route.params.resourceId as string);
|
|
133
|
+
});
|
|
134
|
+
|
|
155
135
|
onMounted(async () => {
|
|
156
136
|
loading.value = true;
|
|
157
137
|
|
|
@@ -173,7 +153,7 @@ onMounted(async () => {
|
|
|
173
153
|
loading.value = false;
|
|
174
154
|
});
|
|
175
155
|
|
|
176
|
-
async function saveRecord(
|
|
156
|
+
async function saveRecord() {
|
|
177
157
|
if (!isValid.value) {
|
|
178
158
|
validating.value = true;
|
|
179
159
|
await nextTick();
|
|
@@ -184,6 +164,18 @@ async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
|
184
164
|
}
|
|
185
165
|
|
|
186
166
|
saving.value = true;
|
|
167
|
+
const interceptorsResult = await runSaveInterceptors({
|
|
168
|
+
action: 'edit',
|
|
169
|
+
values: record.value,
|
|
170
|
+
resource: coreStore.resource,
|
|
171
|
+
resourceId: route.params.resourceId as string,
|
|
172
|
+
});
|
|
173
|
+
if (!interceptorsResult.ok) {
|
|
174
|
+
saving.value = false;
|
|
175
|
+
if (interceptorsResult.error) showErrorTost(interceptorsResult.error);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const interceptorConfirmationResult = interceptorsResult.extra?.confirmationResult;
|
|
187
179
|
const updates: Record<string, any> = {};
|
|
188
180
|
for (const key in record.value) {
|
|
189
181
|
let columnIsUpdated = false;
|
|
@@ -216,14 +208,14 @@ async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
|
216
208
|
recordId: route.params.primaryKey,
|
|
217
209
|
record: updates,
|
|
218
210
|
meta: {
|
|
219
|
-
...(
|
|
211
|
+
...(interceptorConfirmationResult ? { confirmationResult: interceptorConfirmationResult } : {}),
|
|
220
212
|
},
|
|
221
213
|
},
|
|
222
214
|
});
|
|
223
215
|
if (resp.error && resp.error !== 'Operation aborted by hook') {
|
|
224
216
|
showErrorTost(resp.error);
|
|
225
217
|
} else {
|
|
226
|
-
|
|
218
|
+
alert({
|
|
227
219
|
message: t('Record updated successfully'),
|
|
228
220
|
variant: 'success',
|
|
229
221
|
timeout: 400000
|
|
@@ -242,7 +234,7 @@ function scrollToInvalidField() {
|
|
|
242
234
|
}
|
|
243
235
|
}
|
|
244
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>';
|
|
245
|
-
|
|
237
|
+
alert({
|
|
246
238
|
messageHtml: errorMessage,
|
|
247
239
|
variant: 'danger'
|
|
248
240
|
});
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
:adminUser="coreStore.adminUser"
|
|
120
120
|
/>
|
|
121
121
|
<ResourceListTableVirtual
|
|
122
|
-
v-if="isVirtualScrollEnabled"
|
|
122
|
+
v-if="isVirtualScrollEnabled && !coreStore.isResourceFetching"
|
|
123
123
|
:resource="coreStore.resource"
|
|
124
124
|
:rows="rows"
|
|
125
125
|
:page="page"
|
|
@@ -143,6 +143,11 @@
|
|
|
143
143
|
? [coreStore.resourceOptions.pageInjections.list.tableBodyStart]
|
|
144
144
|
: []
|
|
145
145
|
"
|
|
146
|
+
:customActionIconsThreeDotsMenuItems="Array.isArray(coreStore.resourceOptions?.pageInjections?.list?.customActionIconsThreeDotsMenuItems)
|
|
147
|
+
? coreStore.resourceOptions.pageInjections.list.customActionIconsThreeDotsMenuItems
|
|
148
|
+
: coreStore.resourceOptions?.pageInjections?.list?.customActionIconsThreeDotsMenuItems
|
|
149
|
+
? [coreStore.resourceOptions.pageInjections.list.customActionIconsThreeDotsMenuItems]
|
|
150
|
+
: []"
|
|
146
151
|
:tableRowReplaceInjection="Array.isArray(coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace)
|
|
147
152
|
? coreStore.resourceOptions.pageInjections.list.tableRowReplace[0]
|
|
148
153
|
: coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace || undefined"
|
|
@@ -152,7 +157,7 @@
|
|
|
152
157
|
/>
|
|
153
158
|
|
|
154
159
|
<ResourceListTable
|
|
155
|
-
v-else
|
|
160
|
+
v-else-if="!coreStore.isResourceFetching"
|
|
156
161
|
:resource="coreStore.resource"
|
|
157
162
|
:rows="rows"
|
|
158
163
|
:page="page"
|
|
@@ -176,6 +181,11 @@
|
|
|
176
181
|
? [coreStore.resourceOptions.pageInjections.list.tableBodyStart]
|
|
177
182
|
: []
|
|
178
183
|
"
|
|
184
|
+
:customActionIconsThreeDotsMenuItems="Array.isArray(coreStore.resourceOptions?.pageInjections?.list?.customActionIconsThreeDotsMenuItems)
|
|
185
|
+
? coreStore.resourceOptions.pageInjections.list.customActionIconsThreeDotsMenuItems
|
|
186
|
+
: coreStore.resourceOptions?.pageInjections?.list?.customActionIconsThreeDotsMenuItems
|
|
187
|
+
? [coreStore.resourceOptions.pageInjections.list.customActionIconsThreeDotsMenuItems]
|
|
188
|
+
: []"
|
|
179
189
|
:tableRowReplaceInjection="Array.isArray(coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace)
|
|
180
190
|
? coreStore.resourceOptions.pageInjections.list.tableRowReplace[0]
|
|
181
191
|
: coreStore.resourceOptions?.pageInjections?.list?.tableRowReplace || undefined"
|
|
@@ -215,10 +225,10 @@ import {
|
|
|
215
225
|
} from '@iconify-prerendered/vue-flowbite';
|
|
216
226
|
|
|
217
227
|
import Filters from '@/components/Filters.vue';
|
|
218
|
-
import
|
|
228
|
+
import { useAdminforth } from '@/adminforth';
|
|
219
229
|
|
|
220
230
|
const filtersShow = ref(false);
|
|
221
|
-
|
|
231
|
+
const { confirm, alert, list } = useAdminforth();
|
|
222
232
|
const coreStore = useCoreStore();
|
|
223
233
|
const filtersStore = useFiltersStore();
|
|
224
234
|
|
|
@@ -345,7 +355,7 @@ async function refreshExistingList(pk?: any) {
|
|
|
345
355
|
async function startBulkAction(actionId: string) {
|
|
346
356
|
const action = coreStore.resource?.options?.bulkActions?.find(a => a.id === actionId);
|
|
347
357
|
if (action?.confirm) {
|
|
348
|
-
const confirmed = await
|
|
358
|
+
const confirmed = await confirm({
|
|
349
359
|
message: action.confirm,
|
|
350
360
|
});
|
|
351
361
|
if (!confirmed) {
|
|
@@ -370,7 +380,7 @@ async function startBulkAction(actionId: string) {
|
|
|
370
380
|
await getList();
|
|
371
381
|
|
|
372
382
|
if (data.successMessage) {
|
|
373
|
-
|
|
383
|
+
alert({
|
|
374
384
|
message: data.successMessage,
|
|
375
385
|
variant: 'success'
|
|
376
386
|
});
|
|
@@ -454,7 +464,7 @@ async function init() {
|
|
|
454
464
|
clearAutoRefresher();
|
|
455
465
|
if (coreStore.resource!.options?.listRowsAutoRefreshSeconds) {
|
|
456
466
|
listAutorefresher = setInterval(async () => {
|
|
457
|
-
await
|
|
467
|
+
await list.silentRefresh();
|
|
458
468
|
}, coreStore.resource!.options.listRowsAutoRefreshSeconds * 1000);
|
|
459
469
|
}
|
|
460
470
|
}
|
|
@@ -464,7 +474,7 @@ watch([page, sort, () => filtersStore.filters], async () => {
|
|
|
464
474
|
await getList();
|
|
465
475
|
}, { deep: true });
|
|
466
476
|
|
|
467
|
-
|
|
477
|
+
list.refresh = async () => {
|
|
468
478
|
const result = await getList();
|
|
469
479
|
|
|
470
480
|
if (!result) {
|
|
@@ -478,11 +488,11 @@ adminforth.list.refresh = async () => {
|
|
|
478
488
|
return {};
|
|
479
489
|
};
|
|
480
490
|
|
|
481
|
-
|
|
491
|
+
list.silentRefresh = async () => {
|
|
482
492
|
return await refreshExistingList();
|
|
483
493
|
}
|
|
484
494
|
|
|
485
|
-
|
|
495
|
+
list.silentRefreshRow = async (pk: any) => {
|
|
486
496
|
return await refreshExistingList(pk);
|
|
487
497
|
}
|
|
488
498
|
|