@rebasepro/plugin-insights 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/src/collections/default-collections.d.ts +9 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/util/permissions.d.ts +1 -0
- package/dist/core/src/components/LoginView/LoginView.d.ts +25 -1
- package/dist/core/src/components/common/types.d.ts +10 -7
- package/dist/core/src/components/common/useDebouncedData.d.ts +1 -1
- package/dist/core/src/core/RebaseProps.d.ts +13 -2
- package/dist/core/src/core/RebaseRouter.d.ts +1 -1
- package/dist/core/src/hooks/data/useCollectionFetch.d.ts +12 -1
- package/dist/core/src/hooks/index.d.ts +0 -1
- package/dist/core/src/util/entity_cache.d.ts +0 -5
- package/dist/core/src/util/index.d.ts +0 -2
- package/dist/core/src/util/useStorageUploadController.d.ts +2 -2
- package/dist/formex/src/utils.d.ts +2 -2
- package/dist/index.es.js +216 -164
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +216 -164
- package/dist/index.umd.js.map +1 -1
- package/dist/plugin-insights/src/components/InsightWidget.d.ts +2 -2
- package/dist/plugin-insights/src/components/InsightWidgetSkeleton.d.ts +3 -1
- package/dist/plugin-insights/src/components/InsightsScorecardView.d.ts +3 -1
- package/dist/types/src/controllers/auth.d.ts +4 -26
- package/dist/types/src/controllers/client.d.ts +25 -43
- package/dist/types/src/controllers/collection_registry.d.ts +1 -1
- package/dist/types/src/controllers/data.d.ts +4 -0
- package/dist/types/src/controllers/data_driver.d.ts +23 -0
- package/dist/types/src/controllers/registry.d.ts +5 -4
- package/dist/types/src/rebase_context.d.ts +1 -1
- package/dist/types/src/types/auth_adapter.d.ts +5 -60
- package/dist/types/src/types/backend.d.ts +2 -2
- package/dist/types/src/types/backend_hooks.d.ts +2 -17
- package/dist/types/src/types/collections.d.ts +0 -4
- package/dist/types/src/types/component_ref.d.ts +1 -1
- package/dist/types/src/types/cron.d.ts +1 -1
- package/dist/types/src/types/entity_views.d.ts +1 -0
- package/dist/types/src/types/export_import.d.ts +1 -1
- package/dist/types/src/types/formex.d.ts +2 -2
- package/dist/types/src/types/properties.d.ts +9 -7
- package/dist/types/src/types/translations.d.ts +28 -12
- package/dist/types/src/types/user_management_delegate.d.ts +22 -57
- package/dist/types/src/users/index.d.ts +0 -1
- package/dist/types/src/users/user.d.ts +0 -1
- package/dist/ui/src/components/Button.d.ts +2 -2
- package/dist/ui/src/components/ErrorBoundary.d.ts +25 -3
- package/dist/ui/src/components/VirtualTable/VirtualTable.d.ts +1 -1
- package/dist/ui/src/components/VirtualTable/VirtualTableCell.d.ts +6 -6
- package/dist/ui/src/components/VirtualTable/VirtualTableHeader.d.ts +8 -8
- package/dist/ui/src/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +11 -11
- package/dist/ui/src/components/VirtualTable/VirtualTableRow.d.ts +1 -1
- package/dist/ui/src/components/VirtualTable/types.d.ts +9 -9
- package/dist/ui/src/hooks/useDebounceCallback.d.ts +1 -1
- package/dist/ui/src/util/debounce.d.ts +1 -1
- package/package.json +4 -3
- package/src/components/InsightWidget.tsx +33 -4
- package/src/components/InsightWidgetSkeleton.tsx +7 -1
- package/src/components/InsightsScorecardView.tsx +4 -1
- package/src/engine/InsightsCache.test.ts +56 -0
- package/src/engine/useInsightsData.ts +1 -0
- package/dist/core/src/hooks/useValidateAuthenticator.d.ts +0 -21
- package/dist/core/src/util/icon_synonyms.d.ts +0 -1
- package/dist/core/src/util/useTraceUpdate.d.ts +0 -2
- package/dist/types/src/users/roles.d.ts +0 -22
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { FilterFormFieldProps } from "./VirtualTableHeader";
|
|
3
|
-
export type OnRowClickParams<T extends Record<string,
|
|
3
|
+
export type OnRowClickParams<T extends Record<string, unknown>> = {
|
|
4
4
|
rowData: T;
|
|
5
5
|
rowIndex: number;
|
|
6
6
|
event: React.SyntheticEvent;
|
|
@@ -9,7 +9,7 @@ export type OnRowClickParams<T extends Record<string, any>> = {
|
|
|
9
9
|
* @see Table
|
|
10
10
|
* @group Components
|
|
11
11
|
*/
|
|
12
|
-
export interface VirtualTableProps<T extends Record<string,
|
|
12
|
+
export interface VirtualTableProps<T extends Record<string, unknown>> {
|
|
13
13
|
/**
|
|
14
14
|
* Array of arbitrary data
|
|
15
15
|
*/
|
|
@@ -61,12 +61,12 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
61
61
|
/**
|
|
62
62
|
* In case this table should have some filters set by default
|
|
63
63
|
*/
|
|
64
|
-
filter?: VirtualTableFilterValues<
|
|
64
|
+
filter?: VirtualTableFilterValues<string>;
|
|
65
65
|
/**
|
|
66
66
|
* Callback used when filters are updated
|
|
67
67
|
* @param filter
|
|
68
68
|
*/
|
|
69
|
-
onFilterUpdate?: (filter?: VirtualTableFilterValues<
|
|
69
|
+
onFilterUpdate?: (filter?: VirtualTableFilterValues<string> | undefined) => void;
|
|
70
70
|
/**
|
|
71
71
|
* Callback when the table is scrolled
|
|
72
72
|
* @param props
|
|
@@ -111,7 +111,7 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
111
111
|
* Callback to create a filter field, displayed in the header as a dropdown
|
|
112
112
|
* @param props
|
|
113
113
|
*/
|
|
114
|
-
createFilterField?: (props: FilterFormFieldProps<
|
|
114
|
+
createFilterField?: (props: FilterFormFieldProps<unknown>) => React.ReactNode;
|
|
115
115
|
/**
|
|
116
116
|
* Class name applied to the table
|
|
117
117
|
*/
|
|
@@ -141,9 +141,9 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
141
141
|
/**
|
|
142
142
|
* Extra data passed to the cell renderer
|
|
143
143
|
*/
|
|
144
|
-
extraData?:
|
|
144
|
+
extraData?: unknown;
|
|
145
145
|
}
|
|
146
|
-
export type CellRendererParams<T =
|
|
146
|
+
export type CellRendererParams<T = unknown> = {
|
|
147
147
|
column: VirtualTableColumn;
|
|
148
148
|
columns: VirtualTableColumn[];
|
|
149
149
|
columnIndex: number;
|
|
@@ -153,17 +153,17 @@ export type CellRendererParams<T = any> = {
|
|
|
153
153
|
isScrolling?: boolean;
|
|
154
154
|
sortableNodeRef?: (node: HTMLElement | null) => void;
|
|
155
155
|
sortableStyle?: React.CSSProperties;
|
|
156
|
-
sortableAttributes?: Record<string,
|
|
156
|
+
sortableAttributes?: Record<string, unknown>;
|
|
157
157
|
isDragging?: boolean;
|
|
158
158
|
isDraggable?: boolean;
|
|
159
159
|
frozen?: boolean;
|
|
160
|
-
extraData?:
|
|
160
|
+
extraData?: unknown;
|
|
161
161
|
};
|
|
162
162
|
/**
|
|
163
163
|
* @see Table
|
|
164
164
|
* @group Components
|
|
165
165
|
*/
|
|
166
|
-
export interface VirtualTableColumn<CustomProps =
|
|
166
|
+
export interface VirtualTableColumn<CustomProps = unknown> {
|
|
167
167
|
/**
|
|
168
168
|
* Data key for the cell value, could be "a.b.c"
|
|
169
169
|
*/
|
|
@@ -233,7 +233,7 @@ export type VirtualTableSort = "asc" | "desc" | undefined;
|
|
|
233
233
|
* @see Table
|
|
234
234
|
* @group Components
|
|
235
235
|
*/
|
|
236
|
-
export type VirtualTableFilterValues<Key extends string> = Partial<Record<Key, [VirtualTableWhereFilterOp,
|
|
236
|
+
export type VirtualTableFilterValues<Key extends string> = Partial<Record<Key, [VirtualTableWhereFilterOp, unknown]>>;
|
|
237
237
|
/**
|
|
238
238
|
* Filter conditions in a `Query.where()` clause are specified using the
|
|
239
239
|
* strings `<`, `<=`, `==`, `>=`, `>`, `array-contains`, `in`, and `array-contains-any`.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { VirtualTableRowProps } from "./types";
|
|
3
|
-
export declare const VirtualTableRow: React.NamedExoticComponent<VirtualTableRowProps<
|
|
3
|
+
export declare const VirtualTableRow: React.NamedExoticComponent<VirtualTableRowProps<Record<string, unknown>>>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { CellRendererParams, OnRowClickParams, OnVirtualTableColumnResizeParams, VirtualTableColumn, VirtualTableFilterValues, VirtualTableWhereFilterOp } from "./VirtualTableProps";
|
|
3
3
|
import { FilterFormFieldProps } from "./VirtualTableHeader";
|
|
4
|
-
export type VirtualTableRowProps<T
|
|
5
|
-
style:
|
|
4
|
+
export type VirtualTableRowProps<T extends Record<string, unknown>> = {
|
|
5
|
+
style: React.CSSProperties;
|
|
6
6
|
rowHeight: number;
|
|
7
7
|
rowData: T;
|
|
8
8
|
rowIndex: number;
|
|
9
|
-
onRowClick?: (props: OnRowClickParams<
|
|
9
|
+
onRowClick?: (props: OnRowClickParams<Record<string, unknown>>) => void;
|
|
10
10
|
children: React.ReactNode[];
|
|
11
11
|
columns: VirtualTableColumn[];
|
|
12
12
|
hoverRow?: boolean;
|
|
@@ -19,20 +19,20 @@ export type VirtualTableContextProps<T> = {
|
|
|
19
19
|
columns: VirtualTableColumn[];
|
|
20
20
|
cellRenderer: React.ComponentType<CellRendererParams<T>>;
|
|
21
21
|
currentSort: "asc" | "desc" | undefined;
|
|
22
|
-
filter?: VirtualTableFilterValues<
|
|
23
|
-
onRowClick?: (props: OnRowClickParams<
|
|
24
|
-
onColumnSort: (key: string) =>
|
|
22
|
+
filter?: VirtualTableFilterValues<string>;
|
|
23
|
+
onRowClick?: (props: OnRowClickParams<Record<string, unknown>>) => void;
|
|
24
|
+
onColumnSort: (key: string) => void;
|
|
25
25
|
onColumnResize: (params: OnVirtualTableColumnResizeParams) => void;
|
|
26
26
|
onColumnResizeEnd: (params: OnVirtualTableColumnResizeParams) => void;
|
|
27
|
-
onFilterUpdate: (column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp,
|
|
27
|
+
onFilterUpdate: (column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp, unknown]) => void;
|
|
28
28
|
sortByProperty?: string;
|
|
29
29
|
customView?: React.ReactNode;
|
|
30
30
|
hoverRow: boolean;
|
|
31
|
-
createFilterField?: (props: FilterFormFieldProps<
|
|
31
|
+
createFilterField?: (props: FilterFormFieldProps<unknown>) => React.ReactNode;
|
|
32
32
|
rowClassName?: (rowData: T) => string | undefined;
|
|
33
33
|
endAdornment?: React.ReactNode;
|
|
34
34
|
AddColumnComponent?: React.ComponentType;
|
|
35
35
|
onColumnsOrderChange?: (columns: VirtualTableColumn[]) => void;
|
|
36
36
|
draggingColumnId?: string | null;
|
|
37
|
-
extraData?:
|
|
37
|
+
extraData?: unknown;
|
|
38
38
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function useDebounceCallback<T extends (...args: any[]) =>
|
|
1
|
+
export declare function useDebounceCallback<T extends (...args: any[]) => unknown>(callback?: T, delay?: number): T;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @ignore
|
|
3
3
|
*/
|
|
4
|
-
export declare function debounce<T extends (...args: any[]) =>
|
|
4
|
+
export declare function debounce<T extends (...args: any[]) => unknown>(func: T, wait?: number): T & Cancelable;
|
|
5
5
|
/**
|
|
6
6
|
* @ignore
|
|
7
7
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/plugin-insights",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.5",
|
|
5
5
|
"main": "./dist/index.umd.js",
|
|
6
6
|
"module": "./dist/index.es.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
"./package.json": "./package.json"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@rebasepro/
|
|
20
|
-
"@rebasepro/
|
|
19
|
+
"@rebasepro/types": "0.2.5",
|
|
20
|
+
"@rebasepro/ui": "0.2.5",
|
|
21
|
+
"@rebasepro/core": "0.2.5"
|
|
21
22
|
},
|
|
22
23
|
"peerDependencies": {
|
|
23
24
|
"react": ">=19.0.0",
|
|
@@ -1,14 +1,36 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { InsightDefinition, DataRow } from "../types";
|
|
2
|
+
import type { InsightDefinition, DataRow, ScorecardConfig } from "../types";
|
|
3
3
|
import { useInsightsData } from "../engine/useInsightsData";
|
|
4
4
|
import { InsightsScorecardView } from "./InsightsScorecardView";
|
|
5
5
|
import { InsightWidgetSkeleton } from "./InsightWidgetSkeleton";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Compute a deterministic fixed height for a standard scorecard based
|
|
9
|
+
* on which optional elements the config declares. This eliminates
|
|
10
|
+
* layout shift between skeleton and loaded states.
|
|
11
|
+
*
|
|
12
|
+
* Breakdown (non-compact, non-small):
|
|
13
|
+
* py-4 padding: 16 + 16 = 32
|
|
14
|
+
* title row: 16.5 (text-xs leading-snug)
|
|
15
|
+
* mb-2 margin: 8
|
|
16
|
+
* value: 30 (text-2xl leading-tight)
|
|
17
|
+
* ---
|
|
18
|
+
* base: 86.5
|
|
19
|
+
* + dateRange: +16 (14px text + 2px mt-0.5)
|
|
20
|
+
* + comparison: +20 (16px text + 4px mt-1)
|
|
21
|
+
*/
|
|
22
|
+
function computeFixedHeight(config: ScorecardConfig): number {
|
|
23
|
+
let h = 86.5; // base: padding + title + mb-2 + value
|
|
24
|
+
if (config.dateRange) h += 16;
|
|
25
|
+
if (config.comparison) h += 20;
|
|
26
|
+
return Math.ceil(h);
|
|
27
|
+
}
|
|
28
|
+
|
|
7
29
|
/**
|
|
8
30
|
* Single insight widget orchestrator.
|
|
9
31
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
32
|
+
* Wraps skeleton and loaded states in a fixed-height container
|
|
33
|
+
* (computed from the scorecard config) to prevent layout shift.
|
|
12
34
|
*
|
|
13
35
|
* All theme-awareness is handled via Tailwind `dark:` classes.
|
|
14
36
|
*/
|
|
@@ -30,14 +52,19 @@ export function InsightWidget({
|
|
|
30
52
|
}) {
|
|
31
53
|
const { data, loading, error } = useInsightsData(definition, { path, collectionSlug, parentCollectionSlugs });
|
|
32
54
|
|
|
55
|
+
// For non-compact, non-embedded standard scorecards, use a fixed height
|
|
56
|
+
// derived from the config to prevent layout shift between skeleton → loaded.
|
|
57
|
+
const fixedHeight = (!compact && !embedded) ? computeFixedHeight(definition.scorecard) : undefined;
|
|
58
|
+
|
|
33
59
|
if (loading) {
|
|
34
|
-
return <InsightWidgetSkeleton config={definition.scorecard} compact={compact} embedded={embedded} />;
|
|
60
|
+
return <InsightWidgetSkeleton config={definition.scorecard} compact={compact} embedded={embedded} fixedHeight={fixedHeight} />;
|
|
35
61
|
}
|
|
36
62
|
|
|
37
63
|
if (error) {
|
|
38
64
|
return (
|
|
39
65
|
<div
|
|
40
66
|
className={`text-red-500/70 dark:text-red-400/70 text-[0.8125rem] ${embedded ? "px-5 py-4 h-full" : `rounded-lg bg-red-500/5 dark:bg-red-400/5 border border-red-500/10 dark:border-red-400/10 ${compact ? "px-3.5 py-3" : "px-5 py-4"}`}`}
|
|
67
|
+
style={fixedHeight ? { height: fixedHeight } : undefined}
|
|
41
68
|
>
|
|
42
69
|
<div className="font-semibold mb-1">{definition.title}</div>
|
|
43
70
|
<div>{error.message}</div>
|
|
@@ -49,6 +76,7 @@ export function InsightWidget({
|
|
|
49
76
|
return (
|
|
50
77
|
<div
|
|
51
78
|
className={`text-surface-400 dark:text-surface-500 text-[0.8125rem] ${embedded ? "px-5 py-4 h-full" : `rounded-lg bg-surface-100 dark:bg-surface-800 border border-surface-200 dark:border-surface-700 ${compact ? "px-3.5 py-3" : "px-5 py-4"}`}`}
|
|
79
|
+
style={fixedHeight ? { height: fixedHeight } : undefined}
|
|
52
80
|
>
|
|
53
81
|
{definition.title} — No data
|
|
54
82
|
</div>
|
|
@@ -62,6 +90,7 @@ export function InsightWidget({
|
|
|
62
90
|
title={definition.title}
|
|
63
91
|
compact={compact}
|
|
64
92
|
embedded={embedded}
|
|
93
|
+
fixedHeight={fixedHeight}
|
|
65
94
|
/>
|
|
66
95
|
);
|
|
67
96
|
}
|
|
@@ -21,12 +21,15 @@ export function InsightWidgetSkeleton({
|
|
|
21
21
|
config,
|
|
22
22
|
compact = false,
|
|
23
23
|
embedded = false,
|
|
24
|
+
fixedHeight,
|
|
24
25
|
}: {
|
|
25
26
|
/** Scorecard config — used to match optional elements (comparison, dateRange, icon). */
|
|
26
27
|
config: ScorecardConfig;
|
|
27
28
|
compact?: boolean;
|
|
28
29
|
/** When true, skip own border since the parent card provides it. */
|
|
29
30
|
embedded?: boolean;
|
|
31
|
+
/** Explicit height to prevent layout shift between skeleton → loaded. */
|
|
32
|
+
fixedHeight?: number;
|
|
30
33
|
}) {
|
|
31
34
|
const hasComparison = Boolean(config.comparison);
|
|
32
35
|
const hasIcon = Boolean(config.icon);
|
|
@@ -74,6 +77,7 @@ export function InsightWidgetSkeleton({
|
|
|
74
77
|
hasIcon={hasIcon}
|
|
75
78
|
hasDateRange={hasDateRange}
|
|
76
79
|
embedded={embedded}
|
|
80
|
+
fixedHeight={fixedHeight}
|
|
77
81
|
/>;
|
|
78
82
|
}
|
|
79
83
|
|
|
@@ -112,11 +116,13 @@ function StandardSkeleton({
|
|
|
112
116
|
hasIcon,
|
|
113
117
|
hasDateRange,
|
|
114
118
|
embedded,
|
|
119
|
+
fixedHeight,
|
|
115
120
|
}: {
|
|
116
121
|
hasComparison: boolean;
|
|
117
122
|
hasIcon: boolean;
|
|
118
123
|
hasDateRange: boolean;
|
|
119
124
|
embedded: boolean;
|
|
125
|
+
fixedHeight?: number;
|
|
120
126
|
}) {
|
|
121
127
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
122
128
|
const [containerWidth, setContainerWidth] = useState<number | null>(null);
|
|
@@ -158,7 +164,7 @@ function StandardSkeleton({
|
|
|
158
164
|
<div
|
|
159
165
|
ref={containerRef}
|
|
160
166
|
className={cls("animate-pulse", baseClass)}
|
|
161
|
-
style={embedded ? undefined : { minHeight: isSmall ? 68 : 92 }}
|
|
167
|
+
style={embedded ? undefined : fixedHeight ? { height: fixedHeight } : { minHeight: isSmall ? 68 : 92 }}
|
|
162
168
|
>
|
|
163
169
|
{/* Title row — identical flex structure to InsightsScorecardView */}
|
|
164
170
|
<div className={`flex items-center justify-between ${isSmall ? "mb-1" : "mb-2"}`}>
|
|
@@ -39,6 +39,7 @@ export function InsightsScorecardView({
|
|
|
39
39
|
title,
|
|
40
40
|
compact = false,
|
|
41
41
|
embedded = false,
|
|
42
|
+
fixedHeight,
|
|
42
43
|
}: {
|
|
43
44
|
config: ScorecardConfig;
|
|
44
45
|
data: DataRow;
|
|
@@ -46,6 +47,8 @@ export function InsightsScorecardView({
|
|
|
46
47
|
compact?: boolean;
|
|
47
48
|
/** When true, skip own border/bg since the parent card provides them. */
|
|
48
49
|
embedded?: boolean;
|
|
50
|
+
/** Explicit height to prevent layout shift between skeleton → loaded. */
|
|
51
|
+
fixedHeight?: number;
|
|
49
52
|
}) {
|
|
50
53
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
51
54
|
const [containerWidth, setContainerWidth] = useState<number | null>(null);
|
|
@@ -124,7 +127,7 @@ export function InsightsScorecardView({
|
|
|
124
127
|
: cls("rounded-lg flex flex-col min-w-0 bg-transparent border", defaultBorderMixin, isSmall ? "px-3.5 py-3" : "px-5 py-4");
|
|
125
128
|
|
|
126
129
|
return (
|
|
127
|
-
<div ref={containerRef} className={baseClass} style={embedded ? undefined : { minHeight: isSmall ? 68 : 92 }}>
|
|
130
|
+
<div ref={containerRef} className={baseClass} style={embedded ? undefined : fixedHeight ? { height: fixedHeight } : { minHeight: isSmall ? 68 : 92 }}>
|
|
128
131
|
{/* Title row */}
|
|
129
132
|
<div className={`flex items-center justify-between ${isSmall ? "mb-1" : "mb-2"}`}>
|
|
130
133
|
<div className="flex flex-col min-w-0">
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { InsightsCache } from "./InsightsCache";
|
|
2
|
+
import type { InsightDataResult } from "../types";
|
|
3
|
+
|
|
4
|
+
describe("InsightsCache", () => {
|
|
5
|
+
it("should set and get values from cache", () => {
|
|
6
|
+
const cache = new InsightsCache();
|
|
7
|
+
const data: InsightDataResult = {
|
|
8
|
+
data: [{ count: 10 }],
|
|
9
|
+
columns: ["count"]
|
|
10
|
+
};
|
|
11
|
+
cache.set("query_key", data);
|
|
12
|
+
expect(cache.get("query_key")).toEqual(data);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should return null for expired keys", () => {
|
|
16
|
+
const cache = new InsightsCache(-1); // -1ms TTL to force immediate expiry
|
|
17
|
+
const data: InsightDataResult = {
|
|
18
|
+
data: [{ count: 10 }],
|
|
19
|
+
columns: ["count"]
|
|
20
|
+
};
|
|
21
|
+
cache.set("query_key", data);
|
|
22
|
+
// Expired immediately
|
|
23
|
+
expect(cache.get("query_key")).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should manage inflight requests", () => {
|
|
27
|
+
const cache = new InsightsCache();
|
|
28
|
+
const promise = Promise.resolve({
|
|
29
|
+
data: [],
|
|
30
|
+
columns: []
|
|
31
|
+
});
|
|
32
|
+
expect(cache.getInflight("query_key")).toBeNull();
|
|
33
|
+
|
|
34
|
+
cache.setInflight("query_key", promise);
|
|
35
|
+
expect(cache.getInflight("query_key")).toBe(promise);
|
|
36
|
+
|
|
37
|
+
// Setting a result should remove the inflight reference
|
|
38
|
+
const data: InsightDataResult = { data: [], columns: [] };
|
|
39
|
+
cache.set("query_key", data);
|
|
40
|
+
expect(cache.getInflight("query_key")).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should invalidate entries", () => {
|
|
44
|
+
const cache = new InsightsCache();
|
|
45
|
+
const data: InsightDataResult = { data: [], columns: [] };
|
|
46
|
+
cache.set("key_1", data);
|
|
47
|
+
cache.set("key_2", data);
|
|
48
|
+
|
|
49
|
+
cache.invalidate("key_1");
|
|
50
|
+
expect(cache.get("key_1")).toBeNull();
|
|
51
|
+
expect(cache.get("key_2")).toEqual(data);
|
|
52
|
+
|
|
53
|
+
cache.invalidate();
|
|
54
|
+
expect(cache.get("key_2")).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { AuthController, Authenticator, RebaseData, StorageSource, User } from "@rebasepro/types";
|
|
2
|
-
/**
|
|
3
|
-
* This hook is used internally for validating an authenticator.
|
|
4
|
-
*
|
|
5
|
-
* @param authController
|
|
6
|
-
* @param authentication
|
|
7
|
-
* @param storageSource
|
|
8
|
-
* @param data
|
|
9
|
-
*/
|
|
10
|
-
export declare function useValidateAuthenticator<USER extends User = any>({ disabled, authController, authenticator, storageSource, data }: {
|
|
11
|
-
disabled?: boolean;
|
|
12
|
-
authController: AuthController<USER>;
|
|
13
|
-
authenticator?: boolean | Authenticator<USER>;
|
|
14
|
-
data: RebaseData;
|
|
15
|
-
storageSource: StorageSource;
|
|
16
|
-
}): {
|
|
17
|
-
canAccessMainView: boolean;
|
|
18
|
-
authLoading: boolean;
|
|
19
|
-
notAllowedError: any;
|
|
20
|
-
authVerified: boolean;
|
|
21
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const iconSynonyms: Record<string, string>;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export type Role = {
|
|
2
|
-
/**
|
|
3
|
-
* ID of the role
|
|
4
|
-
*/
|
|
5
|
-
id: string;
|
|
6
|
-
/**
|
|
7
|
-
* Name of the role
|
|
8
|
-
*/
|
|
9
|
-
name: string;
|
|
10
|
-
/**
|
|
11
|
-
* If this flag is true, the user can perform any action
|
|
12
|
-
*/
|
|
13
|
-
isAdmin?: boolean;
|
|
14
|
-
/**
|
|
15
|
-
* Permissions related to editing the collections
|
|
16
|
-
*/
|
|
17
|
-
config?: {
|
|
18
|
-
createCollections?: boolean;
|
|
19
|
-
editCollections?: boolean | "own";
|
|
20
|
-
deleteCollections?: boolean | "own";
|
|
21
|
-
};
|
|
22
|
-
};
|