@manta-eu/react 0.10.0 → 0.12.0
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/components/datastore-management/use-datastore-status.d.ts +15 -0
- package/dist/components/datastore-management/use-datastore-status.d.ts.map +1 -1
- package/dist/components/datastore-management/use-datastore-status.js +73 -2
- package/dist/components/datastore-management/use-datastore-status.js.map +1 -1
- package/dist/components/explain-fact/ExplainFact.d.ts +2 -0
- package/dist/components/explain-fact/ExplainFact.d.ts.map +1 -1
- package/dist/components/explain-fact/ExplainFact.js +6 -10
- package/dist/components/explain-fact/ExplainFact.js.map +1 -1
- package/dist/components/fact/Fact.d.ts +16 -0
- package/dist/components/fact/Fact.d.ts.map +1 -0
- package/dist/components/fact/Fact.js +27 -0
- package/dist/components/fact/Fact.js.map +1 -0
- package/dist/globals.css +15 -0
- package/dist/providers/KnowledgeGraphStateContext.d.ts +2 -2
- package/dist/providers/KnowledgeGraphStateContext.d.ts.map +1 -1
- package/dist/providers/KnowledgeGraphStateProvider.d.ts.map +1 -1
- package/dist/providers/KnowledgeGraphStateProvider.js +8 -49
- package/dist/providers/KnowledgeGraphStateProvider.js.map +1 -1
- package/dist/routes/datastores/components/LinkUnlinkedDatastoreDialog.d.ts.map +1 -1
- package/dist/routes/datastores/components/LinkUnlinkedDatastoreDialog.js +2 -0
- package/dist/routes/datastores/components/LinkUnlinkedDatastoreDialog.js.map +1 -1
- package/dist/routes/datastores/components/StatusBadge.d.ts +8 -6
- package/dist/routes/datastores/components/StatusBadge.d.ts.map +1 -1
- package/dist/routes/datastores/components/StatusBadge.js +59 -20
- package/dist/routes/datastores/components/StatusBadge.js.map +1 -1
- package/dist/routes/datastores/deletion-warning.d.ts +2 -0
- package/dist/routes/datastores/deletion-warning.d.ts.map +1 -0
- package/dist/routes/datastores/deletion-warning.js +8 -0
- package/dist/routes/datastores/deletion-warning.js.map +1 -0
- package/dist/routes/datastores/flatten.d.ts +8 -3
- package/dist/routes/datastores/flatten.d.ts.map +1 -1
- package/dist/routes/datastores/flatten.js +16 -11
- package/dist/routes/datastores/flatten.js.map +1 -1
- package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts +12 -2
- package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts.map +1 -1
- package/dist/routes/datastores/hooks/useDatastoreColumns.js +142 -95
- package/dist/routes/datastores/hooks/useDatastoreColumns.js.map +1 -1
- package/dist/routes/datastores/index.d.ts.map +1 -1
- package/dist/routes/datastores/index.js +48 -57
- package/dist/routes/datastores/index.js.map +1 -1
- package/package.json +12 -7
- package/src/app-subpaths.json +1 -0
- package/src/components/datastore-management/use-datastore-status.ts +137 -2
- package/src/components/explain-fact/ExplainFact.tsx +19 -17
- package/src/components/fact/Fact.tsx +103 -0
- package/src/providers/KnowledgeGraphStateContext.ts +2 -2
- package/src/providers/KnowledgeGraphStateProvider.tsx +13 -65
- package/src/routes/datastores/components/LinkUnlinkedDatastoreDialog.tsx +2 -0
- package/src/routes/datastores/components/StatusBadge.tsx +90 -27
- package/src/routes/datastores/deletion-warning.ts +7 -0
- package/src/routes/datastores/flatten.ts +27 -14
- package/src/routes/datastores/hooks/useDatastoreColumns.tsx +198 -117
- package/src/routes/datastores/index.tsx +67 -72
|
@@ -1,19 +1,43 @@
|
|
|
1
|
-
import { enableDatastoreRemoval } from "@manta-eu/client/shared/constants";
|
|
2
1
|
import { isPresent } from "@manta-eu/lib/present";
|
|
3
|
-
import { LoaderCircle } from "lucide-react";
|
|
2
|
+
import { Info, LoaderCircle } from "lucide-react";
|
|
4
3
|
import { Badge, type BadgeVariant } from "#components/badge/index";
|
|
5
4
|
import {
|
|
6
5
|
datastoreStatusCategory,
|
|
7
6
|
type DatastoreStatus,
|
|
8
7
|
type DatastoreStatusCategory,
|
|
9
8
|
} from "#components/datastore-management/tree";
|
|
9
|
+
import type { DatastoreDeletion } from "#components/datastore-management/use-datastore-status";
|
|
10
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "#components/tooltip/index";
|
|
10
11
|
|
|
11
|
-
export type DatastoreStatusFilterValue =
|
|
12
|
+
export type DatastoreStatusFilterValue =
|
|
13
|
+
| "noDatastore"
|
|
14
|
+
| "checking"
|
|
15
|
+
| "notBuilt"
|
|
16
|
+
| "deleting"
|
|
17
|
+
| "deletionRetrying"
|
|
18
|
+
| "deletionStopped"
|
|
19
|
+
| "deletionUnknown"
|
|
20
|
+
| DatastoreStatusCategory;
|
|
12
21
|
|
|
13
22
|
type StatusNode = { datastoreId?: string; removed: boolean; isUnlinked?: boolean; unbuilt?: boolean };
|
|
14
23
|
|
|
15
|
-
export
|
|
24
|
+
export type DatastoreStatusBadgeProps = {
|
|
25
|
+
node: StatusNode;
|
|
26
|
+
status?: DatastoreStatus;
|
|
27
|
+
deletion?: DatastoreDeletion;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function datastoreStatusFilterValue({
|
|
31
|
+
node,
|
|
32
|
+
status,
|
|
33
|
+
deletion,
|
|
34
|
+
}: DatastoreStatusBadgeProps): DatastoreStatusFilterValue {
|
|
16
35
|
if (!isPresent(node.datastoreId)) return "noDatastore";
|
|
36
|
+
if (deletion) {
|
|
37
|
+
if (deletion.unreadable === true) return "deletionUnknown";
|
|
38
|
+
if (isPresent(deletion.error)) return "deletionStopped";
|
|
39
|
+
return deletion.retrying ? "deletionRetrying" : "deleting";
|
|
40
|
+
}
|
|
17
41
|
if (node.unbuilt === true && status?.exists !== true) return "notBuilt";
|
|
18
42
|
return datastoreStatusCategory(node, status) ?? "checking";
|
|
19
43
|
}
|
|
@@ -22,35 +46,54 @@ type BadgeConfig = { label: string; variant: BadgeVariant; title?: string; spinn
|
|
|
22
46
|
|
|
23
47
|
// The only place these strings live: the badge and the filter dropdown both read from here.
|
|
24
48
|
const badgeConfigByFilterValue: Record<DatastoreStatusFilterValue, BadgeConfig> = {
|
|
25
|
-
ready: { label: "Ready", variant: "success" },
|
|
49
|
+
ready: { label: "Ready", variant: "success", title: "Built and ready to use." },
|
|
26
50
|
materializing: {
|
|
27
51
|
label: "Materializing",
|
|
28
52
|
variant: "warning",
|
|
29
53
|
spinning: true,
|
|
30
|
-
title: "
|
|
54
|
+
title: "Building its knowledge graph. This can take a few minutes.",
|
|
31
55
|
},
|
|
32
56
|
notRegistered: {
|
|
33
57
|
label: "Not registered",
|
|
34
58
|
variant: "destructive",
|
|
35
|
-
title: "
|
|
59
|
+
title: "It was never registered, so it can't be built. Use Register to fix it.",
|
|
36
60
|
},
|
|
37
61
|
notBuilt: {
|
|
38
62
|
label: "Not built",
|
|
39
63
|
variant: "warning",
|
|
40
64
|
title: "Registered in Infisical, but no datastore exists for it. Link it to build it, or delete it.",
|
|
41
65
|
},
|
|
42
|
-
offline: {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
66
|
+
offline: {
|
|
67
|
+
label: "Offline",
|
|
68
|
+
variant: "destructive",
|
|
69
|
+
title: "Its data is kept, but it isn't running. Bring it online to use it again.",
|
|
70
|
+
},
|
|
71
|
+
unavailable: {
|
|
72
|
+
label: "Status unavailable",
|
|
73
|
+
variant: "copy",
|
|
74
|
+
title: "Its status couldn't be read just now. It's checked again automatically.",
|
|
75
|
+
},
|
|
76
|
+
checking: { label: "Checking…", variant: "copy", spinning: true, title: "Reading its status." },
|
|
77
|
+
removed: {
|
|
78
|
+
label: "Removed",
|
|
79
|
+
variant: "warning",
|
|
80
|
+
title:
|
|
81
|
+
"Out of use: a permanent delete stopped partway, or it was removed before removal was turned off. " +
|
|
82
|
+
"Delete it permanently only if it should go for good.",
|
|
83
|
+
},
|
|
84
|
+
deleting: {
|
|
85
|
+
label: "Deleting…",
|
|
86
|
+
variant: "warning",
|
|
87
|
+
spinning: true,
|
|
88
|
+
title: "Deleting in the background. This can take a few minutes.",
|
|
89
|
+
},
|
|
90
|
+
deletionRetrying: { label: "Retrying deletion", variant: "warning" },
|
|
91
|
+
deletionStopped: { label: "Deletion stopped", variant: "destructive" },
|
|
92
|
+
deletionUnknown: {
|
|
93
|
+
label: "Deletion unknown",
|
|
94
|
+
variant: "copy",
|
|
95
|
+
title: "Couldn't check how far its deletion got. If this lasts, delete it again to restart it.",
|
|
96
|
+
},
|
|
54
97
|
noDatastore: { label: "No datastore", variant: "copy" },
|
|
55
98
|
};
|
|
56
99
|
|
|
@@ -62,6 +105,10 @@ const filterOptionOrder: DatastoreStatusFilterValue[] = [
|
|
|
62
105
|
"offline",
|
|
63
106
|
"unavailable",
|
|
64
107
|
"removed",
|
|
108
|
+
"deleting",
|
|
109
|
+
"deletionRetrying",
|
|
110
|
+
"deletionStopped",
|
|
111
|
+
"deletionUnknown",
|
|
65
112
|
];
|
|
66
113
|
|
|
67
114
|
export const datastoreStatusFilterOptions: { id: "ALL" | DatastoreStatusFilterValue; label: string }[] = [
|
|
@@ -69,22 +116,38 @@ export const datastoreStatusFilterOptions: { id: "ALL" | DatastoreStatusFilterVa
|
|
|
69
116
|
...filterOptionOrder.map((id) => ({ id, label: badgeConfigByFilterValue[id].label })),
|
|
70
117
|
];
|
|
71
118
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
};
|
|
119
|
+
function retryingExplanation(failure: string | null | undefined): string {
|
|
120
|
+
return `${failure ?? "Part of its deletion failed."} It's retried automatically - select Retry now to try again right away.`;
|
|
121
|
+
}
|
|
76
122
|
|
|
77
123
|
export function DatastoreStatusBadge(props: DatastoreStatusBadgeProps) {
|
|
78
|
-
const { node,
|
|
124
|
+
const { node, deletion } = props;
|
|
79
125
|
|
|
80
126
|
if (!isPresent(node.datastoreId)) return <span className="typography-tiny text-muted-foreground">—</span>;
|
|
81
127
|
|
|
82
|
-
const config = badgeConfigByFilterValue[datastoreStatusFilterValue(
|
|
128
|
+
const config = badgeConfigByFilterValue[datastoreStatusFilterValue(props)];
|
|
129
|
+
const stoppedReason = deletion?.error;
|
|
130
|
+
const retrying = !isPresent(stoppedReason) && deletion?.retrying === true;
|
|
131
|
+
const explanation = stoppedReason ?? (retrying ? retryingExplanation(deletion?.failure) : config.title);
|
|
83
132
|
|
|
84
|
-
|
|
85
|
-
<Badge
|
|
133
|
+
const badge = (
|
|
134
|
+
<Badge
|
|
135
|
+
size="sm"
|
|
136
|
+
variant={config.variant}
|
|
137
|
+
className="cursor-default"
|
|
138
|
+
tabIndex={isPresent(explanation) ? 0 : undefined}
|
|
139
|
+
>
|
|
86
140
|
{config.spinning && <LoaderCircle className="size-3 animate-spin" />}
|
|
87
141
|
{config.label}
|
|
142
|
+
{(isPresent(stoppedReason) || retrying) && <Info className="size-3" aria-hidden />}
|
|
88
143
|
</Badge>
|
|
89
144
|
);
|
|
145
|
+
if (!isPresent(explanation)) return badge;
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<Tooltip>
|
|
149
|
+
<TooltipTrigger asChild>{badge}</TooltipTrigger>
|
|
150
|
+
<TooltipContent className="max-w-80">{explanation}</TooltipContent>
|
|
151
|
+
</Tooltip>
|
|
152
|
+
);
|
|
90
153
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { isPresent } from "@manta-eu/lib/present";
|
|
2
|
+
import { toast } from "sonner";
|
|
3
|
+
|
|
4
|
+
export function toastDeletionWarning(deletionWarning: string | null | undefined) {
|
|
5
|
+
if (!isPresent(deletionWarning)) return;
|
|
6
|
+
toast.warning("It was taken back from its deletion", { description: deletionWarning });
|
|
7
|
+
}
|
|
@@ -63,8 +63,21 @@ export type DatastoreRowVisibility = {
|
|
|
63
63
|
showUnprovisioned: boolean;
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
export type DatastoreRowFilter = {
|
|
67
|
+
rows: DatastoreRow[];
|
|
68
|
+
visibility: DatastoreRowVisibility;
|
|
69
|
+
deleting: ReadonlySet<string>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function matchesVisibility(
|
|
73
|
+
row: DatastoreRow,
|
|
74
|
+
{ visibility, deleting }: Pick<DatastoreRowFilter, "visibility" | "deleting">,
|
|
75
|
+
): boolean {
|
|
76
|
+
const beingDeleted = isPresent(row.datastoreId) && deleting.has(row.datastoreId);
|
|
77
|
+
return (
|
|
78
|
+
(visibility.showArchived || !row.removed || beingDeleted) &&
|
|
79
|
+
(visibility.showUnprovisioned || isPresent(row.datastoreId))
|
|
80
|
+
);
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
function hasVisibleDescendant(rows: DatastoreRow[], shown: boolean[], index: number): boolean {
|
|
@@ -75,8 +88,9 @@ function hasVisibleDescendant(rows: DatastoreRow[], shown: boolean[], index: num
|
|
|
75
88
|
return false;
|
|
76
89
|
}
|
|
77
90
|
|
|
78
|
-
export function visibleDatastoreRows(
|
|
79
|
-
const
|
|
91
|
+
export function visibleDatastoreRows(filter: DatastoreRowFilter): DatastoreRow[] {
|
|
92
|
+
const { rows } = filter;
|
|
93
|
+
const shown = rows.map((row) => matchesVisibility(row, filter));
|
|
80
94
|
return rows.filter((_row, index) => shown[index] || hasVisibleDescendant(rows, shown, index));
|
|
81
95
|
}
|
|
82
96
|
|
|
@@ -96,23 +110,21 @@ export function nestedDatastoreNamesByRowId(rows: DatastoreRow[]): Map<string, s
|
|
|
96
110
|
}
|
|
97
111
|
|
|
98
112
|
export function hiddenRowCount(
|
|
99
|
-
|
|
100
|
-
visibility: DatastoreRowVisibility,
|
|
113
|
+
filter: DatastoreRowFilter,
|
|
101
114
|
key: keyof DatastoreRowVisibility,
|
|
102
115
|
shownCount: number,
|
|
103
116
|
): number {
|
|
104
|
-
if (visibility[key]) return 0;
|
|
117
|
+
if (filter.visibility[key]) return 0;
|
|
105
118
|
|
|
106
|
-
return visibleDatastoreRows(
|
|
119
|
+
return visibleDatastoreRows({ ...filter, visibility: { ...filter.visibility, [key]: true } }).length - shownCount;
|
|
107
120
|
}
|
|
108
121
|
|
|
109
|
-
export function hiddenRemovedRowCount(
|
|
110
|
-
if (visibility.showArchived) return 0;
|
|
122
|
+
export function hiddenRemovedRowCount(filter: DatastoreRowFilter): number {
|
|
123
|
+
if (filter.visibility.showArchived) return 0;
|
|
111
124
|
|
|
112
|
-
const shown = new Set(visibleDatastoreRows(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
).length;
|
|
125
|
+
const shown = new Set(visibleDatastoreRows(filter));
|
|
126
|
+
const revealed = { ...filter, visibility: { ...filter.visibility, showArchived: true } };
|
|
127
|
+
return filter.rows.filter((row) => row.removed && !shown.has(row) && matchesVisibility(row, revealed)).length;
|
|
116
128
|
}
|
|
117
129
|
|
|
118
130
|
// Matches Keycloak's own org lookup (ensureOrganization), which is case-insensitive and trims too.
|
|
@@ -162,6 +174,7 @@ export function visibilityForStatusFilter(
|
|
|
162
174
|
return match(status)
|
|
163
175
|
.with("removed", () => ({ ...visibility, showArchived: true }))
|
|
164
176
|
.with("noDatastore", () => ({ ...visibility, showUnprovisioned: true }))
|
|
177
|
+
.with("deleting", "deletionRetrying", "deletionStopped", "deletionUnknown", () => visibility)
|
|
165
178
|
.with(
|
|
166
179
|
"ALL",
|
|
167
180
|
"ready",
|