xladmin 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +11 -3
- package/dist/components/FieldEditor.d.ts +2 -2
- package/dist/components/ModelPage.d.ts +19 -1
- package/dist/components/layout/AdminDataContext.d.ts +1 -1
- package/dist/components/layout/Sidebar.d.ts +1 -1
- package/dist/components/model-page/ListFiltersBar.d.ts +2 -2
- package/dist/components/model-page/ListRow.d.ts +1 -1
- package/dist/components/model-page/useModelPageController.d.ts +17 -11
- package/dist/components/models-blocks/types.d.ts +1 -1
- package/dist/components/object-page/ObjectField.d.ts +2 -2
- package/dist/components/object-page/ReadonlyObjectField.d.ts +1 -1
- package/dist/components/object-page/useObjectPageController.d.ts +7 -7
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +262 -93
- package/dist/utils/adminFields.d.ts +1 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -2,6 +2,14 @@ import type { AdminChoicesResponse, AdminDeletePreviewResponse, AdminDetailRespo
|
|
|
2
2
|
export type XLAdminRequestOptions = {
|
|
3
3
|
signal?: AbortSignal;
|
|
4
4
|
};
|
|
5
|
+
export type XLAdminSelectionScope = {
|
|
6
|
+
q?: string;
|
|
7
|
+
filters?: Record<string, string>;
|
|
8
|
+
};
|
|
9
|
+
export type XLAdminSelectionOptions = {
|
|
10
|
+
selectAll?: boolean;
|
|
11
|
+
selectionScope?: XLAdminSelectionScope;
|
|
12
|
+
};
|
|
5
13
|
export type XLAdminClient = {
|
|
6
14
|
getModels: () => Promise<AdminModelsResponse>;
|
|
7
15
|
getModel: (slug: string) => Promise<AdminModelMeta>;
|
|
@@ -16,11 +24,11 @@ export type XLAdminClient = {
|
|
|
16
24
|
patchItem: (slug: string, id: string | number, payload: Record<string, unknown>) => Promise<AdminDetailResponse>;
|
|
17
25
|
deleteItem: (slug: string, id: string | number) => Promise<void>;
|
|
18
26
|
getDeletePreview: (slug: string, id: string | number) => Promise<AdminDeletePreviewResponse>;
|
|
19
|
-
bulkDelete: (slug: string, ids: Array<string | number
|
|
27
|
+
bulkDelete: (slug: string, ids: Array<string | number>, options?: XLAdminSelectionOptions) => Promise<{
|
|
20
28
|
deleted: number;
|
|
21
29
|
}>;
|
|
22
|
-
getBulkDeletePreview: (slug: string, ids: Array<string | number
|
|
23
|
-
runBulkAction: (slug: string, actionSlug: string, ids: Array<string | number>, payload?: Record<string, unknown
|
|
30
|
+
getBulkDeletePreview: (slug: string, ids: Array<string | number>, options?: XLAdminSelectionOptions) => Promise<AdminDeletePreviewResponse>;
|
|
31
|
+
runBulkAction: (slug: string, actionSlug: string, ids: Array<string | number>, payload?: Record<string, unknown>, options?: XLAdminSelectionOptions) => Promise<{
|
|
24
32
|
processed: number;
|
|
25
33
|
} & Record<string, unknown>>;
|
|
26
34
|
runObjectAction: (slug: string, id: string | number, actionSlug: string, payload?: Record<string, unknown>) => Promise<AdminObjectActionResponse>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { XLAdminClient } from '
|
|
2
|
-
import type { AdminFieldMeta } from '
|
|
1
|
+
import type { XLAdminClient } from '@xladmin-core/client';
|
|
2
|
+
import type { AdminFieldMeta } from '@xladmin-core/types';
|
|
3
3
|
type AdminFieldEditorProps = {
|
|
4
4
|
field: AdminFieldMeta;
|
|
5
5
|
value: unknown;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
import type { XLAdminClient } from '../client';
|
|
2
3
|
import type { XLAdminRouter } from '../router';
|
|
3
4
|
type AdminModelPageProps = {
|
|
@@ -5,7 +6,24 @@ type AdminModelPageProps = {
|
|
|
5
6
|
basePath: string;
|
|
6
7
|
slug: string;
|
|
7
8
|
router?: XLAdminRouter;
|
|
9
|
+
renderBeforePagination?: (context: ModelPageToolbarContext) => ReactNode;
|
|
8
10
|
};
|
|
9
11
|
export type ModelPageProps = AdminModelPageProps;
|
|
10
|
-
export
|
|
12
|
+
export type ModelPageToolbarContext = {
|
|
13
|
+
client: XLAdminClient;
|
|
14
|
+
slug: string;
|
|
15
|
+
meta: {
|
|
16
|
+
slug: string;
|
|
17
|
+
title: string;
|
|
18
|
+
};
|
|
19
|
+
selectedIds: Array<string | number>;
|
|
20
|
+
isAllMatchingSelected: boolean;
|
|
21
|
+
selectionCount: number;
|
|
22
|
+
total: number;
|
|
23
|
+
appliedQuery: string;
|
|
24
|
+
sortValue: string;
|
|
25
|
+
appliedFilters: Record<string, string>;
|
|
26
|
+
refresh: () => Promise<void>;
|
|
27
|
+
};
|
|
28
|
+
export declare function ModelPage({ client, basePath, slug, router, renderBeforePagination }: ModelPageProps): import("react/jsx-runtime").JSX.Element;
|
|
11
29
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
-
import type { AdminLocale, AdminModelMeta, AdminModelsBlockMeta } from '
|
|
2
|
+
import type { AdminLocale, AdminModelMeta, AdminModelsBlockMeta } from '@xladmin-core/types';
|
|
3
3
|
type AdminDataContextValue = {
|
|
4
4
|
locale: AdminLocale;
|
|
5
5
|
models: AdminModelMeta[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { XLAdminClient } from '
|
|
2
|
-
import type { AdminListFilterMeta } from '
|
|
1
|
+
import type { XLAdminClient } from '@xladmin-core/client';
|
|
2
|
+
import type { AdminListFilterMeta } from '@xladmin-core/types';
|
|
3
3
|
type ListFiltersSidebarProps = {
|
|
4
4
|
client: XLAdminClient;
|
|
5
5
|
slug: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { XLAdminClient } from '
|
|
2
|
-
import type { AdminTranslationKey } from '
|
|
3
|
-
import type { XLAdminRouter } from '
|
|
4
|
-
import type { AdminDeletePreviewResponse, AdminListResponse } from '
|
|
1
|
+
import type { XLAdminClient } from '@xladmin-core/client';
|
|
2
|
+
import type { AdminTranslationKey } from '@xladmin-core/i18n';
|
|
3
|
+
import type { XLAdminRouter } from '@xladmin-core/router';
|
|
4
|
+
import type { AdminDeletePreviewResponse, AdminListResponse } from '@xladmin-core/types';
|
|
5
5
|
type UseModelPageControllerOptions = {
|
|
6
6
|
client: XLAdminClient;
|
|
7
7
|
slug: string;
|
|
@@ -15,7 +15,8 @@ export declare function useModelPageController({ client, slug, pathname, locatio
|
|
|
15
15
|
appliedFilters: Record<string, string>;
|
|
16
16
|
appliedQuery: string;
|
|
17
17
|
bulkActionMenuAnchor: HTMLElement | null;
|
|
18
|
-
bulkActions: import("
|
|
18
|
+
bulkActions: import("@xladmin-core/types").AdminBulkActionMeta[];
|
|
19
|
+
clearBulkDeleteState: () => void;
|
|
19
20
|
createOpen: boolean;
|
|
20
21
|
currentPage: number;
|
|
21
22
|
data: AdminListResponse | null;
|
|
@@ -23,8 +24,11 @@ export declare function useModelPageController({ client, slug, pathname, locatio
|
|
|
23
24
|
deletePreviewError: string | null;
|
|
24
25
|
deletePreviewOpen: boolean;
|
|
25
26
|
error: string | null;
|
|
26
|
-
fieldMap: Map<string, import("
|
|
27
|
+
fieldMap: Map<string, import("@xladmin-core/types").AdminFieldMeta>;
|
|
27
28
|
filtersOpen: boolean;
|
|
29
|
+
handleClearDeletePreview: () => void;
|
|
30
|
+
handleCloseBulkActionMenu: () => void;
|
|
31
|
+
handleCloseRowMenu: () => void;
|
|
28
32
|
handleConfirmDelete: () => Promise<void>;
|
|
29
33
|
handleFilterChange: (filterSlug: string, value: string) => void;
|
|
30
34
|
handleOpenRowMenu: (event: {
|
|
@@ -36,16 +40,19 @@ export declare function useModelPageController({ client, slug, pathname, locatio
|
|
|
36
40
|
handleRowDelete: (rowId: string | number) => Promise<void>;
|
|
37
41
|
handleRunNamedBulkAction: (actionSlug: string) => Promise<void>;
|
|
38
42
|
handleSearchCommit: (nextQuery: string) => void;
|
|
43
|
+
handleSelectAllMatching: () => void;
|
|
39
44
|
handleToggleAllVisible: (checked: boolean) => void;
|
|
40
45
|
handleToggleSelection: (rowId: string | number, checked: boolean) => void;
|
|
41
46
|
hasListFilters: boolean;
|
|
47
|
+
hasSelection: boolean;
|
|
42
48
|
hasVisibleSelection: boolean;
|
|
49
|
+
isAllMatchingSelected: boolean;
|
|
43
50
|
isDeletePreviewLoading: boolean;
|
|
44
51
|
isDeleteSubmitting: boolean;
|
|
45
52
|
isLoading: boolean;
|
|
46
53
|
listFields: string[];
|
|
47
|
-
listFilters: import("
|
|
48
|
-
meta: import("
|
|
54
|
+
listFilters: import("@xladmin-core/types").AdminListFilterMeta[];
|
|
55
|
+
meta: import("@xladmin-core/types").AdminModelMeta | null;
|
|
49
56
|
pageInput: string;
|
|
50
57
|
pendingDeleteIds: (string | number)[];
|
|
51
58
|
pendingDeleteMode: "single" | "bulk";
|
|
@@ -53,6 +60,7 @@ export declare function useModelPageController({ client, slug, pathname, locatio
|
|
|
53
60
|
rowActionMenuAnchor: HTMLElement | null;
|
|
54
61
|
rowActionMenuId: string | number | null;
|
|
55
62
|
rows: Record<string, unknown>[];
|
|
63
|
+
selectionCount: number;
|
|
56
64
|
selectedIdSet: Set<string>;
|
|
57
65
|
selectedIds: (string | number)[];
|
|
58
66
|
setBulkActionMenuAnchor: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
|
|
@@ -62,9 +70,7 @@ export declare function useModelPageController({ client, slug, pathname, locatio
|
|
|
62
70
|
setDeletePreviewOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
63
71
|
setFiltersOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
64
72
|
setPageInput: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
65
|
-
|
|
66
|
-
setRowActionMenuAnchor: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
|
|
67
|
-
setRowActionMenuId: import("react").Dispatch<import("react").SetStateAction<string | number | null>>;
|
|
73
|
+
sortValue: string;
|
|
68
74
|
sortFields: string[];
|
|
69
75
|
toggleSort: (fieldName: string) => void;
|
|
70
76
|
total: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { XLAdminClient } from '
|
|
2
|
-
import type { AdminFieldMeta } from '
|
|
1
|
+
import type { XLAdminClient } from '@xladmin-core/client';
|
|
2
|
+
import type { AdminFieldMeta } from '@xladmin-core/types';
|
|
3
3
|
type ObjectFieldProps = {
|
|
4
4
|
field: AdminFieldMeta;
|
|
5
5
|
value: unknown;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { XLAdminClient } from '
|
|
2
|
-
import type { AdminTranslationKey } from '
|
|
3
|
-
import type { XLAdminRouter } from '
|
|
4
|
-
import type { AdminDeletePreviewResponse, AdminDetailResponse } from '
|
|
1
|
+
import type { XLAdminClient } from '@xladmin-core/client';
|
|
2
|
+
import type { AdminTranslationKey } from '@xladmin-core/i18n';
|
|
3
|
+
import type { XLAdminRouter } from '@xladmin-core/router';
|
|
4
|
+
import type { AdminDeletePreviewResponse, AdminDetailResponse } from '@xladmin-core/types';
|
|
5
5
|
type UseObjectPageControllerOptions = {
|
|
6
6
|
client: XLAdminClient;
|
|
7
7
|
slug: string;
|
|
@@ -20,7 +20,7 @@ export declare function useObjectPageController({ client, slug, id, listPath, ro
|
|
|
20
20
|
detailFields: string[];
|
|
21
21
|
editableFieldNames: Set<string>;
|
|
22
22
|
error: string | null;
|
|
23
|
-
fieldMap: Map<string, import("
|
|
23
|
+
fieldMap: Map<string, import("@xladmin-core/types").AdminFieldMeta>;
|
|
24
24
|
handleDelete: () => Promise<void>;
|
|
25
25
|
handleFieldChange: (fieldName: string, nextValue: unknown) => void;
|
|
26
26
|
handleNavigateBack: () => void;
|
|
@@ -34,8 +34,8 @@ export declare function useObjectPageController({ client, slug, id, listPath, ro
|
|
|
34
34
|
isDirty: boolean;
|
|
35
35
|
isLoading: boolean;
|
|
36
36
|
isSaving: boolean;
|
|
37
|
-
meta: import("
|
|
38
|
-
objectActions: import("
|
|
37
|
+
meta: import("@xladmin-core/types").AdminModelMeta | null;
|
|
38
|
+
objectActions: import("@xladmin-core/types").AdminObjectActionMeta[];
|
|
39
39
|
objectTitle: string;
|
|
40
40
|
setActionsAnchorEl: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
|
|
41
41
|
setDeleteConfirmOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ export { createAxiosXLAdminClient, createFetchXLAdminClient, createFetchXLAdminT
|
|
|
2
2
|
export { XLAdminRouterProvider, buildUrlWithParams, createBrowserXLAdminRouter, handleNavLinkClick, type XLAdminAnchorProps, type XLAdminLocation, type XLAdminRouter, useXLAdminLocation, useXLAdminRouter, } from './router';
|
|
3
3
|
export { FormDialog, type FormDialogProps } from './components/FormDialog';
|
|
4
4
|
export { OverviewPage, type OverviewPageProps } from './components/OverviewPage';
|
|
5
|
-
export { ModelPage, type ModelPageProps } from './components/ModelPage';
|
|
5
|
+
export { ModelPage, type ModelPageProps, type ModelPageToolbarContext } from './components/ModelPage';
|
|
6
6
|
export { ObjectPage, type ObjectPageProps } from './components/ObjectPage';
|
|
7
7
|
export { Shell, type ShellProps } from './components/Shell';
|
|
8
8
|
export { FieldEditor, type FieldEditorProps } from './components/FieldEditor';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { createAxiosXLAdminClient, createFetchXLAdminClient, createFetchXLAdminT
|
|
|
2
2
|
export { XLAdminRouterProvider, buildUrlWithParams, createBrowserXLAdminRouter, handleNavLinkClick, type XLAdminAnchorProps, type XLAdminLocation, type XLAdminRouter, useXLAdminLocation, useXLAdminRouter, } from './router';
|
|
3
3
|
export { FormDialog, type FormDialogProps } from './components/FormDialog';
|
|
4
4
|
export { OverviewPage, type OverviewPageProps } from './components/OverviewPage';
|
|
5
|
-
export { ModelPage, type ModelPageProps } from './components/ModelPage';
|
|
5
|
+
export { ModelPage, type ModelPageProps, type ModelPageToolbarContext } from './components/ModelPage';
|
|
6
6
|
export { ObjectPage, type ObjectPageProps } from './components/ObjectPage';
|
|
7
7
|
export { Shell, type ShellProps } from './components/Shell';
|
|
8
8
|
export { FieldEditor, type FieldEditorProps } from './components/FieldEditor';
|
package/dist/index.js
CHANGED
|
@@ -25,17 +25,25 @@ function createXLAdminClient(transport) {
|
|
|
25
25
|
async getDeletePreview(slug, id) {
|
|
26
26
|
return await transportGet(transport, `/xladmin/models/${slug}/items/${id}/delete-preview/`);
|
|
27
27
|
},
|
|
28
|
-
async bulkDelete(slug, ids) {
|
|
29
|
-
return await transportPost(
|
|
28
|
+
async bulkDelete(slug, ids, options) {
|
|
29
|
+
return await transportPost(
|
|
30
|
+
transport,
|
|
31
|
+
`/xladmin/models/${slug}/bulk-delete/`,
|
|
32
|
+
buildSelectionPayload(ids, void 0, options)
|
|
33
|
+
);
|
|
30
34
|
},
|
|
31
|
-
async getBulkDeletePreview(slug, ids) {
|
|
32
|
-
return await transportPost(
|
|
35
|
+
async getBulkDeletePreview(slug, ids, options) {
|
|
36
|
+
return await transportPost(
|
|
37
|
+
transport,
|
|
38
|
+
`/xladmin/models/${slug}/bulk-delete-preview/`,
|
|
39
|
+
buildSelectionPayload(ids, void 0, options)
|
|
40
|
+
);
|
|
33
41
|
},
|
|
34
|
-
async runBulkAction(slug, actionSlug, ids, payload) {
|
|
42
|
+
async runBulkAction(slug, actionSlug, ids, payload, options) {
|
|
35
43
|
return await transportPost(
|
|
36
44
|
transport,
|
|
37
45
|
`/xladmin/models/${slug}/bulk-actions/${actionSlug}/`,
|
|
38
|
-
|
|
46
|
+
buildSelectionPayload(ids, payload, options)
|
|
39
47
|
);
|
|
40
48
|
},
|
|
41
49
|
async runObjectAction(slug, id, actionSlug, payload) {
|
|
@@ -181,6 +189,23 @@ function buildSearchParams(params) {
|
|
|
181
189
|
}
|
|
182
190
|
return searchParams.toString();
|
|
183
191
|
}
|
|
192
|
+
function buildSelectionPayload(ids, payload, options) {
|
|
193
|
+
var _a;
|
|
194
|
+
const result = {
|
|
195
|
+
ids,
|
|
196
|
+
...payload != null ? payload : {}
|
|
197
|
+
};
|
|
198
|
+
if (options == null ? void 0 : options.selectAll) {
|
|
199
|
+
result.select_all = true;
|
|
200
|
+
}
|
|
201
|
+
if (options == null ? void 0 : options.selectionScope) {
|
|
202
|
+
result.selection_scope = {
|
|
203
|
+
q: options.selectionScope.q,
|
|
204
|
+
filters: (_a = options.selectionScope.filters) != null ? _a : {}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
184
209
|
|
|
185
210
|
// src/router.tsx
|
|
186
211
|
import { createContext, useContext, useMemo, useRef, useSyncExternalStore } from "react";
|
|
@@ -762,7 +787,7 @@ var FieldEditor = memo(function FieldEditor2({
|
|
|
762
787
|
label: field.label,
|
|
763
788
|
disabled: readOnly,
|
|
764
789
|
value: value ? dayjs(String(value)) : null,
|
|
765
|
-
onChange: (nextValue) => onChange(nextValue ? nextValue.format("YYYY-MM-
|
|
790
|
+
onChange: (nextValue) => onChange(nextValue ? nextValue.format("YYYY-MM-DD[T]HH:mm:ss") : null),
|
|
766
791
|
slotProps: {
|
|
767
792
|
popper: { disablePortal: true },
|
|
768
793
|
desktopPaper: buildPickerPaperProps(),
|
|
@@ -898,17 +923,19 @@ function renderChoiceEditor({
|
|
|
898
923
|
label: field.label,
|
|
899
924
|
placeholder: searchPlaceholder,
|
|
900
925
|
helperText: (_a2 = field.help_text) != null ? _a2 : void 0,
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
926
|
+
slotProps: {
|
|
927
|
+
input: {
|
|
928
|
+
...InputProps,
|
|
929
|
+
endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
930
|
+
isLoadingChoices ? /* @__PURE__ */ jsx3(CircularProgress, { color: "inherit", size: 16 }) : null,
|
|
931
|
+
InputProps.endAdornment
|
|
932
|
+
] })
|
|
933
|
+
},
|
|
934
|
+
htmlInput: {
|
|
935
|
+
...inputProps,
|
|
936
|
+
autoComplete: "new-password",
|
|
937
|
+
name: `admin-choice-${field.name}`
|
|
938
|
+
}
|
|
912
939
|
}
|
|
913
940
|
}
|
|
914
941
|
);
|
|
@@ -954,17 +981,19 @@ function renderChoiceEditor({
|
|
|
954
981
|
label: field.label,
|
|
955
982
|
placeholder: searchPlaceholder,
|
|
956
983
|
helperText: (_a2 = field.help_text) != null ? _a2 : void 0,
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
984
|
+
slotProps: {
|
|
985
|
+
input: {
|
|
986
|
+
...InputProps,
|
|
987
|
+
endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
988
|
+
isLoadingChoices ? /* @__PURE__ */ jsx3(CircularProgress, { color: "inherit", size: 16 }) : null,
|
|
989
|
+
InputProps.endAdornment
|
|
990
|
+
] })
|
|
991
|
+
},
|
|
992
|
+
htmlInput: {
|
|
993
|
+
...inputProps,
|
|
994
|
+
autoComplete: "new-password",
|
|
995
|
+
name: `admin-choice-${field.name}`
|
|
996
|
+
}
|
|
968
997
|
}
|
|
969
998
|
}
|
|
970
999
|
);
|
|
@@ -2238,14 +2267,16 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
|
|
|
2238
2267
|
...textFieldParams,
|
|
2239
2268
|
label: filter.label,
|
|
2240
2269
|
placeholder: (_a2 = filter.placeholder) != null ? _a2 : t("search"),
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2270
|
+
slotProps: {
|
|
2271
|
+
input: {
|
|
2272
|
+
...InputProps,
|
|
2273
|
+
endAdornment: /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
2274
|
+
isLoadingChoices ? /* @__PURE__ */ jsx15(CircularProgress3, { color: "inherit", size: 16 }) : null,
|
|
2275
|
+
InputProps.endAdornment
|
|
2276
|
+
] })
|
|
2277
|
+
},
|
|
2278
|
+
htmlInput: inputProps
|
|
2279
|
+
}
|
|
2249
2280
|
}
|
|
2250
2281
|
);
|
|
2251
2282
|
})()
|
|
@@ -2556,6 +2587,7 @@ function useModelPageController({
|
|
|
2556
2587
|
})
|
|
2557
2588
|
)) != null ? _c : null;
|
|
2558
2589
|
const [selectedIds, setSelectedIds] = useState9([]);
|
|
2590
|
+
const [isAllMatchingSelected, setIsAllMatchingSelected] = useState9(false);
|
|
2559
2591
|
const [createOpen, setCreateOpen] = useState9(false);
|
|
2560
2592
|
const [data, setData] = useState9(() => initialCachedResponse);
|
|
2561
2593
|
const [error, setError] = useState9(null);
|
|
@@ -2574,6 +2606,8 @@ function useModelPageController({
|
|
|
2574
2606
|
const [isDeletePreviewLoading, setIsDeletePreviewLoading] = useState9(false);
|
|
2575
2607
|
const [isDeleteSubmitting, setIsDeleteSubmitting] = useState9(false);
|
|
2576
2608
|
const [pendingDeleteIds, setPendingDeleteIds] = useState9([]);
|
|
2609
|
+
const [pendingDeleteSelectAll, setPendingDeleteSelectAll] = useState9(false);
|
|
2610
|
+
const [pendingDeleteScope, setPendingDeleteScope] = useState9(null);
|
|
2577
2611
|
const [pendingDeleteMode, setPendingDeleteMode] = useState9("single");
|
|
2578
2612
|
const [filtersOpen, setFiltersOpen] = useState9(false);
|
|
2579
2613
|
const requestIdRef = useRef3(0);
|
|
@@ -2596,15 +2630,32 @@ function useModelPageController({
|
|
|
2596
2630
|
const listFilters = (_j = meta == null ? void 0 : meta.list_filters) != null ? _j : [];
|
|
2597
2631
|
const hasListFilters = listFilters.length > 0;
|
|
2598
2632
|
const bulkActions = (_k = meta == null ? void 0 : meta.bulk_actions) != null ? _k : [];
|
|
2599
|
-
const
|
|
2600
|
-
|
|
2633
|
+
const selectionScope = useMemo8(
|
|
2634
|
+
() => ({
|
|
2635
|
+
q: appliedQuery || void 0,
|
|
2636
|
+
filters: { ...appliedFilters }
|
|
2637
|
+
}),
|
|
2638
|
+
[appliedFilters, appliedQuery]
|
|
2639
|
+
);
|
|
2640
|
+
const selectedIdSet = useMemo8(() => {
|
|
2641
|
+
if (isAllMatchingSelected) {
|
|
2642
|
+
return new Set(rows.map((row) => {
|
|
2643
|
+
var _a2;
|
|
2644
|
+
return String(row[(_a2 = meta == null ? void 0 : meta.pk_field) != null ? _a2 : "id"]);
|
|
2645
|
+
}));
|
|
2646
|
+
}
|
|
2647
|
+
return new Set(selectedIds.map((item) => String(item)));
|
|
2648
|
+
}, [isAllMatchingSelected, meta == null ? void 0 : meta.pk_field, rows, selectedIds]);
|
|
2649
|
+
const allVisibleSelected = rows.length > 0 && (isAllMatchingSelected || rows.every((row) => {
|
|
2601
2650
|
var _a2;
|
|
2602
2651
|
return selectedIdSet.has(String(row[(_a2 = meta == null ? void 0 : meta.pk_field) != null ? _a2 : "id"]));
|
|
2603
|
-
});
|
|
2604
|
-
const hasVisibleSelection = rows.some((row) => {
|
|
2652
|
+
}));
|
|
2653
|
+
const hasVisibleSelection = isAllMatchingSelected || rows.some((row) => {
|
|
2605
2654
|
var _a2;
|
|
2606
2655
|
return selectedIdSet.has(String(row[(_a2 = meta == null ? void 0 : meta.pk_field) != null ? _a2 : "id"]));
|
|
2607
2656
|
});
|
|
2657
|
+
const hasSelection = isAllMatchingSelected || selectedIds.length > 0;
|
|
2658
|
+
const selectionCount = isAllMatchingSelected ? total : selectedIds.length;
|
|
2608
2659
|
useEffect9(() => {
|
|
2609
2660
|
dataRef.current = data;
|
|
2610
2661
|
}, [data]);
|
|
@@ -2624,6 +2675,10 @@ function useModelPageController({
|
|
|
2624
2675
|
setPageInput(String(nextPage));
|
|
2625
2676
|
setAppliedFilters(nextFilters);
|
|
2626
2677
|
}, [locationSearch]);
|
|
2678
|
+
const clearSelection = useCallback4(() => {
|
|
2679
|
+
setSelectedIds([]);
|
|
2680
|
+
setIsAllMatchingSelected(false);
|
|
2681
|
+
}, []);
|
|
2627
2682
|
const loadItems = useCallback4(async () => {
|
|
2628
2683
|
var _a2;
|
|
2629
2684
|
const activeRequestId = requestIdRef.current + 1;
|
|
@@ -2640,7 +2695,9 @@ function useModelPageController({
|
|
|
2640
2695
|
const cachedResponse = (_a2 = getClientCacheBucket(client).listResponseCache.get(requestKey)) != null ? _a2 : null;
|
|
2641
2696
|
if (cachedResponse) {
|
|
2642
2697
|
setData(cachedResponse);
|
|
2643
|
-
|
|
2698
|
+
if (!isAllMatchingSelected) {
|
|
2699
|
+
setSelectedIds([]);
|
|
2700
|
+
}
|
|
2644
2701
|
setIsLoading(false);
|
|
2645
2702
|
return;
|
|
2646
2703
|
}
|
|
@@ -2655,7 +2712,9 @@ function useModelPageController({
|
|
|
2655
2712
|
}
|
|
2656
2713
|
pageSizeRef.current = response.meta.page_size;
|
|
2657
2714
|
setData(response);
|
|
2658
|
-
|
|
2715
|
+
if (!isAllMatchingSelected) {
|
|
2716
|
+
setSelectedIds([]);
|
|
2717
|
+
}
|
|
2659
2718
|
} catch (reason) {
|
|
2660
2719
|
setError(reason instanceof Error ? reason.message : t("model_load_error"));
|
|
2661
2720
|
} finally {
|
|
@@ -2663,7 +2722,7 @@ function useModelPageController({
|
|
|
2663
2722
|
setIsLoading(false);
|
|
2664
2723
|
}
|
|
2665
2724
|
}
|
|
2666
|
-
}, [appliedFilters, appliedQuery, client, currentPage, slug, sortValue, t]);
|
|
2725
|
+
}, [appliedFilters, appliedQuery, client, currentPage, isAllMatchingSelected, slug, sortValue, t]);
|
|
2667
2726
|
useEffect9(() => {
|
|
2668
2727
|
void loadItems();
|
|
2669
2728
|
}, [loadItems]);
|
|
@@ -2678,11 +2737,12 @@ function useModelPageController({
|
|
|
2678
2737
|
if (nextQuery === appliedQuery) {
|
|
2679
2738
|
return;
|
|
2680
2739
|
}
|
|
2740
|
+
clearSelection();
|
|
2681
2741
|
setAppliedQuery(nextQuery);
|
|
2682
2742
|
setCurrentPage(1);
|
|
2683
2743
|
setPageInput("1");
|
|
2684
2744
|
replaceLocation(nextQuery, sortValue, 1, appliedFilters);
|
|
2685
|
-
}, [appliedFilters, appliedQuery, replaceLocation, sortValue]);
|
|
2745
|
+
}, [appliedFilters, appliedQuery, clearSelection, replaceLocation, sortValue]);
|
|
2686
2746
|
const handlePageChange = useCallback4((nextPage) => {
|
|
2687
2747
|
const safePage = Math.min(Math.max(nextPage, 1), totalPages);
|
|
2688
2748
|
setCurrentPage(safePage);
|
|
@@ -2717,22 +2777,26 @@ function useModelPageController({
|
|
|
2717
2777
|
if (!value) {
|
|
2718
2778
|
delete nextFilters[filterSlug];
|
|
2719
2779
|
}
|
|
2780
|
+
clearSelection();
|
|
2720
2781
|
setAppliedFilters(nextFilters);
|
|
2721
2782
|
setCurrentPage(1);
|
|
2722
2783
|
setPageInput("1");
|
|
2723
2784
|
replaceLocation(appliedQuery, sortValue, 1, nextFilters);
|
|
2724
|
-
}, [appliedFilters, appliedQuery, replaceLocation, sortValue]);
|
|
2785
|
+
}, [appliedFilters, appliedQuery, clearSelection, replaceLocation, sortValue]);
|
|
2725
2786
|
const handleResetFilters = useCallback4(() => {
|
|
2726
2787
|
if (Object.keys(appliedFilters).length === 0) {
|
|
2727
2788
|
return;
|
|
2728
2789
|
}
|
|
2790
|
+
clearSelection();
|
|
2729
2791
|
setAppliedFilters({});
|
|
2730
2792
|
setCurrentPage(1);
|
|
2731
2793
|
setPageInput("1");
|
|
2732
2794
|
replaceLocation(appliedQuery, sortValue, 1, {});
|
|
2733
|
-
}, [appliedFilters, appliedQuery, replaceLocation, sortValue]);
|
|
2795
|
+
}, [appliedFilters, appliedQuery, clearSelection, replaceLocation, sortValue]);
|
|
2734
2796
|
const openSingleDeletePreview = useCallback4(async (rowId) => {
|
|
2735
2797
|
setPendingDeleteIds([rowId]);
|
|
2798
|
+
setPendingDeleteSelectAll(false);
|
|
2799
|
+
setPendingDeleteScope(null);
|
|
2736
2800
|
setPendingDeleteMode("single");
|
|
2737
2801
|
setDeletePreviewOpen(true);
|
|
2738
2802
|
setDeletePreview(null);
|
|
@@ -2748,17 +2812,23 @@ function useModelPageController({
|
|
|
2748
2812
|
}
|
|
2749
2813
|
}, [client, slug, t]);
|
|
2750
2814
|
const openBulkDeletePreview = useCallback4(async () => {
|
|
2751
|
-
if (
|
|
2815
|
+
if (!hasSelection) {
|
|
2752
2816
|
return;
|
|
2753
2817
|
}
|
|
2754
|
-
setPendingDeleteIds(selectedIds);
|
|
2818
|
+
setPendingDeleteIds(isAllMatchingSelected ? [] : selectedIds);
|
|
2819
|
+
setPendingDeleteSelectAll(isAllMatchingSelected);
|
|
2820
|
+
setPendingDeleteScope(isAllMatchingSelected ? selectionScope : null);
|
|
2755
2821
|
setPendingDeleteMode("bulk");
|
|
2756
2822
|
setDeletePreviewOpen(true);
|
|
2757
2823
|
setDeletePreview(null);
|
|
2758
2824
|
setDeletePreviewError(null);
|
|
2759
2825
|
setIsDeletePreviewLoading(true);
|
|
2760
2826
|
try {
|
|
2761
|
-
const preview = await client.getBulkDeletePreview(
|
|
2827
|
+
const preview = await client.getBulkDeletePreview(
|
|
2828
|
+
slug,
|
|
2829
|
+
isAllMatchingSelected ? [] : selectedIds,
|
|
2830
|
+
isAllMatchingSelected ? { selectAll: true, selectionScope } : void 0
|
|
2831
|
+
);
|
|
2762
2832
|
setDeletePreview(preview);
|
|
2763
2833
|
} catch (reason) {
|
|
2764
2834
|
setDeletePreviewError(reason instanceof Error ? reason.message : t("delete_preview_error"));
|
|
@@ -2766,9 +2836,12 @@ function useModelPageController({
|
|
|
2766
2836
|
setIsDeletePreviewLoading(false);
|
|
2767
2837
|
setBulkActionMenuAnchor(null);
|
|
2768
2838
|
}
|
|
2769
|
-
}, [client, selectedIds, slug, t]);
|
|
2839
|
+
}, [client, hasSelection, isAllMatchingSelected, selectedIds, selectionScope, slug, t]);
|
|
2770
2840
|
const handleConfirmDelete = useCallback4(async () => {
|
|
2771
|
-
if (pendingDeleteIds.length === 0) {
|
|
2841
|
+
if (pendingDeleteMode === "single" && pendingDeleteIds.length === 0) {
|
|
2842
|
+
return;
|
|
2843
|
+
}
|
|
2844
|
+
if (pendingDeleteMode === "bulk" && pendingDeleteIds.length === 0 && !pendingDeleteSelectAll) {
|
|
2772
2845
|
return;
|
|
2773
2846
|
}
|
|
2774
2847
|
setIsDeleteSubmitting(true);
|
|
@@ -2777,21 +2850,28 @@ function useModelPageController({
|
|
|
2777
2850
|
if (pendingDeleteMode === "single") {
|
|
2778
2851
|
await client.deleteItem(slug, pendingDeleteIds[0]);
|
|
2779
2852
|
} else {
|
|
2780
|
-
await client.bulkDelete(
|
|
2853
|
+
await client.bulkDelete(
|
|
2854
|
+
slug,
|
|
2855
|
+
pendingDeleteIds,
|
|
2856
|
+
pendingDeleteSelectAll && pendingDeleteScope ? { selectAll: true, selectionScope: pendingDeleteScope } : void 0
|
|
2857
|
+
);
|
|
2781
2858
|
}
|
|
2782
2859
|
setDeletePreviewOpen(false);
|
|
2783
2860
|
setDeletePreview(null);
|
|
2784
2861
|
setDeletePreviewError(null);
|
|
2785
2862
|
setPendingDeleteIds([]);
|
|
2863
|
+
setPendingDeleteSelectAll(false);
|
|
2864
|
+
setPendingDeleteScope(null);
|
|
2865
|
+
clearSelection();
|
|
2786
2866
|
await refresh();
|
|
2787
2867
|
} catch (reason) {
|
|
2788
2868
|
setDeletePreviewError(reason instanceof Error ? reason.message : t("object_delete_error"));
|
|
2789
2869
|
} finally {
|
|
2790
2870
|
setIsDeleteSubmitting(false);
|
|
2791
2871
|
}
|
|
2792
|
-
}, [client, pendingDeleteIds, pendingDeleteMode, refresh, slug, t]);
|
|
2872
|
+
}, [clearSelection, client, pendingDeleteIds, pendingDeleteMode, pendingDeleteScope, pendingDeleteSelectAll, refresh, slug, t]);
|
|
2793
2873
|
const handleRunNamedBulkAction = useCallback4(async (actionSlug) => {
|
|
2794
|
-
if (!actionSlug ||
|
|
2874
|
+
if (!actionSlug || !hasSelection) {
|
|
2795
2875
|
return;
|
|
2796
2876
|
}
|
|
2797
2877
|
if (actionSlug === "delete") {
|
|
@@ -2799,19 +2879,40 @@ function useModelPageController({
|
|
|
2799
2879
|
return;
|
|
2800
2880
|
}
|
|
2801
2881
|
try {
|
|
2802
|
-
await client.runBulkAction(
|
|
2882
|
+
await client.runBulkAction(
|
|
2883
|
+
slug,
|
|
2884
|
+
actionSlug,
|
|
2885
|
+
isAllMatchingSelected ? [] : selectedIds,
|
|
2886
|
+
void 0,
|
|
2887
|
+
isAllMatchingSelected ? { selectAll: true, selectionScope } : void 0
|
|
2888
|
+
);
|
|
2803
2889
|
setBulkActionMenuAnchor(null);
|
|
2890
|
+
clearSelection();
|
|
2804
2891
|
await refresh();
|
|
2805
2892
|
} catch (reason) {
|
|
2806
2893
|
setError(reason instanceof Error ? reason.message : t("object_action_error"));
|
|
2807
2894
|
}
|
|
2808
|
-
}, [client, openBulkDeletePreview, refresh, selectedIds, slug, t]);
|
|
2895
|
+
}, [clearSelection, client, hasSelection, isAllMatchingSelected, openBulkDeletePreview, refresh, selectedIds, selectionScope, slug, t]);
|
|
2809
2896
|
const handleRowDelete = useCallback4(async (rowId) => {
|
|
2810
2897
|
setRowActionMenuAnchor(null);
|
|
2811
2898
|
setRowActionMenuId(null);
|
|
2812
2899
|
await openSingleDeletePreview(rowId);
|
|
2813
2900
|
}, [openSingleDeletePreview]);
|
|
2814
2901
|
const handleToggleSelection = useCallback4((rowId, checked) => {
|
|
2902
|
+
if (isAllMatchingSelected) {
|
|
2903
|
+
if (checked) {
|
|
2904
|
+
return;
|
|
2905
|
+
}
|
|
2906
|
+
setIsAllMatchingSelected(false);
|
|
2907
|
+
if (!meta) {
|
|
2908
|
+
setSelectedIds([]);
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2911
|
+
setSelectedIds(
|
|
2912
|
+
rows.map((row) => row[meta.pk_field]).filter((item) => String(item) !== String(rowId))
|
|
2913
|
+
);
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2815
2916
|
setSelectedIds((current) => {
|
|
2816
2917
|
const rowKey = String(rowId);
|
|
2817
2918
|
if (checked) {
|
|
@@ -2822,27 +2923,54 @@ function useModelPageController({
|
|
|
2822
2923
|
}
|
|
2823
2924
|
return current.filter((item) => String(item) !== rowKey);
|
|
2824
2925
|
});
|
|
2825
|
-
}, []);
|
|
2926
|
+
}, [isAllMatchingSelected, meta, rows]);
|
|
2826
2927
|
const handleToggleAllVisible = useCallback4((checked) => {
|
|
2827
2928
|
if (!meta) {
|
|
2828
2929
|
return;
|
|
2829
2930
|
}
|
|
2830
2931
|
if (checked) {
|
|
2932
|
+
setIsAllMatchingSelected(false);
|
|
2831
2933
|
setSelectedIds(rows.map((row) => row[meta.pk_field]));
|
|
2832
2934
|
return;
|
|
2833
2935
|
}
|
|
2936
|
+
clearSelection();
|
|
2937
|
+
}, [clearSelection, meta, rows]);
|
|
2938
|
+
const handleSelectAllMatching = useCallback4(() => {
|
|
2939
|
+
if (!hasSelection || total === 0) {
|
|
2940
|
+
return;
|
|
2941
|
+
}
|
|
2834
2942
|
setSelectedIds([]);
|
|
2835
|
-
|
|
2943
|
+
setIsAllMatchingSelected(true);
|
|
2944
|
+
}, [hasSelection, total]);
|
|
2945
|
+
const clearBulkDeleteState = useCallback4(() => {
|
|
2946
|
+
setPendingDeleteIds([]);
|
|
2947
|
+
setPendingDeleteSelectAll(false);
|
|
2948
|
+
setPendingDeleteScope(null);
|
|
2949
|
+
}, []);
|
|
2950
|
+
const handleClearDeletePreview = useCallback4(() => {
|
|
2951
|
+
setDeletePreviewOpen(false);
|
|
2952
|
+
setDeletePreview(null);
|
|
2953
|
+
setDeletePreviewError(null);
|
|
2954
|
+
clearBulkDeleteState();
|
|
2955
|
+
}, [clearBulkDeleteState]);
|
|
2836
2956
|
const handleOpenRowMenu = useCallback4((event, rowId) => {
|
|
2837
2957
|
setRowActionMenuAnchor(event.currentTarget);
|
|
2838
2958
|
setRowActionMenuId(rowId);
|
|
2839
2959
|
}, []);
|
|
2960
|
+
const handleCloseRowMenu = useCallback4(() => {
|
|
2961
|
+
setRowActionMenuAnchor(null);
|
|
2962
|
+
setRowActionMenuId(null);
|
|
2963
|
+
}, []);
|
|
2964
|
+
const handleCloseBulkActionMenu = useCallback4(() => {
|
|
2965
|
+
setBulkActionMenuAnchor(null);
|
|
2966
|
+
}, []);
|
|
2840
2967
|
return {
|
|
2841
2968
|
allVisibleSelected,
|
|
2842
2969
|
appliedFilters,
|
|
2843
2970
|
appliedQuery,
|
|
2844
2971
|
bulkActionMenuAnchor,
|
|
2845
2972
|
bulkActions,
|
|
2973
|
+
clearBulkDeleteState,
|
|
2846
2974
|
createOpen,
|
|
2847
2975
|
currentPage,
|
|
2848
2976
|
data,
|
|
@@ -2852,6 +2980,9 @@ function useModelPageController({
|
|
|
2852
2980
|
error,
|
|
2853
2981
|
fieldMap,
|
|
2854
2982
|
filtersOpen,
|
|
2983
|
+
handleClearDeletePreview,
|
|
2984
|
+
handleCloseBulkActionMenu,
|
|
2985
|
+
handleCloseRowMenu,
|
|
2855
2986
|
handleConfirmDelete,
|
|
2856
2987
|
handleFilterChange,
|
|
2857
2988
|
handleOpenRowMenu,
|
|
@@ -2861,10 +2992,13 @@ function useModelPageController({
|
|
|
2861
2992
|
handleRowDelete,
|
|
2862
2993
|
handleRunNamedBulkAction,
|
|
2863
2994
|
handleSearchCommit,
|
|
2995
|
+
handleSelectAllMatching,
|
|
2864
2996
|
handleToggleAllVisible,
|
|
2865
2997
|
handleToggleSelection,
|
|
2866
2998
|
hasListFilters,
|
|
2999
|
+
hasSelection,
|
|
2867
3000
|
hasVisibleSelection,
|
|
3001
|
+
isAllMatchingSelected,
|
|
2868
3002
|
isDeletePreviewLoading,
|
|
2869
3003
|
isDeleteSubmitting,
|
|
2870
3004
|
isLoading,
|
|
@@ -2878,6 +3012,7 @@ function useModelPageController({
|
|
|
2878
3012
|
rowActionMenuAnchor,
|
|
2879
3013
|
rowActionMenuId,
|
|
2880
3014
|
rows,
|
|
3015
|
+
selectionCount,
|
|
2881
3016
|
selectedIdSet,
|
|
2882
3017
|
selectedIds,
|
|
2883
3018
|
setBulkActionMenuAnchor,
|
|
@@ -2887,9 +3022,7 @@ function useModelPageController({
|
|
|
2887
3022
|
setDeletePreviewOpen,
|
|
2888
3023
|
setFiltersOpen,
|
|
2889
3024
|
setPageInput,
|
|
2890
|
-
|
|
2891
|
-
setRowActionMenuAnchor,
|
|
2892
|
-
setRowActionMenuId,
|
|
3025
|
+
sortValue,
|
|
2893
3026
|
sortFields,
|
|
2894
3027
|
toggleSort,
|
|
2895
3028
|
total,
|
|
@@ -2965,10 +3098,11 @@ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
|
2965
3098
|
var SEARCH_DEBOUNCE_MS = 300;
|
|
2966
3099
|
var CHECKBOX_COLUMN_WIDTH = 56;
|
|
2967
3100
|
var ACTIONS_COLUMN_WIDTH = 56;
|
|
2968
|
-
function ModelPage({ client, basePath, slug, router }) {
|
|
3101
|
+
function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
|
|
2969
3102
|
var _a, _b;
|
|
2970
3103
|
const locale = useAdminLocale();
|
|
2971
3104
|
const t = useAdminTranslation();
|
|
3105
|
+
const selectAllLabel = locale === "ru" ? "\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435" : "Select All";
|
|
2972
3106
|
const resolvedRouter = useXLAdminRouter(router);
|
|
2973
3107
|
const location = useXLAdminLocation(resolvedRouter);
|
|
2974
3108
|
const theme = useTheme2();
|
|
@@ -2989,6 +3123,22 @@ function ModelPage({ client, basePath, slug, router }) {
|
|
|
2989
3123
|
return /* @__PURE__ */ jsx19(ModelPageSkeleton, {});
|
|
2990
3124
|
}
|
|
2991
3125
|
const meta = controller.meta;
|
|
3126
|
+
const beforePagination = renderBeforePagination == null ? void 0 : renderBeforePagination({
|
|
3127
|
+
client,
|
|
3128
|
+
slug,
|
|
3129
|
+
meta: {
|
|
3130
|
+
slug: meta.slug,
|
|
3131
|
+
title: meta.title
|
|
3132
|
+
},
|
|
3133
|
+
selectedIds: controller.selectedIds,
|
|
3134
|
+
isAllMatchingSelected: controller.isAllMatchingSelected,
|
|
3135
|
+
selectionCount: controller.selectionCount,
|
|
3136
|
+
total: controller.total,
|
|
3137
|
+
appliedQuery: controller.appliedQuery,
|
|
3138
|
+
sortValue: controller.sortValue,
|
|
3139
|
+
appliedFilters: controller.appliedFilters,
|
|
3140
|
+
refresh: controller.refresh
|
|
3141
|
+
});
|
|
2992
3142
|
return /* @__PURE__ */ jsx19(XLAdminRouterProvider, { router: resolvedRouter, children: /* @__PURE__ */ jsxs12(Stack9, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
|
|
2993
3143
|
/* @__PURE__ */ jsx19(
|
|
2994
3144
|
MainHeader,
|
|
@@ -3000,8 +3150,8 @@ function ModelPage({ client, basePath, slug, router }) {
|
|
|
3000
3150
|
"aria-label": t("create"),
|
|
3001
3151
|
onClick: () => controller.setCreateOpen(true),
|
|
3002
3152
|
sx: {
|
|
3003
|
-
width:
|
|
3004
|
-
height:
|
|
3153
|
+
width: 29,
|
|
3154
|
+
height: 29,
|
|
3005
3155
|
p: 0.5,
|
|
3006
3156
|
backgroundColor: "primary.main",
|
|
3007
3157
|
color: "primary.contrastText",
|
|
@@ -3025,28 +3175,53 @@ function ModelPage({ client, basePath, slug, router }) {
|
|
|
3025
3175
|
flexShrink: 0
|
|
3026
3176
|
},
|
|
3027
3177
|
children: /* @__PURE__ */ jsxs12(Stack9, { direction: { xs: "column", lg: "row" }, spacing: 1.5, alignItems: { lg: "center" }, children: [
|
|
3028
|
-
/* @__PURE__ */
|
|
3029
|
-
|
|
3178
|
+
/* @__PURE__ */ jsxs12(
|
|
3179
|
+
Stack9,
|
|
3030
3180
|
{
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3181
|
+
direction: { xs: "column", xl: "row" },
|
|
3182
|
+
spacing: 1.5,
|
|
3183
|
+
alignItems: { xl: "center" },
|
|
3184
|
+
sx: { flex: 1, minWidth: 0 },
|
|
3185
|
+
children: [
|
|
3186
|
+
/* @__PURE__ */ jsx19(
|
|
3187
|
+
SearchField,
|
|
3188
|
+
{
|
|
3189
|
+
value: controller.appliedQuery,
|
|
3190
|
+
onCommit: controller.handleSearchCommit,
|
|
3191
|
+
debounceMs: SEARCH_DEBOUNCE_MS,
|
|
3192
|
+
placeholder: t("search")
|
|
3193
|
+
}
|
|
3194
|
+
),
|
|
3195
|
+
controller.hasSelection ? /* @__PURE__ */ jsxs12(Stack9, { direction: "row", spacing: 1, alignItems: "center", sx: { minWidth: 0, flexWrap: "wrap" }, children: [
|
|
3196
|
+
/* @__PURE__ */ jsx19(
|
|
3197
|
+
Button4,
|
|
3198
|
+
{
|
|
3199
|
+
variant: "outlined",
|
|
3200
|
+
endIcon: /* @__PURE__ */ jsx19(ExpandMoreIcon4, {}),
|
|
3201
|
+
onClick: (event) => controller.setBulkActionMenuAnchor(event.currentTarget),
|
|
3202
|
+
children: t("actions")
|
|
3203
|
+
}
|
|
3204
|
+
),
|
|
3205
|
+
!controller.isAllMatchingSelected && controller.selectionCount < controller.total ? /* @__PURE__ */ jsx19(
|
|
3206
|
+
Button4,
|
|
3207
|
+
{
|
|
3208
|
+
variant: "text",
|
|
3209
|
+
onClick: controller.handleSelectAllMatching,
|
|
3210
|
+
sx: { px: 0.5, minWidth: "auto" },
|
|
3211
|
+
children: selectAllLabel
|
|
3212
|
+
}
|
|
3213
|
+
) : null,
|
|
3214
|
+
/* @__PURE__ */ jsxs12(Typography5, { color: "text.secondary", sx: { alignSelf: "center", whiteSpace: "nowrap" }, children: [
|
|
3215
|
+
t("selected_count", { count: controller.selectionCount }),
|
|
3216
|
+
" / ",
|
|
3217
|
+
controller.total
|
|
3218
|
+
] })
|
|
3219
|
+
] }) : null
|
|
3220
|
+
]
|
|
3035
3221
|
}
|
|
3036
|
-
)
|
|
3037
|
-
controller.selectedIds.length > 0 ? /* @__PURE__ */ jsxs12(Stack9, { direction: "row", spacing: 1, sx: { flex: { lg: 1 }, minWidth: 0 }, children: [
|
|
3038
|
-
/* @__PURE__ */ jsx19(
|
|
3039
|
-
Button4,
|
|
3040
|
-
{
|
|
3041
|
-
variant: "outlined",
|
|
3042
|
-
endIcon: /* @__PURE__ */ jsx19(ExpandMoreIcon4, {}),
|
|
3043
|
-
onClick: (event) => controller.setBulkActionMenuAnchor(event.currentTarget),
|
|
3044
|
-
children: t("actions")
|
|
3045
|
-
}
|
|
3046
|
-
),
|
|
3047
|
-
/* @__PURE__ */ jsx19(Typography5, { color: "text.secondary", sx: { alignSelf: "center" }, children: t("selected_count", { count: controller.selectedIds.length }) })
|
|
3048
|
-
] }) : null,
|
|
3222
|
+
),
|
|
3049
3223
|
/* @__PURE__ */ jsxs12(Stack9, { direction: "row", spacing: 1, alignItems: "center", sx: { marginLeft: "auto" }, children: [
|
|
3224
|
+
beforePagination ? /* @__PURE__ */ jsx19(Box9, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforePagination }) : null,
|
|
3050
3225
|
isMobile && controller.hasListFilters ? /* @__PURE__ */ jsx19(Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsx19(
|
|
3051
3226
|
IconButton3,
|
|
3052
3227
|
{
|
|
@@ -3251,7 +3426,7 @@ function ModelPage({ client, basePath, slug, router }) {
|
|
|
3251
3426
|
{
|
|
3252
3427
|
anchorEl: controller.bulkActionMenuAnchor,
|
|
3253
3428
|
open: Boolean(controller.bulkActionMenuAnchor),
|
|
3254
|
-
onClose:
|
|
3429
|
+
onClose: controller.handleCloseBulkActionMenu,
|
|
3255
3430
|
children: controller.bulkActions.map((action) => /* @__PURE__ */ jsx19(
|
|
3256
3431
|
MenuItem2,
|
|
3257
3432
|
{
|
|
@@ -3267,10 +3442,7 @@ function ModelPage({ client, basePath, slug, router }) {
|
|
|
3267
3442
|
{
|
|
3268
3443
|
anchorEl: controller.rowActionMenuAnchor,
|
|
3269
3444
|
open: Boolean(controller.rowActionMenuAnchor),
|
|
3270
|
-
onClose:
|
|
3271
|
-
controller.setRowActionMenuAnchor(null);
|
|
3272
|
-
controller.setRowActionMenuId(null);
|
|
3273
|
-
},
|
|
3445
|
+
onClose: controller.handleCloseRowMenu,
|
|
3274
3446
|
children: /* @__PURE__ */ jsx19(
|
|
3275
3447
|
MenuItem2,
|
|
3276
3448
|
{
|
|
@@ -3347,10 +3519,7 @@ function ModelPage({ client, basePath, slug, router }) {
|
|
|
3347
3519
|
if (controller.isDeleteSubmitting) {
|
|
3348
3520
|
return;
|
|
3349
3521
|
}
|
|
3350
|
-
controller.
|
|
3351
|
-
controller.setDeletePreview(null);
|
|
3352
|
-
controller.setDeletePreviewError(null);
|
|
3353
|
-
controller.setPendingDeleteIds([]);
|
|
3522
|
+
controller.handleClearDeletePreview();
|
|
3354
3523
|
},
|
|
3355
3524
|
onConfirm: () => void controller.handleConfirmDelete()
|
|
3356
3525
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AdminFieldMeta, AdminLocale } from '
|
|
1
|
+
import type { AdminFieldMeta, AdminLocale } from '@xladmin-core/types';
|
|
2
2
|
/**
|
|
3
3
|
* Готовит payload для create/patch так, чтобы nullable-поля можно было очищать,
|
|
4
4
|
* а служебные пустые поля вроде пароля не улетали в API без необходимости.
|