@appcorp/fusion-storybook 0.4.39 → 0.4.40

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.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Bulk Operations Constants
3
+ *
4
+ * Organization:
5
+ * - Page Configuration
6
+ * - Status Options
7
+ */
8
+ export declare const pageLimit: number;
9
+ export declare const BULK_JOB_STATUS_OPTIONS: {
10
+ label: string;
11
+ value: string;
12
+ }[];
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Bulk Operations Constants
3
+ *
4
+ * Organization:
5
+ * - Page Configuration
6
+ * - Status Options
7
+ */
8
+ // ============================================================================
9
+ // PAGE CONFIGURATION
10
+ // ============================================================================
11
+ export const pageLimit = Number(process.env.NEXT_PUBLIC_PAGE_LIMIT) || 10;
12
+ // ============================================================================
13
+ // STATUS OPTIONS
14
+ // ============================================================================
15
+ export const BULK_JOB_STATUS_OPTIONS = [
16
+ { label: "queued", value: "queued" },
17
+ { label: "running", value: "running" },
18
+ { label: "completed", value: "completed" },
19
+ { label: "failed", value: "failed" },
20
+ ];
@@ -0,0 +1,172 @@
1
+ import { type HeaderAction, type RowAction, type TableRow } from "@appcorp/shadcn/components/enhanced-table";
2
+ import { BulkJobRecord } from "../../type";
3
+ export declare const BULK_OPERATIONS_DRAWER: {
4
+ readonly FILTER_DRAWER: string;
5
+ readonly VIEW_DRAWER: string;
6
+ };
7
+ export declare const BULK_OPERATIONS_ACTION_TYPES: {
8
+ readonly RESET_FORM: "RESET_FORM";
9
+ readonly SET_CURRENT_PAGE: "SET_CURRENT_PAGE";
10
+ readonly SET_PAGE_LIMIT: "SET_PAGE_LIMIT";
11
+ readonly SET_SEARCH_QUERY: "SET_SEARCH_QUERY";
12
+ readonly SET_DRAWER: "SET_DRAWER";
13
+ readonly SET_ITEMS: "SET_ITEMS";
14
+ readonly SET_FORM_DATA: "SET_FORM_DATA";
15
+ readonly SET_DISABLE_SAVE_BUTTON: "SET_DISABLE_SAVE_BUTTON";
16
+ readonly SET_INPUT_FIELD: "SET_INPUT_FIELD";
17
+ readonly SET_ERRORS: "SET_ERRORS";
18
+ readonly SET_FILTERS: "SET_FILTERS";
19
+ }, bulkOperationsModuleConfig: import("@react-pakistan/util-functions/factory/generic-module-factory").ModuleConfig<{
20
+ items: BulkJobRecord[];
21
+ count: number;
22
+ types: string[];
23
+ currentPage: number;
24
+ pageLimit: number;
25
+ searchQuery: string;
26
+ filterStatus: string;
27
+ filterType: string;
28
+ createdAt: string;
29
+ errors: Record<string, string>;
30
+ jobId: string;
31
+ processed: number;
32
+ results: BulkJobRecord["results"];
33
+ status: string;
34
+ total: number;
35
+ type: string;
36
+ updatedAt: string;
37
+ webhookUrl: string | null;
38
+ disableSaveButton: boolean;
39
+ drawer: string | null;
40
+ }>, initialBulkOperationsState: {
41
+ items: BulkJobRecord[];
42
+ count: number;
43
+ types: string[];
44
+ currentPage: number;
45
+ pageLimit: number;
46
+ searchQuery: string;
47
+ filterStatus: string;
48
+ filterType: string;
49
+ createdAt: string;
50
+ errors: Record<string, string>;
51
+ jobId: string;
52
+ processed: number;
53
+ results: BulkJobRecord["results"];
54
+ status: string;
55
+ total: number;
56
+ type: string;
57
+ updatedAt: string;
58
+ webhookUrl: string | null;
59
+ disableSaveButton: boolean;
60
+ drawer: string | null;
61
+ }, BulkOperationsProvider: import("react").FC<{
62
+ children: React.ReactNode;
63
+ }>, bulkOperationsReducer: (state: {
64
+ items: BulkJobRecord[];
65
+ count: number;
66
+ types: string[];
67
+ currentPage: number;
68
+ pageLimit: number;
69
+ searchQuery: string;
70
+ filterStatus: string;
71
+ filterType: string;
72
+ createdAt: string;
73
+ errors: Record<string, string>;
74
+ jobId: string;
75
+ processed: number;
76
+ results: BulkJobRecord["results"];
77
+ status: string;
78
+ total: number;
79
+ type: string;
80
+ updatedAt: string;
81
+ webhookUrl: string | null;
82
+ disableSaveButton: boolean;
83
+ drawer: string | null;
84
+ }, action: any) => {
85
+ items: BulkJobRecord[];
86
+ count: number;
87
+ types: string[];
88
+ currentPage: number;
89
+ pageLimit: number;
90
+ searchQuery: string;
91
+ filterStatus: string;
92
+ filterType: string;
93
+ createdAt: string;
94
+ errors: Record<string, string>;
95
+ jobId: string;
96
+ processed: number;
97
+ results: BulkJobRecord["results"];
98
+ status: string;
99
+ total: number;
100
+ type: string;
101
+ updatedAt: string;
102
+ webhookUrl: string | null;
103
+ disableSaveButton: boolean;
104
+ drawer: string | null;
105
+ }, useBulkOperationsContext: () => import("@react-pakistan/util-functions/factory/generic-module-factory").GenericModuleContextWithHandlers<{
106
+ items: BulkJobRecord[];
107
+ count: number;
108
+ types: string[];
109
+ currentPage: number;
110
+ pageLimit: number;
111
+ searchQuery: string;
112
+ filterStatus: string;
113
+ filterType: string;
114
+ createdAt: string;
115
+ errors: Record<string, string>;
116
+ jobId: string;
117
+ processed: number;
118
+ results: BulkJobRecord["results"];
119
+ status: string;
120
+ total: number;
121
+ type: string;
122
+ updatedAt: string;
123
+ webhookUrl: string | null;
124
+ disableSaveButton: boolean;
125
+ drawer: string | null;
126
+ }>;
127
+ export declare const BULK_OPERATIONS_STATUS_OPTIONS: {
128
+ label: string;
129
+ value: string;
130
+ }[];
131
+ export declare const useBulkOperationsModule: () => {
132
+ applyFilters: () => void;
133
+ clearFilters: () => void;
134
+ clearSearch: () => void;
135
+ closeDrawer: () => void;
136
+ handleChange: (field: string, value: string | number | boolean | undefined) => void;
137
+ handleFilters: () => void;
138
+ handlePageChange: (pageOrEvent?: unknown) => void;
139
+ handlePageLimitChange: (k: string, value: object) => void;
140
+ handleRefresh: () => void;
141
+ handleSearch: (query: string) => void;
142
+ handleView: (row?: TableRow) => void;
143
+ headerActions: HeaderAction[];
144
+ listFetchNow: (url?: string, config?: import("@react-pakistan/util-functions/hooks/use-fetch").FetchConfig) => void;
145
+ listLoading: boolean;
146
+ rowActions: RowAction[];
147
+ handleCloseDrawer?: () => void;
148
+ handleSubmit?: (data: any) => void;
149
+ state: {
150
+ items: BulkJobRecord[];
151
+ count: number;
152
+ types: string[];
153
+ currentPage: number;
154
+ pageLimit: number;
155
+ searchQuery: string;
156
+ filterStatus: string;
157
+ filterType: string;
158
+ createdAt: string;
159
+ errors: Record<string, string>;
160
+ jobId: string;
161
+ processed: number;
162
+ results: BulkJobRecord["results"];
163
+ status: string;
164
+ total: number;
165
+ type: string;
166
+ updatedAt: string;
167
+ webhookUrl: string | null;
168
+ disableSaveButton: boolean;
169
+ drawer: string | null;
170
+ };
171
+ dispatch: React.Dispatch<any>;
172
+ };
@@ -0,0 +1,283 @@
1
+ "use client";
2
+ /**
3
+ * Bulk Operations Module — business logic + API integration
4
+ *
5
+ * Read-only module that lists all Redis-backed bulk jobs for the current school.
6
+ * Uses the generic module state (`createGenericModule`) wired to `useModuleEntityV2`.
7
+ * No create/edit/delete — only list (search, filter, paginate), a view drawer,
8
+ * and a manual refresh header action.
9
+ */
10
+ import { useCallback, useEffect, useMemo, useRef } from "react";
11
+ import { useTheme } from "next-themes";
12
+ import { useTranslations } from "next-intl";
13
+ import { useDebounce } from "@react-pakistan/util-functions/hooks/use-debounce";
14
+ import { useModuleEntityV2, } from "@react-pakistan/util-functions/hooks/use-module-entity-v2";
15
+ import { createGenericModule } from "@react-pakistan/util-functions/factory/generic-module-factory";
16
+ import { DRAWER_TYPES } from "@react-pakistan/util-functions/factory/generic-component-factory";
17
+ import { generateThemeToast, TOAST_VARIANT, } from "@appcorp/shadcn/lib/toast-utils";
18
+ import { pageLimit } from "./constants";
19
+ import { BULK_OPERATIONS_API_ROUTES } from "../../constants";
20
+ import { getCachedWorkspaceSync } from "../workspace/cache";
21
+ // ============================================================================
22
+ // 1.1 DRAWER TYPES
23
+ // ============================================================================
24
+ export const BULK_OPERATIONS_DRAWER = {
25
+ FILTER_DRAWER: DRAWER_TYPES.FILTER_DRAWER,
26
+ VIEW_DRAWER: DRAWER_TYPES.VIEW_DRAWER,
27
+ };
28
+ // ============================================================================
29
+ // 1.2 MODULE CONFIGURATION
30
+ // ============================================================================
31
+ const BULK_OPERATIONS_CONFIG = {
32
+ name: "Bulk Operations",
33
+ displayName: "Bulk Operations",
34
+ drawerTypes: DRAWER_TYPES,
35
+ initialState: {
36
+ // List Data
37
+ items: [],
38
+ count: 0,
39
+ types: [],
40
+ // Search & Pagination
41
+ currentPage: 1,
42
+ pageLimit,
43
+ searchQuery: "",
44
+ // Filters
45
+ filterStatus: "",
46
+ filterType: "",
47
+ // View Drawer Data (populated via SET_FORM_DATA spread on row View)
48
+ createdAt: "",
49
+ errors: {},
50
+ jobId: "",
51
+ processed: 0,
52
+ results: null,
53
+ status: "",
54
+ total: 0,
55
+ type: "",
56
+ updatedAt: "",
57
+ webhookUrl: null,
58
+ // UI State
59
+ disableSaveButton: false,
60
+ drawer: null,
61
+ },
62
+ };
63
+ export const { actionTypes: BULK_OPERATIONS_ACTION_TYPES, config: bulkOperationsModuleConfig, initialState: initialBulkOperationsState, Provider: BulkOperationsProvider, reducer: bulkOperationsReducer, useContext: useBulkOperationsContext, } = createGenericModule(BULK_OPERATIONS_CONFIG);
64
+ // ============================================================================
65
+ // 1.3 ENHANCED BULK OPERATIONS HOOK WITH API INTEGRATION
66
+ // ============================================================================
67
+ export const BULK_OPERATIONS_STATUS_OPTIONS = [
68
+ { label: "queued", value: "queued" },
69
+ { label: "running", value: "running" },
70
+ { label: "completed", value: "completed" },
71
+ { label: "failed", value: "failed" },
72
+ ];
73
+ export const useBulkOperationsModule = () => {
74
+ var _a;
75
+ const context = useBulkOperationsContext();
76
+ const { dispatch } = context;
77
+ const state = context.state;
78
+ const t = useTranslations("bulkOperations");
79
+ const { theme } = useTheme();
80
+ const workspace = getCachedWorkspaceSync();
81
+ const schoolId = ((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id) || "";
82
+ const listFetchNowRef = useRef(null);
83
+ const debouncedQuery = useDebounce(state.searchQuery, 800);
84
+ // ==========================================================================
85
+ // 1.3.1 API PARAMETERS
86
+ // ==========================================================================
87
+ const listParams = useMemo(() => (Object.assign(Object.assign(Object.assign({ currentPage: state.currentPage, pageLimit: state.pageLimit, schoolId }, (state.filterType ? { type: state.filterType } : {})), (state.filterStatus ? { status: state.filterStatus } : {})), (debouncedQuery ? { q: debouncedQuery } : {}))), [
88
+ state.currentPage,
89
+ state.filterStatus,
90
+ state.filterType,
91
+ state.pageLimit,
92
+ debouncedQuery,
93
+ schoolId,
94
+ ]);
95
+ const noopParams = useMemo(() => ({}), []);
96
+ const noopCallback = useCallback(() => { }, []);
97
+ // ==========================================================================
98
+ // 1.3.2 UTILITIES
99
+ // ==========================================================================
100
+ const showToast = useCallback((description, variant) => {
101
+ generateThemeToast({
102
+ description,
103
+ theme: theme,
104
+ variant,
105
+ });
106
+ }, [theme]);
107
+ const closeDrawer = useCallback(() => {
108
+ dispatch({ type: BULK_OPERATIONS_ACTION_TYPES.SET_DRAWER, payload: { drawer: null } });
109
+ }, [dispatch]);
110
+ // ==========================================================================
111
+ // 1.3.3 API CALLBACKS
112
+ // ==========================================================================
113
+ const listCallback = useCallback(({ data, error }) => {
114
+ var _a, _b;
115
+ if (error) {
116
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
117
+ return;
118
+ }
119
+ if (data) {
120
+ const response = data;
121
+ dispatch({
122
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_ITEMS,
123
+ payload: {
124
+ items: (_a = response.items) !== null && _a !== void 0 ? _a : [],
125
+ count: typeof response.count === "number" ? response.count : 0,
126
+ },
127
+ });
128
+ dispatch({
129
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_INPUT_FIELD,
130
+ payload: { key: "types", value: (_b = response.types) !== null && _b !== void 0 ? _b : [] },
131
+ });
132
+ }
133
+ }, [dispatch, showToast, t]);
134
+ // ==========================================================================
135
+ // 1.3.4 API HOOKS
136
+ // ==========================================================================
137
+ const { listFetchNow, listLoading } = useModuleEntityV2({
138
+ byIdCallback: noopCallback,
139
+ byIdParams: noopParams,
140
+ listCallback,
141
+ listParams,
142
+ listUrl: BULK_OPERATIONS_API_ROUTES.LIST,
143
+ searchQuery: debouncedQuery,
144
+ unitByIdUrl: BULK_OPERATIONS_API_ROUTES.LIST,
145
+ unitUrl: BULK_OPERATIONS_API_ROUTES.LIST,
146
+ updateCallback: noopCallback,
147
+ updateParams: noopParams,
148
+ headers: {},
149
+ });
150
+ // ==========================================================================
151
+ // 1.3.5 HANDLERS
152
+ // ==========================================================================
153
+ const handleChange = useCallback((field, value) => {
154
+ dispatch({
155
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_INPUT_FIELD,
156
+ payload: { key: field, value },
157
+ });
158
+ }, [dispatch]);
159
+ const handlePageChange = useCallback((pageOrEvent) => {
160
+ const page = typeof pageOrEvent === "number" && !isNaN(pageOrEvent)
161
+ ? pageOrEvent
162
+ : state.currentPage + 1;
163
+ dispatch({
164
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_CURRENT_PAGE,
165
+ payload: { currentPage: page },
166
+ });
167
+ }, [dispatch, state.currentPage]);
168
+ const handlePageLimitChange = useCallback((k, value) => {
169
+ const val = Object.assign({}, value);
170
+ dispatch({
171
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_PAGE_LIMIT,
172
+ payload: { pageLimit: Number(val.option) },
173
+ });
174
+ dispatch({
175
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_CURRENT_PAGE,
176
+ payload: { currentPage: 1 },
177
+ });
178
+ }, [dispatch]);
179
+ const handleSearch = useCallback((query) => {
180
+ dispatch({
181
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_SEARCH_QUERY,
182
+ payload: { searchQuery: query },
183
+ });
184
+ }, [dispatch]);
185
+ const clearFilters = useCallback(() => {
186
+ dispatch({
187
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_FILTERS,
188
+ payload: { filters: { filterType: "", filterStatus: "" } },
189
+ });
190
+ dispatch({
191
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_CURRENT_PAGE,
192
+ payload: { currentPage: 1 },
193
+ });
194
+ }, [dispatch]);
195
+ const clearSearch = useCallback(() => {
196
+ dispatch({
197
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_SEARCH_QUERY,
198
+ payload: { searchQuery: "" },
199
+ });
200
+ }, [dispatch]);
201
+ const handleFilters = useCallback(() => {
202
+ dispatch({
203
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_DRAWER,
204
+ payload: { drawer: BULK_OPERATIONS_DRAWER.FILTER_DRAWER },
205
+ });
206
+ }, [dispatch]);
207
+ const handleRefresh = useCallback(() => {
208
+ var _a;
209
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
210
+ }, []);
211
+ const handleView = useCallback((row) => {
212
+ if (!row)
213
+ return;
214
+ dispatch({
215
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_FORM_DATA,
216
+ payload: { form: Object.assign({}, row) },
217
+ });
218
+ dispatch({
219
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_DRAWER,
220
+ payload: { drawer: BULK_OPERATIONS_DRAWER.VIEW_DRAWER },
221
+ });
222
+ }, [dispatch]);
223
+ const applyFilters = useCallback(() => {
224
+ dispatch({
225
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_CURRENT_PAGE,
226
+ payload: { currentPage: 1 },
227
+ });
228
+ closeDrawer();
229
+ }, [dispatch, closeDrawer]);
230
+ // ==========================================================================
231
+ // 1.3.6 EFFECTS
232
+ // ==========================================================================
233
+ useEffect(() => {
234
+ listFetchNowRef.current = listFetchNow;
235
+ }, [listFetchNow]);
236
+ useEffect(() => {
237
+ var _a;
238
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
239
+ }, [listParams]);
240
+ // ==========================================================================
241
+ // 1.3.7 HEADER & ROW ACTIONS
242
+ // ==========================================================================
243
+ const headerActions = useMemo(() => [
244
+ {
245
+ enabled: true,
246
+ handleOnClick: handleRefresh,
247
+ label: t("actionsButtonRefresh"),
248
+ order: 0,
249
+ },
250
+ {
251
+ enabled: true,
252
+ handleOnClick: handleFilters,
253
+ label: t("actionsButtonFilters"),
254
+ order: 1,
255
+ },
256
+ ], [handleFilters, handleRefresh, t]);
257
+ const rowActions = useMemo(() => [
258
+ {
259
+ enabled: true,
260
+ handleOnClick: handleView,
261
+ label: t("actionsButtonView"),
262
+ order: 0,
263
+ },
264
+ ], [handleView, t]);
265
+ // ==========================================================================
266
+ // 1.3.8 RETURN
267
+ // ==========================================================================
268
+ return Object.assign(Object.assign({}, context), { applyFilters,
269
+ clearFilters,
270
+ clearSearch,
271
+ closeDrawer,
272
+ handleChange,
273
+ handleFilters,
274
+ handlePageChange,
275
+ handlePageLimitChange,
276
+ handleRefresh,
277
+ handleSearch,
278
+ handleView,
279
+ headerActions,
280
+ listFetchNow,
281
+ listLoading,
282
+ rowActions });
283
+ };
@@ -0,0 +1 @@
1
+ export declare const BulkOperationsFilter: () => import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Bulk Operations Filter
5
+ *
6
+ * Filter UI for the bulk-operations list. Supports filterType (select, options
7
+ * populated from the list response `types`) and filterStatus (select).
8
+ *
9
+ * Uses the base generic context directly (state + dispatch) rather than the
10
+ * enhanced module hook, so consuming this component does not create a second
11
+ * useModuleEntityV2 instance / auto-fetch effect.
12
+ */
13
+ import { useTranslations } from "next-intl";
14
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@appcorp/shadcn/components/ui/select";
15
+ import { Label } from "@appcorp/shadcn/components/ui/label";
16
+ import { BULK_OPERATIONS_ACTION_TYPES, useBulkOperationsContext } from "./context";
17
+ import { BULK_JOB_STATUS_OPTIONS } from "./constants";
18
+ export const BulkOperationsFilter = () => {
19
+ const t = useTranslations("bulkOperations");
20
+ const { state, dispatch } = useBulkOperationsContext();
21
+ const { filterType, filterStatus, types } = state;
22
+ const handleChange = (field, value) => {
23
+ dispatch({
24
+ type: BULK_OPERATIONS_ACTION_TYPES.SET_INPUT_FIELD,
25
+ payload: { key: field, value },
26
+ });
27
+ };
28
+ const typeValue = filterType || "__none";
29
+ const statusValue = filterStatus || "__none";
30
+ return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "filterType", children: t("filterTypeLabel") }), _jsxs(Select, { value: typeValue, onValueChange: (v) => handleChange("filterType", v === "__none" ? "" : v), children: [_jsx(SelectTrigger, { id: "filterType", className: "w-full", children: _jsx(SelectValue, { placeholder: t("filterAllTypes") }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "__none", children: t("filterAllTypes") }), types.map((type) => (_jsx(SelectItem, { value: type, children: type }, type)))] })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "filterStatus", children: t("filterStatusLabel") }), _jsxs(Select, { value: statusValue, onValueChange: (v) => handleChange("filterStatus", v === "__none" ? "" : v), children: [_jsx(SelectTrigger, { id: "filterStatus", className: "w-full", children: _jsx(SelectValue, { placeholder: t("filterAllStatuses") }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "__none", children: t("filterAllStatuses") }), BULK_JOB_STATUS_OPTIONS.map((opt) => (_jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)))] })] })] })] }));
31
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Bulk Operations Page Component
3
+ *
4
+ * Thin wrapper around GenericModulePage. All handlers, header actions, and row
5
+ * actions live in context.tsx — this file only owns:
6
+ * - tableBodyCols (static, module-level constant)
7
+ * - bulkOperationsConfig (memoised on locale + drawer change only)
8
+ * - permission guard
9
+ *
10
+ * Exported utilities: `BulkOperationsPage`
11
+ */
12
+ import { FC } from "react";
13
+ import { USER_ROLE } from "../../type";
14
+ interface Props {
15
+ cancelLabel: string;
16
+ drawerFilterDescription: string;
17
+ drawerFilterTitle: string;
18
+ drawerViewDescription: string;
19
+ drawerViewTitle: string;
20
+ labelActions: string;
21
+ labelId: string;
22
+ labelProgress: string;
23
+ labelState: string;
24
+ labelStatus: string;
25
+ labelType: string;
26
+ saveLabel: string;
27
+ searchPlaceholder: string;
28
+ tableDescription: string;
29
+ tableTitle: string;
30
+ userRole: USER_ROLE;
31
+ }
32
+ export declare const BulkOperationsPage: FC<Props>;
33
+ export {};