@tidecloak/ui-framework 0.0.1
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/README.md +377 -0
- package/dist/index.d.mts +2739 -0
- package/dist/index.d.ts +2739 -0
- package/dist/index.js +12869 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +12703 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +54 -0
- package/src/components/common/ActionButton.tsx +234 -0
- package/src/components/common/EmptyState.tsx +140 -0
- package/src/components/common/LoadingSkeleton.tsx +121 -0
- package/src/components/common/RefreshButton.tsx +127 -0
- package/src/components/common/StatusBadge.tsx +177 -0
- package/src/components/common/index.ts +31 -0
- package/src/components/data-table/DataTable.tsx +201 -0
- package/src/components/data-table/PaginatedTable.tsx +247 -0
- package/src/components/data-table/index.ts +2 -0
- package/src/components/dialogs/CollapsibleSection.tsx +184 -0
- package/src/components/dialogs/ConfirmDialog.tsx +264 -0
- package/src/components/dialogs/DetailDialog.tsx +228 -0
- package/src/components/dialogs/index.ts +3 -0
- package/src/components/index.ts +5 -0
- package/src/components/pages/base/ApprovalsPageBase.tsx +680 -0
- package/src/components/pages/base/LogsPageBase.tsx +581 -0
- package/src/components/pages/base/RolesPageBase.tsx +1470 -0
- package/src/components/pages/base/TemplatesPageBase.tsx +761 -0
- package/src/components/pages/base/UsersPageBase.tsx +843 -0
- package/src/components/pages/base/index.ts +58 -0
- package/src/components/pages/connected/ApprovalsPage.tsx +797 -0
- package/src/components/pages/connected/LogsPage.tsx +267 -0
- package/src/components/pages/connected/RolesPage.tsx +525 -0
- package/src/components/pages/connected/TemplatesPage.tsx +181 -0
- package/src/components/pages/connected/UsersPage.tsx +237 -0
- package/src/components/pages/connected/index.ts +36 -0
- package/src/components/pages/index.ts +5 -0
- package/src/components/tabs/TabsView.tsx +300 -0
- package/src/components/tabs/index.ts +1 -0
- package/src/components/ui/index.tsx +1001 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useAutoRefresh.ts +119 -0
- package/src/hooks/usePagination.ts +152 -0
- package/src/hooks/useSelection.ts +81 -0
- package/src/index.ts +256 -0
- package/src/theme.ts +185 -0
- package/src/tide/index.ts +19 -0
- package/src/tide/tidePolicy.ts +270 -0
- package/src/types/index.ts +484 -0
- package/src/utils/index.ts +121 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,2739 @@
|
|
|
1
|
+
export { QueryClient, QueryClientConfig, QueryClientProvider, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
+
import React$1, { ReactNode } from 'react';
|
|
3
|
+
import { ClassValue } from 'clsx';
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Theme constants for consistent styling across components.
|
|
8
|
+
* Use CSS variables for runtime theming, constants for TypeScript type safety.
|
|
9
|
+
*/
|
|
10
|
+
declare const colors: {
|
|
11
|
+
readonly background: {
|
|
12
|
+
readonly primary: "var(--tc-bg-primary, #ffffff)";
|
|
13
|
+
readonly secondary: "var(--tc-bg-secondary, #f9fafb)";
|
|
14
|
+
readonly muted: "var(--tc-bg-muted, #f3f4f6)";
|
|
15
|
+
readonly overlay: "var(--tc-bg-overlay, rgba(0, 0, 0, 0.5))";
|
|
16
|
+
};
|
|
17
|
+
readonly foreground: {
|
|
18
|
+
readonly primary: "var(--tc-fg-primary, #111827)";
|
|
19
|
+
readonly secondary: "var(--tc-fg-secondary, #374151)";
|
|
20
|
+
readonly muted: "var(--tc-fg-muted, #6b7280)";
|
|
21
|
+
readonly disabled: "var(--tc-fg-disabled, #9ca3af)";
|
|
22
|
+
};
|
|
23
|
+
readonly border: {
|
|
24
|
+
readonly default: "var(--tc-border, #e5e7eb)";
|
|
25
|
+
readonly focus: "var(--tc-border-focus, #3b82f6)";
|
|
26
|
+
readonly error: "var(--tc-border-error, #dc2626)";
|
|
27
|
+
};
|
|
28
|
+
readonly status: {
|
|
29
|
+
readonly success: "var(--tc-success, #16a34a)";
|
|
30
|
+
readonly successBg: "var(--tc-success-bg, #dcfce7)";
|
|
31
|
+
readonly error: "var(--tc-error, #dc2626)";
|
|
32
|
+
readonly errorBg: "var(--tc-error-bg, #fef2f2)";
|
|
33
|
+
readonly warning: "var(--tc-warning, #f59e0b)";
|
|
34
|
+
readonly warningBg: "var(--tc-warning-bg, #fef3c7)";
|
|
35
|
+
readonly info: "var(--tc-info, #3b82f6)";
|
|
36
|
+
readonly infoBg: "var(--tc-info-bg, #eff6ff)";
|
|
37
|
+
readonly pending: "var(--tc-pending, #6b7280)";
|
|
38
|
+
readonly pendingBg: "var(--tc-pending-bg, #f3f4f6)";
|
|
39
|
+
};
|
|
40
|
+
readonly action: {
|
|
41
|
+
readonly primary: "var(--tc-action-primary, #3b82f6)";
|
|
42
|
+
readonly primaryHover: "var(--tc-action-primary-hover, #2563eb)";
|
|
43
|
+
readonly danger: "var(--tc-action-danger, #dc2626)";
|
|
44
|
+
readonly dangerHover: "var(--tc-action-danger-hover, #b91c1c)";
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
declare const spacing: {
|
|
48
|
+
readonly xs: "0.25rem";
|
|
49
|
+
readonly sm: "0.5rem";
|
|
50
|
+
readonly md: "1rem";
|
|
51
|
+
readonly lg: "1.5rem";
|
|
52
|
+
readonly xl: "2rem";
|
|
53
|
+
readonly "2xl": "3rem";
|
|
54
|
+
};
|
|
55
|
+
declare const radius: {
|
|
56
|
+
readonly sm: "0.25rem";
|
|
57
|
+
readonly md: "0.375rem";
|
|
58
|
+
readonly lg: "0.5rem";
|
|
59
|
+
readonly full: "9999px";
|
|
60
|
+
};
|
|
61
|
+
declare const fontSize: {
|
|
62
|
+
readonly xs: "0.75rem";
|
|
63
|
+
readonly sm: "0.875rem";
|
|
64
|
+
readonly base: "1rem";
|
|
65
|
+
readonly lg: "1.125rem";
|
|
66
|
+
readonly xl: "1.25rem";
|
|
67
|
+
readonly "2xl": "1.5rem";
|
|
68
|
+
};
|
|
69
|
+
declare const zIndex: {
|
|
70
|
+
readonly dropdown: 50;
|
|
71
|
+
readonly sticky: 100;
|
|
72
|
+
readonly modal: 200;
|
|
73
|
+
readonly overlay: 300;
|
|
74
|
+
readonly toast: 400;
|
|
75
|
+
};
|
|
76
|
+
declare const duration: {
|
|
77
|
+
readonly fast: "150ms";
|
|
78
|
+
readonly normal: "200ms";
|
|
79
|
+
readonly slow: "300ms";
|
|
80
|
+
};
|
|
81
|
+
declare const focusRing: {
|
|
82
|
+
readonly outline: "2px solid var(--tc-border-focus, #3b82f6)";
|
|
83
|
+
readonly outlineOffset: "2px";
|
|
84
|
+
};
|
|
85
|
+
declare const shadow: {
|
|
86
|
+
readonly sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)";
|
|
87
|
+
readonly md: "0 4px 6px -1px rgba(0, 0, 0, 0.1)";
|
|
88
|
+
readonly lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1)";
|
|
89
|
+
};
|
|
90
|
+
declare const themeCSS = "\n :root {\n --tc-bg-primary: #ffffff;\n --tc-bg-secondary: #f9fafb;\n --tc-bg-muted: #f3f4f6;\n --tc-bg-overlay: rgba(0, 0, 0, 0.5);\n --tc-fg-primary: #111827;\n --tc-fg-secondary: #374151;\n --tc-fg-muted: #6b7280;\n --tc-fg-disabled: #9ca3af;\n --tc-border: #e5e7eb;\n --tc-border-focus: #3b82f6;\n --tc-border-error: #dc2626;\n --tc-success: #16a34a;\n --tc-success-bg: #dcfce7;\n --tc-error: #dc2626;\n --tc-error-bg: #fef2f2;\n --tc-warning: #f59e0b;\n --tc-warning-bg: #fef3c7;\n --tc-info: #3b82f6;\n --tc-info-bg: #eff6ff;\n --tc-pending: #6b7280;\n --tc-pending-bg: #f3f4f6;\n --tc-action-primary: #3b82f6;\n --tc-action-primary-hover: #2563eb;\n --tc-action-danger: #dc2626;\n --tc-action-danger-hover: #b91c1c;\n }\n\n @media (prefers-color-scheme: dark) {\n :root {\n --tc-bg-primary: #1f2937;\n --tc-bg-secondary: #111827;\n --tc-bg-muted: #374151;\n --tc-bg-overlay: rgba(0, 0, 0, 0.7);\n --tc-fg-primary: #f9fafb;\n --tc-fg-secondary: #e5e7eb;\n --tc-fg-muted: #9ca3af;\n --tc-fg-disabled: #6b7280;\n --tc-border: #374151;\n --tc-border-focus: #60a5fa;\n --tc-border-error: #f87171;\n --tc-success: #22c55e;\n --tc-success-bg: #14532d;\n --tc-error: #f87171;\n --tc-error-bg: #7f1d1d;\n --tc-warning: #fbbf24;\n --tc-warning-bg: #78350f;\n --tc-info: #60a5fa;\n --tc-info-bg: #1e3a8a;\n --tc-pending: #9ca3af;\n --tc-pending-bg: #374151;\n --tc-action-primary: #60a5fa;\n --tc-action-primary-hover: #3b82f6;\n --tc-action-danger: #f87171;\n --tc-action-danger-hover: #dc2626;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n }\n";
|
|
91
|
+
declare function injectThemeCSS(): void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Base interface for all data items - requires an id
|
|
95
|
+
*/
|
|
96
|
+
interface BaseDataItem {
|
|
97
|
+
id: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Generic change set request structure for approval workflows
|
|
101
|
+
*/
|
|
102
|
+
interface ChangeSetRequest {
|
|
103
|
+
changeSetId: string;
|
|
104
|
+
changeSetType: string;
|
|
105
|
+
actionType: string;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Base interface for items that can be approved
|
|
109
|
+
*/
|
|
110
|
+
interface ApprovableItem extends BaseDataItem {
|
|
111
|
+
status: string;
|
|
112
|
+
retrievalInfo?: ChangeSetRequest;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Column definition for data tables
|
|
116
|
+
* Note: T can be any type with the properties needed for rendering
|
|
117
|
+
*/
|
|
118
|
+
interface ColumnDef<T = any> {
|
|
119
|
+
/** Unique key for the column */
|
|
120
|
+
key: string;
|
|
121
|
+
/** Display header */
|
|
122
|
+
header: string | ReactNode;
|
|
123
|
+
/** Cell renderer */
|
|
124
|
+
cell: (item: T, index: number) => ReactNode;
|
|
125
|
+
/** Optional sorting key (if different from key) */
|
|
126
|
+
sortKey?: keyof T | string;
|
|
127
|
+
/** Enable sorting for this column */
|
|
128
|
+
sortable?: boolean;
|
|
129
|
+
/** Responsive visibility */
|
|
130
|
+
responsive?: "sm" | "md" | "lg" | "xl" | "always";
|
|
131
|
+
/** Column width class */
|
|
132
|
+
width?: string;
|
|
133
|
+
/** Alignment */
|
|
134
|
+
align?: "left" | "center" | "right";
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Table action definition
|
|
138
|
+
*/
|
|
139
|
+
interface TableAction<T extends BaseDataItem> {
|
|
140
|
+
/** Action identifier */
|
|
141
|
+
key: string;
|
|
142
|
+
/** Display label */
|
|
143
|
+
label: string;
|
|
144
|
+
/** Icon component */
|
|
145
|
+
icon?: ReactNode;
|
|
146
|
+
/** Action handler */
|
|
147
|
+
onClick: (item: T) => void | Promise<void>;
|
|
148
|
+
/** Visibility condition */
|
|
149
|
+
visible?: (item: T) => boolean;
|
|
150
|
+
/** Disabled condition */
|
|
151
|
+
disabled?: (item: T) => boolean;
|
|
152
|
+
/** Button variant */
|
|
153
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline";
|
|
154
|
+
/** Color class */
|
|
155
|
+
colorClass?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Bulk action definition for multi-select
|
|
159
|
+
*/
|
|
160
|
+
interface BulkAction<T extends BaseDataItem> {
|
|
161
|
+
key: string;
|
|
162
|
+
label: string;
|
|
163
|
+
icon?: ReactNode;
|
|
164
|
+
onClick: (items: T[]) => void | Promise<void>;
|
|
165
|
+
disabled?: (items: T[]) => boolean;
|
|
166
|
+
variant?: "default" | "destructive" | "ghost" | "outline";
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Sort configuration
|
|
170
|
+
*/
|
|
171
|
+
interface SortConfig {
|
|
172
|
+
key: string;
|
|
173
|
+
direction: "asc" | "desc";
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Pagination configuration
|
|
177
|
+
*/
|
|
178
|
+
interface PaginationConfig {
|
|
179
|
+
page: number;
|
|
180
|
+
pageSize: number;
|
|
181
|
+
totalItems: number;
|
|
182
|
+
totalPages: number;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Tab definition
|
|
186
|
+
*/
|
|
187
|
+
interface TabDef {
|
|
188
|
+
/** Unique tab key */
|
|
189
|
+
key: string;
|
|
190
|
+
/** Display label */
|
|
191
|
+
label: string;
|
|
192
|
+
/** Optional badge count */
|
|
193
|
+
badge?: number | null;
|
|
194
|
+
/** Badge variant */
|
|
195
|
+
badgeVariant?: "default" | "secondary" | "destructive" | "outline";
|
|
196
|
+
/** Tab icon */
|
|
197
|
+
icon?: ReactNode;
|
|
198
|
+
/** Tab content */
|
|
199
|
+
content: ReactNode;
|
|
200
|
+
/** Disabled state */
|
|
201
|
+
disabled?: boolean;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Dialog configuration
|
|
205
|
+
*/
|
|
206
|
+
interface DialogConfig {
|
|
207
|
+
/** Dialog title */
|
|
208
|
+
title: string;
|
|
209
|
+
/** Dialog description */
|
|
210
|
+
description?: string;
|
|
211
|
+
/** Dialog size */
|
|
212
|
+
size?: "sm" | "md" | "lg" | "xl" | "full";
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Confirmation dialog configuration
|
|
216
|
+
*/
|
|
217
|
+
interface ConfirmDialogConfig extends DialogConfig {
|
|
218
|
+
/** Confirm button label */
|
|
219
|
+
confirmLabel?: string;
|
|
220
|
+
/** Cancel button label */
|
|
221
|
+
cancelLabel?: string;
|
|
222
|
+
/** Confirm button variant */
|
|
223
|
+
confirmVariant?: "default" | "destructive";
|
|
224
|
+
/** Whether action is in progress */
|
|
225
|
+
isLoading?: boolean;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Detail dialog field definition
|
|
229
|
+
*/
|
|
230
|
+
interface DetailField<T> {
|
|
231
|
+
/** Field key */
|
|
232
|
+
key: string;
|
|
233
|
+
/** Display label */
|
|
234
|
+
label: string;
|
|
235
|
+
/** Value renderer */
|
|
236
|
+
render: (item: T) => ReactNode;
|
|
237
|
+
/** Full width */
|
|
238
|
+
fullWidth?: boolean;
|
|
239
|
+
/** Hide condition */
|
|
240
|
+
hidden?: (item: T) => boolean;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Form field types
|
|
244
|
+
*/
|
|
245
|
+
type FormFieldType = "text" | "number" | "boolean" | "select" | "textarea" | "code" | "password" | "email" | "date" | "datetime";
|
|
246
|
+
/**
|
|
247
|
+
* Form field definition
|
|
248
|
+
*/
|
|
249
|
+
interface FormFieldDef {
|
|
250
|
+
/** Field key */
|
|
251
|
+
key: string;
|
|
252
|
+
/** Display label */
|
|
253
|
+
label: string;
|
|
254
|
+
/** Field type */
|
|
255
|
+
type: FormFieldType;
|
|
256
|
+
/** Help text */
|
|
257
|
+
helpText?: string;
|
|
258
|
+
/** Required field */
|
|
259
|
+
required?: boolean;
|
|
260
|
+
/** Placeholder text */
|
|
261
|
+
placeholder?: string;
|
|
262
|
+
/** Default value */
|
|
263
|
+
defaultValue?: unknown;
|
|
264
|
+
/** Options for select fields */
|
|
265
|
+
options?: SelectOption[];
|
|
266
|
+
/** Validation function */
|
|
267
|
+
validate?: (value: unknown) => string | null;
|
|
268
|
+
/** Code editor language */
|
|
269
|
+
codeLanguage?: string;
|
|
270
|
+
/** Disabled condition */
|
|
271
|
+
disabled?: boolean;
|
|
272
|
+
/** Full width */
|
|
273
|
+
fullWidth?: boolean;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Select option
|
|
277
|
+
*/
|
|
278
|
+
interface SelectOption {
|
|
279
|
+
label: string;
|
|
280
|
+
value: string | number | boolean;
|
|
281
|
+
description?: string;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Dynamic parameter definition (for policy templates etc.)
|
|
285
|
+
*/
|
|
286
|
+
interface ParameterDef {
|
|
287
|
+
name: string;
|
|
288
|
+
type: "string" | "number" | "boolean" | "select";
|
|
289
|
+
helpText: string;
|
|
290
|
+
required: boolean;
|
|
291
|
+
defaultValue?: unknown;
|
|
292
|
+
options?: string[];
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Status types with associated colors
|
|
296
|
+
*/
|
|
297
|
+
type StatusType = "pending" | "approved" | "rejected" | "committed" | "cancelled" | "mixed" | "ready" | "error" | "warning" | "info" | "success";
|
|
298
|
+
/**
|
|
299
|
+
* Status configuration
|
|
300
|
+
*/
|
|
301
|
+
interface StatusConfig {
|
|
302
|
+
label: string;
|
|
303
|
+
variant: StatusType;
|
|
304
|
+
icon?: ReactNode;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Badge configuration for custom badges
|
|
308
|
+
*/
|
|
309
|
+
interface BadgeConfig {
|
|
310
|
+
label: string;
|
|
311
|
+
colorClass?: string;
|
|
312
|
+
variant?: "default" | "secondary" | "destructive" | "outline";
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Action result for async operations
|
|
316
|
+
*/
|
|
317
|
+
interface ActionResult {
|
|
318
|
+
success: boolean;
|
|
319
|
+
message?: string;
|
|
320
|
+
error?: Error;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Async action handler type
|
|
324
|
+
*/
|
|
325
|
+
type AsyncActionHandler<T = void, R = ActionResult> = (arg: T) => Promise<R>;
|
|
326
|
+
/**
|
|
327
|
+
* Approval decision
|
|
328
|
+
*/
|
|
329
|
+
interface ApprovalDecision$1 {
|
|
330
|
+
userId: string;
|
|
331
|
+
userName?: string;
|
|
332
|
+
userEmail?: string;
|
|
333
|
+
approved: boolean;
|
|
334
|
+
timestamp: string | number;
|
|
335
|
+
signature?: string;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Approval status with threshold
|
|
339
|
+
*/
|
|
340
|
+
interface ApprovalStatus {
|
|
341
|
+
approvalCount: number;
|
|
342
|
+
rejectionCount: number;
|
|
343
|
+
threshold: number;
|
|
344
|
+
decisions?: ApprovalDecision$1[];
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Raw approval request for signing
|
|
348
|
+
*/
|
|
349
|
+
interface RawApprovalRequest {
|
|
350
|
+
changesetId: string;
|
|
351
|
+
changeSetDraftRequests: string;
|
|
352
|
+
requiresApprovalPopup?: boolean;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Signed approval response
|
|
356
|
+
*/
|
|
357
|
+
interface SignedApprovalResponse {
|
|
358
|
+
id: string;
|
|
359
|
+
approved?: {
|
|
360
|
+
request: Uint8Array;
|
|
361
|
+
};
|
|
362
|
+
denied?: boolean;
|
|
363
|
+
}
|
|
364
|
+
interface AutoRefreshOptions {
|
|
365
|
+
/** Refresh interval in seconds */
|
|
366
|
+
intervalSeconds: number;
|
|
367
|
+
/** Whether auto-refresh is enabled */
|
|
368
|
+
enabled?: boolean;
|
|
369
|
+
/** Refresh callback */
|
|
370
|
+
refresh: () => void | Promise<unknown>;
|
|
371
|
+
/** Block refresh while condition is true */
|
|
372
|
+
isBlocked?: boolean;
|
|
373
|
+
/** Error callback - called when refresh fails */
|
|
374
|
+
onError?: (error: Error) => void;
|
|
375
|
+
/** Max consecutive failures before stopping (default: unlimited) */
|
|
376
|
+
maxRetries?: number;
|
|
377
|
+
}
|
|
378
|
+
interface AutoRefreshReturn {
|
|
379
|
+
/** Seconds until next refresh */
|
|
380
|
+
secondsRemaining: number | null;
|
|
381
|
+
/** Trigger immediate refresh */
|
|
382
|
+
refreshNow: () => Promise<void>;
|
|
383
|
+
/** Reset the timer */
|
|
384
|
+
resetTimer: () => void;
|
|
385
|
+
/** Last error from refresh (null if no error) */
|
|
386
|
+
lastError: Error | null;
|
|
387
|
+
/** Number of consecutive failures */
|
|
388
|
+
failureCount: number;
|
|
389
|
+
/** Whether auto-refresh stopped due to max retries */
|
|
390
|
+
isStopped: boolean;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Selection hook return type
|
|
394
|
+
*/
|
|
395
|
+
interface SelectionReturn<T extends BaseDataItem> {
|
|
396
|
+
/** Currently selected item IDs */
|
|
397
|
+
selectedIds: string[];
|
|
398
|
+
/** Check if item is selected */
|
|
399
|
+
isSelected: (id: string) => boolean;
|
|
400
|
+
/** Toggle item selection */
|
|
401
|
+
toggle: (id: string) => void;
|
|
402
|
+
/** Select all items */
|
|
403
|
+
selectAll: (items: T[]) => void;
|
|
404
|
+
/** Clear all selections */
|
|
405
|
+
clearAll: () => void;
|
|
406
|
+
/** Toggle all items */
|
|
407
|
+
toggleAll: (items: T[]) => void;
|
|
408
|
+
/** Get selected items from a list */
|
|
409
|
+
getSelected: (items: T[]) => T[];
|
|
410
|
+
/** Whether all items are selected */
|
|
411
|
+
allSelected: (items: T[]) => boolean;
|
|
412
|
+
/** Whether some (but not all) items are selected */
|
|
413
|
+
someSelected: (items: T[]) => boolean;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Pagination hook return type
|
|
417
|
+
*/
|
|
418
|
+
interface PaginationReturn {
|
|
419
|
+
page: number;
|
|
420
|
+
pageSize: number;
|
|
421
|
+
setPage: (page: number) => void;
|
|
422
|
+
setPageSize: (size: number) => void;
|
|
423
|
+
nextPage: () => void;
|
|
424
|
+
prevPage: () => void;
|
|
425
|
+
canNextPage: boolean;
|
|
426
|
+
canPrevPage: boolean;
|
|
427
|
+
totalPages: number;
|
|
428
|
+
startIndex: number;
|
|
429
|
+
endIndex: number;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Toast notification type
|
|
433
|
+
*/
|
|
434
|
+
interface ToastConfig {
|
|
435
|
+
title: string;
|
|
436
|
+
description?: string;
|
|
437
|
+
variant?: "default" | "destructive";
|
|
438
|
+
duration?: number;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Empty state configuration
|
|
442
|
+
*/
|
|
443
|
+
interface EmptyStateConfig {
|
|
444
|
+
icon?: ReactNode;
|
|
445
|
+
title: string;
|
|
446
|
+
description?: string;
|
|
447
|
+
action?: {
|
|
448
|
+
label: string;
|
|
449
|
+
onClick: () => void;
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Loading state configuration
|
|
454
|
+
*/
|
|
455
|
+
interface LoadingStateConfig {
|
|
456
|
+
/** Number of skeleton rows */
|
|
457
|
+
rows?: number;
|
|
458
|
+
/** Type of skeleton */
|
|
459
|
+
type?: "table" | "card" | "list";
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Framework configuration
|
|
463
|
+
*/
|
|
464
|
+
interface FrameworkConfig {
|
|
465
|
+
/** Toast function (from your toast library) */
|
|
466
|
+
toast?: (config: ToastConfig) => void;
|
|
467
|
+
/** Custom class name generator */
|
|
468
|
+
cn?: (...inputs: unknown[]) => string;
|
|
469
|
+
/** Default page size */
|
|
470
|
+
defaultPageSize?: number;
|
|
471
|
+
/** Default auto-refresh interval */
|
|
472
|
+
defaultRefreshInterval?: number;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Merge Tailwind classes with clsx
|
|
477
|
+
*/
|
|
478
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
479
|
+
/**
|
|
480
|
+
* Convert base64 string to Uint8Array
|
|
481
|
+
*/
|
|
482
|
+
declare function base64ToBytes(base64: string): Uint8Array;
|
|
483
|
+
/**
|
|
484
|
+
* Convert Uint8Array to base64 string
|
|
485
|
+
*/
|
|
486
|
+
declare function bytesToBase64(bytes: Uint8Array): string;
|
|
487
|
+
/**
|
|
488
|
+
* Format timestamp to locale string
|
|
489
|
+
*/
|
|
490
|
+
declare function formatTimestamp(timestamp: string | number, options?: Intl.DateTimeFormatOptions): string;
|
|
491
|
+
/**
|
|
492
|
+
* Format date for logs (includes seconds)
|
|
493
|
+
*/
|
|
494
|
+
declare function formatLogTimestamp(timestampMs: number): string;
|
|
495
|
+
/**
|
|
496
|
+
* Compute optimal number of rows for viewport height
|
|
497
|
+
*/
|
|
498
|
+
declare function computeRowsForViewportHeight(viewportHeight: number, headerPx?: number, rowPx?: number): number;
|
|
499
|
+
/**
|
|
500
|
+
* Delay helper for async operations
|
|
501
|
+
*/
|
|
502
|
+
declare function delay(ms: number): Promise<void>;
|
|
503
|
+
/**
|
|
504
|
+
* Safe JSON parse
|
|
505
|
+
*/
|
|
506
|
+
declare function safeJsonParse<T>(json: string, fallback: T): T;
|
|
507
|
+
/**
|
|
508
|
+
* Truncate text with ellipsis
|
|
509
|
+
*/
|
|
510
|
+
declare function truncate(text: string, maxLength: number): string;
|
|
511
|
+
/**
|
|
512
|
+
* Check if a value is defined (not null or undefined)
|
|
513
|
+
*/
|
|
514
|
+
declare function isDefined<T>(value: T | null | undefined): value is T;
|
|
515
|
+
/**
|
|
516
|
+
* Generate unique ID
|
|
517
|
+
*/
|
|
518
|
+
declare function generateId(): string;
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Hook for auto-refreshing data at a configurable interval
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```tsx
|
|
525
|
+
* const { secondsRemaining, refreshNow, lastError, failureCount } = useAutoRefresh({
|
|
526
|
+
* intervalSeconds: 15,
|
|
527
|
+
* refresh: fetchData,
|
|
528
|
+
* isBlocked: isLoading,
|
|
529
|
+
* onError: (err) => console.error('Refresh failed:', err),
|
|
530
|
+
* maxRetries: 3,
|
|
531
|
+
* });
|
|
532
|
+
* ```
|
|
533
|
+
*/
|
|
534
|
+
declare function useAutoRefresh(options: AutoRefreshOptions): AutoRefreshReturn;
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Hook for managing multi-select state in tables
|
|
538
|
+
*
|
|
539
|
+
* @example
|
|
540
|
+
* ```tsx
|
|
541
|
+
* const selection = useSelection<MyItem>();
|
|
542
|
+
*
|
|
543
|
+
* // Toggle single item
|
|
544
|
+
* selection.toggle(item.id);
|
|
545
|
+
*
|
|
546
|
+
* // Check if selected
|
|
547
|
+
* const isSelected = selection.isSelected(item.id);
|
|
548
|
+
*
|
|
549
|
+
* // Toggle all
|
|
550
|
+
* selection.toggleAll(items);
|
|
551
|
+
* ```
|
|
552
|
+
*/
|
|
553
|
+
declare function useSelection<T extends BaseDataItem>(): SelectionReturn<T>;
|
|
554
|
+
|
|
555
|
+
type PageSizeMode = "auto" | "manual";
|
|
556
|
+
interface UsePaginationOptions {
|
|
557
|
+
/** Initial page (0-indexed) */
|
|
558
|
+
initialPage?: number;
|
|
559
|
+
/** Initial page size */
|
|
560
|
+
initialPageSize?: number;
|
|
561
|
+
/** Total number of items (for calculating total pages) */
|
|
562
|
+
totalItems?: number;
|
|
563
|
+
/** Whether to enable auto page size based on viewport */
|
|
564
|
+
autoPageSize?: boolean;
|
|
565
|
+
/** Ref to viewport element for auto sizing */
|
|
566
|
+
viewportRef?: React.RefObject<HTMLDivElement>;
|
|
567
|
+
/** Callback when page changes */
|
|
568
|
+
onPageChange?: (page: number) => void;
|
|
569
|
+
/** Callback when page size changes */
|
|
570
|
+
onPageSizeChange?: (pageSize: number) => void;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Hook for managing pagination state
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* ```tsx
|
|
577
|
+
* const pagination = usePagination({
|
|
578
|
+
* initialPageSize: 25,
|
|
579
|
+
* totalItems: data.length,
|
|
580
|
+
* });
|
|
581
|
+
*
|
|
582
|
+
* // Use in query
|
|
583
|
+
* const { data } = useQuery({
|
|
584
|
+
* queryKey: ['items', pagination.page, pagination.pageSize],
|
|
585
|
+
* queryFn: () => fetchItems(pagination.pageSize, pagination.page * pagination.pageSize),
|
|
586
|
+
* });
|
|
587
|
+
* ```
|
|
588
|
+
*/
|
|
589
|
+
declare function usePagination(options?: UsePaginationOptions): PaginationReturn & {
|
|
590
|
+
pageSizeMode: PageSizeMode;
|
|
591
|
+
setPageSizeMode: (mode: PageSizeMode) => void;
|
|
592
|
+
pageSizeSelectValue: string;
|
|
593
|
+
onPageSizeSelect: (value: string) => void;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
interface RefreshButtonProps {
|
|
597
|
+
onClick: () => void;
|
|
598
|
+
isRefreshing: boolean;
|
|
599
|
+
secondsRemaining: number | null;
|
|
600
|
+
disabled?: boolean;
|
|
601
|
+
className?: string;
|
|
602
|
+
"data-testid"?: string;
|
|
603
|
+
title?: string;
|
|
604
|
+
/** Accessible label for screen readers */
|
|
605
|
+
"aria-label"?: string;
|
|
606
|
+
ButtonComponent?: React$1.ComponentType<{
|
|
607
|
+
variant?: string;
|
|
608
|
+
onClick: () => void;
|
|
609
|
+
disabled?: boolean;
|
|
610
|
+
"data-testid"?: string;
|
|
611
|
+
title?: string;
|
|
612
|
+
className?: string;
|
|
613
|
+
style?: React$1.CSSProperties;
|
|
614
|
+
"aria-label"?: string;
|
|
615
|
+
"aria-busy"?: boolean;
|
|
616
|
+
children: React$1.ReactNode;
|
|
617
|
+
}>;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* RefreshButton - Displays refresh button with auto-refresh countdown
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```tsx
|
|
624
|
+
* <RefreshButton
|
|
625
|
+
* onClick={() => void refreshNow()}
|
|
626
|
+
* isRefreshing={isLoading}
|
|
627
|
+
* secondsRemaining={secondsRemaining}
|
|
628
|
+
* title="Refresh now"
|
|
629
|
+
* />
|
|
630
|
+
* ```
|
|
631
|
+
*/
|
|
632
|
+
declare function RefreshButton({ onClick, isRefreshing, secondsRemaining, disabled, className, "data-testid": dataTestId, title, "aria-label": ariaLabel, ButtonComponent, }: RefreshButtonProps): react_jsx_runtime.JSX.Element;
|
|
633
|
+
|
|
634
|
+
declare const STATUS_COLORS: Record<StatusType, string>;
|
|
635
|
+
/**
|
|
636
|
+
* Default status icons
|
|
637
|
+
*/
|
|
638
|
+
declare const STATUS_ICONS: Record<StatusType, React$1.ComponentType<{
|
|
639
|
+
style?: React$1.CSSProperties;
|
|
640
|
+
}>>;
|
|
641
|
+
interface StatusBadgeProps {
|
|
642
|
+
/** Status type */
|
|
643
|
+
status: StatusType | string;
|
|
644
|
+
/** Custom label (defaults to capitalized status) */
|
|
645
|
+
label?: string;
|
|
646
|
+
/** Show icon */
|
|
647
|
+
showIcon?: boolean;
|
|
648
|
+
/** Custom icon override */
|
|
649
|
+
icon?: React$1.ReactNode;
|
|
650
|
+
/** Additional class name */
|
|
651
|
+
className?: string;
|
|
652
|
+
/** Custom status configurations for non-standard statuses */
|
|
653
|
+
customStatuses?: Record<string, {
|
|
654
|
+
colorClass?: string;
|
|
655
|
+
style?: React$1.CSSProperties;
|
|
656
|
+
icon?: React$1.ComponentType<{
|
|
657
|
+
style?: React$1.CSSProperties;
|
|
658
|
+
}>;
|
|
659
|
+
}>;
|
|
660
|
+
/** Custom badge component */
|
|
661
|
+
BadgeComponent?: React$1.ComponentType<{
|
|
662
|
+
variant?: string;
|
|
663
|
+
className?: string;
|
|
664
|
+
style?: React$1.CSSProperties;
|
|
665
|
+
children: React$1.ReactNode;
|
|
666
|
+
}>;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* StatusBadge - Displays a colored badge based on status
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* ```tsx
|
|
673
|
+
* <StatusBadge status="pending" />
|
|
674
|
+
* <StatusBadge status="approved" showIcon />
|
|
675
|
+
* <StatusBadge status="custom" customStatuses={{ custom: { style: { backgroundColor: "#fdf4ff", color: "#a21caf" } } }} />
|
|
676
|
+
* ```
|
|
677
|
+
*/
|
|
678
|
+
declare function StatusBadge({ status, label, showIcon, icon, className, customStatuses, BadgeComponent, }: StatusBadgeProps): react_jsx_runtime.JSX.Element;
|
|
679
|
+
/**
|
|
680
|
+
* Helper to get status badge configuration
|
|
681
|
+
*/
|
|
682
|
+
declare function getStatusConfig(status: string): StatusConfig;
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Action button color presets (Tailwind classes for custom Button components)
|
|
686
|
+
*/
|
|
687
|
+
declare const ACTION_COLORS: {
|
|
688
|
+
readonly view: "text-cyan-600 dark:text-cyan-400";
|
|
689
|
+
readonly review: "text-cyan-600 dark:text-cyan-400";
|
|
690
|
+
readonly approve: "text-green-600 dark:text-green-400";
|
|
691
|
+
readonly commit: "text-green-600 dark:text-green-400";
|
|
692
|
+
readonly reject: "text-red-600 dark:text-red-400";
|
|
693
|
+
readonly delete: "text-red-600 dark:text-red-400";
|
|
694
|
+
readonly cancel: "text-red-600 dark:text-red-400";
|
|
695
|
+
readonly revoke: "text-orange-600 dark:text-orange-400";
|
|
696
|
+
readonly edit: "text-blue-600 dark:text-blue-400";
|
|
697
|
+
readonly create: "text-primary";
|
|
698
|
+
readonly download: "text-purple-600 dark:text-purple-400";
|
|
699
|
+
readonly settings: "text-gray-600 dark:text-gray-400";
|
|
700
|
+
readonly default: "";
|
|
701
|
+
};
|
|
702
|
+
type ActionType = keyof typeof ACTION_COLORS;
|
|
703
|
+
/**
|
|
704
|
+
* Default icons for action types
|
|
705
|
+
*/
|
|
706
|
+
declare const ACTION_ICONS: Record<ActionType, React$1.ComponentType<{
|
|
707
|
+
className?: string;
|
|
708
|
+
}>>;
|
|
709
|
+
interface ActionButtonProps {
|
|
710
|
+
/** Action type for automatic styling */
|
|
711
|
+
action?: ActionType;
|
|
712
|
+
/** Click handler */
|
|
713
|
+
onClick: () => void | Promise<void>;
|
|
714
|
+
/** Custom icon override */
|
|
715
|
+
icon?: React$1.ReactNode;
|
|
716
|
+
/** Button label (for accessibility) */
|
|
717
|
+
label?: string;
|
|
718
|
+
/** Tooltip title */
|
|
719
|
+
title?: string;
|
|
720
|
+
/** Disabled state */
|
|
721
|
+
disabled?: boolean;
|
|
722
|
+
/** Loading state */
|
|
723
|
+
isLoading?: boolean;
|
|
724
|
+
/** Custom color class override */
|
|
725
|
+
colorClass?: string;
|
|
726
|
+
/** Additional class name */
|
|
727
|
+
className?: string;
|
|
728
|
+
/** Button size */
|
|
729
|
+
size?: "sm" | "md" | "lg";
|
|
730
|
+
/** Button variant */
|
|
731
|
+
variant?: "ghost" | "outline" | "default";
|
|
732
|
+
/** Custom button component */
|
|
733
|
+
ButtonComponent?: React$1.ComponentType<{
|
|
734
|
+
size?: string;
|
|
735
|
+
variant?: string;
|
|
736
|
+
onClick: () => void;
|
|
737
|
+
disabled?: boolean;
|
|
738
|
+
title?: string;
|
|
739
|
+
className?: string;
|
|
740
|
+
children: React$1.ReactNode;
|
|
741
|
+
}>;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* ActionButton - Icon button with preset action types
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```tsx
|
|
748
|
+
* <ActionButton action="view" onClick={() => handleView(item)} title="View details" />
|
|
749
|
+
* <ActionButton action="delete" onClick={() => handleDelete(item)} title="Delete item" />
|
|
750
|
+
* ```
|
|
751
|
+
*/
|
|
752
|
+
declare function ActionButton({ action, onClick, icon, label, title, disabled, isLoading, colorClass, className, size, variant, ButtonComponent, }: ActionButtonProps): react_jsx_runtime.JSX.Element;
|
|
753
|
+
interface ActionButtonGroupProps {
|
|
754
|
+
children: React$1.ReactNode;
|
|
755
|
+
className?: string;
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* ActionButtonGroup - Container for action buttons
|
|
759
|
+
*/
|
|
760
|
+
declare function ActionButtonGroup({ children, className }: ActionButtonGroupProps): react_jsx_runtime.JSX.Element;
|
|
761
|
+
|
|
762
|
+
interface EmptyStateProps extends EmptyStateConfig {
|
|
763
|
+
/** Additional class name */
|
|
764
|
+
className?: string;
|
|
765
|
+
/** Custom button component for action */
|
|
766
|
+
ButtonComponent?: React$1.ComponentType<{
|
|
767
|
+
onClick: () => void;
|
|
768
|
+
children: React$1.ReactNode;
|
|
769
|
+
className?: string;
|
|
770
|
+
style?: React$1.CSSProperties;
|
|
771
|
+
}>;
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* EmptyState - Displays when there's no data
|
|
775
|
+
*
|
|
776
|
+
* @example
|
|
777
|
+
* ```tsx
|
|
778
|
+
* <EmptyState
|
|
779
|
+
* icon={<FileKey style={{ height: "3rem", width: "3rem" }} />}
|
|
780
|
+
* title="No pending requests"
|
|
781
|
+
* description="New requests will appear here."
|
|
782
|
+
* />
|
|
783
|
+
* ```
|
|
784
|
+
*/
|
|
785
|
+
declare function EmptyState({ icon, title, description, action, className, ButtonComponent, }: EmptyStateProps): react_jsx_runtime.JSX.Element;
|
|
786
|
+
/**
|
|
787
|
+
* Preset empty states for common scenarios
|
|
788
|
+
*/
|
|
789
|
+
declare function EmptyStateNoData({ title, description, ...props }: Partial<EmptyStateProps>): react_jsx_runtime.JSX.Element;
|
|
790
|
+
declare function EmptyStateNoResults({ title, description, ...props }: Partial<EmptyStateProps>): react_jsx_runtime.JSX.Element;
|
|
791
|
+
declare function EmptyStateNoFiles({ title, description, ...props }: Partial<EmptyStateProps>): react_jsx_runtime.JSX.Element;
|
|
792
|
+
|
|
793
|
+
interface SkeletonProps {
|
|
794
|
+
className?: string;
|
|
795
|
+
style?: React$1.CSSProperties;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Base Skeleton component with inline styles
|
|
799
|
+
*/
|
|
800
|
+
declare function Skeleton$1({ className, style }: SkeletonProps): react_jsx_runtime.JSX.Element;
|
|
801
|
+
interface LoadingSkeletonProps {
|
|
802
|
+
/** Number of skeleton rows */
|
|
803
|
+
rows?: number;
|
|
804
|
+
/** Type of skeleton layout */
|
|
805
|
+
type?: "table" | "card" | "list";
|
|
806
|
+
/** Additional class name */
|
|
807
|
+
className?: string;
|
|
808
|
+
/** Custom skeleton component */
|
|
809
|
+
SkeletonComponent?: React$1.ComponentType<{
|
|
810
|
+
className?: string;
|
|
811
|
+
style?: React$1.CSSProperties;
|
|
812
|
+
}>;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* LoadingSkeleton - Displays loading state with skeleton placeholders
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* ```tsx
|
|
819
|
+
* <LoadingSkeleton rows={5} type="table" />
|
|
820
|
+
* ```
|
|
821
|
+
*/
|
|
822
|
+
declare function LoadingSkeleton({ rows, type, className, SkeletonComponent, }: LoadingSkeletonProps): react_jsx_runtime.JSX.Element;
|
|
823
|
+
/**
|
|
824
|
+
* TableRowSkeleton - Single skeleton row for tables
|
|
825
|
+
*/
|
|
826
|
+
declare function TableRowSkeleton({ columns, className, SkeletonComponent, }: {
|
|
827
|
+
columns?: number;
|
|
828
|
+
className?: string;
|
|
829
|
+
SkeletonComponent?: React$1.ComponentType<{
|
|
830
|
+
className?: string;
|
|
831
|
+
style?: React$1.CSSProperties;
|
|
832
|
+
}>;
|
|
833
|
+
}): react_jsx_runtime.JSX.Element;
|
|
834
|
+
|
|
835
|
+
interface DataTableProps<T extends BaseDataItem> {
|
|
836
|
+
/** Data items to display */
|
|
837
|
+
data: T[];
|
|
838
|
+
/** Column definitions */
|
|
839
|
+
columns: ColumnDef<T>[];
|
|
840
|
+
/** Loading state */
|
|
841
|
+
isLoading?: boolean;
|
|
842
|
+
/** Row key getter (defaults to item.id) */
|
|
843
|
+
getRowKey?: (item: T) => string;
|
|
844
|
+
/** Row click handler */
|
|
845
|
+
onRowClick?: (item: T) => void;
|
|
846
|
+
/** Selected row IDs for highlighting */
|
|
847
|
+
selectedIds?: string[];
|
|
848
|
+
/** Empty state configuration */
|
|
849
|
+
emptyState?: EmptyStateConfig;
|
|
850
|
+
/** Additional class name */
|
|
851
|
+
className?: string;
|
|
852
|
+
/** Custom table components */
|
|
853
|
+
components?: {
|
|
854
|
+
Table?: React$1.ComponentType<{
|
|
855
|
+
children: React$1.ReactNode;
|
|
856
|
+
className?: string;
|
|
857
|
+
style?: React$1.CSSProperties;
|
|
858
|
+
}>;
|
|
859
|
+
TableHeader?: React$1.ComponentType<{
|
|
860
|
+
children: React$1.ReactNode;
|
|
861
|
+
}>;
|
|
862
|
+
TableBody?: React$1.ComponentType<{
|
|
863
|
+
children: React$1.ReactNode;
|
|
864
|
+
}>;
|
|
865
|
+
TableRow?: React$1.ComponentType<{
|
|
866
|
+
children: React$1.ReactNode;
|
|
867
|
+
className?: string;
|
|
868
|
+
style?: React$1.CSSProperties;
|
|
869
|
+
onClick?: () => void;
|
|
870
|
+
}>;
|
|
871
|
+
TableHead?: React$1.ComponentType<{
|
|
872
|
+
children: React$1.ReactNode;
|
|
873
|
+
className?: string;
|
|
874
|
+
style?: React$1.CSSProperties;
|
|
875
|
+
}>;
|
|
876
|
+
TableCell?: React$1.ComponentType<{
|
|
877
|
+
children: React$1.ReactNode;
|
|
878
|
+
className?: string;
|
|
879
|
+
style?: React$1.CSSProperties;
|
|
880
|
+
}>;
|
|
881
|
+
Skeleton?: React$1.ComponentType<{
|
|
882
|
+
className?: string;
|
|
883
|
+
style?: React$1.CSSProperties;
|
|
884
|
+
}>;
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* DataTable - Generic data table component
|
|
889
|
+
*
|
|
890
|
+
* @example
|
|
891
|
+
* ```tsx
|
|
892
|
+
* <DataTable
|
|
893
|
+
* data={items}
|
|
894
|
+
* columns={[
|
|
895
|
+
* { key: 'name', header: 'Name', cell: (item) => item.name },
|
|
896
|
+
* { key: 'status', header: 'Status', cell: (item) => <StatusBadge status={item.status} /> },
|
|
897
|
+
* { key: 'actions', header: 'Actions', cell: (item) => <ActionButton action="view" onClick={() => view(item)} /> },
|
|
898
|
+
* ]}
|
|
899
|
+
* isLoading={isLoading}
|
|
900
|
+
* emptyState={{ title: 'No items', description: 'Create an item to get started.' }}
|
|
901
|
+
* />
|
|
902
|
+
* ```
|
|
903
|
+
*/
|
|
904
|
+
declare function DataTable<T extends BaseDataItem>({ data, columns, isLoading, getRowKey, onRowClick, selectedIds, emptyState, className, components, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
905
|
+
|
|
906
|
+
interface PaginatedTableProps<T extends BaseDataItem> extends Omit<DataTableProps<T>, 'data'> {
|
|
907
|
+
/** Data items (all or paginated from server) */
|
|
908
|
+
data: T[];
|
|
909
|
+
/** Total items count (for server-side pagination) */
|
|
910
|
+
totalItems?: number;
|
|
911
|
+
/** Whether pagination is server-side */
|
|
912
|
+
serverSide?: boolean;
|
|
913
|
+
/** Current page (controlled) */
|
|
914
|
+
page?: number;
|
|
915
|
+
/** Page size (controlled) */
|
|
916
|
+
pageSize?: number;
|
|
917
|
+
/** Page change callback */
|
|
918
|
+
onPageChange?: (page: number) => void;
|
|
919
|
+
/** Page size change callback */
|
|
920
|
+
onPageSizeChange?: (pageSize: number) => void;
|
|
921
|
+
/** Whether to show pagination controls */
|
|
922
|
+
showPagination?: boolean;
|
|
923
|
+
/** Available page sizes */
|
|
924
|
+
pageSizes?: number[];
|
|
925
|
+
/** Whether to enable auto page size */
|
|
926
|
+
autoPageSize?: boolean;
|
|
927
|
+
/** Header content (rendered above table) */
|
|
928
|
+
headerContent?: React$1.ReactNode;
|
|
929
|
+
/** Custom components */
|
|
930
|
+
components?: DataTableProps<T>['components'] & {
|
|
931
|
+
Select?: React$1.ComponentType<{
|
|
932
|
+
value: string;
|
|
933
|
+
onValueChange: (value: string) => void;
|
|
934
|
+
children: React$1.ReactNode;
|
|
935
|
+
}>;
|
|
936
|
+
SelectTrigger?: React$1.ComponentType<{
|
|
937
|
+
className?: string;
|
|
938
|
+
children: React$1.ReactNode;
|
|
939
|
+
}>;
|
|
940
|
+
SelectValue?: React$1.ComponentType<Record<string, unknown>>;
|
|
941
|
+
SelectContent?: React$1.ComponentType<{
|
|
942
|
+
children: React$1.ReactNode;
|
|
943
|
+
}>;
|
|
944
|
+
SelectItem?: React$1.ComponentType<{
|
|
945
|
+
value: string;
|
|
946
|
+
children: React$1.ReactNode;
|
|
947
|
+
}>;
|
|
948
|
+
Button?: React$1.ComponentType<{
|
|
949
|
+
size?: string;
|
|
950
|
+
variant?: string;
|
|
951
|
+
onClick?: () => void;
|
|
952
|
+
disabled?: boolean;
|
|
953
|
+
className?: string;
|
|
954
|
+
children: React$1.ReactNode;
|
|
955
|
+
}>;
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* PaginatedTable - DataTable with built-in pagination
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* ```tsx
|
|
963
|
+
* // Client-side pagination
|
|
964
|
+
* <PaginatedTable
|
|
965
|
+
* data={items}
|
|
966
|
+
* columns={columns}
|
|
967
|
+
* showPagination
|
|
968
|
+
* />
|
|
969
|
+
*
|
|
970
|
+
* // Server-side pagination
|
|
971
|
+
* <PaginatedTable
|
|
972
|
+
* data={pageData}
|
|
973
|
+
* columns={columns}
|
|
974
|
+
* serverSide
|
|
975
|
+
* totalItems={totalCount}
|
|
976
|
+
* page={page}
|
|
977
|
+
* pageSize={pageSize}
|
|
978
|
+
* onPageChange={setPage}
|
|
979
|
+
* onPageSizeChange={setPageSize}
|
|
980
|
+
* />
|
|
981
|
+
* ```
|
|
982
|
+
*/
|
|
983
|
+
declare function PaginatedTable<T extends BaseDataItem>({ data, totalItems, serverSide, page: controlledPage, pageSize: controlledPageSize, onPageChange, onPageSizeChange, showPagination, pageSizes, autoPageSize, headerContent, components, className, ...tableProps }: PaginatedTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
984
|
+
|
|
985
|
+
interface TabsViewProps {
|
|
986
|
+
/** Tab definitions */
|
|
987
|
+
tabs: TabDef[];
|
|
988
|
+
/** Currently active tab key */
|
|
989
|
+
activeTab: string;
|
|
990
|
+
/** Tab change callback */
|
|
991
|
+
onTabChange: (tabKey: string) => void;
|
|
992
|
+
/** Additional class name */
|
|
993
|
+
className?: string;
|
|
994
|
+
/** Tab list class name */
|
|
995
|
+
tabListClassName?: string;
|
|
996
|
+
/** Custom components */
|
|
997
|
+
components?: {
|
|
998
|
+
Tabs?: React$1.ComponentType<{
|
|
999
|
+
value: string;
|
|
1000
|
+
onValueChange: (value: string) => void;
|
|
1001
|
+
children: React$1.ReactNode;
|
|
1002
|
+
className?: string;
|
|
1003
|
+
}>;
|
|
1004
|
+
TabsList?: React$1.ComponentType<{
|
|
1005
|
+
children: React$1.ReactNode;
|
|
1006
|
+
className?: string;
|
|
1007
|
+
}>;
|
|
1008
|
+
TabsTrigger?: React$1.ComponentType<{
|
|
1009
|
+
value: string;
|
|
1010
|
+
disabled?: boolean;
|
|
1011
|
+
className?: string;
|
|
1012
|
+
children: React$1.ReactNode;
|
|
1013
|
+
}>;
|
|
1014
|
+
TabsContent?: React$1.ComponentType<{
|
|
1015
|
+
value: string;
|
|
1016
|
+
className?: string;
|
|
1017
|
+
children: React$1.ReactNode;
|
|
1018
|
+
}>;
|
|
1019
|
+
Badge?: React$1.ComponentType<{
|
|
1020
|
+
variant?: string;
|
|
1021
|
+
className?: string;
|
|
1022
|
+
children: React$1.ReactNode;
|
|
1023
|
+
}>;
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* TabsView - Generic tabbed view component
|
|
1028
|
+
*
|
|
1029
|
+
* @example
|
|
1030
|
+
* ```tsx
|
|
1031
|
+
* <TabsView
|
|
1032
|
+
* tabs={[
|
|
1033
|
+
* { key: 'access', label: 'Access', badge: 5, content: <AccessTab /> },
|
|
1034
|
+
* { key: 'roles', label: 'Roles', badge: 2, content: <RolesTab /> },
|
|
1035
|
+
* { key: 'policies', label: 'Policies', content: <PoliciesTab /> },
|
|
1036
|
+
* ]}
|
|
1037
|
+
* activeTab={activeTab}
|
|
1038
|
+
* onTabChange={setActiveTab}
|
|
1039
|
+
* />
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
declare function TabsView({ tabs, activeTab, onTabChange, className, tabListClassName, components, }: TabsViewProps): react_jsx_runtime.JSX.Element;
|
|
1043
|
+
|
|
1044
|
+
interface DetailDialogProps<T extends BaseDataItem> {
|
|
1045
|
+
/** Whether dialog is open */
|
|
1046
|
+
open: boolean;
|
|
1047
|
+
/** Close handler */
|
|
1048
|
+
onClose: () => void;
|
|
1049
|
+
/** Item to display */
|
|
1050
|
+
item: T | null;
|
|
1051
|
+
/** Dialog title */
|
|
1052
|
+
title: string;
|
|
1053
|
+
/** Dialog description */
|
|
1054
|
+
description?: string;
|
|
1055
|
+
/** Field definitions */
|
|
1056
|
+
fields: DetailField<T>[];
|
|
1057
|
+
/** Footer content (actions) */
|
|
1058
|
+
footer?: React$1.ReactNode;
|
|
1059
|
+
/** Additional content after fields */
|
|
1060
|
+
children?: React$1.ReactNode;
|
|
1061
|
+
/** Dialog size */
|
|
1062
|
+
size?: "sm" | "md" | "lg" | "xl" | "full";
|
|
1063
|
+
/** Additional class name */
|
|
1064
|
+
className?: string;
|
|
1065
|
+
/** Custom components */
|
|
1066
|
+
components?: {
|
|
1067
|
+
Dialog?: React$1.ComponentType<{
|
|
1068
|
+
open: boolean;
|
|
1069
|
+
onOpenChange: (open: boolean) => void;
|
|
1070
|
+
children: React$1.ReactNode;
|
|
1071
|
+
}>;
|
|
1072
|
+
DialogContent?: React$1.ComponentType<{
|
|
1073
|
+
className?: string;
|
|
1074
|
+
children: React$1.ReactNode;
|
|
1075
|
+
}>;
|
|
1076
|
+
DialogHeader?: React$1.ComponentType<{
|
|
1077
|
+
children: React$1.ReactNode;
|
|
1078
|
+
}>;
|
|
1079
|
+
DialogTitle?: React$1.ComponentType<{
|
|
1080
|
+
children: React$1.ReactNode;
|
|
1081
|
+
className?: string;
|
|
1082
|
+
}>;
|
|
1083
|
+
DialogDescription?: React$1.ComponentType<{
|
|
1084
|
+
children: React$1.ReactNode;
|
|
1085
|
+
}>;
|
|
1086
|
+
DialogFooter?: React$1.ComponentType<{
|
|
1087
|
+
children: React$1.ReactNode;
|
|
1088
|
+
className?: string;
|
|
1089
|
+
}>;
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* DetailDialog - Dialog for displaying item details
|
|
1094
|
+
*
|
|
1095
|
+
* @example
|
|
1096
|
+
* ```tsx
|
|
1097
|
+
* <DetailDialog
|
|
1098
|
+
* open={!!selectedItem}
|
|
1099
|
+
* onClose={() => setSelectedItem(null)}
|
|
1100
|
+
* item={selectedItem}
|
|
1101
|
+
* title="Policy Details"
|
|
1102
|
+
* fields={[
|
|
1103
|
+
* { key: 'role', label: 'Role', render: (item) => item.roleId },
|
|
1104
|
+
* { key: 'status', label: 'Status', render: (item) => <StatusBadge status={item.status} /> },
|
|
1105
|
+
* ]}
|
|
1106
|
+
* footer={<Button onClick={() => handleApprove()}>Approve</Button>}
|
|
1107
|
+
* />
|
|
1108
|
+
* ```
|
|
1109
|
+
*/
|
|
1110
|
+
declare function DetailDialog<T extends BaseDataItem>({ open, onClose, item, title, description, fields, footer, children, size, className, components, }: DetailDialogProps<T>): react_jsx_runtime.JSX.Element | null;
|
|
1111
|
+
|
|
1112
|
+
interface ConfirmDialogProps {
|
|
1113
|
+
/** Whether dialog is open */
|
|
1114
|
+
open: boolean;
|
|
1115
|
+
/** Close handler */
|
|
1116
|
+
onClose: () => void;
|
|
1117
|
+
/** Confirm handler */
|
|
1118
|
+
onConfirm: () => void | Promise<void>;
|
|
1119
|
+
/** Dialog title */
|
|
1120
|
+
title: string;
|
|
1121
|
+
/** Dialog description */
|
|
1122
|
+
description: string;
|
|
1123
|
+
/** Confirm button label */
|
|
1124
|
+
confirmLabel?: string;
|
|
1125
|
+
/** Cancel button label */
|
|
1126
|
+
cancelLabel?: string;
|
|
1127
|
+
/** Confirm button variant */
|
|
1128
|
+
confirmVariant?: "default" | "destructive";
|
|
1129
|
+
/** Whether action is in progress */
|
|
1130
|
+
isLoading?: boolean;
|
|
1131
|
+
/** Additional class name */
|
|
1132
|
+
className?: string;
|
|
1133
|
+
/** Custom components */
|
|
1134
|
+
components?: {
|
|
1135
|
+
AlertDialog?: React$1.ComponentType<{
|
|
1136
|
+
open: boolean;
|
|
1137
|
+
onOpenChange: (open: boolean) => void;
|
|
1138
|
+
children: React$1.ReactNode;
|
|
1139
|
+
}>;
|
|
1140
|
+
AlertDialogContent?: React$1.ComponentType<{
|
|
1141
|
+
children: React$1.ReactNode;
|
|
1142
|
+
}>;
|
|
1143
|
+
AlertDialogHeader?: React$1.ComponentType<{
|
|
1144
|
+
children: React$1.ReactNode;
|
|
1145
|
+
}>;
|
|
1146
|
+
AlertDialogTitle?: React$1.ComponentType<{
|
|
1147
|
+
children: React$1.ReactNode;
|
|
1148
|
+
}>;
|
|
1149
|
+
AlertDialogDescription?: React$1.ComponentType<{
|
|
1150
|
+
children: React$1.ReactNode;
|
|
1151
|
+
}>;
|
|
1152
|
+
AlertDialogFooter?: React$1.ComponentType<{
|
|
1153
|
+
children: React$1.ReactNode;
|
|
1154
|
+
}>;
|
|
1155
|
+
AlertDialogAction?: React$1.ComponentType<{
|
|
1156
|
+
onClick: () => void;
|
|
1157
|
+
className?: string;
|
|
1158
|
+
style?: React$1.CSSProperties;
|
|
1159
|
+
disabled?: boolean;
|
|
1160
|
+
children: React$1.ReactNode;
|
|
1161
|
+
}>;
|
|
1162
|
+
AlertDialogCancel?: React$1.ComponentType<{
|
|
1163
|
+
onClick?: () => void;
|
|
1164
|
+
children: React$1.ReactNode;
|
|
1165
|
+
}>;
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* ConfirmDialog - Confirmation dialog for destructive actions
|
|
1170
|
+
*
|
|
1171
|
+
* @example
|
|
1172
|
+
* ```tsx
|
|
1173
|
+
* <ConfirmDialog
|
|
1174
|
+
* open={showDelete}
|
|
1175
|
+
* onClose={() => setShowDelete(false)}
|
|
1176
|
+
* onConfirm={handleDelete}
|
|
1177
|
+
* title="Delete Item"
|
|
1178
|
+
* description="Are you sure? This action cannot be undone."
|
|
1179
|
+
* confirmLabel="Delete"
|
|
1180
|
+
* confirmVariant="destructive"
|
|
1181
|
+
* isLoading={isDeleting}
|
|
1182
|
+
* />
|
|
1183
|
+
* ```
|
|
1184
|
+
*/
|
|
1185
|
+
declare function ConfirmDialog({ open, onClose, onConfirm, title, description, confirmLabel, cancelLabel, confirmVariant, isLoading, className, components, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
|
|
1186
|
+
|
|
1187
|
+
interface CollapsibleSectionProps {
|
|
1188
|
+
/** Trigger/header content */
|
|
1189
|
+
trigger: React$1.ReactNode;
|
|
1190
|
+
/** Collapsible content */
|
|
1191
|
+
children: React$1.ReactNode;
|
|
1192
|
+
/** Default open state */
|
|
1193
|
+
defaultOpen?: boolean;
|
|
1194
|
+
/** Controlled open state */
|
|
1195
|
+
open?: boolean;
|
|
1196
|
+
/** Open state change handler */
|
|
1197
|
+
onOpenChange?: (open: boolean) => void;
|
|
1198
|
+
/** Icon to show when collapsed */
|
|
1199
|
+
collapsedIcon?: React$1.ReactNode;
|
|
1200
|
+
/** Icon to show when expanded */
|
|
1201
|
+
expandedIcon?: React$1.ReactNode;
|
|
1202
|
+
/** Additional class name */
|
|
1203
|
+
className?: string;
|
|
1204
|
+
/** Trigger class name */
|
|
1205
|
+
triggerClassName?: string;
|
|
1206
|
+
/** Content class name */
|
|
1207
|
+
contentClassName?: string;
|
|
1208
|
+
/** Custom components */
|
|
1209
|
+
components?: {
|
|
1210
|
+
Collapsible?: React$1.ComponentType<{
|
|
1211
|
+
open: boolean;
|
|
1212
|
+
onOpenChange: (open: boolean) => void;
|
|
1213
|
+
children: React$1.ReactNode;
|
|
1214
|
+
}>;
|
|
1215
|
+
CollapsibleTrigger?: React$1.ComponentType<{
|
|
1216
|
+
asChild?: boolean;
|
|
1217
|
+
children: React$1.ReactNode;
|
|
1218
|
+
}>;
|
|
1219
|
+
CollapsibleContent?: React$1.ComponentType<{
|
|
1220
|
+
children: React$1.ReactNode;
|
|
1221
|
+
className?: string;
|
|
1222
|
+
}>;
|
|
1223
|
+
Button?: React$1.ComponentType<{
|
|
1224
|
+
variant?: string;
|
|
1225
|
+
size?: string;
|
|
1226
|
+
className?: string;
|
|
1227
|
+
children: React$1.ReactNode;
|
|
1228
|
+
onClick?: () => void;
|
|
1229
|
+
}>;
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* CollapsibleSection - Expandable content section
|
|
1234
|
+
*
|
|
1235
|
+
* @example
|
|
1236
|
+
* ```tsx
|
|
1237
|
+
* <CollapsibleSection
|
|
1238
|
+
* trigger={<><Code className="h-4 w-4" /> View Code</>}
|
|
1239
|
+
* defaultOpen={false}
|
|
1240
|
+
* >
|
|
1241
|
+
* <pre className="p-3 text-xs font-mono">{code}</pre>
|
|
1242
|
+
* </CollapsibleSection>
|
|
1243
|
+
* ```
|
|
1244
|
+
*/
|
|
1245
|
+
declare function CollapsibleSection({ trigger, children, defaultOpen, open: controlledOpen, onOpenChange, collapsedIcon, expandedIcon, className, triggerClassName, contentClassName, components, }: CollapsibleSectionProps): react_jsx_runtime.JSX.Element;
|
|
1246
|
+
/**
|
|
1247
|
+
* CodePreview - Pre-styled collapsible code section
|
|
1248
|
+
*/
|
|
1249
|
+
declare function CodePreview({ code, language, label, icon, maxHeight, className, ...props }: {
|
|
1250
|
+
code: string;
|
|
1251
|
+
language?: string;
|
|
1252
|
+
label?: string;
|
|
1253
|
+
icon?: React$1.ReactNode;
|
|
1254
|
+
maxHeight?: string;
|
|
1255
|
+
className?: string;
|
|
1256
|
+
} & Omit<CollapsibleSectionProps, 'trigger' | 'children'>): react_jsx_runtime.JSX.Element;
|
|
1257
|
+
|
|
1258
|
+
interface BaseApprovalItem extends BaseDataItem {
|
|
1259
|
+
status: string;
|
|
1260
|
+
timestamp: string | number;
|
|
1261
|
+
retrievalInfo?: ChangeSetRequest;
|
|
1262
|
+
}
|
|
1263
|
+
interface AccessApprovalItem extends BaseApprovalItem {
|
|
1264
|
+
username: string;
|
|
1265
|
+
role: string;
|
|
1266
|
+
clientId: string;
|
|
1267
|
+
commitReady: boolean;
|
|
1268
|
+
decisionMade: boolean;
|
|
1269
|
+
rejectionFound?: boolean;
|
|
1270
|
+
}
|
|
1271
|
+
interface RoleApprovalItem extends BaseApprovalItem {
|
|
1272
|
+
role: string;
|
|
1273
|
+
compositeRole?: string;
|
|
1274
|
+
clientId: string;
|
|
1275
|
+
requestType: string;
|
|
1276
|
+
requestedBy: string;
|
|
1277
|
+
}
|
|
1278
|
+
interface PolicyApprovalItem extends BaseApprovalItem {
|
|
1279
|
+
roleId: string;
|
|
1280
|
+
requestedBy: string;
|
|
1281
|
+
requestedByEmail?: string;
|
|
1282
|
+
threshold: number;
|
|
1283
|
+
approvalCount: number;
|
|
1284
|
+
rejectionCount?: number;
|
|
1285
|
+
commitReady?: boolean;
|
|
1286
|
+
approvedBy?: string[];
|
|
1287
|
+
deniedBy?: string[];
|
|
1288
|
+
policyRequestData: string;
|
|
1289
|
+
contractCode?: string;
|
|
1290
|
+
}
|
|
1291
|
+
interface ApprovalDecision {
|
|
1292
|
+
decidedBy: string;
|
|
1293
|
+
decidedByEmail?: string;
|
|
1294
|
+
decision: "approved" | "rejected";
|
|
1295
|
+
timestamp: string | number;
|
|
1296
|
+
}
|
|
1297
|
+
interface ApprovalTabConfig<T extends BaseApprovalItem> {
|
|
1298
|
+
key: string;
|
|
1299
|
+
label: string;
|
|
1300
|
+
icon?: React$1.ReactNode;
|
|
1301
|
+
/** Data fetcher */
|
|
1302
|
+
fetchData: () => Promise<T[]>;
|
|
1303
|
+
/** Column definitions for the table */
|
|
1304
|
+
columns: ColumnDef<T>[];
|
|
1305
|
+
/** Empty state configuration */
|
|
1306
|
+
emptyState: {
|
|
1307
|
+
icon: React$1.ReactNode;
|
|
1308
|
+
title: string;
|
|
1309
|
+
description: string;
|
|
1310
|
+
};
|
|
1311
|
+
/** Action handlers */
|
|
1312
|
+
actions: {
|
|
1313
|
+
onReview?: (item: T) => Promise<void>;
|
|
1314
|
+
onCommit?: (item: T) => Promise<void>;
|
|
1315
|
+
onCancel?: (item: T) => Promise<void>;
|
|
1316
|
+
onRevoke?: (item: T) => Promise<void>;
|
|
1317
|
+
onView?: (item: T) => void;
|
|
1318
|
+
onDelete?: (item: T) => Promise<void>;
|
|
1319
|
+
};
|
|
1320
|
+
/** Check if item is ready to commit */
|
|
1321
|
+
canCommit?: (item: T) => boolean;
|
|
1322
|
+
/** Check if user has made a decision */
|
|
1323
|
+
hasUserDecided?: (item: T) => boolean;
|
|
1324
|
+
/** Query keys for cache invalidation */
|
|
1325
|
+
queryKeys?: string[];
|
|
1326
|
+
}
|
|
1327
|
+
interface ApprovalsPageBaseProps<TAccess extends AccessApprovalItem = AccessApprovalItem, TRole extends RoleApprovalItem = RoleApprovalItem, TPolicy extends PolicyApprovalItem = PolicyApprovalItem> {
|
|
1328
|
+
/** Page title */
|
|
1329
|
+
title?: string;
|
|
1330
|
+
/** Page description */
|
|
1331
|
+
description?: string;
|
|
1332
|
+
/** Tab configurations for default tabs */
|
|
1333
|
+
tabs: {
|
|
1334
|
+
access?: ApprovalTabConfig<TAccess>;
|
|
1335
|
+
roles?: ApprovalTabConfig<TRole>;
|
|
1336
|
+
policies?: ApprovalTabConfig<TPolicy>;
|
|
1337
|
+
};
|
|
1338
|
+
/** Additional custom tabs */
|
|
1339
|
+
additionalTabs?: ApprovalTabConfig<any>[];
|
|
1340
|
+
/** Initial active tab (can be any tab key) */
|
|
1341
|
+
initialTab?: string;
|
|
1342
|
+
/** Toast notification handler */
|
|
1343
|
+
toast?: (config: ToastConfig) => void;
|
|
1344
|
+
/** Auto-refresh interval in seconds */
|
|
1345
|
+
refreshInterval?: number;
|
|
1346
|
+
/** Query invalidation handler */
|
|
1347
|
+
invalidateQueries?: (queryKeys: string[]) => void;
|
|
1348
|
+
/** Current user ID (for checking decisions) */
|
|
1349
|
+
currentUserId?: string;
|
|
1350
|
+
/** Custom components */
|
|
1351
|
+
components?: {
|
|
1352
|
+
Card?: React$1.ComponentType<{
|
|
1353
|
+
children: React$1.ReactNode;
|
|
1354
|
+
className?: string;
|
|
1355
|
+
}>;
|
|
1356
|
+
CardContent?: React$1.ComponentType<{
|
|
1357
|
+
children: React$1.ReactNode;
|
|
1358
|
+
className?: string;
|
|
1359
|
+
}>;
|
|
1360
|
+
Button?: React$1.ComponentType<any>;
|
|
1361
|
+
Badge?: React$1.ComponentType<any>;
|
|
1362
|
+
Skeleton?: React$1.ComponentType<{
|
|
1363
|
+
className?: string;
|
|
1364
|
+
}>;
|
|
1365
|
+
Table?: React$1.ComponentType<any>;
|
|
1366
|
+
TableHeader?: React$1.ComponentType<any>;
|
|
1367
|
+
TableBody?: React$1.ComponentType<any>;
|
|
1368
|
+
TableRow?: React$1.ComponentType<any>;
|
|
1369
|
+
TableHead?: React$1.ComponentType<any>;
|
|
1370
|
+
TableCell?: React$1.ComponentType<any>;
|
|
1371
|
+
Tabs?: React$1.ComponentType<any>;
|
|
1372
|
+
TabsList?: React$1.ComponentType<any>;
|
|
1373
|
+
TabsTrigger?: React$1.ComponentType<any>;
|
|
1374
|
+
TabsContent?: React$1.ComponentType<any>;
|
|
1375
|
+
Dialog?: React$1.ComponentType<any>;
|
|
1376
|
+
DialogContent?: React$1.ComponentType<any>;
|
|
1377
|
+
DialogHeader?: React$1.ComponentType<any>;
|
|
1378
|
+
DialogTitle?: React$1.ComponentType<any>;
|
|
1379
|
+
DialogDescription?: React$1.ComponentType<any>;
|
|
1380
|
+
DialogFooter?: React$1.ComponentType<any>;
|
|
1381
|
+
};
|
|
1382
|
+
/** Additional class name */
|
|
1383
|
+
className?: string;
|
|
1384
|
+
/** Optional help text shown below description */
|
|
1385
|
+
helpText?: React$1.ReactNode;
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* ApprovalsPage - Generic approvals page with tabs for access, roles, and policies
|
|
1389
|
+
*
|
|
1390
|
+
* @example
|
|
1391
|
+
* ```tsx
|
|
1392
|
+
* <ApprovalsPage
|
|
1393
|
+
* tabs={{
|
|
1394
|
+
* access: {
|
|
1395
|
+
* key: 'access',
|
|
1396
|
+
* label: 'Access',
|
|
1397
|
+
* fetchData: api.admin.accessApprovals.list,
|
|
1398
|
+
* columns: accessColumns,
|
|
1399
|
+
* emptyState: { icon: <User />, title: 'No pending requests', description: '...' },
|
|
1400
|
+
* actions: {
|
|
1401
|
+
* onReview: handleReview,
|
|
1402
|
+
* onCommit: handleCommit,
|
|
1403
|
+
* onCancel: handleCancel,
|
|
1404
|
+
* },
|
|
1405
|
+
* canCommit: (item) => item.commitReady,
|
|
1406
|
+
* },
|
|
1407
|
+
* // ... other tabs
|
|
1408
|
+
* }}
|
|
1409
|
+
* toast={toast}
|
|
1410
|
+
* invalidateQueries={queryClient.invalidateQueries}
|
|
1411
|
+
* />
|
|
1412
|
+
* ```
|
|
1413
|
+
*/
|
|
1414
|
+
declare function ApprovalsPageBase<TAccess extends AccessApprovalItem = AccessApprovalItem, TRole extends RoleApprovalItem = RoleApprovalItem, TPolicy extends PolicyApprovalItem = PolicyApprovalItem>({ title, description, tabs, additionalTabs, initialTab, toast, refreshInterval, invalidateQueries, currentUserId, components, className, helpText, }: ApprovalsPageBaseProps<TAccess, TRole, TPolicy>): react_jsx_runtime.JSX.Element;
|
|
1415
|
+
/**
|
|
1416
|
+
* Create user column for access approvals
|
|
1417
|
+
*/
|
|
1418
|
+
declare function createUserColumn<T extends {
|
|
1419
|
+
username: string;
|
|
1420
|
+
}>(): ColumnDef<T>;
|
|
1421
|
+
/**
|
|
1422
|
+
* Create role column
|
|
1423
|
+
*/
|
|
1424
|
+
declare function createRoleColumn<T extends {
|
|
1425
|
+
role?: string;
|
|
1426
|
+
roleId?: string;
|
|
1427
|
+
}>(): ColumnDef<T>;
|
|
1428
|
+
/**
|
|
1429
|
+
* Create timestamp column
|
|
1430
|
+
*/
|
|
1431
|
+
declare function createTimestampColumn<T extends {
|
|
1432
|
+
timestamp?: string | number;
|
|
1433
|
+
createdAt?: number;
|
|
1434
|
+
}>(options?: {
|
|
1435
|
+
header?: string;
|
|
1436
|
+
responsive?: "sm" | "md" | "lg";
|
|
1437
|
+
}): ColumnDef<T>;
|
|
1438
|
+
/**
|
|
1439
|
+
* Create status column
|
|
1440
|
+
*/
|
|
1441
|
+
declare function createStatusColumn<T extends {
|
|
1442
|
+
status?: string;
|
|
1443
|
+
commitReady?: boolean;
|
|
1444
|
+
}>(options?: {
|
|
1445
|
+
getStatus?: (item: T) => string;
|
|
1446
|
+
}): ColumnDef<T>;
|
|
1447
|
+
/**
|
|
1448
|
+
* Create progress column for threshold-based approvals
|
|
1449
|
+
*/
|
|
1450
|
+
declare function createProgressColumn<T extends {
|
|
1451
|
+
approvalCount?: number;
|
|
1452
|
+
rejectionCount?: number;
|
|
1453
|
+
threshold: number;
|
|
1454
|
+
}>(): ColumnDef<T>;
|
|
1455
|
+
|
|
1456
|
+
interface BaseLogItem extends BaseDataItem {
|
|
1457
|
+
timestamp: number;
|
|
1458
|
+
type?: string;
|
|
1459
|
+
action?: string;
|
|
1460
|
+
}
|
|
1461
|
+
interface AccessLogItem extends BaseLogItem {
|
|
1462
|
+
type: string;
|
|
1463
|
+
clientId?: string;
|
|
1464
|
+
userId?: string;
|
|
1465
|
+
ipAddress?: string;
|
|
1466
|
+
details?: Record<string, any>;
|
|
1467
|
+
}
|
|
1468
|
+
interface PolicyLogItem extends BaseLogItem {
|
|
1469
|
+
policyId: string;
|
|
1470
|
+
roleId: string;
|
|
1471
|
+
action: string;
|
|
1472
|
+
performedBy: string;
|
|
1473
|
+
performedByEmail?: string;
|
|
1474
|
+
details?: string;
|
|
1475
|
+
policyStatus?: string;
|
|
1476
|
+
policyThreshold?: number;
|
|
1477
|
+
approvalCount?: number;
|
|
1478
|
+
rejectionCount?: number;
|
|
1479
|
+
}
|
|
1480
|
+
interface LogsTabConfig<T extends BaseLogItem> {
|
|
1481
|
+
key: string;
|
|
1482
|
+
label: string;
|
|
1483
|
+
icon?: React$1.ReactNode;
|
|
1484
|
+
/** Data fetcher - receives limit and offset */
|
|
1485
|
+
fetchData: (limit: number, offset: number) => Promise<T[]>;
|
|
1486
|
+
/** Column definitions for the table */
|
|
1487
|
+
columns: ColumnDef<T>[];
|
|
1488
|
+
/** Empty state configuration */
|
|
1489
|
+
emptyState: {
|
|
1490
|
+
icon: React$1.ReactNode;
|
|
1491
|
+
title: string;
|
|
1492
|
+
description: string;
|
|
1493
|
+
};
|
|
1494
|
+
/** Optional row click handler */
|
|
1495
|
+
onRowClick?: (item: T) => void;
|
|
1496
|
+
/** Query keys for cache invalidation */
|
|
1497
|
+
queryKeys?: string[];
|
|
1498
|
+
}
|
|
1499
|
+
interface LogsPageBaseProps<TAccess extends AccessLogItem = AccessLogItem, TPolicy extends PolicyLogItem = PolicyLogItem> {
|
|
1500
|
+
/** Page title */
|
|
1501
|
+
title?: string;
|
|
1502
|
+
/** Page description */
|
|
1503
|
+
description?: string;
|
|
1504
|
+
/** Tab configurations */
|
|
1505
|
+
tabs: {
|
|
1506
|
+
access?: LogsTabConfig<TAccess>;
|
|
1507
|
+
sessions?: {
|
|
1508
|
+
key: string;
|
|
1509
|
+
label: string;
|
|
1510
|
+
icon?: React$1.ReactNode;
|
|
1511
|
+
/** Embedded content component */
|
|
1512
|
+
content: React$1.ReactNode;
|
|
1513
|
+
};
|
|
1514
|
+
policies?: LogsTabConfig<TPolicy>;
|
|
1515
|
+
};
|
|
1516
|
+
/** Initial active tab */
|
|
1517
|
+
initialTab?: "access" | "sessions" | "policies";
|
|
1518
|
+
/** Toast notification handler */
|
|
1519
|
+
toast?: (config: ToastConfig) => void;
|
|
1520
|
+
/** Auto-refresh interval in seconds */
|
|
1521
|
+
refreshInterval?: number;
|
|
1522
|
+
/** Query invalidation handler */
|
|
1523
|
+
invalidateQueries?: (queryKeys: string[]) => void;
|
|
1524
|
+
/** Available page sizes */
|
|
1525
|
+
pageSizes?: number[];
|
|
1526
|
+
/** Enable auto page sizing */
|
|
1527
|
+
autoPageSize?: boolean;
|
|
1528
|
+
/** URL state management */
|
|
1529
|
+
urlState?: {
|
|
1530
|
+
tab: string;
|
|
1531
|
+
setTab: (tab: string) => void;
|
|
1532
|
+
};
|
|
1533
|
+
/** Custom components */
|
|
1534
|
+
components?: {
|
|
1535
|
+
Card?: React$1.ComponentType<{
|
|
1536
|
+
children: React$1.ReactNode;
|
|
1537
|
+
className?: string;
|
|
1538
|
+
}>;
|
|
1539
|
+
CardContent?: React$1.ComponentType<{
|
|
1540
|
+
children: React$1.ReactNode;
|
|
1541
|
+
className?: string;
|
|
1542
|
+
}>;
|
|
1543
|
+
Button?: React$1.ComponentType<any>;
|
|
1544
|
+
Badge?: React$1.ComponentType<any>;
|
|
1545
|
+
Skeleton?: React$1.ComponentType<{
|
|
1546
|
+
className?: string;
|
|
1547
|
+
}>;
|
|
1548
|
+
Select?: React$1.ComponentType<any>;
|
|
1549
|
+
SelectTrigger?: React$1.ComponentType<any>;
|
|
1550
|
+
SelectValue?: React$1.ComponentType<any>;
|
|
1551
|
+
SelectContent?: React$1.ComponentType<any>;
|
|
1552
|
+
SelectItem?: React$1.ComponentType<any>;
|
|
1553
|
+
Table?: React$1.ComponentType<any>;
|
|
1554
|
+
TableHeader?: React$1.ComponentType<any>;
|
|
1555
|
+
TableBody?: React$1.ComponentType<any>;
|
|
1556
|
+
TableRow?: React$1.ComponentType<any>;
|
|
1557
|
+
TableHead?: React$1.ComponentType<any>;
|
|
1558
|
+
TableCell?: React$1.ComponentType<any>;
|
|
1559
|
+
Tabs?: React$1.ComponentType<any>;
|
|
1560
|
+
TabsList?: React$1.ComponentType<any>;
|
|
1561
|
+
TabsTrigger?: React$1.ComponentType<any>;
|
|
1562
|
+
TabsContent?: React$1.ComponentType<any>;
|
|
1563
|
+
Dialog?: React$1.ComponentType<any>;
|
|
1564
|
+
DialogContent?: React$1.ComponentType<any>;
|
|
1565
|
+
DialogHeader?: React$1.ComponentType<any>;
|
|
1566
|
+
DialogTitle?: React$1.ComponentType<any>;
|
|
1567
|
+
DialogDescription?: React$1.ComponentType<any>;
|
|
1568
|
+
DialogFooter?: React$1.ComponentType<any>;
|
|
1569
|
+
};
|
|
1570
|
+
/** Additional class name */
|
|
1571
|
+
className?: string;
|
|
1572
|
+
/** Optional help text shown below description */
|
|
1573
|
+
helpText?: React$1.ReactNode;
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* LogsPage - Generic logs page with tabs for access, sessions, and policies
|
|
1577
|
+
*
|
|
1578
|
+
* @example
|
|
1579
|
+
* ```tsx
|
|
1580
|
+
* <LogsPage
|
|
1581
|
+
* tabs={{
|
|
1582
|
+
* access: {
|
|
1583
|
+
* key: 'access',
|
|
1584
|
+
* label: 'Access',
|
|
1585
|
+
* fetchData: (limit, offset) => api.admin.logs.access(limit, offset),
|
|
1586
|
+
* columns: accessColumns,
|
|
1587
|
+
* emptyState: { icon: <ScrollText />, title: 'No logs', description: '...' },
|
|
1588
|
+
* },
|
|
1589
|
+
* sessions: {
|
|
1590
|
+
* key: 'sessions',
|
|
1591
|
+
* label: 'Sessions',
|
|
1592
|
+
* content: <SessionHistoryContent />,
|
|
1593
|
+
* },
|
|
1594
|
+
* policies: {
|
|
1595
|
+
* key: 'policies',
|
|
1596
|
+
* label: 'Policies',
|
|
1597
|
+
* fetchData: (limit, offset) => api.admin.sshPolicies.getLogs(limit, offset),
|
|
1598
|
+
* columns: policyColumns,
|
|
1599
|
+
* emptyState: { icon: <Shield />, title: 'No policy logs', description: '...' },
|
|
1600
|
+
* },
|
|
1601
|
+
* }}
|
|
1602
|
+
* />
|
|
1603
|
+
* ```
|
|
1604
|
+
*/
|
|
1605
|
+
declare function LogsPageBase<TAccess extends AccessLogItem = AccessLogItem, TPolicy extends PolicyLogItem = PolicyLogItem>({ title, description, tabs, initialTab, toast, refreshInterval, invalidateQueries, pageSizes, autoPageSize, urlState, components, className, helpText, }: LogsPageBaseProps<TAccess, TPolicy>): react_jsx_runtime.JSX.Element;
|
|
1606
|
+
/**
|
|
1607
|
+
* Create timestamp column for logs
|
|
1608
|
+
*/
|
|
1609
|
+
declare function createLogTimestampColumn<T extends {
|
|
1610
|
+
timestamp?: number;
|
|
1611
|
+
createdAt?: number;
|
|
1612
|
+
time?: number;
|
|
1613
|
+
}>(options?: {
|
|
1614
|
+
header?: string;
|
|
1615
|
+
field?: "timestamp" | "createdAt" | "time";
|
|
1616
|
+
}): ColumnDef<T>;
|
|
1617
|
+
/**
|
|
1618
|
+
* Create action column with icon and color
|
|
1619
|
+
*/
|
|
1620
|
+
declare function createActionColumn<T extends {
|
|
1621
|
+
action: string;
|
|
1622
|
+
}>(): ColumnDef<T>;
|
|
1623
|
+
/**
|
|
1624
|
+
* Create progress column for policy logs
|
|
1625
|
+
*/
|
|
1626
|
+
declare function createLogProgressColumn<T extends {
|
|
1627
|
+
policyThreshold?: number;
|
|
1628
|
+
approvalCount?: number;
|
|
1629
|
+
rejectionCount?: number;
|
|
1630
|
+
}>(): ColumnDef<T>;
|
|
1631
|
+
|
|
1632
|
+
interface TemplateParameter$1 {
|
|
1633
|
+
name: string;
|
|
1634
|
+
type: "string" | "number" | "boolean" | "select";
|
|
1635
|
+
helpText: string;
|
|
1636
|
+
required: boolean;
|
|
1637
|
+
defaultValue?: any;
|
|
1638
|
+
options?: string[];
|
|
1639
|
+
}
|
|
1640
|
+
interface PolicyTemplateItem$1 extends BaseDataItem {
|
|
1641
|
+
name: string;
|
|
1642
|
+
description: string;
|
|
1643
|
+
csCode: string;
|
|
1644
|
+
parameters: TemplateParameter$1[];
|
|
1645
|
+
createdBy: string;
|
|
1646
|
+
}
|
|
1647
|
+
interface TemplateFormData {
|
|
1648
|
+
name: string;
|
|
1649
|
+
description: string;
|
|
1650
|
+
csCode: string;
|
|
1651
|
+
parameters: TemplateParameter$1[];
|
|
1652
|
+
}
|
|
1653
|
+
interface TemplatesPageBaseProps<T extends PolicyTemplateItem$1 = PolicyTemplateItem$1> {
|
|
1654
|
+
/** Page title */
|
|
1655
|
+
title?: string;
|
|
1656
|
+
/** Page description */
|
|
1657
|
+
description?: string;
|
|
1658
|
+
/** Help text shown below description */
|
|
1659
|
+
helpText?: React$1.ReactNode;
|
|
1660
|
+
/** Data fetcher */
|
|
1661
|
+
fetchData: () => Promise<{
|
|
1662
|
+
templates: T[];
|
|
1663
|
+
}>;
|
|
1664
|
+
/** Create handler */
|
|
1665
|
+
onCreate: (data: TemplateFormData) => Promise<void>;
|
|
1666
|
+
/** Update handler */
|
|
1667
|
+
onUpdate: (id: string, data: Partial<TemplateFormData>) => Promise<void>;
|
|
1668
|
+
/** Delete handler */
|
|
1669
|
+
onDelete: (id: string) => Promise<void>;
|
|
1670
|
+
/** Check if user can edit templates */
|
|
1671
|
+
canEdit?: boolean;
|
|
1672
|
+
/** Default code for new templates */
|
|
1673
|
+
defaultCode?: string;
|
|
1674
|
+
/** Code editor language */
|
|
1675
|
+
codeLanguage?: string;
|
|
1676
|
+
/** Toast notification handler */
|
|
1677
|
+
toast?: (config: ToastConfig) => void;
|
|
1678
|
+
/** Auto-refresh interval in seconds */
|
|
1679
|
+
refreshInterval?: number;
|
|
1680
|
+
/** Query invalidation handler */
|
|
1681
|
+
invalidateQueries?: (queryKeys: string[]) => void;
|
|
1682
|
+
/** Query keys */
|
|
1683
|
+
queryKeys?: string[];
|
|
1684
|
+
/** Custom column definitions */
|
|
1685
|
+
columns?: ColumnDef<T>[];
|
|
1686
|
+
/** Empty state configuration */
|
|
1687
|
+
emptyState?: {
|
|
1688
|
+
icon?: React$1.ReactNode;
|
|
1689
|
+
title?: string;
|
|
1690
|
+
description?: string;
|
|
1691
|
+
};
|
|
1692
|
+
/** Custom components */
|
|
1693
|
+
components?: {
|
|
1694
|
+
Card?: React$1.ComponentType<{
|
|
1695
|
+
children: React$1.ReactNode;
|
|
1696
|
+
className?: string;
|
|
1697
|
+
}>;
|
|
1698
|
+
CardContent?: React$1.ComponentType<{
|
|
1699
|
+
children: React$1.ReactNode;
|
|
1700
|
+
className?: string;
|
|
1701
|
+
}>;
|
|
1702
|
+
Button?: React$1.ComponentType<any>;
|
|
1703
|
+
Badge?: React$1.ComponentType<any>;
|
|
1704
|
+
Skeleton?: React$1.ComponentType<{
|
|
1705
|
+
className?: string;
|
|
1706
|
+
}>;
|
|
1707
|
+
Input?: React$1.ComponentType<any>;
|
|
1708
|
+
Textarea?: React$1.ComponentType<any>;
|
|
1709
|
+
Label?: React$1.ComponentType<any>;
|
|
1710
|
+
Switch?: React$1.ComponentType<any>;
|
|
1711
|
+
Select?: React$1.ComponentType<any>;
|
|
1712
|
+
SelectTrigger?: React$1.ComponentType<any>;
|
|
1713
|
+
SelectValue?: React$1.ComponentType<any>;
|
|
1714
|
+
SelectContent?: React$1.ComponentType<any>;
|
|
1715
|
+
SelectItem?: React$1.ComponentType<any>;
|
|
1716
|
+
Table?: React$1.ComponentType<any>;
|
|
1717
|
+
TableHeader?: React$1.ComponentType<any>;
|
|
1718
|
+
TableBody?: React$1.ComponentType<any>;
|
|
1719
|
+
TableRow?: React$1.ComponentType<any>;
|
|
1720
|
+
TableHead?: React$1.ComponentType<any>;
|
|
1721
|
+
TableCell?: React$1.ComponentType<any>;
|
|
1722
|
+
Dialog?: React$1.ComponentType<any>;
|
|
1723
|
+
DialogContent?: React$1.ComponentType<any>;
|
|
1724
|
+
DialogHeader?: React$1.ComponentType<any>;
|
|
1725
|
+
DialogTitle?: React$1.ComponentType<any>;
|
|
1726
|
+
DialogDescription?: React$1.ComponentType<any>;
|
|
1727
|
+
DialogFooter?: React$1.ComponentType<any>;
|
|
1728
|
+
AlertDialog?: React$1.ComponentType<any>;
|
|
1729
|
+
AlertDialogContent?: React$1.ComponentType<any>;
|
|
1730
|
+
AlertDialogHeader?: React$1.ComponentType<any>;
|
|
1731
|
+
AlertDialogTitle?: React$1.ComponentType<any>;
|
|
1732
|
+
AlertDialogDescription?: React$1.ComponentType<any>;
|
|
1733
|
+
AlertDialogFooter?: React$1.ComponentType<any>;
|
|
1734
|
+
AlertDialogAction?: React$1.ComponentType<any>;
|
|
1735
|
+
AlertDialogCancel?: React$1.ComponentType<any>;
|
|
1736
|
+
CodeEditor?: React$1.ComponentType<{
|
|
1737
|
+
value: string;
|
|
1738
|
+
onChange: (value: string) => void;
|
|
1739
|
+
language?: string;
|
|
1740
|
+
height?: string;
|
|
1741
|
+
}>;
|
|
1742
|
+
};
|
|
1743
|
+
/** Additional class name */
|
|
1744
|
+
className?: string;
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* TemplatesPage - Generic template management page
|
|
1748
|
+
*
|
|
1749
|
+
* @example
|
|
1750
|
+
* ```tsx
|
|
1751
|
+
* <TemplatesPage
|
|
1752
|
+
* fetchData={api.admin.policyTemplates.list}
|
|
1753
|
+
* onCreate={api.admin.policyTemplates.create}
|
|
1754
|
+
* onUpdate={api.admin.policyTemplates.update}
|
|
1755
|
+
* onDelete={api.admin.policyTemplates.delete}
|
|
1756
|
+
* canEdit={canManageTemplates()}
|
|
1757
|
+
* toast={toast}
|
|
1758
|
+
* />
|
|
1759
|
+
* ```
|
|
1760
|
+
*/
|
|
1761
|
+
declare function TemplatesPageBase<T extends PolicyTemplateItem$1 = PolicyTemplateItem$1>({ title, description, helpText, fetchData, onCreate, onUpdate, onDelete, canEdit, defaultCode, codeLanguage, toast, refreshInterval, invalidateQueries, queryKeys, columns: customColumns, emptyState, components, className, }: TemplatesPageBaseProps<T>): react_jsx_runtime.JSX.Element;
|
|
1762
|
+
|
|
1763
|
+
interface UserItem extends BaseDataItem {
|
|
1764
|
+
username?: string;
|
|
1765
|
+
firstName: string;
|
|
1766
|
+
lastName: string;
|
|
1767
|
+
email: string;
|
|
1768
|
+
role: string | string[];
|
|
1769
|
+
enabled: boolean;
|
|
1770
|
+
linked?: boolean;
|
|
1771
|
+
isAdmin?: boolean;
|
|
1772
|
+
}
|
|
1773
|
+
interface RoleItem$1 {
|
|
1774
|
+
id: string;
|
|
1775
|
+
name: string;
|
|
1776
|
+
description?: string;
|
|
1777
|
+
}
|
|
1778
|
+
interface UserFormData {
|
|
1779
|
+
id: string;
|
|
1780
|
+
firstName: string;
|
|
1781
|
+
lastName: string;
|
|
1782
|
+
email: string;
|
|
1783
|
+
assignedRoles: string[];
|
|
1784
|
+
}
|
|
1785
|
+
interface CreateUserFormData {
|
|
1786
|
+
username: string;
|
|
1787
|
+
firstName: string;
|
|
1788
|
+
lastName: string;
|
|
1789
|
+
email: string;
|
|
1790
|
+
}
|
|
1791
|
+
interface UsersPageBaseProps<T extends UserItem = UserItem> {
|
|
1792
|
+
/** Page title */
|
|
1793
|
+
title?: string;
|
|
1794
|
+
/** Page description */
|
|
1795
|
+
description?: string;
|
|
1796
|
+
/** Whether the API is ready to be called (defaults to true for backwards compatibility) */
|
|
1797
|
+
isReady?: boolean;
|
|
1798
|
+
/** Data fetcher */
|
|
1799
|
+
fetchUsers: () => Promise<T[]>;
|
|
1800
|
+
/** Fetch available roles */
|
|
1801
|
+
fetchRoles: () => Promise<{
|
|
1802
|
+
roles: RoleItem$1[];
|
|
1803
|
+
}>;
|
|
1804
|
+
/** Create user handler */
|
|
1805
|
+
onCreate: (data: CreateUserFormData) => Promise<void>;
|
|
1806
|
+
/** Update profile handler */
|
|
1807
|
+
onUpdateProfile: (data: {
|
|
1808
|
+
id: string;
|
|
1809
|
+
firstName: string;
|
|
1810
|
+
lastName: string;
|
|
1811
|
+
email: string;
|
|
1812
|
+
}) => Promise<void>;
|
|
1813
|
+
/** Update roles handler */
|
|
1814
|
+
onUpdateRoles: (data: {
|
|
1815
|
+
id: string;
|
|
1816
|
+
rolesToAdd?: string[];
|
|
1817
|
+
rolesToRemove?: string[];
|
|
1818
|
+
}) => Promise<void>;
|
|
1819
|
+
/** Delete user handler */
|
|
1820
|
+
onDelete: (userId: string) => Promise<void>;
|
|
1821
|
+
/** Set user enabled/disabled */
|
|
1822
|
+
onSetEnabled?: (userId: string, enabled: boolean) => Promise<void>;
|
|
1823
|
+
/** Get Tide link URL */
|
|
1824
|
+
getTideLinkUrl?: (userId: string) => Promise<{
|
|
1825
|
+
linkUrl: string;
|
|
1826
|
+
}>;
|
|
1827
|
+
/** Check if user can create more users */
|
|
1828
|
+
checkUserLimit?: () => Promise<{
|
|
1829
|
+
allowed: boolean;
|
|
1830
|
+
current: number;
|
|
1831
|
+
limit: number;
|
|
1832
|
+
tierName?: string;
|
|
1833
|
+
}>;
|
|
1834
|
+
/** License info for over-limit warnings */
|
|
1835
|
+
licenseInfo?: {
|
|
1836
|
+
overLimit?: {
|
|
1837
|
+
users: {
|
|
1838
|
+
isOverLimit: boolean;
|
|
1839
|
+
enabled: number;
|
|
1840
|
+
limit: number;
|
|
1841
|
+
overBy: number;
|
|
1842
|
+
};
|
|
1843
|
+
};
|
|
1844
|
+
};
|
|
1845
|
+
/** Toast handler */
|
|
1846
|
+
toast?: (config: ToastConfig) => void;
|
|
1847
|
+
/** Auto-refresh interval */
|
|
1848
|
+
refreshInterval?: number;
|
|
1849
|
+
/** Query invalidation */
|
|
1850
|
+
invalidateQueries?: (queryKeys: string[]) => void;
|
|
1851
|
+
/** Query keys */
|
|
1852
|
+
queryKeys?: string[];
|
|
1853
|
+
/** Custom columns */
|
|
1854
|
+
columns?: ColumnDef<T>[];
|
|
1855
|
+
/** Custom components */
|
|
1856
|
+
components?: {
|
|
1857
|
+
Card?: React$1.ComponentType<any>;
|
|
1858
|
+
CardContent?: React$1.ComponentType<any>;
|
|
1859
|
+
Button?: React$1.ComponentType<any>;
|
|
1860
|
+
Badge?: React$1.ComponentType<any>;
|
|
1861
|
+
Skeleton?: React$1.ComponentType<any>;
|
|
1862
|
+
Input?: React$1.ComponentType<any>;
|
|
1863
|
+
Label?: React$1.ComponentType<any>;
|
|
1864
|
+
Switch?: React$1.ComponentType<any>;
|
|
1865
|
+
ScrollArea?: React$1.ComponentType<any>;
|
|
1866
|
+
Table?: React$1.ComponentType<any>;
|
|
1867
|
+
TableHeader?: React$1.ComponentType<any>;
|
|
1868
|
+
TableBody?: React$1.ComponentType<any>;
|
|
1869
|
+
TableRow?: React$1.ComponentType<any>;
|
|
1870
|
+
TableHead?: React$1.ComponentType<any>;
|
|
1871
|
+
TableCell?: React$1.ComponentType<any>;
|
|
1872
|
+
Dialog?: React$1.ComponentType<any>;
|
|
1873
|
+
DialogContent?: React$1.ComponentType<any>;
|
|
1874
|
+
DialogHeader?: React$1.ComponentType<any>;
|
|
1875
|
+
DialogTitle?: React$1.ComponentType<any>;
|
|
1876
|
+
DialogDescription?: React$1.ComponentType<any>;
|
|
1877
|
+
DialogFooter?: React$1.ComponentType<any>;
|
|
1878
|
+
AlertDialog?: React$1.ComponentType<any>;
|
|
1879
|
+
AlertDialogContent?: React$1.ComponentType<any>;
|
|
1880
|
+
AlertDialogHeader?: React$1.ComponentType<any>;
|
|
1881
|
+
AlertDialogTitle?: React$1.ComponentType<any>;
|
|
1882
|
+
AlertDialogDescription?: React$1.ComponentType<any>;
|
|
1883
|
+
AlertDialogFooter?: React$1.ComponentType<any>;
|
|
1884
|
+
AlertDialogAction?: React$1.ComponentType<any>;
|
|
1885
|
+
AlertDialogCancel?: React$1.ComponentType<any>;
|
|
1886
|
+
Alert?: React$1.ComponentType<any>;
|
|
1887
|
+
AlertDescription?: React$1.ComponentType<any>;
|
|
1888
|
+
UpgradeBanner?: React$1.ComponentType<any>;
|
|
1889
|
+
};
|
|
1890
|
+
/** Additional class name */
|
|
1891
|
+
className?: string;
|
|
1892
|
+
}
|
|
1893
|
+
/**
|
|
1894
|
+
* UsersPage - Generic user management page
|
|
1895
|
+
*
|
|
1896
|
+
* @example
|
|
1897
|
+
* ```tsx
|
|
1898
|
+
* <UsersPage
|
|
1899
|
+
* fetchUsers={api.admin.users.list}
|
|
1900
|
+
* fetchRoles={() => api.admin.roles.listAll()}
|
|
1901
|
+
* onCreate={api.admin.users.add}
|
|
1902
|
+
* onUpdateProfile={api.admin.users.updateProfile}
|
|
1903
|
+
* onUpdateRoles={api.admin.users.updateRoles}
|
|
1904
|
+
* onDelete={api.admin.users.delete}
|
|
1905
|
+
* onSetEnabled={(id, enabled) => api.admin.users.setEnabled(id, enabled)}
|
|
1906
|
+
* toast={toast}
|
|
1907
|
+
* />
|
|
1908
|
+
* ```
|
|
1909
|
+
*/
|
|
1910
|
+
declare function UsersPageBase<T extends UserItem = UserItem>({ title, description, isReady, fetchUsers, fetchRoles, onCreate, onUpdateProfile, onUpdateRoles, onDelete, onSetEnabled, getTideLinkUrl, checkUserLimit, licenseInfo, toast, refreshInterval, invalidateQueries, queryKeys, columns: customColumns, components, className, }: UsersPageBaseProps<T>): react_jsx_runtime.JSX.Element;
|
|
1911
|
+
|
|
1912
|
+
interface RoleItem extends BaseDataItem {
|
|
1913
|
+
name: string;
|
|
1914
|
+
description?: string;
|
|
1915
|
+
clientRole?: boolean;
|
|
1916
|
+
/** For display purposes - which type this role belongs to */
|
|
1917
|
+
roleType?: "realm" | "client";
|
|
1918
|
+
}
|
|
1919
|
+
/** Role type configuration for RolesPage */
|
|
1920
|
+
type RoleTypeConfig = "realm" | "client" | "all";
|
|
1921
|
+
interface PolicyTemplateItem {
|
|
1922
|
+
id: string;
|
|
1923
|
+
name: string;
|
|
1924
|
+
description?: string;
|
|
1925
|
+
csCode: string;
|
|
1926
|
+
parameters: TemplateParameter[];
|
|
1927
|
+
}
|
|
1928
|
+
interface TemplateParameter {
|
|
1929
|
+
name: string;
|
|
1930
|
+
type: "string" | "number" | "boolean" | "select";
|
|
1931
|
+
required?: boolean;
|
|
1932
|
+
defaultValue?: string | number | boolean;
|
|
1933
|
+
helpText?: string;
|
|
1934
|
+
options?: string[];
|
|
1935
|
+
}
|
|
1936
|
+
interface PolicyConfig {
|
|
1937
|
+
enabled: boolean;
|
|
1938
|
+
contractType: string;
|
|
1939
|
+
approvalType: "implicit" | "explicit";
|
|
1940
|
+
executionType: "public" | "private";
|
|
1941
|
+
threshold: number;
|
|
1942
|
+
}
|
|
1943
|
+
interface RolesPageBaseProps<TRole extends RoleItem = RoleItem> {
|
|
1944
|
+
/** Page title */
|
|
1945
|
+
title?: string;
|
|
1946
|
+
/** Page description */
|
|
1947
|
+
description?: string;
|
|
1948
|
+
/** Help text shown below description */
|
|
1949
|
+
helpText?: React$1.ReactNode;
|
|
1950
|
+
/** SSH role info text */
|
|
1951
|
+
sshRoleInfo?: string;
|
|
1952
|
+
/** Whether the API is ready to be called (defaults to true for backwards compatibility) */
|
|
1953
|
+
isReady?: boolean;
|
|
1954
|
+
/** Role type configuration: 'realm', 'client', or 'all' (default: 'realm') */
|
|
1955
|
+
roleType?: RoleTypeConfig;
|
|
1956
|
+
/** Special role prefix (e.g., "ssh:", "admin:"). Used to identify and auto-prefix special roles. */
|
|
1957
|
+
specialRolePrefix?: string;
|
|
1958
|
+
/** Special role type label (e.g., "SSH", "Admin"). Used for display purposes. */
|
|
1959
|
+
specialRoleType?: string;
|
|
1960
|
+
/** Fetch roles */
|
|
1961
|
+
fetchRoles: () => Promise<{
|
|
1962
|
+
roles: TRole[];
|
|
1963
|
+
} | TRole[]>;
|
|
1964
|
+
/** Fetch policy templates */
|
|
1965
|
+
fetchTemplates?: () => Promise<{
|
|
1966
|
+
templates: PolicyTemplateItem[];
|
|
1967
|
+
} | PolicyTemplateItem[]>;
|
|
1968
|
+
/** Fetch users for threshold calculation */
|
|
1969
|
+
fetchUsers?: () => Promise<any[]>;
|
|
1970
|
+
/** Fetch pending approvals */
|
|
1971
|
+
fetchPendingApprovals?: () => Promise<any[]>;
|
|
1972
|
+
/** Fetch existing policy for a role */
|
|
1973
|
+
fetchRolePolicy?: (roleName: string) => Promise<{
|
|
1974
|
+
policy: PolicyConfig | null;
|
|
1975
|
+
}>;
|
|
1976
|
+
/** Create role */
|
|
1977
|
+
onCreate: (data: {
|
|
1978
|
+
name: string;
|
|
1979
|
+
description?: string;
|
|
1980
|
+
policy?: PolicyConfig;
|
|
1981
|
+
roleType?: "realm" | "client";
|
|
1982
|
+
}) => Promise<void>;
|
|
1983
|
+
/** Update role */
|
|
1984
|
+
onUpdate: (data: {
|
|
1985
|
+
name: string;
|
|
1986
|
+
description?: string;
|
|
1987
|
+
}) => Promise<void>;
|
|
1988
|
+
/** Delete role */
|
|
1989
|
+
onDelete: (roleName: string) => Promise<{
|
|
1990
|
+
approvalCreated?: boolean;
|
|
1991
|
+
}>;
|
|
1992
|
+
/** Create policy request (for SSH roles) */
|
|
1993
|
+
onCreatePolicy?: (params: {
|
|
1994
|
+
roleName: string;
|
|
1995
|
+
policyConfig: PolicyConfig;
|
|
1996
|
+
templateId?: string;
|
|
1997
|
+
templateParams?: Record<string, any>;
|
|
1998
|
+
threshold: number;
|
|
1999
|
+
}) => Promise<void>;
|
|
2000
|
+
/** Contract type options */
|
|
2001
|
+
contractTypes?: {
|
|
2002
|
+
value: string;
|
|
2003
|
+
label: string;
|
|
2004
|
+
description?: string;
|
|
2005
|
+
}[];
|
|
2006
|
+
/** Default policy config */
|
|
2007
|
+
defaultPolicyConfig?: PolicyConfig;
|
|
2008
|
+
/** Check if role is a special prefixed role */
|
|
2009
|
+
isSpecialRole?: (role: TRole | string) => boolean;
|
|
2010
|
+
/** Normalize special role name (add prefix) */
|
|
2011
|
+
normalizeSpecialRoleName?: (name: string) => string;
|
|
2012
|
+
/** Customizable UI labels */
|
|
2013
|
+
labels?: {
|
|
2014
|
+
/** Special role prefix (default: "ssh:") */
|
|
2015
|
+
specialRolePrefix?: string;
|
|
2016
|
+
/** Special role type label (default: "SSH") */
|
|
2017
|
+
specialRoleType?: string;
|
|
2018
|
+
/** Special role checkbox label */
|
|
2019
|
+
specialRoleCheckbox?: string;
|
|
2020
|
+
/** Special role hint text */
|
|
2021
|
+
specialRoleHint?: string;
|
|
2022
|
+
/** Policy section title */
|
|
2023
|
+
policySectionTitle?: string;
|
|
2024
|
+
/** Policy section description */
|
|
2025
|
+
policySectionDescription?: string;
|
|
2026
|
+
/** Default policy option label */
|
|
2027
|
+
defaultPolicyLabel?: string;
|
|
2028
|
+
/** Default policy description */
|
|
2029
|
+
defaultPolicyDescription?: string;
|
|
2030
|
+
/** Create policy checkbox label */
|
|
2031
|
+
createPolicyCheckbox?: string;
|
|
2032
|
+
/** Role type labels */
|
|
2033
|
+
clientRoleLabel?: string;
|
|
2034
|
+
realmRoleLabel?: string;
|
|
2035
|
+
/** Info text shown in header */
|
|
2036
|
+
specialRoleInfo?: string;
|
|
2037
|
+
/** Button labels */
|
|
2038
|
+
addRoleButton?: string;
|
|
2039
|
+
createButton?: string;
|
|
2040
|
+
saveButton?: string;
|
|
2041
|
+
cancelButton?: string;
|
|
2042
|
+
deleteButton?: string;
|
|
2043
|
+
/** Dialog titles */
|
|
2044
|
+
addRoleTitle?: string;
|
|
2045
|
+
editRoleTitle?: string;
|
|
2046
|
+
deleteRoleTitle?: string;
|
|
2047
|
+
/** Placeholders */
|
|
2048
|
+
searchPlaceholder?: string;
|
|
2049
|
+
roleNamePlaceholder?: string;
|
|
2050
|
+
specialRoleNamePlaceholder?: string;
|
|
2051
|
+
descriptionPlaceholder?: string;
|
|
2052
|
+
/** Empty state */
|
|
2053
|
+
noRolesTitle?: string;
|
|
2054
|
+
noRolesDescription?: string;
|
|
2055
|
+
/** No search results message */
|
|
2056
|
+
noSearchResultsMessage?: string;
|
|
2057
|
+
/** Messages */
|
|
2058
|
+
roleCreatedMessage?: string;
|
|
2059
|
+
roleUpdatedMessage?: string;
|
|
2060
|
+
roleDeletedMessage?: string;
|
|
2061
|
+
policyCreatedMessage?: string;
|
|
2062
|
+
/** Badge text for special roles in table */
|
|
2063
|
+
specialRoleBadge?: string;
|
|
2064
|
+
/** Description for create role dialog */
|
|
2065
|
+
createRoleDescription?: string;
|
|
2066
|
+
/** Description for edit role dialog */
|
|
2067
|
+
editRoleDescription?: string;
|
|
2068
|
+
/** Role name disabled hint */
|
|
2069
|
+
roleNameDisabledHint?: string;
|
|
2070
|
+
/** Policy update warning */
|
|
2071
|
+
policyUpdateWarning?: string;
|
|
2072
|
+
/** Delete confirmation message */
|
|
2073
|
+
deleteConfirmMessage?: string;
|
|
2074
|
+
/** Approval request message */
|
|
2075
|
+
approvalRequestMessage?: string;
|
|
2076
|
+
/** No description text */
|
|
2077
|
+
noDescriptionText?: string;
|
|
2078
|
+
/** Loading policy text */
|
|
2079
|
+
loadingPolicyText?: string;
|
|
2080
|
+
/** Update signing policy checkbox label */
|
|
2081
|
+
updatePolicyCheckbox?: string;
|
|
2082
|
+
/** Policy template label */
|
|
2083
|
+
policyTemplateLabel?: string;
|
|
2084
|
+
};
|
|
2085
|
+
/** Calculate threshold from users */
|
|
2086
|
+
calculateThreshold?: (users: any[], pendingApprovals: any[]) => number;
|
|
2087
|
+
/** Admin role set for threshold calculation */
|
|
2088
|
+
adminRoleSet?: Set<string>;
|
|
2089
|
+
/** Custom columns for role table */
|
|
2090
|
+
columns?: ColumnDef<TRole>[];
|
|
2091
|
+
/** Toast function */
|
|
2092
|
+
toast?: (options: {
|
|
2093
|
+
title: string;
|
|
2094
|
+
description?: string;
|
|
2095
|
+
variant?: string;
|
|
2096
|
+
}) => void;
|
|
2097
|
+
/** Invalidate queries */
|
|
2098
|
+
invalidateQueries?: (keys: string[]) => void;
|
|
2099
|
+
/** Query keys to invalidate on changes */
|
|
2100
|
+
queryKeys?: string[];
|
|
2101
|
+
/** Auto-refresh interval in seconds */
|
|
2102
|
+
refreshInterval?: number;
|
|
2103
|
+
/** Additional class name */
|
|
2104
|
+
className?: string;
|
|
2105
|
+
components?: {
|
|
2106
|
+
Card?: React$1.ComponentType<{
|
|
2107
|
+
children: React$1.ReactNode;
|
|
2108
|
+
className?: string;
|
|
2109
|
+
}>;
|
|
2110
|
+
CardContent?: React$1.ComponentType<{
|
|
2111
|
+
children: React$1.ReactNode;
|
|
2112
|
+
className?: string;
|
|
2113
|
+
}>;
|
|
2114
|
+
Button?: React$1.ComponentType<any>;
|
|
2115
|
+
Badge?: React$1.ComponentType<{
|
|
2116
|
+
children: React$1.ReactNode;
|
|
2117
|
+
variant?: string;
|
|
2118
|
+
className?: string;
|
|
2119
|
+
}>;
|
|
2120
|
+
Skeleton?: React$1.ComponentType<{
|
|
2121
|
+
className?: string;
|
|
2122
|
+
}>;
|
|
2123
|
+
Input?: React$1.ComponentType<any>;
|
|
2124
|
+
Label?: React$1.ComponentType<any>;
|
|
2125
|
+
Textarea?: React$1.ComponentType<any>;
|
|
2126
|
+
Checkbox?: React$1.ComponentType<any>;
|
|
2127
|
+
Select?: React$1.ComponentType<any>;
|
|
2128
|
+
SelectTrigger?: React$1.ComponentType<any>;
|
|
2129
|
+
SelectValue?: React$1.ComponentType<any>;
|
|
2130
|
+
SelectContent?: React$1.ComponentType<any>;
|
|
2131
|
+
SelectItem?: React$1.ComponentType<any>;
|
|
2132
|
+
Table?: React$1.ComponentType<{
|
|
2133
|
+
children: React$1.ReactNode;
|
|
2134
|
+
}>;
|
|
2135
|
+
TableHeader?: React$1.ComponentType<{
|
|
2136
|
+
children: React$1.ReactNode;
|
|
2137
|
+
}>;
|
|
2138
|
+
TableBody?: React$1.ComponentType<{
|
|
2139
|
+
children: React$1.ReactNode;
|
|
2140
|
+
}>;
|
|
2141
|
+
TableRow?: React$1.ComponentType<{
|
|
2142
|
+
children: React$1.ReactNode;
|
|
2143
|
+
}>;
|
|
2144
|
+
TableHead?: React$1.ComponentType<{
|
|
2145
|
+
children: React$1.ReactNode;
|
|
2146
|
+
className?: string;
|
|
2147
|
+
}>;
|
|
2148
|
+
TableCell?: React$1.ComponentType<{
|
|
2149
|
+
children: React$1.ReactNode;
|
|
2150
|
+
className?: string;
|
|
2151
|
+
}>;
|
|
2152
|
+
Dialog?: React$1.ComponentType<{
|
|
2153
|
+
open: boolean;
|
|
2154
|
+
onOpenChange: (open: boolean) => void;
|
|
2155
|
+
children: React$1.ReactNode;
|
|
2156
|
+
}>;
|
|
2157
|
+
DialogContent?: React$1.ComponentType<{
|
|
2158
|
+
className?: string;
|
|
2159
|
+
children: React$1.ReactNode;
|
|
2160
|
+
}>;
|
|
2161
|
+
DialogHeader?: React$1.ComponentType<{
|
|
2162
|
+
children: React$1.ReactNode;
|
|
2163
|
+
}>;
|
|
2164
|
+
DialogTitle?: React$1.ComponentType<{
|
|
2165
|
+
children: React$1.ReactNode;
|
|
2166
|
+
}>;
|
|
2167
|
+
DialogDescription?: React$1.ComponentType<{
|
|
2168
|
+
children: React$1.ReactNode;
|
|
2169
|
+
}>;
|
|
2170
|
+
DialogFooter?: React$1.ComponentType<{
|
|
2171
|
+
children: React$1.ReactNode;
|
|
2172
|
+
className?: string;
|
|
2173
|
+
}>;
|
|
2174
|
+
AlertDialog?: React$1.ComponentType<{
|
|
2175
|
+
open: boolean;
|
|
2176
|
+
onOpenChange: (open: boolean) => void;
|
|
2177
|
+
children: React$1.ReactNode;
|
|
2178
|
+
}>;
|
|
2179
|
+
AlertDialogContent?: React$1.ComponentType<{
|
|
2180
|
+
children: React$1.ReactNode;
|
|
2181
|
+
}>;
|
|
2182
|
+
AlertDialogHeader?: React$1.ComponentType<{
|
|
2183
|
+
children: React$1.ReactNode;
|
|
2184
|
+
}>;
|
|
2185
|
+
AlertDialogTitle?: React$1.ComponentType<{
|
|
2186
|
+
children: React$1.ReactNode;
|
|
2187
|
+
}>;
|
|
2188
|
+
AlertDialogDescription?: React$1.ComponentType<{
|
|
2189
|
+
children: React$1.ReactNode;
|
|
2190
|
+
}>;
|
|
2191
|
+
AlertDialogFooter?: React$1.ComponentType<{
|
|
2192
|
+
children: React$1.ReactNode;
|
|
2193
|
+
}>;
|
|
2194
|
+
AlertDialogCancel?: React$1.ComponentType<{
|
|
2195
|
+
children: React$1.ReactNode;
|
|
2196
|
+
}>;
|
|
2197
|
+
AlertDialogAction?: React$1.ComponentType<any>;
|
|
2198
|
+
Separator?: React$1.ComponentType<{
|
|
2199
|
+
className?: string;
|
|
2200
|
+
}>;
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
declare function RolesPageBase<TRole extends RoleItem = RoleItem>({ title, description, helpText, isReady, roleType, specialRolePrefix, specialRoleType, fetchRoles, fetchTemplates, fetchUsers, fetchPendingApprovals, fetchRolePolicy, onCreate, onUpdate, onDelete, onCreatePolicy, contractTypes, defaultPolicyConfig, isSpecialRole: isSpecialRoleProp, normalizeSpecialRoleName: normalizeSpecialRoleNameProp, labels: customLabels, calculateThreshold, adminRoleSet, columns, toast, invalidateQueries, queryKeys, refreshInterval, className, components, }: RolesPageBaseProps<TRole>): react_jsx_runtime.JSX.Element;
|
|
2204
|
+
|
|
2205
|
+
/** Implement this to store templates (or use createLocalStorageTemplateAPI for dev) */
|
|
2206
|
+
interface TemplateAPI {
|
|
2207
|
+
getTemplates: () => Promise<PolicyTemplateItem$1[]>;
|
|
2208
|
+
getTemplate?: (id: string) => Promise<PolicyTemplateItem$1>;
|
|
2209
|
+
createTemplate: (data: TemplateFormData) => Promise<PolicyTemplateItem$1 | void>;
|
|
2210
|
+
updateTemplate: (id: string, data: Partial<TemplateFormData>) => Promise<PolicyTemplateItem$1 | void>;
|
|
2211
|
+
deleteTemplate: (id: string) => Promise<void>;
|
|
2212
|
+
_isLocalStorage?: boolean;
|
|
2213
|
+
}
|
|
2214
|
+
/** localStorage adapter for development */
|
|
2215
|
+
declare function createLocalStorageTemplateAPI(storageKey?: string): TemplateAPI;
|
|
2216
|
+
interface TemplatesPageProps<T extends PolicyTemplateItem$1 = PolicyTemplateItem$1> extends Omit<TemplatesPageBaseProps<T>, "fetchData" | "onCreate" | "onUpdate" | "onDelete"> {
|
|
2217
|
+
/** Template storage adapter */
|
|
2218
|
+
api: TemplateAPI;
|
|
2219
|
+
/** Override fetch templates */
|
|
2220
|
+
fetchData?: TemplatesPageBaseProps<T>["fetchData"];
|
|
2221
|
+
/** Override create */
|
|
2222
|
+
onCreate?: TemplatesPageBaseProps<T>["onCreate"];
|
|
2223
|
+
/** Override update */
|
|
2224
|
+
onUpdate?: TemplatesPageBaseProps<T>["onUpdate"];
|
|
2225
|
+
/** Override delete */
|
|
2226
|
+
onDelete?: TemplatesPageBaseProps<T>["onDelete"];
|
|
2227
|
+
}
|
|
2228
|
+
declare function TemplatesPage<T extends PolicyTemplateItem$1 = PolicyTemplateItem$1>({ api, fetchData: fetchDataProp, onCreate: onCreateProp, onUpdate: onUpdateProp, onDelete: onDeleteProp, helpText: helpTextProp, ...props }: TemplatesPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
2229
|
+
|
|
2230
|
+
type AdminAPIInstance$3 = {
|
|
2231
|
+
setRealm?: (realm: string) => void;
|
|
2232
|
+
getAccessLogs: (params: {
|
|
2233
|
+
first: number;
|
|
2234
|
+
max: number;
|
|
2235
|
+
}) => Promise<any>;
|
|
2236
|
+
};
|
|
2237
|
+
interface PolicyLogData {
|
|
2238
|
+
id: string;
|
|
2239
|
+
policyId: string;
|
|
2240
|
+
roleId: string;
|
|
2241
|
+
action: string;
|
|
2242
|
+
performedBy: string;
|
|
2243
|
+
performedByEmail?: string;
|
|
2244
|
+
timestamp: number;
|
|
2245
|
+
createdAt?: number;
|
|
2246
|
+
policyStatus?: string;
|
|
2247
|
+
policyThreshold?: number;
|
|
2248
|
+
approvalCount?: number;
|
|
2249
|
+
rejectionCount?: number;
|
|
2250
|
+
details?: string;
|
|
2251
|
+
}
|
|
2252
|
+
/** Implement this to store policy logs (or use createLocalStoragePolicyLogsAPI for dev) */
|
|
2253
|
+
interface PolicyLogsAPI {
|
|
2254
|
+
getPolicyLogs: (params: {
|
|
2255
|
+
first: number;
|
|
2256
|
+
max: number;
|
|
2257
|
+
}) => Promise<PolicyLogData[]>;
|
|
2258
|
+
addLog: (log: Omit<PolicyLogData, "id" | "timestamp" | "createdAt">) => Promise<void>;
|
|
2259
|
+
_isLocalStorage?: boolean;
|
|
2260
|
+
}
|
|
2261
|
+
/** localStorage adapter for development */
|
|
2262
|
+
declare function createLocalStoragePolicyLogsAPI(storageKey?: string): PolicyLogsAPI;
|
|
2263
|
+
interface LogsPageProps extends Omit<LogsPageBaseProps, "tabs"> {
|
|
2264
|
+
/** AdminAPI instance */
|
|
2265
|
+
adminAPI?: AdminAPIInstance$3;
|
|
2266
|
+
/** Policy logs adapter */
|
|
2267
|
+
policyLogsAPI?: PolicyLogsAPI;
|
|
2268
|
+
/** Realm name */
|
|
2269
|
+
realm?: string;
|
|
2270
|
+
/** Custom tabs config */
|
|
2271
|
+
tabs?: LogsPageBaseProps["tabs"];
|
|
2272
|
+
/** Show policy tab (default: true) */
|
|
2273
|
+
showPolicyTab?: boolean;
|
|
2274
|
+
/** Help text below description */
|
|
2275
|
+
helpText?: LogsPageBaseProps["helpText"];
|
|
2276
|
+
}
|
|
2277
|
+
declare function LogsPage({ adminAPI: adminAPIProp, policyLogsAPI: policyLogsAPIProp, realm, tabs: tabsProp, showPolicyTab, helpText: helpTextProp, ...props }: LogsPageProps): react_jsx_runtime.JSX.Element;
|
|
2278
|
+
|
|
2279
|
+
/**
|
|
2280
|
+
* Tide Policy Workflow Helpers
|
|
2281
|
+
*
|
|
2282
|
+
* Provides functions for creating Tide policy requests that can be signed
|
|
2283
|
+
* by the TideCloak context. Uses heimdall-tide and asgard-tide libraries.
|
|
2284
|
+
*
|
|
2285
|
+
* This is the default policy creation workflow used by RolesPage when
|
|
2286
|
+
* Tide libraries are available.
|
|
2287
|
+
*/
|
|
2288
|
+
|
|
2289
|
+
/**
|
|
2290
|
+
* Attempts to load the Tide libraries (heimdall-tide and asgard-tide).
|
|
2291
|
+
* Returns true if both libraries are available, false otherwise.
|
|
2292
|
+
*/
|
|
2293
|
+
declare function loadTideLibs(): Promise<boolean>;
|
|
2294
|
+
/**
|
|
2295
|
+
* Checks if Tide libraries are available without loading them.
|
|
2296
|
+
* Must call loadTideLibs() first.
|
|
2297
|
+
*/
|
|
2298
|
+
declare function areTideLibsAvailable(): boolean;
|
|
2299
|
+
declare const DEFAULT_MODEL_IDS: {
|
|
2300
|
+
readonly BASIC: "BasicCustom<Role>:BasicCustom<1>";
|
|
2301
|
+
readonly DYNAMIC: "DynamicCustom<Role>:DynamicCustom<1>";
|
|
2302
|
+
readonly DYNAMIC_APPROVED: "DynamicApprovedCustom<Role>:DynamicApprovedCustom<1>";
|
|
2303
|
+
};
|
|
2304
|
+
/**
|
|
2305
|
+
* Default Forseti contract for role-based access control.
|
|
2306
|
+
* This is a simple contract that validates approvers and executors have the required role.
|
|
2307
|
+
*/
|
|
2308
|
+
declare const DEFAULT_ROLE_CONTRACT = "using Ork.Forseti.Sdk;\nusing System;\nusing System.Collections.Generic;\n\n/// <summary>\n/// Default Role-Based Access Policy.\n/// Validates that approvers and executors have the required role for a resource.\n/// </summary>\npublic class RolePolicy : IAccessPolicy\n{\n [PolicyParam(Required = true, Description = \"Role required for access\")]\n public string Role { get; set; }\n\n [PolicyParam(Required = true, Description = \"Resource identifier for role check\")]\n public string Resource { get; set; }\n\n public PolicyDecision ValidateData(DataContext ctx)\n {\n // No data validation needed for role-based policies\n return PolicyDecision.Allow();\n }\n\n public PolicyDecision ValidateApprovers(ApproversContext ctx)\n {\n var approvers = DokenDto.WrapAll(ctx.Dokens);\n return Decision\n .Require(approvers != null && approvers.Count > 0, \"No approver dokens provided\")\n .RequireAnyWithRole(approvers, Resource, Role);\n }\n\n public PolicyDecision ValidateExecutor(ExecutorContext ctx)\n {\n var executor = new DokenDto(ctx.Doken);\n return Decision\n .RequireNotExpired(executor)\n .RequireRole(executor, Resource, Role);\n }\n}";
|
|
2309
|
+
interface TidePolicyConfig {
|
|
2310
|
+
roleName: string;
|
|
2311
|
+
threshold: number;
|
|
2312
|
+
approvalType: "implicit" | "explicit";
|
|
2313
|
+
executionType: "public" | "private";
|
|
2314
|
+
modelId?: string;
|
|
2315
|
+
resource: string;
|
|
2316
|
+
vendorId: string;
|
|
2317
|
+
contractCode?: string;
|
|
2318
|
+
}
|
|
2319
|
+
interface TideContextMethods {
|
|
2320
|
+
initializeTideRequest: <T extends {
|
|
2321
|
+
encode: () => Uint8Array;
|
|
2322
|
+
}>(request: T) => Promise<T>;
|
|
2323
|
+
getVendorId: () => string;
|
|
2324
|
+
getResource: () => string;
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Computes the contract ID (SHA512 hash) for a Forseti contract source.
|
|
2328
|
+
* This must match what the Ork server computes.
|
|
2329
|
+
*/
|
|
2330
|
+
declare function computeContractId(source: string): Promise<string>;
|
|
2331
|
+
/**
|
|
2332
|
+
* Creates a Tide PolicySignRequest for a role policy.
|
|
2333
|
+
*
|
|
2334
|
+
* @param config - Policy configuration
|
|
2335
|
+
* @param context - TideCloak context methods for signing
|
|
2336
|
+
* @returns The signed PolicySignRequest
|
|
2337
|
+
* @throws Error if Tide libraries are not available
|
|
2338
|
+
*/
|
|
2339
|
+
declare function createTidePolicyRequest(config: TidePolicyConfig, context: TideContextMethods): Promise<any>;
|
|
2340
|
+
/**
|
|
2341
|
+
* Creates a policy creation handler that uses the Tide workflow.
|
|
2342
|
+
* This is used as the default onCreatePolicy in RolesPage when Tide libs are available.
|
|
2343
|
+
*
|
|
2344
|
+
* @param context - TideCloak context methods
|
|
2345
|
+
* @param onRequestCreated - Optional callback when request is created (for custom handling)
|
|
2346
|
+
* @returns Policy creation handler function
|
|
2347
|
+
*/
|
|
2348
|
+
declare function createTidePolicyHandler(context: TideContextMethods, onRequestCreated?: (request: any, roleName: string) => Promise<void>): (params: {
|
|
2349
|
+
roleName: string;
|
|
2350
|
+
policyConfig: any;
|
|
2351
|
+
templateId?: string;
|
|
2352
|
+
templateParams?: Record<string, any>;
|
|
2353
|
+
threshold: number;
|
|
2354
|
+
contractCode?: string;
|
|
2355
|
+
}) => Promise<any>;
|
|
2356
|
+
/**
|
|
2357
|
+
* Converts a RolePolicy to TidePolicyConfig.
|
|
2358
|
+
* Useful when loading existing policies for re-signing or updates.
|
|
2359
|
+
*/
|
|
2360
|
+
declare function rolePolicyToTideConfig(policy: RolePolicy, context: TideContextMethods): TidePolicyConfig;
|
|
2361
|
+
|
|
2362
|
+
type AdminAPIInstance$2 = {
|
|
2363
|
+
setRealm?: (realm: string) => void;
|
|
2364
|
+
getRoles: () => Promise<any>;
|
|
2365
|
+
createRole: (role: any) => Promise<any>;
|
|
2366
|
+
updateRole: (roleName: string, role: any) => Promise<any>;
|
|
2367
|
+
deleteRole: (roleName: string) => Promise<any>;
|
|
2368
|
+
getClientRoles?: (clientId?: string) => Promise<any>;
|
|
2369
|
+
createClientRole?: (role: any, clientId?: string) => Promise<any>;
|
|
2370
|
+
updateClientRole?: (roleName: string, role: any, clientId?: string) => Promise<any>;
|
|
2371
|
+
deleteClientRole?: (roleName: string, clientId?: string) => Promise<any>;
|
|
2372
|
+
getTemplates?: () => Promise<any>;
|
|
2373
|
+
getUsers?: () => Promise<any>;
|
|
2374
|
+
getPendingChangeSets?: () => Promise<any>;
|
|
2375
|
+
};
|
|
2376
|
+
interface RolePolicy {
|
|
2377
|
+
roleName: string;
|
|
2378
|
+
enabled: boolean;
|
|
2379
|
+
contractType: string;
|
|
2380
|
+
approvalType: "implicit" | "explicit";
|
|
2381
|
+
executionType: "public" | "private";
|
|
2382
|
+
threshold: number;
|
|
2383
|
+
templateId?: string;
|
|
2384
|
+
templateParams?: Record<string, any>;
|
|
2385
|
+
createdAt?: string;
|
|
2386
|
+
updatedAt?: string;
|
|
2387
|
+
}
|
|
2388
|
+
/** Implement this to store role policies (or use createLocalStoragePolicyAPI for dev) */
|
|
2389
|
+
interface PolicyAPI {
|
|
2390
|
+
getPolicy: (roleName: string) => Promise<RolePolicy | null>;
|
|
2391
|
+
upsertPolicy: (policy: RolePolicy) => Promise<RolePolicy | void>;
|
|
2392
|
+
deletePolicy?: (roleName: string) => Promise<void>;
|
|
2393
|
+
_isLocalStorage?: boolean;
|
|
2394
|
+
}
|
|
2395
|
+
/** localStorage adapter for development */
|
|
2396
|
+
declare function createLocalStoragePolicyAPI(storageKey?: string): PolicyAPI;
|
|
2397
|
+
interface RolesPageProps<T extends RoleItem = RoleItem> extends Omit<RolesPageBaseProps<T>, "fetchRoles" | "fetchTemplates" | "fetchUsers" | "fetchPendingApprovals" | "fetchRolePolicy" | "onCreate" | "onUpdate" | "onDelete" | "onCreatePolicy" | "toast" | "invalidateQueries" | "components" | "roleType"> {
|
|
2398
|
+
/** AdminAPI instance */
|
|
2399
|
+
adminAPI?: AdminAPIInstance$2;
|
|
2400
|
+
/** Template adapter for policy templates */
|
|
2401
|
+
templateAPI?: TemplateAPI;
|
|
2402
|
+
/** Policy storage adapter */
|
|
2403
|
+
policyAPI?: PolicyAPI;
|
|
2404
|
+
/** Policy logs adapter for activity tracking */
|
|
2405
|
+
policyLogsAPI?: PolicyLogsAPI;
|
|
2406
|
+
/** Tide context for enclave workflow (from useTideCloak hook) */
|
|
2407
|
+
tideContext?: TideContextMethods;
|
|
2408
|
+
/** Callback when Tide policy request is created */
|
|
2409
|
+
onTideRequestCreated?: (request: any, roleName: string) => Promise<void>;
|
|
2410
|
+
/** Realm name */
|
|
2411
|
+
realm?: string;
|
|
2412
|
+
/** Role type: 'realm', 'client', or 'all' (default: 'realm') */
|
|
2413
|
+
roleType?: RoleTypeConfig;
|
|
2414
|
+
/** Override fetch roles */
|
|
2415
|
+
fetchRoles?: RolesPageBaseProps<T>["fetchRoles"];
|
|
2416
|
+
/** Override create */
|
|
2417
|
+
onCreate?: RolesPageBaseProps<T>["onCreate"];
|
|
2418
|
+
/** Override update */
|
|
2419
|
+
onUpdate?: RolesPageBaseProps<T>["onUpdate"];
|
|
2420
|
+
/** Override delete */
|
|
2421
|
+
onDelete?: RolesPageBaseProps<T>["onDelete"];
|
|
2422
|
+
/** Override policy creation */
|
|
2423
|
+
onCreatePolicy?: RolesPageBaseProps<T>["onCreatePolicy"];
|
|
2424
|
+
/** Toast handler */
|
|
2425
|
+
toast?: RolesPageBaseProps<T>["toast"];
|
|
2426
|
+
/** Query invalidation */
|
|
2427
|
+
invalidateQueries?: RolesPageBaseProps<T>["invalidateQueries"];
|
|
2428
|
+
/** Custom components */
|
|
2429
|
+
components?: RolesPageBaseProps<T>["components"];
|
|
2430
|
+
/** Help text below description */
|
|
2431
|
+
helpText?: RolesPageBaseProps<T>["helpText"];
|
|
2432
|
+
/** Current username for logging */
|
|
2433
|
+
currentUsername?: string;
|
|
2434
|
+
}
|
|
2435
|
+
declare function RolesPage<T extends RoleItem = RoleItem>({ adminAPI: adminAPIProp, templateAPI, policyAPI, policyLogsAPI, tideContext, onTideRequestCreated, realm, roleType, fetchRoles: fetchRolesProp, onCreate: onCreateProp, onUpdate: onUpdateProp, onDelete: onDeleteProp, onCreatePolicy: onCreatePolicyProp, helpText: helpTextProp, currentUsername, ...props }: RolesPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
2436
|
+
|
|
2437
|
+
type AdminAPIInstance$1 = {
|
|
2438
|
+
setRealm?: (realm: string) => void;
|
|
2439
|
+
getPendingChangeSets: () => Promise<any>;
|
|
2440
|
+
approveChangeSet: (changeSet: any) => Promise<any>;
|
|
2441
|
+
commitChangeSet: (changeSet: any) => Promise<any>;
|
|
2442
|
+
cancelChangeSet: (changeSet: any) => Promise<any>;
|
|
2443
|
+
getRawChangeSetRequest?: (changeSet: any) => Promise<any[]>;
|
|
2444
|
+
approveChangeSetWithSignature?: (changeSet: any, signedRequest: string) => Promise<void>;
|
|
2445
|
+
};
|
|
2446
|
+
interface TideApprovalResult {
|
|
2447
|
+
id: string;
|
|
2448
|
+
approved?: {
|
|
2449
|
+
request: Uint8Array;
|
|
2450
|
+
};
|
|
2451
|
+
denied?: boolean;
|
|
2452
|
+
pending?: boolean;
|
|
2453
|
+
}
|
|
2454
|
+
/** Get from useTideCloak() hook */
|
|
2455
|
+
interface TideApprovalContext {
|
|
2456
|
+
initializeTideRequest: <T extends {
|
|
2457
|
+
encode: () => Uint8Array;
|
|
2458
|
+
}>(request: T) => Promise<T>;
|
|
2459
|
+
approveTideRequests: (requests: {
|
|
2460
|
+
id: string;
|
|
2461
|
+
request: Uint8Array;
|
|
2462
|
+
}[]) => Promise<TideApprovalResult[]>;
|
|
2463
|
+
}
|
|
2464
|
+
interface PolicyApprovalData {
|
|
2465
|
+
id: string;
|
|
2466
|
+
roleId: string;
|
|
2467
|
+
requestedBy: string;
|
|
2468
|
+
requestedByEmail?: string;
|
|
2469
|
+
threshold: number;
|
|
2470
|
+
approvalCount: number;
|
|
2471
|
+
rejectionCount?: number;
|
|
2472
|
+
commitReady?: boolean;
|
|
2473
|
+
approvedBy?: string[];
|
|
2474
|
+
deniedBy?: string[];
|
|
2475
|
+
status: string;
|
|
2476
|
+
timestamp: string | number;
|
|
2477
|
+
policyRequestData: string;
|
|
2478
|
+
contractCode?: string;
|
|
2479
|
+
}
|
|
2480
|
+
/** Implement this to store policy approvals (or use createLocalStoragePolicyApprovalsAPI for dev) */
|
|
2481
|
+
interface PolicyApprovalsAPI {
|
|
2482
|
+
getPendingPolicies: () => Promise<PolicyApprovalData[]>;
|
|
2483
|
+
approve?: (id: string, rejected?: boolean, username?: string) => Promise<void>;
|
|
2484
|
+
revoke?: (id: string, username?: string) => Promise<void>;
|
|
2485
|
+
commit?: (id: string) => Promise<void>;
|
|
2486
|
+
cancel?: (id: string) => Promise<void>;
|
|
2487
|
+
_isLocalStorage?: boolean;
|
|
2488
|
+
}
|
|
2489
|
+
/** localStorage adapter for development */
|
|
2490
|
+
declare function createLocalStoragePolicyApprovalsAPI(storageKey?: string): PolicyApprovalsAPI;
|
|
2491
|
+
interface AccessMetadataRecord {
|
|
2492
|
+
changeSetId: string;
|
|
2493
|
+
username: string;
|
|
2494
|
+
userEmail?: string;
|
|
2495
|
+
clientId?: string;
|
|
2496
|
+
role?: string;
|
|
2497
|
+
timestamp: string | number;
|
|
2498
|
+
actionType?: string;
|
|
2499
|
+
changeSetType?: string;
|
|
2500
|
+
}
|
|
2501
|
+
/** Implement this to store access change metadata (or use createLocalStorageAccessMetadataAPI for dev) */
|
|
2502
|
+
interface AccessMetadataAPI {
|
|
2503
|
+
getMetadata: (changeSetId: string) => Promise<AccessMetadataRecord | null>;
|
|
2504
|
+
getAllMetadata: () => Promise<AccessMetadataRecord[]>;
|
|
2505
|
+
saveMetadata: (record: AccessMetadataRecord) => Promise<void>;
|
|
2506
|
+
deleteMetadata: (changeSetId: string) => Promise<void>;
|
|
2507
|
+
_isLocalStorage?: boolean;
|
|
2508
|
+
}
|
|
2509
|
+
/** localStorage adapter for development */
|
|
2510
|
+
declare function createLocalStorageAccessMetadataAPI(storageKey?: string): AccessMetadataAPI;
|
|
2511
|
+
/** Tab config with optional enclave support */
|
|
2512
|
+
interface EnclaveApprovalTabConfig {
|
|
2513
|
+
/** Get raw request bytes for enclave approval (enables enclave if provided) */
|
|
2514
|
+
getRawRequest?: (item: any) => Promise<Uint8Array | null>;
|
|
2515
|
+
/** Submit signed approval after user approves in enclave */
|
|
2516
|
+
submitSignedApproval?: (item: any, signedRequest: string) => Promise<void>;
|
|
2517
|
+
/** Handle denial from enclave */
|
|
2518
|
+
onEnclaveDenied?: (item: any) => Promise<void>;
|
|
2519
|
+
}
|
|
2520
|
+
interface ApprovalsPageProps extends Omit<ApprovalsPageBaseProps, "tabs"> {
|
|
2521
|
+
/** AdminAPI instance */
|
|
2522
|
+
adminAPI?: AdminAPIInstance$1;
|
|
2523
|
+
/** Policy approvals storage adapter */
|
|
2524
|
+
policyApprovalsAPI?: PolicyApprovalsAPI;
|
|
2525
|
+
/** Policy logs adapter for activity tracking */
|
|
2526
|
+
policyLogsAPI?: PolicyLogsAPI;
|
|
2527
|
+
/** Access metadata adapter (merges with AdminAPI data) */
|
|
2528
|
+
accessMetadataAPI?: AccessMetadataAPI;
|
|
2529
|
+
/** Tide context for enclave approvals (from useTideCloak hook) */
|
|
2530
|
+
tideContext?: TideApprovalContext;
|
|
2531
|
+
/** Realm name */
|
|
2532
|
+
realm?: string;
|
|
2533
|
+
/** Custom tabs config */
|
|
2534
|
+
tabs?: ApprovalsPageBaseProps["tabs"];
|
|
2535
|
+
/** Additional tabs with optional enclave support */
|
|
2536
|
+
additionalTabs?: (ApprovalTabConfig<BaseApprovalItem> & EnclaveApprovalTabConfig)[];
|
|
2537
|
+
/** Show policy tab (default: true) */
|
|
2538
|
+
showPolicyTab?: boolean;
|
|
2539
|
+
/** Help text below description */
|
|
2540
|
+
helpText?: ApprovalsPageBaseProps["helpText"];
|
|
2541
|
+
/** Current username for logging */
|
|
2542
|
+
currentUsername?: string;
|
|
2543
|
+
}
|
|
2544
|
+
declare function ApprovalsPage({ adminAPI: adminAPIProp, policyApprovalsAPI: policyApprovalsAPIProp, policyLogsAPI, accessMetadataAPI: accessMetadataAPIProp, tideContext, realm, tabs: tabsProp, additionalTabs, showPolicyTab, helpText: helpTextProp, currentUsername, ...props }: ApprovalsPageProps): react_jsx_runtime.JSX.Element;
|
|
2545
|
+
|
|
2546
|
+
type AdminAPIInstance = {
|
|
2547
|
+
setRealm?: (realm: string) => void;
|
|
2548
|
+
getUsers: () => Promise<any>;
|
|
2549
|
+
getRoles: () => Promise<any>;
|
|
2550
|
+
getRole: (roleName: string) => Promise<any>;
|
|
2551
|
+
createUser: (user: any) => Promise<any>;
|
|
2552
|
+
updateUser: (userId: string, user: any) => Promise<any>;
|
|
2553
|
+
deleteUser: (userId: string) => Promise<any>;
|
|
2554
|
+
addUserRoles?: (userId: string, roles: any[]) => Promise<any>;
|
|
2555
|
+
removeUserRoles?: (userId: string, roles: any[]) => Promise<any>;
|
|
2556
|
+
setUserEnabled?: (userId: string, enabled: boolean) => Promise<any>;
|
|
2557
|
+
getTideLinkUrl?: (userId: string, redirectUri: string, lifespan?: number) => Promise<string>;
|
|
2558
|
+
};
|
|
2559
|
+
interface ChangeSetInfo {
|
|
2560
|
+
changeSetId: string;
|
|
2561
|
+
changeSetType: string;
|
|
2562
|
+
actionType: string;
|
|
2563
|
+
username: string;
|
|
2564
|
+
userId: string;
|
|
2565
|
+
roles: string[];
|
|
2566
|
+
timestamp: number;
|
|
2567
|
+
}
|
|
2568
|
+
interface UsersPageProps<T extends UserItem = UserItem> extends Omit<UsersPageBaseProps<T>, "fetchUsers" | "fetchRoles" | "onCreate" | "onUpdateProfile" | "onUpdateRoles" | "onDelete" | "onSetEnabled" | "getTideLinkUrl"> {
|
|
2569
|
+
/** AdminAPI instance */
|
|
2570
|
+
adminAPI?: AdminAPIInstance;
|
|
2571
|
+
/** Realm name */
|
|
2572
|
+
realm?: string;
|
|
2573
|
+
/** Redirect URI for Tide link */
|
|
2574
|
+
tideLinkRedirectUri?: string;
|
|
2575
|
+
/** Access metadata adapter (saves metadata when role changes create change sets) */
|
|
2576
|
+
accessMetadataAPI?: AccessMetadataAPI;
|
|
2577
|
+
/** Callback when a change set is created */
|
|
2578
|
+
onChangeSetCreated?: (info: ChangeSetInfo) => void | Promise<void>;
|
|
2579
|
+
/** Override fetch users */
|
|
2580
|
+
fetchUsers?: UsersPageBaseProps<T>["fetchUsers"];
|
|
2581
|
+
/** Override create */
|
|
2582
|
+
onCreate?: UsersPageBaseProps<T>["onCreate"];
|
|
2583
|
+
/** Override delete */
|
|
2584
|
+
onDelete?: UsersPageBaseProps<T>["onDelete"];
|
|
2585
|
+
/** Override getTideLinkUrl */
|
|
2586
|
+
getTideLinkUrl?: UsersPageBaseProps<T>["getTideLinkUrl"];
|
|
2587
|
+
}
|
|
2588
|
+
declare function UsersPage<T extends UserItem = UserItem>({ adminAPI: adminAPIProp, realm, tideLinkRedirectUri, accessMetadataAPI, onChangeSetCreated, fetchUsers: fetchUsersProp, onCreate: onCreateProp, onDelete: onDeleteProp, getTideLinkUrl: getTideLinkUrlProp, ...props }: UsersPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
2589
|
+
|
|
2590
|
+
declare function Card({ children, className, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2591
|
+
declare function CardContent({ children, className, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2592
|
+
declare function CardHeader({ children, className, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2593
|
+
declare function CardTitle({ children, className, style, ...props }: React$1.HTMLAttributes<HTMLHeadingElement>): react_jsx_runtime.JSX.Element;
|
|
2594
|
+
declare function CardDescription({ children, className, style, ...props }: React$1.HTMLAttributes<HTMLParagraphElement>): react_jsx_runtime.JSX.Element;
|
|
2595
|
+
interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
2596
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
|
|
2597
|
+
size?: "default" | "sm" | "lg" | "icon";
|
|
2598
|
+
}
|
|
2599
|
+
declare function Button({ children, variant, size, style, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
2600
|
+
interface BadgeProps extends React$1.HTMLAttributes<HTMLSpanElement> {
|
|
2601
|
+
variant?: "default" | "secondary" | "destructive" | "outline";
|
|
2602
|
+
}
|
|
2603
|
+
declare function Badge({ children, variant, style, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
|
|
2604
|
+
declare function Input({ className, style, ...props }: React$1.InputHTMLAttributes<HTMLInputElement>): react_jsx_runtime.JSX.Element;
|
|
2605
|
+
declare function Label({ children, className, style, ...props }: React$1.LabelHTMLAttributes<HTMLLabelElement>): react_jsx_runtime.JSX.Element;
|
|
2606
|
+
declare function Textarea({ className, style, ...props }: React$1.TextareaHTMLAttributes<HTMLTextAreaElement>): react_jsx_runtime.JSX.Element;
|
|
2607
|
+
interface CheckboxProps extends Omit<React$1.InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
2608
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
2609
|
+
}
|
|
2610
|
+
declare function Checkbox({ onCheckedChange, onChange, style, ...props }: CheckboxProps): react_jsx_runtime.JSX.Element;
|
|
2611
|
+
declare function Select({ children, onValueChange, value, ...props }: {
|
|
2612
|
+
children: React$1.ReactNode;
|
|
2613
|
+
onValueChange?: (value: string) => void;
|
|
2614
|
+
value?: string;
|
|
2615
|
+
}): react_jsx_runtime.JSX.Element;
|
|
2616
|
+
declare function SelectTrigger({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2617
|
+
declare function SelectValue({ placeholder }: {
|
|
2618
|
+
placeholder?: string;
|
|
2619
|
+
}): react_jsx_runtime.JSX.Element;
|
|
2620
|
+
declare function SelectContent({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element | null;
|
|
2621
|
+
declare function SelectItem({ children, value, style, ...props }: React$1.HTMLAttributes<HTMLDivElement> & {
|
|
2622
|
+
value: string;
|
|
2623
|
+
}): react_jsx_runtime.JSX.Element;
|
|
2624
|
+
declare function Skeleton({ className, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2625
|
+
declare function Table({ children, style, ...props }: React$1.HTMLAttributes<HTMLTableElement>): react_jsx_runtime.JSX.Element;
|
|
2626
|
+
declare function TableHeader({ children, style, ...props }: React$1.HTMLAttributes<HTMLTableSectionElement>): react_jsx_runtime.JSX.Element;
|
|
2627
|
+
declare function TableBody({ children, style, ...props }: React$1.HTMLAttributes<HTMLTableSectionElement>): react_jsx_runtime.JSX.Element;
|
|
2628
|
+
declare function TableRow({ children, style, ...props }: React$1.HTMLAttributes<HTMLTableRowElement>): react_jsx_runtime.JSX.Element;
|
|
2629
|
+
declare function TableHead({ children, style, ...props }: React$1.ThHTMLAttributes<HTMLTableCellElement>): react_jsx_runtime.JSX.Element;
|
|
2630
|
+
declare function TableCell({ children, style, ...props }: React$1.TdHTMLAttributes<HTMLTableCellElement>): react_jsx_runtime.JSX.Element;
|
|
2631
|
+
interface DialogProps {
|
|
2632
|
+
open?: boolean;
|
|
2633
|
+
onOpenChange?: (open: boolean) => void;
|
|
2634
|
+
children: React$1.ReactNode;
|
|
2635
|
+
}
|
|
2636
|
+
declare function Dialog({ open, onOpenChange, children }: DialogProps): react_jsx_runtime.JSX.Element | null;
|
|
2637
|
+
declare function DialogContent({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2638
|
+
declare function DialogHeader({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2639
|
+
declare function DialogTitle({ children, style, ...props }: React$1.HTMLAttributes<HTMLHeadingElement>): react_jsx_runtime.JSX.Element;
|
|
2640
|
+
declare function DialogDescription({ children, style, ...props }: React$1.HTMLAttributes<HTMLParagraphElement>): react_jsx_runtime.JSX.Element;
|
|
2641
|
+
declare function DialogFooter({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2642
|
+
interface TabsProps {
|
|
2643
|
+
value?: string;
|
|
2644
|
+
defaultValue?: string;
|
|
2645
|
+
onValueChange?: (value: string) => void;
|
|
2646
|
+
children: React$1.ReactNode;
|
|
2647
|
+
}
|
|
2648
|
+
declare function Tabs({ value, defaultValue, onValueChange, children }: TabsProps): react_jsx_runtime.JSX.Element;
|
|
2649
|
+
declare function TabsList({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2650
|
+
declare function TabsTrigger({ children, value, style, ...props }: React$1.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
2651
|
+
value: string;
|
|
2652
|
+
}): react_jsx_runtime.JSX.Element;
|
|
2653
|
+
declare function TabsContent({ children, value, style, ...props }: React$1.HTMLAttributes<HTMLDivElement> & {
|
|
2654
|
+
value: string;
|
|
2655
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
2656
|
+
declare function AlertDialog({ open, onOpenChange, children }: {
|
|
2657
|
+
open?: boolean;
|
|
2658
|
+
onOpenChange?: (open: boolean) => void;
|
|
2659
|
+
children: React$1.ReactNode;
|
|
2660
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
2661
|
+
declare function AlertDialogContent({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2662
|
+
declare function AlertDialogHeader({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2663
|
+
declare function AlertDialogTitle({ children, style, ...props }: React$1.HTMLAttributes<HTMLHeadingElement>): react_jsx_runtime.JSX.Element;
|
|
2664
|
+
declare function AlertDialogDescription({ children, style, ...props }: React$1.HTMLAttributes<HTMLParagraphElement>): react_jsx_runtime.JSX.Element;
|
|
2665
|
+
declare function AlertDialogFooter({ children, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2666
|
+
declare function AlertDialogCancel({ children, style, onClick, ...props }: React$1.ButtonHTMLAttributes<HTMLButtonElement>): react_jsx_runtime.JSX.Element;
|
|
2667
|
+
declare function AlertDialogAction({ children, style, onClick, ...props }: React$1.ButtonHTMLAttributes<HTMLButtonElement>): react_jsx_runtime.JSX.Element;
|
|
2668
|
+
interface SwitchProps {
|
|
2669
|
+
checked?: boolean;
|
|
2670
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
2671
|
+
disabled?: boolean;
|
|
2672
|
+
style?: React$1.CSSProperties;
|
|
2673
|
+
}
|
|
2674
|
+
declare function Switch({ checked, onCheckedChange, disabled, style }: SwitchProps): react_jsx_runtime.JSX.Element;
|
|
2675
|
+
declare function ScrollArea({ children, className, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2676
|
+
interface AlertProps extends React$1.HTMLAttributes<HTMLDivElement> {
|
|
2677
|
+
variant?: "default" | "destructive";
|
|
2678
|
+
}
|
|
2679
|
+
declare function Alert({ children, variant, style, ...props }: AlertProps): react_jsx_runtime.JSX.Element;
|
|
2680
|
+
declare function AlertDescription({ children, style, ...props }: React$1.HTMLAttributes<HTMLParagraphElement>): react_jsx_runtime.JSX.Element;
|
|
2681
|
+
interface CodeEditorProps {
|
|
2682
|
+
value?: string;
|
|
2683
|
+
onChange?: (value: string) => void;
|
|
2684
|
+
height?: string;
|
|
2685
|
+
style?: React$1.CSSProperties;
|
|
2686
|
+
}
|
|
2687
|
+
declare function CodeEditor({ value, onChange, height, style }: CodeEditorProps): react_jsx_runtime.JSX.Element;
|
|
2688
|
+
declare function Separator({ className, style, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2689
|
+
declare const defaultComponents: {
|
|
2690
|
+
Card: typeof Card;
|
|
2691
|
+
CardContent: typeof CardContent;
|
|
2692
|
+
CardHeader: typeof CardHeader;
|
|
2693
|
+
CardTitle: typeof CardTitle;
|
|
2694
|
+
CardDescription: typeof CardDescription;
|
|
2695
|
+
Button: typeof Button;
|
|
2696
|
+
Badge: typeof Badge;
|
|
2697
|
+
Input: typeof Input;
|
|
2698
|
+
Label: typeof Label;
|
|
2699
|
+
Textarea: typeof Textarea;
|
|
2700
|
+
Checkbox: typeof Checkbox;
|
|
2701
|
+
Select: typeof Select;
|
|
2702
|
+
SelectTrigger: typeof SelectTrigger;
|
|
2703
|
+
SelectValue: typeof SelectValue;
|
|
2704
|
+
SelectContent: typeof SelectContent;
|
|
2705
|
+
SelectItem: typeof SelectItem;
|
|
2706
|
+
Skeleton: typeof Skeleton;
|
|
2707
|
+
Switch: typeof Switch;
|
|
2708
|
+
ScrollArea: typeof ScrollArea;
|
|
2709
|
+
Alert: typeof Alert;
|
|
2710
|
+
AlertDescription: typeof AlertDescription;
|
|
2711
|
+
CodeEditor: typeof CodeEditor;
|
|
2712
|
+
Table: typeof Table;
|
|
2713
|
+
TableHeader: typeof TableHeader;
|
|
2714
|
+
TableBody: typeof TableBody;
|
|
2715
|
+
TableRow: typeof TableRow;
|
|
2716
|
+
TableHead: typeof TableHead;
|
|
2717
|
+
TableCell: typeof TableCell;
|
|
2718
|
+
Dialog: typeof Dialog;
|
|
2719
|
+
DialogContent: typeof DialogContent;
|
|
2720
|
+
DialogHeader: typeof DialogHeader;
|
|
2721
|
+
DialogTitle: typeof DialogTitle;
|
|
2722
|
+
DialogDescription: typeof DialogDescription;
|
|
2723
|
+
DialogFooter: typeof DialogFooter;
|
|
2724
|
+
AlertDialog: typeof AlertDialog;
|
|
2725
|
+
AlertDialogContent: typeof AlertDialogContent;
|
|
2726
|
+
AlertDialogHeader: typeof AlertDialogHeader;
|
|
2727
|
+
AlertDialogTitle: typeof AlertDialogTitle;
|
|
2728
|
+
AlertDialogDescription: typeof AlertDialogDescription;
|
|
2729
|
+
AlertDialogFooter: typeof AlertDialogFooter;
|
|
2730
|
+
AlertDialogCancel: typeof AlertDialogCancel;
|
|
2731
|
+
AlertDialogAction: typeof AlertDialogAction;
|
|
2732
|
+
Separator: typeof Separator;
|
|
2733
|
+
Tabs: typeof Tabs;
|
|
2734
|
+
TabsList: typeof TabsList;
|
|
2735
|
+
TabsTrigger: typeof TabsTrigger;
|
|
2736
|
+
TabsContent: typeof TabsContent;
|
|
2737
|
+
};
|
|
2738
|
+
|
|
2739
|
+
export { ACTION_COLORS, ACTION_ICONS, type AccessApprovalItem, type AccessLogItem, type AccessMetadataAPI, type AccessMetadataRecord, ActionButton, ActionButtonGroup, type ActionButtonGroupProps, type ActionButtonProps, type ActionResult, type ActionType, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, type ApprovableItem, type ApprovalDecision, type ApprovalStatus, type ApprovalTabConfig, ApprovalsPage, ApprovalsPageBase, type ApprovalsPageBaseProps, type ApprovalsPageProps, type AsyncActionHandler, type AutoRefreshOptions, type AutoRefreshReturn, Badge, type BadgeConfig, type BaseApprovalItem, type BaseDataItem, type BaseLogItem, type BulkAction, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, type ChangeSetInfo, type ChangeSetRequest, Checkbox, CodeEditor, CodePreview, CollapsibleSection, type CollapsibleSectionProps, type ColumnDef, ConfirmDialog, type ConfirmDialogConfig, type ConfirmDialogProps, type CreateUserFormData, DEFAULT_MODEL_IDS, DEFAULT_ROLE_CONTRACT, DataTable, type DataTableProps, DetailDialog, type DetailDialogProps, type DetailField, Dialog, type DialogConfig, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, EmptyState, type EmptyStateConfig, EmptyStateNoData, EmptyStateNoFiles, EmptyStateNoResults, type EmptyStateProps, type EnclaveApprovalTabConfig, type FormFieldDef, type FormFieldType, type FrameworkConfig, Input, Label, LoadingSkeleton, type LoadingSkeletonProps, type LoadingStateConfig, LogsPage, LogsPageBase, type LogsPageBaseProps, type LogsPageProps, type LogsTabConfig, type PageSizeMode, PaginatedTable, type PaginatedTableProps, type PaginationConfig, type PaginationReturn, type ParameterDef, type PolicyAPI, type PolicyApprovalData, type PolicyApprovalItem, type PolicyApprovalsAPI, type PolicyConfig, type PolicyLogData, type PolicyLogItem, type PolicyLogsAPI, type PolicyTemplateItem$1 as PolicyTemplateItem, type RawApprovalRequest, RefreshButton, type RefreshButtonProps, type RoleApprovalItem, type RoleItem, type RolePolicy, type PolicyTemplateItem as RolePolicyTemplateItem, type TemplateParameter as RoleTemplateParameter, RolesPage, RolesPageBase, type RolesPageBaseProps, type RolesPageProps, STATUS_COLORS, STATUS_ICONS, ScrollArea, Select, SelectContent, SelectItem, type SelectOption, SelectTrigger, SelectValue, type SelectionReturn, Separator, type SignedApprovalResponse, Skeleton$1 as Skeleton, type SkeletonProps, type SortConfig, StatusBadge, type StatusBadgeProps, type StatusConfig, type StatusType, Switch, type TabDef, Table, type TableAction, TableBody, TableCell, TableHead, TableHeader, TableRow, TableRowSkeleton, Tabs, TabsContent, TabsList, TabsTrigger, TabsView, type TabsViewProps, type TemplateAPI, type TemplateFormData, type TemplateParameter$1 as TemplateParameter, TemplatesPage, TemplatesPageBase, type TemplatesPageBaseProps, type TemplatesPageProps, Textarea, type TideApprovalContext, type TideApprovalResult, type TideContextMethods, type TidePolicyConfig, type ToastConfig, Skeleton as UIComponentSkeleton, type UsePaginationOptions, type UserFormData, type UserItem, type RoleItem$1 as UserRoleItem, UsersPage, UsersPageBase, type UsersPageBaseProps, type UsersPageProps, areTideLibsAvailable, base64ToBytes, bytesToBase64, cn, colors, computeContractId, computeRowsForViewportHeight, createActionColumn, createLocalStorageAccessMetadataAPI, createLocalStoragePolicyAPI, createLocalStoragePolicyApprovalsAPI, createLocalStoragePolicyLogsAPI, createLocalStorageTemplateAPI, createLogProgressColumn, createLogTimestampColumn, createProgressColumn, createRoleColumn, createStatusColumn, createTidePolicyHandler, createTidePolicyRequest, createTimestampColumn, createUserColumn, defaultComponents, delay, duration, focusRing, fontSize, formatLogTimestamp, formatTimestamp, generateId, getStatusConfig, injectThemeCSS, isDefined, loadTideLibs, radius, rolePolicyToTideConfig, safeJsonParse, shadow, spacing, themeCSS, truncate, useAutoRefresh, usePagination, useSelection, zIndex };
|