@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
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import type { AutoRefreshOptions, AutoRefreshReturn } from "../types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook for auto-refreshing data at a configurable interval
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* const { secondsRemaining, refreshNow, lastError, failureCount } = useAutoRefresh({
|
|
10
|
+
* intervalSeconds: 15,
|
|
11
|
+
* refresh: fetchData,
|
|
12
|
+
* isBlocked: isLoading,
|
|
13
|
+
* onError: (err) => console.error('Refresh failed:', err),
|
|
14
|
+
* maxRetries: 3,
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function useAutoRefresh(options: AutoRefreshOptions): AutoRefreshReturn {
|
|
19
|
+
const {
|
|
20
|
+
intervalSeconds,
|
|
21
|
+
enabled = true,
|
|
22
|
+
refresh,
|
|
23
|
+
isBlocked = false,
|
|
24
|
+
onError,
|
|
25
|
+
maxRetries,
|
|
26
|
+
} = options;
|
|
27
|
+
|
|
28
|
+
const refreshRef = useRef(refresh);
|
|
29
|
+
refreshRef.current = refresh;
|
|
30
|
+
|
|
31
|
+
const onErrorRef = useRef(onError);
|
|
32
|
+
onErrorRef.current = onError;
|
|
33
|
+
|
|
34
|
+
const isBlockedRef = useRef(isBlocked);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
isBlockedRef.current = isBlocked;
|
|
37
|
+
}, [isBlocked]);
|
|
38
|
+
|
|
39
|
+
const [nextRefreshAt, setNextRefreshAt] = useState(() => Date.now() + intervalSeconds * 1000);
|
|
40
|
+
const [now, setNow] = useState(() => Date.now());
|
|
41
|
+
const [lastError, setLastError] = useState<Error | null>(null);
|
|
42
|
+
const [failureCount, setFailureCount] = useState(0);
|
|
43
|
+
const [isStopped, setIsStopped] = useState(false);
|
|
44
|
+
|
|
45
|
+
const secondsRemaining = useMemo(() => {
|
|
46
|
+
if (!enabled || isStopped) return null;
|
|
47
|
+
return Math.max(0, Math.ceil((nextRefreshAt - now) / 1000));
|
|
48
|
+
}, [enabled, isStopped, nextRefreshAt, now]);
|
|
49
|
+
|
|
50
|
+
// Update current time every 250ms
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!enabled || isStopped) return;
|
|
53
|
+
const id = window.setInterval(() => setNow(Date.now()), 250);
|
|
54
|
+
return () => window.clearInterval(id);
|
|
55
|
+
}, [enabled, isStopped]);
|
|
56
|
+
|
|
57
|
+
const runRefresh = useCallback(async () => {
|
|
58
|
+
if (!enabled || isStopped) return;
|
|
59
|
+
if (isBlockedRef.current) return;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
await refreshRef.current();
|
|
63
|
+
// Success - reset error state
|
|
64
|
+
setLastError(null);
|
|
65
|
+
setFailureCount(0);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
68
|
+
setLastError(error);
|
|
69
|
+
setFailureCount(prev => {
|
|
70
|
+
const newCount = prev + 1;
|
|
71
|
+
// Stop if max retries exceeded
|
|
72
|
+
if (maxRetries !== undefined && newCount >= maxRetries) {
|
|
73
|
+
setIsStopped(true);
|
|
74
|
+
}
|
|
75
|
+
return newCount;
|
|
76
|
+
});
|
|
77
|
+
// Call error callback
|
|
78
|
+
onErrorRef.current?.(error);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
setNextRefreshAt(Date.now() + intervalSeconds * 1000);
|
|
82
|
+
}, [enabled, isStopped, intervalSeconds, maxRetries]);
|
|
83
|
+
|
|
84
|
+
// Trigger refresh when time is up
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (!enabled || isStopped) return;
|
|
87
|
+
if (isBlockedRef.current) return;
|
|
88
|
+
if (now < nextRefreshAt) return;
|
|
89
|
+
void runRefresh();
|
|
90
|
+
}, [enabled, isStopped, now, nextRefreshAt, runRefresh]);
|
|
91
|
+
|
|
92
|
+
const refreshNow = useCallback(async () => {
|
|
93
|
+
// Allow manual refresh even if stopped
|
|
94
|
+
if (!enabled) return;
|
|
95
|
+
if (isBlockedRef.current) return;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await refreshRef.current();
|
|
99
|
+
setLastError(null);
|
|
100
|
+
setFailureCount(0);
|
|
101
|
+
setIsStopped(false); // Resume auto-refresh on successful manual refresh
|
|
102
|
+
} catch (err) {
|
|
103
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
104
|
+
setLastError(error);
|
|
105
|
+
onErrorRef.current?.(error);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
setNextRefreshAt(Date.now() + intervalSeconds * 1000);
|
|
109
|
+
}, [enabled, intervalSeconds]);
|
|
110
|
+
|
|
111
|
+
const resetTimer = useCallback(() => {
|
|
112
|
+
setNextRefreshAt(Date.now() + intervalSeconds * 1000);
|
|
113
|
+
setIsStopped(false); // Also resume auto-refresh
|
|
114
|
+
setFailureCount(0);
|
|
115
|
+
setLastError(null);
|
|
116
|
+
}, [intervalSeconds]);
|
|
117
|
+
|
|
118
|
+
return { secondsRemaining, refreshNow, resetTimer, lastError, failureCount, isStopped };
|
|
119
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { useCallback, useMemo, useState, useEffect, useRef } from "react";
|
|
2
|
+
import type { PaginationReturn } from "../types";
|
|
3
|
+
import { computeRowsForViewportHeight } from "../utils";
|
|
4
|
+
|
|
5
|
+
export type PageSizeMode = "auto" | "manual";
|
|
6
|
+
|
|
7
|
+
export interface UsePaginationOptions {
|
|
8
|
+
/** Initial page (0-indexed) */
|
|
9
|
+
initialPage?: number;
|
|
10
|
+
/** Initial page size */
|
|
11
|
+
initialPageSize?: number;
|
|
12
|
+
/** Total number of items (for calculating total pages) */
|
|
13
|
+
totalItems?: number;
|
|
14
|
+
/** Whether to enable auto page size based on viewport */
|
|
15
|
+
autoPageSize?: boolean;
|
|
16
|
+
/** Ref to viewport element for auto sizing */
|
|
17
|
+
viewportRef?: React.RefObject<HTMLDivElement>;
|
|
18
|
+
/** Callback when page changes */
|
|
19
|
+
onPageChange?: (page: number) => void;
|
|
20
|
+
/** Callback when page size changes */
|
|
21
|
+
onPageSizeChange?: (pageSize: number) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Hook for managing pagination state
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* const pagination = usePagination({
|
|
30
|
+
* initialPageSize: 25,
|
|
31
|
+
* totalItems: data.length,
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // Use in query
|
|
35
|
+
* const { data } = useQuery({
|
|
36
|
+
* queryKey: ['items', pagination.page, pagination.pageSize],
|
|
37
|
+
* queryFn: () => fetchItems(pagination.pageSize, pagination.page * pagination.pageSize),
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function usePagination(options: UsePaginationOptions = {}): PaginationReturn & {
|
|
42
|
+
pageSizeMode: PageSizeMode;
|
|
43
|
+
setPageSizeMode: (mode: PageSizeMode) => void;
|
|
44
|
+
pageSizeSelectValue: string;
|
|
45
|
+
onPageSizeSelect: (value: string) => void;
|
|
46
|
+
} {
|
|
47
|
+
const {
|
|
48
|
+
initialPage = 0,
|
|
49
|
+
initialPageSize = 25,
|
|
50
|
+
totalItems = 0,
|
|
51
|
+
autoPageSize = false,
|
|
52
|
+
viewportRef,
|
|
53
|
+
onPageChange,
|
|
54
|
+
onPageSizeChange,
|
|
55
|
+
} = options;
|
|
56
|
+
|
|
57
|
+
const [page, setPageState] = useState(initialPage);
|
|
58
|
+
const [pageSize, setPageSizeState] = useState(initialPageSize);
|
|
59
|
+
const [pageSizeMode, setPageSizeMode] = useState<PageSizeMode>(
|
|
60
|
+
autoPageSize ? "auto" : "manual"
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// Handle auto page size with ResizeObserver
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (pageSizeMode !== "auto" || !viewportRef?.current) return;
|
|
66
|
+
|
|
67
|
+
const el = viewportRef.current;
|
|
68
|
+
const ro = new ResizeObserver((entries) => {
|
|
69
|
+
const h = entries[0]?.contentRect.height ?? 0;
|
|
70
|
+
if (!h) return;
|
|
71
|
+
const newSize = computeRowsForViewportHeight(h);
|
|
72
|
+
setPageSizeState(newSize);
|
|
73
|
+
onPageSizeChange?.(newSize);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
ro.observe(el);
|
|
77
|
+
return () => ro.disconnect();
|
|
78
|
+
}, [pageSizeMode, viewportRef, onPageSizeChange]);
|
|
79
|
+
|
|
80
|
+
const setPage = useCallback(
|
|
81
|
+
(newPage: number) => {
|
|
82
|
+
setPageState(newPage);
|
|
83
|
+
onPageChange?.(newPage);
|
|
84
|
+
},
|
|
85
|
+
[onPageChange]
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const setPageSize = useCallback(
|
|
89
|
+
(newSize: number) => {
|
|
90
|
+
setPageSizeState(newSize);
|
|
91
|
+
onPageSizeChange?.(newSize);
|
|
92
|
+
// Reset to first page when page size changes
|
|
93
|
+
setPageState(0);
|
|
94
|
+
onPageChange?.(0);
|
|
95
|
+
},
|
|
96
|
+
[onPageChange, onPageSizeChange]
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const totalPages = useMemo(
|
|
100
|
+
() => Math.max(1, Math.ceil(totalItems / pageSize)),
|
|
101
|
+
[totalItems, pageSize]
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const nextPage = useCallback(() => {
|
|
105
|
+
const newPage = Math.min(page + 1, totalPages - 1);
|
|
106
|
+
setPage(newPage);
|
|
107
|
+
}, [page, totalPages, setPage]);
|
|
108
|
+
|
|
109
|
+
const prevPage = useCallback(() => {
|
|
110
|
+
const newPage = Math.max(0, page - 1);
|
|
111
|
+
setPage(newPage);
|
|
112
|
+
}, [page, setPage]);
|
|
113
|
+
|
|
114
|
+
const canNextPage = page < totalPages - 1;
|
|
115
|
+
const canPrevPage = page > 0;
|
|
116
|
+
|
|
117
|
+
const startIndex = page * pageSize;
|
|
118
|
+
const endIndex = Math.min(startIndex + pageSize, totalItems);
|
|
119
|
+
|
|
120
|
+
// For select component
|
|
121
|
+
const pageSizeSelectValue = pageSizeMode === "auto" ? "auto" : String(pageSize);
|
|
122
|
+
|
|
123
|
+
const onPageSizeSelect = useCallback(
|
|
124
|
+
(value: string) => {
|
|
125
|
+
if (value === "auto") {
|
|
126
|
+
setPageSizeMode("auto");
|
|
127
|
+
} else {
|
|
128
|
+
setPageSizeMode("manual");
|
|
129
|
+
setPageSize(parseInt(value, 10));
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
[setPageSize]
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
page,
|
|
137
|
+
pageSize,
|
|
138
|
+
setPage,
|
|
139
|
+
setPageSize,
|
|
140
|
+
nextPage,
|
|
141
|
+
prevPage,
|
|
142
|
+
canNextPage,
|
|
143
|
+
canPrevPage,
|
|
144
|
+
totalPages,
|
|
145
|
+
startIndex,
|
|
146
|
+
endIndex,
|
|
147
|
+
pageSizeMode,
|
|
148
|
+
setPageSizeMode,
|
|
149
|
+
pageSizeSelectValue,
|
|
150
|
+
onPageSizeSelect,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
import type { BaseDataItem, SelectionReturn } from "../types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook for managing multi-select state in tables
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* const selection = useSelection<MyItem>();
|
|
10
|
+
*
|
|
11
|
+
* // Toggle single item
|
|
12
|
+
* selection.toggle(item.id);
|
|
13
|
+
*
|
|
14
|
+
* // Check if selected
|
|
15
|
+
* const isSelected = selection.isSelected(item.id);
|
|
16
|
+
*
|
|
17
|
+
* // Toggle all
|
|
18
|
+
* selection.toggleAll(items);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function useSelection<T extends BaseDataItem>(): SelectionReturn<T> {
|
|
22
|
+
const [selectedIds, setSelectedIds] = useState<string[]>([]);
|
|
23
|
+
|
|
24
|
+
const isSelected = useCallback(
|
|
25
|
+
(id: string) => selectedIds.includes(id),
|
|
26
|
+
[selectedIds]
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const toggle = useCallback((id: string) => {
|
|
30
|
+
setSelectedIds((prev) =>
|
|
31
|
+
prev.includes(id) ? prev.filter((p) => p !== id) : [...prev, id]
|
|
32
|
+
);
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
const selectAll = useCallback((items: T[]) => {
|
|
36
|
+
setSelectedIds(items.map((item) => item.id));
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
const clearAll = useCallback(() => {
|
|
40
|
+
setSelectedIds([]);
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const toggleAll = useCallback(
|
|
44
|
+
(items: T[]) => {
|
|
45
|
+
if (selectedIds.length === items.length) {
|
|
46
|
+
setSelectedIds([]);
|
|
47
|
+
} else {
|
|
48
|
+
setSelectedIds(items.map((item) => item.id));
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
[selectedIds.length]
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const getSelected = useCallback(
|
|
55
|
+
(items: T[]) => items.filter((item) => selectedIds.includes(item.id)),
|
|
56
|
+
[selectedIds]
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const allSelected = useCallback(
|
|
60
|
+
(items: T[]) => items.length > 0 && selectedIds.length === items.length,
|
|
61
|
+
[selectedIds.length]
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const someSelected = useCallback(
|
|
65
|
+
(items: T[]) =>
|
|
66
|
+
selectedIds.length > 0 && selectedIds.length < items.length,
|
|
67
|
+
[selectedIds.length]
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
selectedIds,
|
|
72
|
+
isSelected,
|
|
73
|
+
toggle,
|
|
74
|
+
selectAll,
|
|
75
|
+
clearAll,
|
|
76
|
+
toggleAll,
|
|
77
|
+
getSelected,
|
|
78
|
+
allSelected,
|
|
79
|
+
someSelected,
|
|
80
|
+
};
|
|
81
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
// @tidecloak/ui-framework
|
|
2
|
+
|
|
3
|
+
// Theme (colors, spacing, CSS variables)
|
|
4
|
+
export {
|
|
5
|
+
colors,
|
|
6
|
+
spacing,
|
|
7
|
+
radius,
|
|
8
|
+
fontSize,
|
|
9
|
+
zIndex,
|
|
10
|
+
duration,
|
|
11
|
+
focusRing,
|
|
12
|
+
shadow,
|
|
13
|
+
themeCSS,
|
|
14
|
+
injectThemeCSS,
|
|
15
|
+
} from "./theme";
|
|
16
|
+
|
|
17
|
+
// Re-export react-query so users don't need to install it separately
|
|
18
|
+
export {
|
|
19
|
+
QueryClient,
|
|
20
|
+
QueryClientProvider,
|
|
21
|
+
useQuery,
|
|
22
|
+
useMutation,
|
|
23
|
+
useQueryClient,
|
|
24
|
+
type QueryClientConfig,
|
|
25
|
+
} from "@tanstack/react-query";
|
|
26
|
+
|
|
27
|
+
// Types
|
|
28
|
+
export * from "./types";
|
|
29
|
+
|
|
30
|
+
// Utils
|
|
31
|
+
export {
|
|
32
|
+
cn,
|
|
33
|
+
base64ToBytes,
|
|
34
|
+
bytesToBase64,
|
|
35
|
+
formatTimestamp,
|
|
36
|
+
formatLogTimestamp,
|
|
37
|
+
computeRowsForViewportHeight,
|
|
38
|
+
delay,
|
|
39
|
+
safeJsonParse,
|
|
40
|
+
truncate,
|
|
41
|
+
isDefined,
|
|
42
|
+
generateId,
|
|
43
|
+
} from "./utils";
|
|
44
|
+
|
|
45
|
+
// Hooks
|
|
46
|
+
export {
|
|
47
|
+
useAutoRefresh,
|
|
48
|
+
useSelection,
|
|
49
|
+
usePagination,
|
|
50
|
+
type PageSizeMode,
|
|
51
|
+
type UsePaginationOptions,
|
|
52
|
+
} from "./hooks";
|
|
53
|
+
|
|
54
|
+
// Common Components
|
|
55
|
+
export {
|
|
56
|
+
RefreshButton,
|
|
57
|
+
StatusBadge,
|
|
58
|
+
STATUS_COLORS,
|
|
59
|
+
STATUS_ICONS,
|
|
60
|
+
getStatusConfig,
|
|
61
|
+
ActionButton,
|
|
62
|
+
ActionButtonGroup,
|
|
63
|
+
ACTION_COLORS,
|
|
64
|
+
ACTION_ICONS,
|
|
65
|
+
EmptyState,
|
|
66
|
+
EmptyStateNoData,
|
|
67
|
+
EmptyStateNoResults,
|
|
68
|
+
EmptyStateNoFiles,
|
|
69
|
+
Skeleton,
|
|
70
|
+
LoadingSkeleton,
|
|
71
|
+
TableRowSkeleton,
|
|
72
|
+
type RefreshButtonProps,
|
|
73
|
+
type StatusBadgeProps,
|
|
74
|
+
type ActionButtonProps,
|
|
75
|
+
type ActionButtonGroupProps,
|
|
76
|
+
type ActionType,
|
|
77
|
+
type EmptyStateProps,
|
|
78
|
+
type SkeletonProps,
|
|
79
|
+
type LoadingSkeletonProps,
|
|
80
|
+
} from "./components/common";
|
|
81
|
+
|
|
82
|
+
// Data Table Components
|
|
83
|
+
export {
|
|
84
|
+
DataTable,
|
|
85
|
+
PaginatedTable,
|
|
86
|
+
type DataTableProps,
|
|
87
|
+
type PaginatedTableProps,
|
|
88
|
+
} from "./components/data-table";
|
|
89
|
+
|
|
90
|
+
// Tabs Components
|
|
91
|
+
export {
|
|
92
|
+
TabsView,
|
|
93
|
+
type TabsViewProps,
|
|
94
|
+
} from "./components/tabs";
|
|
95
|
+
|
|
96
|
+
// Dialog Components
|
|
97
|
+
export {
|
|
98
|
+
DetailDialog,
|
|
99
|
+
ConfirmDialog,
|
|
100
|
+
CollapsibleSection,
|
|
101
|
+
CodePreview,
|
|
102
|
+
type DetailDialogProps,
|
|
103
|
+
type ConfirmDialogProps,
|
|
104
|
+
type CollapsibleSectionProps,
|
|
105
|
+
} from "./components/dialogs";
|
|
106
|
+
|
|
107
|
+
// Page Components - Base (headless)
|
|
108
|
+
export {
|
|
109
|
+
// Approvals
|
|
110
|
+
ApprovalsPageBase,
|
|
111
|
+
type ApprovalsPageBaseProps,
|
|
112
|
+
type ApprovalTabConfig,
|
|
113
|
+
type BaseApprovalItem,
|
|
114
|
+
type AccessApprovalItem,
|
|
115
|
+
type RoleApprovalItem,
|
|
116
|
+
type PolicyApprovalItem,
|
|
117
|
+
type ApprovalDecision,
|
|
118
|
+
createUserColumn,
|
|
119
|
+
createRoleColumn,
|
|
120
|
+
createTimestampColumn,
|
|
121
|
+
createStatusColumn,
|
|
122
|
+
createProgressColumn,
|
|
123
|
+
// Logs
|
|
124
|
+
LogsPageBase,
|
|
125
|
+
type LogsPageBaseProps,
|
|
126
|
+
type LogsTabConfig,
|
|
127
|
+
type BaseLogItem,
|
|
128
|
+
type AccessLogItem,
|
|
129
|
+
type PolicyLogItem,
|
|
130
|
+
createLogTimestampColumn,
|
|
131
|
+
createActionColumn,
|
|
132
|
+
createLogProgressColumn,
|
|
133
|
+
// Templates
|
|
134
|
+
TemplatesPageBase,
|
|
135
|
+
type TemplatesPageBaseProps,
|
|
136
|
+
type PolicyTemplateItem,
|
|
137
|
+
type TemplateParameter,
|
|
138
|
+
type TemplateFormData,
|
|
139
|
+
// Users
|
|
140
|
+
UsersPageBase,
|
|
141
|
+
type UsersPageBaseProps,
|
|
142
|
+
type UserItem,
|
|
143
|
+
type UserRoleItem,
|
|
144
|
+
type UserFormData,
|
|
145
|
+
type CreateUserFormData,
|
|
146
|
+
// Roles
|
|
147
|
+
RolesPageBase,
|
|
148
|
+
type RolesPageBaseProps,
|
|
149
|
+
type RoleItem,
|
|
150
|
+
type PolicyConfig,
|
|
151
|
+
type RolePolicyTemplateItem,
|
|
152
|
+
type RoleTemplateParameter,
|
|
153
|
+
} from "./components/pages";
|
|
154
|
+
|
|
155
|
+
// Page Components - Pre-made (uses @tidecloak/react)
|
|
156
|
+
export {
|
|
157
|
+
RolesPage,
|
|
158
|
+
UsersPage,
|
|
159
|
+
TemplatesPage,
|
|
160
|
+
LogsPage,
|
|
161
|
+
ApprovalsPage,
|
|
162
|
+
// Template API helpers
|
|
163
|
+
createLocalStorageTemplateAPI,
|
|
164
|
+
// Policy API helpers
|
|
165
|
+
createLocalStoragePolicyAPI,
|
|
166
|
+
// Policy Approvals API helpers
|
|
167
|
+
createLocalStoragePolicyApprovalsAPI,
|
|
168
|
+
// Access Metadata API helpers
|
|
169
|
+
createLocalStorageAccessMetadataAPI,
|
|
170
|
+
// Policy Logs API helpers
|
|
171
|
+
createLocalStoragePolicyLogsAPI,
|
|
172
|
+
type RolesPageProps,
|
|
173
|
+
type UsersPageProps,
|
|
174
|
+
type ChangeSetInfo,
|
|
175
|
+
type TemplatesPageProps,
|
|
176
|
+
type TemplateAPI,
|
|
177
|
+
type PolicyAPI,
|
|
178
|
+
type RolePolicy,
|
|
179
|
+
type LogsPageProps,
|
|
180
|
+
type PolicyLogsAPI,
|
|
181
|
+
type PolicyLogData,
|
|
182
|
+
type ApprovalsPageProps,
|
|
183
|
+
type PolicyApprovalsAPI,
|
|
184
|
+
type PolicyApprovalData,
|
|
185
|
+
type AccessMetadataAPI,
|
|
186
|
+
type AccessMetadataRecord,
|
|
187
|
+
type TideApprovalContext,
|
|
188
|
+
type TideApprovalResult,
|
|
189
|
+
type EnclaveApprovalTabConfig,
|
|
190
|
+
} from "./components/pages/connected";
|
|
191
|
+
|
|
192
|
+
// Tide Policy Workflow Helpers
|
|
193
|
+
export {
|
|
194
|
+
loadTideLibs,
|
|
195
|
+
areTideLibsAvailable,
|
|
196
|
+
computeContractId,
|
|
197
|
+
createTidePolicyRequest,
|
|
198
|
+
createTidePolicyHandler,
|
|
199
|
+
rolePolicyToTideConfig,
|
|
200
|
+
DEFAULT_MODEL_IDS,
|
|
201
|
+
DEFAULT_ROLE_CONTRACT,
|
|
202
|
+
type TidePolicyConfig,
|
|
203
|
+
type TideContextMethods,
|
|
204
|
+
} from "./tide";
|
|
205
|
+
|
|
206
|
+
// Default UI Components (works out of the box with inline styles)
|
|
207
|
+
export {
|
|
208
|
+
defaultComponents,
|
|
209
|
+
Card,
|
|
210
|
+
CardContent,
|
|
211
|
+
CardHeader,
|
|
212
|
+
CardTitle,
|
|
213
|
+
CardDescription,
|
|
214
|
+
Button,
|
|
215
|
+
Badge,
|
|
216
|
+
Input,
|
|
217
|
+
Label,
|
|
218
|
+
Textarea,
|
|
219
|
+
Checkbox,
|
|
220
|
+
Select,
|
|
221
|
+
SelectTrigger,
|
|
222
|
+
SelectValue,
|
|
223
|
+
SelectContent,
|
|
224
|
+
SelectItem,
|
|
225
|
+
Skeleton as UIComponentSkeleton,
|
|
226
|
+
Switch,
|
|
227
|
+
ScrollArea,
|
|
228
|
+
Alert,
|
|
229
|
+
AlertDescription,
|
|
230
|
+
CodeEditor,
|
|
231
|
+
Table,
|
|
232
|
+
TableHeader,
|
|
233
|
+
TableBody,
|
|
234
|
+
TableRow,
|
|
235
|
+
TableHead,
|
|
236
|
+
TableCell,
|
|
237
|
+
Dialog,
|
|
238
|
+
DialogContent,
|
|
239
|
+
DialogHeader,
|
|
240
|
+
DialogTitle,
|
|
241
|
+
DialogDescription,
|
|
242
|
+
DialogFooter,
|
|
243
|
+
AlertDialog,
|
|
244
|
+
AlertDialogContent,
|
|
245
|
+
AlertDialogHeader,
|
|
246
|
+
AlertDialogTitle,
|
|
247
|
+
AlertDialogDescription,
|
|
248
|
+
AlertDialogFooter,
|
|
249
|
+
AlertDialogCancel,
|
|
250
|
+
AlertDialogAction,
|
|
251
|
+
Separator,
|
|
252
|
+
Tabs,
|
|
253
|
+
TabsList,
|
|
254
|
+
TabsTrigger,
|
|
255
|
+
TabsContent,
|
|
256
|
+
} from "./components/ui";
|