@manta-eu/react 0.1.4 → 0.1.6
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 +4 -8
- package/dist/components/audience-phase-badge/index.d.ts +1 -1
- package/dist/components/audience-phase-badge/index.d.ts.map +1 -1
- package/dist/components/audience-phase-badge/index.js +3 -0
- package/dist/components/authenticated-chat/index.d.ts.map +1 -1
- package/dist/components/authenticated-chat/index.js +0 -5
- package/dist/components/chat/chat-input/index.d.ts +1 -1
- package/dist/components/chat/chat-input/index.d.ts.map +1 -1
- package/dist/components/chat/chat-input/index.js +4 -5
- package/dist/components/chat-view/Chat.d.ts +6 -0
- package/dist/components/chat-view/Chat.d.ts.map +1 -1
- package/dist/components/chat-view/Chat.js +18 -8
- package/dist/components/chat-view/ChatHeaders.d.ts.map +1 -1
- package/dist/components/chat-view/ChatHeaders.js +3 -2
- package/dist/components/embedded-chat/EmbeddedDatastorePicker.d.ts +1 -0
- package/dist/components/embedded-chat/EmbeddedDatastorePicker.d.ts.map +1 -1
- package/dist/components/embedded-chat/EmbeddedDatastorePicker.js +9 -3
- package/dist/components/embedded-chat/index.d.ts.map +1 -1
- package/dist/components/embedded-chat/index.js +1 -8
- package/dist/components/layouts/Sidebar.d.ts.map +1 -1
- package/dist/components/layouts/Sidebar.js +25 -5
- package/dist/components/planning/ActioningView.d.ts.map +1 -1
- package/dist/components/planning/ActioningView.js +11 -6
- package/dist/components/planning/ExecutionSectionItem.d.ts +2 -3
- package/dist/components/planning/ExecutionSectionItem.d.ts.map +1 -1
- package/dist/components/planning/ExecutionSectionItem.js +3 -6
- package/dist/components/planning/ExecutionSections.d.ts +2 -3
- package/dist/components/planning/ExecutionSections.d.ts.map +1 -1
- package/dist/components/planning/ExecutionSections.js +2 -2
- package/dist/components/planning/ManualActionCard.d.ts +3 -4
- package/dist/components/planning/ManualActionCard.d.ts.map +1 -1
- package/dist/components/planning/ManualActionCard.js +24 -6
- package/dist/components/rdf-insights/CampaignChannelMix.js +1 -1
- package/dist/components/rdf-insights/CampaignGrid.d.ts.map +1 -1
- package/dist/components/rdf-insights/CampaignGrid.js +2 -2
- package/dist/components/rdf-insights/DailyPerformance.js +2 -2
- package/dist/components/rdf-insights/KpiDashboard.d.ts +2 -2
- package/dist/components/rdf-insights/KpiDashboard.d.ts.map +1 -1
- package/dist/components/rdf-insights/KpiDashboard.js +33 -53
- package/dist/components/rdf-insights/MetaDailyInsights.js +2 -2
- package/dist/components/rdf-insights/ProductCard.d.ts.map +1 -1
- package/dist/components/rdf-insights/ProductCard.js +1 -1
- package/dist/components/rdf-insights/ProductVariantsTable.js +1 -1
- package/dist/components/rdf-insights/useExtractedInsights.d.ts +1 -1
- package/dist/components/rdf-insights/useExtractedInsights.js +3 -3
- package/dist/components/sidebar/nav-menu.d.ts +2 -0
- package/dist/components/sidebar/nav-menu.d.ts.map +1 -1
- package/dist/components/sidebar/nav-menu.js +11 -6
- package/dist/components/table/index.d.ts +26 -0
- package/dist/components/table/index.d.ts.map +1 -1
- package/dist/components/table/index.js +31 -1
- package/dist/datastore-picker/datastore-picker-rows.d.ts +1 -0
- package/dist/datastore-picker/datastore-picker-rows.d.ts.map +1 -1
- package/dist/datastore-picker/datastore-picker-rows.js +6 -2
- package/dist/explain-fact/DatalogCode.d.ts.map +1 -1
- package/dist/explain-fact/DatalogCode.js +7 -2
- package/dist/explain-fact/FactValue.js +3 -3
- package/dist/explain-fact/proof-tree/ProofTreeFormulaFooter.d.ts.map +1 -1
- package/dist/explain-fact/proof-tree/ProofTreeFormulaFooter.js +2 -1
- package/dist/globals.css +10 -102
- package/dist/graph/createNodeRouter.d.ts.map +1 -1
- package/dist/graph/createNodeRouter.js +3 -0
- package/dist/graph/nodes/BrandFacetRuleView.d.ts.map +1 -1
- package/dist/graph/nodes/BrandFacetRuleView.js +6 -4
- package/dist/graph/nodes/BrandFontFamilyView.d.ts +3 -0
- package/dist/graph/nodes/BrandFontFamilyView.d.ts.map +1 -0
- package/dist/graph/nodes/BrandFontFamilyView.js +56 -0
- package/dist/graph/nodes/BrandFontUploadButton.d.ts +6 -0
- package/dist/graph/nodes/BrandFontUploadButton.d.ts.map +1 -0
- package/dist/graph/nodes/BrandFontUploadButton.js +65 -0
- package/dist/graph/nodes/BrandGuidelinesView.d.ts.map +1 -1
- package/dist/graph/nodes/BrandGuidelinesView.js +2 -6
- package/dist/graph/nodes/GoogleCampaignView.js +2 -2
- package/dist/graph/nodes/brand-font.d.ts +12 -0
- package/dist/graph/nodes/brand-font.d.ts.map +1 -0
- package/dist/graph/nodes/brand-font.js +12 -0
- package/dist/graph/nodes/brand-shared.d.ts +3 -2
- package/dist/graph/nodes/brand-shared.d.ts.map +1 -1
- package/dist/graph/nodes/brand-shared.js +3 -2
- package/dist/hooks/use-action-plans-list.js +1 -1
- package/dist/hooks/use-connection-problems.d.ts +15 -0
- package/dist/hooks/use-connection-problems.d.ts.map +1 -0
- package/dist/hooks/use-connection-problems.js +9 -0
- package/dist/hooks/use-font-face.d.ts +3 -0
- package/dist/hooks/use-font-face.d.ts.map +1 -0
- package/dist/hooks/use-font-face.js +33 -0
- package/dist/hooks/use-graph-refresh-after-turn.d.ts +2 -0
- package/dist/hooks/use-graph-refresh-after-turn.d.ts.map +1 -0
- package/dist/hooks/use-graph-refresh-after-turn.js +12 -0
- package/dist/hooks/use-manual-actions.d.ts +11 -1
- package/dist/hooks/use-manual-actions.d.ts.map +1 -1
- package/dist/hooks/use-manual-actions.js +47 -100
- package/dist/hooks/useAuth.d.ts +6 -1
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +36 -9
- package/dist/hooks/useValidateActionPlan.d.ts.map +1 -1
- package/dist/ldo-ui.d.ts +1 -1
- package/dist/ldo-ui.d.ts.map +1 -1
- package/dist/lib/activity-changeset.d.ts.map +1 -1
- package/dist/lib/activity-changeset.js +6 -3
- package/dist/lib/datastore-route-table.d.ts +1 -0
- package/dist/lib/datastore-route-table.d.ts.map +1 -1
- package/dist/lib/datastore-route-table.js +2 -0
- package/dist/lib/manual-actions.js +1 -1
- package/dist/lib/rdf/index.d.ts +4 -2
- package/dist/lib/rdf/index.d.ts.map +1 -1
- package/dist/lib/rdf/index.js +48 -18
- package/dist/lib/rdf/insights.d.ts +6 -1
- package/dist/lib/rdf/insights.d.ts.map +1 -1
- package/dist/lib/rdf/insights.js +15 -3
- package/dist/lib/rdf/types.d.ts +21 -8
- package/dist/lib/rdf/types.d.ts.map +1 -1
- package/dist/lib/tool-icons.d.ts.map +1 -1
- package/dist/lib/tool-icons.js +1 -5
- package/dist/providers/ActiveChatProvider.d.ts.map +1 -1
- package/dist/providers/ActiveChatProvider.js +2 -0
- package/dist/providers/AuthContext.d.ts +1 -1
- package/dist/providers/AuthContext.d.ts.map +1 -1
- package/dist/providers/KnowledgeGraphStateContext.d.ts +0 -1
- package/dist/providers/KnowledgeGraphStateContext.d.ts.map +1 -1
- package/dist/providers/KnowledgeGraphStateProvider.d.ts.map +1 -1
- package/dist/providers/KnowledgeGraphStateProvider.js +8 -19
- package/dist/providers/index.d.ts +4 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +2 -1
- package/dist/routes/activity/change-display.js +1 -1
- package/dist/routes/data-explorer/components/record-detail/ActionFormDialog.d.ts.map +1 -1
- package/dist/routes/data-explorer/components/record-detail/ActionFormDialog.js +23 -9
- package/dist/routes/data-explorer/components/record-detail/action-properties.d.ts +2 -4
- package/dist/routes/data-explorer/components/record-detail/action-properties.d.ts.map +1 -1
- package/dist/routes/data-explorer/components/record-detail/action-properties.js +8 -50
- package/dist/routes/datastores/components/DatastoreFormDialog.d.ts +4 -2
- package/dist/routes/datastores/components/DatastoreFormDialog.d.ts.map +1 -1
- package/dist/routes/datastores/components/DatastoreFormDialog.js +7 -4
- package/dist/routes/datastores/components/DatastoresToolbar.d.ts +3 -1
- package/dist/routes/datastores/components/DatastoresToolbar.d.ts.map +1 -1
- package/dist/routes/datastores/components/DatastoresToolbar.js +18 -5
- package/dist/routes/datastores/components/LinkUnlinkedDatastoreDialog.d.ts.map +1 -1
- package/dist/routes/datastores/components/LinkUnlinkedDatastoreDialog.js +6 -2
- package/dist/routes/datastores/components/ProvisionDatastoreDialog.d.ts +7 -0
- package/dist/routes/datastores/components/ProvisionDatastoreDialog.d.ts.map +1 -0
- package/dist/routes/datastores/components/ProvisionDatastoreDialog.js +10 -0
- package/dist/routes/datastores/flatten.d.ts +4 -0
- package/dist/routes/datastores/flatten.d.ts.map +1 -1
- package/dist/routes/datastores/flatten.js +11 -0
- package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts +4 -1
- package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts.map +1 -1
- package/dist/routes/datastores/hooks/useDatastoreColumns.js +6 -2
- package/dist/routes/datastores/hooks/useTenantOrganizationCheck.d.ts +3 -0
- package/dist/routes/datastores/hooks/useTenantOrganizationCheck.d.ts.map +1 -0
- package/dist/routes/datastores/hooks/useTenantOrganizationCheck.js +21 -0
- package/dist/routes/datastores/index.d.ts.map +1 -1
- package/dist/routes/datastores/index.js +44 -6
- package/dist/routes/datastores/link-provider.d.ts +11 -0
- package/dist/routes/datastores/link-provider.d.ts.map +1 -0
- package/dist/routes/datastores/link-provider.js +34 -0
- package/dist/routes/integrations/components/connect-forms/types.d.ts +1 -0
- package/dist/routes/integrations/components/connect-forms/types.d.ts.map +1 -1
- package/dist/routes/integrations/connection-view.d.ts +4 -1
- package/dist/routes/integrations/connection-view.d.ts.map +1 -1
- package/dist/routes/integrations/connection-view.js +39 -6
- package/dist/routes/integrations/types.d.ts +3 -0
- package/dist/routes/integrations/types.d.ts.map +1 -1
- package/dist/routes/memories/components/ChangeScopeDialog.d.ts +1 -1
- package/dist/routes/memories/components/ChangeScopeDialog.d.ts.map +1 -1
- package/dist/routes/memories/components/ChangeScopeDialog.js +3 -3
- package/dist/routes/memories/components/EmptyStates.d.ts +1 -2
- package/dist/routes/memories/components/EmptyStates.d.ts.map +1 -1
- package/dist/routes/memories/components/EmptyStates.js +2 -2
- package/dist/routes/memories/components/MemoriesPanel.d.ts +1 -1
- package/dist/routes/memories/components/MemoriesPanel.d.ts.map +1 -1
- package/dist/routes/memories/components/MemoriesPanel.js +9 -9
- package/dist/routes/memories/components/MemoryActions.d.ts +1 -1
- package/dist/routes/memories/components/MemoryActions.d.ts.map +1 -1
- package/dist/routes/memories/components/MemoryActions.js +4 -4
- package/dist/routes/memories/components/MemoryFields.d.ts +1 -1
- package/dist/routes/memories/components/MemoryFields.d.ts.map +1 -1
- package/dist/routes/memories/components/MemoryFields.js +2 -2
- package/dist/routes/memories/components/MemoryFormDialog.d.ts +1 -1
- package/dist/routes/memories/components/MemoryFormDialog.d.ts.map +1 -1
- package/dist/routes/memories/components/MemoryFormDialog.js +2 -2
- package/dist/routes/memories/components/TeamPicker.d.ts +1 -1
- package/dist/routes/memories/components/TeamPicker.d.ts.map +1 -1
- package/dist/routes/memories/components/TeamPicker.js +2 -2
- package/dist/routes/memories/hooks/useMemoryColumns.d.ts +1 -1
- package/dist/routes/memories/hooks/useMemoryColumns.d.ts.map +1 -1
- package/dist/routes/memories/hooks/useMemoryColumns.js +3 -3
- package/dist/routes/memories/index.d.ts.map +1 -1
- package/dist/routes/memories/index.js +21 -21
- package/dist/shacl/shacl-form-types.d.ts +2 -3
- package/dist/shacl/shacl-form-types.d.ts.map +1 -1
- package/dist/shared/graph-derived-queries.d.ts +5 -0
- package/dist/shared/graph-derived-queries.d.ts.map +1 -0
- package/dist/shared/graph-derived-queries.js +28 -0
- package/package.json +8 -10
- package/dist/components/ai-elements/chain-of-thought.d.ts +0 -30
- package/dist/components/ai-elements/chain-of-thought.d.ts.map +0 -1
- package/dist/components/ai-elements/chain-of-thought.js +0 -57
- package/dist/components/context-menu.d.ts +0 -29
- package/dist/components/context-menu.d.ts.map +0 -1
- package/dist/components/context-menu.js +0 -67
- package/dist/components/hover-card.d.ts +0 -6
- package/dist/components/hover-card.d.ts.map +0 -1
- package/dist/components/hover-card.js +0 -15
- package/dist/components/layouts/ChatHistoryItem.d.ts +0 -9
- package/dist/components/layouts/ChatHistoryItem.d.ts.map +0 -1
- package/dist/components/layouts/ChatHistoryItem.js +0 -7
- package/dist/components/layouts/SectionHeader.d.ts +0 -8
- package/dist/components/layouts/SectionHeader.d.ts.map +0 -1
- package/dist/components/layouts/SectionHeader.js +0 -6
- package/dist/components/orbit-site/Block.d.ts +0 -8
- package/dist/components/orbit-site/Block.d.ts.map +0 -1
- package/dist/components/orbit-site/Block.js +0 -7
- package/dist/components/orbit-site/Inset.d.ts +0 -7
- package/dist/components/orbit-site/Inset.d.ts.map +0 -1
- package/dist/components/orbit-site/Inset.js +0 -6
- package/dist/components/orbit-site/Section.d.ts +0 -7
- package/dist/components/orbit-site/Section.d.ts.map +0 -1
- package/dist/components/orbit-site/Section.js +0 -6
- package/dist/components/orbit-site/ThemeSelector.d.ts +0 -3
- package/dist/components/orbit-site/ThemeSelector.d.ts.map +0 -1
- package/dist/components/orbit-site/ThemeSelector.js +0 -42
- package/dist/components/planning/SampleChanges.d.ts +0 -9
- package/dist/components/planning/SampleChanges.d.ts.map +0 -1
- package/dist/components/planning/SampleChanges.js +0 -117
- package/dist/components/tool-invocation-card/index.d.ts +0 -8
- package/dist/components/tool-invocation-card/index.d.ts.map +0 -1
- package/dist/components/tool-invocation-card/index.js +0 -7
- package/dist/lib/schema-fields.d.ts +0 -2
- package/dist/lib/schema-fields.d.ts.map +0 -1
- package/dist/lib/schema-fields.js +0 -3
- package/dist/routes/memories/components/ConflictTimeoutFooter.d.ts +0 -7
- package/dist/routes/memories/components/ConflictTimeoutFooter.d.ts.map +0 -1
- package/dist/routes/memories/components/ConflictTimeoutFooter.js +0 -6
|
@@ -28,6 +28,7 @@ export function ActionFormDialog(props) {
|
|
|
28
28
|
const baselineRef = useRef(null);
|
|
29
29
|
const [refusal, setRefusal] = useState(null);
|
|
30
30
|
const [formElement, setFormElement] = useState(null);
|
|
31
|
+
const [isReadingForm, setIsReadingForm] = useState(false);
|
|
31
32
|
const attachForm = useCallback((element) => setFormElement(element), []);
|
|
32
33
|
const { data, isLoading, error } = useShaclShapesQuery(mantaClient, { shapeIri: actionShape }, { enabled: open });
|
|
33
34
|
const hasShapesError = isPresent(error);
|
|
@@ -38,25 +39,38 @@ export function ActionFormDialog(props) {
|
|
|
38
39
|
useEffect(() => {
|
|
39
40
|
if (!formElement || !isUpdate)
|
|
40
41
|
return;
|
|
42
|
+
let cancelled = false;
|
|
41
43
|
// Baseline is the form's own serialization: its editors normalize literals, the triples do not.
|
|
42
|
-
function captureBaseline() {
|
|
44
|
+
async function captureBaseline() {
|
|
43
45
|
const store = formElement?.toRDF();
|
|
44
|
-
const baseline = store ? baselineFromStore(store, subjectIri) : null;
|
|
45
|
-
if (baseline)
|
|
46
|
+
const baseline = store ? await baselineFromStore(store, subjectIri) : null;
|
|
47
|
+
if (baseline && !cancelled)
|
|
46
48
|
baselineRef.current = baseline;
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
function onReady() {
|
|
51
|
+
void captureBaseline();
|
|
52
|
+
}
|
|
53
|
+
onReady();
|
|
54
|
+
formElement.addEventListener("ready", onReady);
|
|
55
|
+
return () => {
|
|
56
|
+
cancelled = true;
|
|
57
|
+
formElement.removeEventListener("ready", onReady);
|
|
58
|
+
};
|
|
51
59
|
}, [formElement, isUpdate, subjectIri]);
|
|
52
|
-
function submit() {
|
|
60
|
+
async function submit() {
|
|
53
61
|
const store = formElement?.toRDF();
|
|
54
62
|
const baseline = baselineRef.current;
|
|
55
63
|
if (!store || (isUpdate && !baseline)) {
|
|
56
64
|
setRefusal("The form is not ready yet.");
|
|
57
65
|
return;
|
|
58
66
|
}
|
|
59
|
-
|
|
67
|
+
setIsReadingForm(true);
|
|
68
|
+
const edited = await propertiesFromStore(store, subjectIri).catch(() => null);
|
|
69
|
+
setIsReadingForm(false);
|
|
70
|
+
if (!edited) {
|
|
71
|
+
setRefusal("The form could not be read.");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
60
74
|
if (isUpdate && baseline) {
|
|
61
75
|
const cleared = removedPredicates(baseline, edited);
|
|
62
76
|
if (isPresent(cleared)) {
|
|
@@ -72,5 +86,5 @@ export function ActionFormDialog(props) {
|
|
|
72
86
|
setRefusal(null);
|
|
73
87
|
onSubmit(properties);
|
|
74
88
|
}
|
|
75
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "flex max-h-[85vh] flex-col overflow-hidden", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { text: copy.title }), _jsxs(DialogDescription, { children: [copy.description, " Shape ", _jsx("code", { className: "font-mono", children: compactUri(actionShape) }), "."] })] }), _jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [isLoading && _jsx(LoadingRows, { rows: 4 }), hasShapesError && _jsx(StatusText, { children: "Failed to load the form for this shape." }), !isLoading && !hasShapesError && !shapesTurtle && _jsx(StatusText, { children: "This shape defines no fields." }), shapesTurtle && (_jsx(ShaclForm, { shapes: shapesTurtle, shapeSubject: actionShape, values: valuesTurtle, valuesSubject: subjectIri, collapse: "open", formRef: attachForm }))] }), refusal && (_jsx(StatusText, { className: "text-error-foreground", role: "alert", children: refusal })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "tertiary", size: "sm", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { size: "sm", onClick: submit, isLoading: isPending, disabled: !shapesTurtle, children: copy.submitLabel })] })] }) }));
|
|
89
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "flex max-h-[85vh] flex-col overflow-hidden", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { text: copy.title }), _jsxs(DialogDescription, { children: [copy.description, " Shape ", _jsx("code", { className: "font-mono", children: compactUri(actionShape) }), "."] })] }), _jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [isLoading && _jsx(LoadingRows, { rows: 4 }), hasShapesError && _jsx(StatusText, { children: "Failed to load the form for this shape." }), !isLoading && !hasShapesError && !shapesTurtle && _jsx(StatusText, { children: "This shape defines no fields." }), shapesTurtle && (_jsx(ShaclForm, { shapes: shapesTurtle, shapeSubject: actionShape, values: valuesTurtle, valuesSubject: subjectIri, collapse: "open", formRef: attachForm }))] }), refusal && (_jsx(StatusText, { className: "text-error-foreground", role: "alert", children: refusal })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "tertiary", size: "sm", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { size: "sm", onClick: () => void submit(), isLoading: isPending || isReadingForm, disabled: !shapesTurtle, children: copy.submitLabel })] })] }) }));
|
|
76
90
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { ShaclFormStore } from "@ulb-darmstadt/shacl-form";
|
|
2
2
|
export type PropertyMap = Record<string, unknown>;
|
|
3
|
-
export declare function propertiesFromStore(store: ShaclFormStore, subjectIri: string): PropertyMap
|
|
4
|
-
export declare function baselineFromStore(store: ShaclFormStore, subjectIri: string): PropertyMap | null
|
|
5
|
-
/** Only what changed: the backend merges the rest, and a predicate the form dropped cannot express a retraction. */
|
|
3
|
+
export declare function propertiesFromStore(store: ShaclFormStore, subjectIri: string): Promise<PropertyMap>;
|
|
4
|
+
export declare function baselineFromStore(store: ShaclFormStore, subjectIri: string): Promise<PropertyMap | null>;
|
|
6
5
|
export declare function changedProperties(current: PropertyMap, next: PropertyMap): PropertyMap;
|
|
7
|
-
/** The predicates the edit cleared: a patch cannot retract, so the caller must refuse rather than claim success. */
|
|
8
6
|
export declare function removedPredicates(current: PropertyMap, next: PropertyMap): string[];
|
|
9
7
|
//# sourceMappingURL=action-properties.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-properties.d.ts","sourceRoot":"","sources":["../../../../../src/routes/data-explorer/components/record-detail/action-properties.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"action-properties.d.ts","sourceRoot":"","sources":["../../../../../src/routes/data-explorer/components/record-detail/action-properties.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAKlD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAKzG;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAI9G;AASD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,WAAW,CAUtF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,CAEnF"}
|
|
@@ -1,54 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
/** The form stamps this on every serialization; it describes the shape, not the record. */
|
|
1
|
+
import { documentFromQuads } from "@manta-eu/client/shared/action-document";
|
|
2
|
+
import { namespaces } from "@manta-eu/client/shared/rdf-namespaces";
|
|
3
|
+
// The form stamps this on every serialization
|
|
5
4
|
const conformsTo = `${namespaces.dcterms}conformsTo`;
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return { "@value": value, "@type": datatype };
|
|
10
|
-
}
|
|
11
|
-
function addValue(properties, predicate, value) {
|
|
12
|
-
const existing = properties[predicate];
|
|
13
|
-
if (existing === undefined) {
|
|
14
|
-
properties[predicate] = value;
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
properties[predicate] = Array.isArray(existing) ? [...existing, value] : [existing, value];
|
|
18
|
-
}
|
|
19
|
-
// `seen` is path-scoped: a cycle still terminates, but two references to one blank node each get described.
|
|
20
|
-
function nodeDescription(store, subject, visited, includeType) {
|
|
21
|
-
const properties = {};
|
|
22
|
-
const seen = new Set(visited).add(subject);
|
|
23
|
-
for (const quad of store.getQuads(null, null, null, null)) {
|
|
24
|
-
if (quad.subject.value !== subject)
|
|
25
|
-
continue;
|
|
26
|
-
if (quad.predicate.value === conformsTo)
|
|
27
|
-
continue;
|
|
28
|
-
const isType = quad.predicate.value === wellKnownPredicates.type;
|
|
29
|
-
if (isType && !includeType)
|
|
30
|
-
continue;
|
|
31
|
-
let value;
|
|
32
|
-
if (quad.object.termType === "NamedNode") {
|
|
33
|
-
value = isType ? quad.object.value : { "@id": quad.object.value };
|
|
34
|
-
}
|
|
35
|
-
else if (quad.object.termType === "BlankNode") {
|
|
36
|
-
if (seen.has(quad.object.value))
|
|
37
|
-
continue;
|
|
38
|
-
value = nodeDescription(store, quad.object.value, seen, true);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
value = literalValue(quad.object.value, quad.object.datatype?.value);
|
|
42
|
-
}
|
|
43
|
-
addValue(properties, isType ? "@type" : quad.predicate.value, value);
|
|
44
|
-
}
|
|
5
|
+
export async function propertiesFromStore(store, subjectIri) {
|
|
6
|
+
const quads = [...store].filter((quad) => quad.predicate.value !== conformsTo);
|
|
7
|
+
const { "@id": _id, "@type": _type, ...properties } = await documentFromQuads(quads, subjectIri);
|
|
45
8
|
return properties;
|
|
46
9
|
}
|
|
47
|
-
export function
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
export function baselineFromStore(store, subjectIri) {
|
|
51
|
-
if (!isPresent(store.getQuads(null, null, null, null)))
|
|
10
|
+
export async function baselineFromStore(store, subjectIri) {
|
|
11
|
+
if (store.size === 0)
|
|
52
12
|
return null;
|
|
53
13
|
return propertiesFromStore(store, subjectIri);
|
|
54
14
|
}
|
|
@@ -56,7 +16,6 @@ function sameValue(left, right) {
|
|
|
56
16
|
const normalize = (value) => Array.isArray(value) ? JSON.stringify(value.map((entry) => JSON.stringify(entry)).sort()) : JSON.stringify(value);
|
|
57
17
|
return normalize(left) === normalize(right);
|
|
58
18
|
}
|
|
59
|
-
/** Only what changed: the backend merges the rest, and a predicate the form dropped cannot express a retraction. */
|
|
60
19
|
export function changedProperties(current, next) {
|
|
61
20
|
const changed = {};
|
|
62
21
|
for (const [predicate, value] of Object.entries(next)) {
|
|
@@ -66,7 +25,6 @@ export function changedProperties(current, next) {
|
|
|
66
25
|
}
|
|
67
26
|
return changed;
|
|
68
27
|
}
|
|
69
|
-
/** The predicates the edit cleared: a patch cannot retract, so the caller must refuse rather than claim success. */
|
|
70
28
|
export function removedPredicates(current, next) {
|
|
71
29
|
return Object.keys(current).filter((predicate) => !(predicate in next));
|
|
72
30
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TenantOrganizationCheck } from "../link-provider.js";
|
|
1
2
|
export type DatastoreFormTarget = {
|
|
2
3
|
kind: "organization";
|
|
3
4
|
} | {
|
|
@@ -6,15 +7,16 @@ export type DatastoreFormTarget = {
|
|
|
6
7
|
parentName: string;
|
|
7
8
|
organizationName: string;
|
|
8
9
|
};
|
|
9
|
-
type DatastoreFormDialogProps = {
|
|
10
|
+
export type DatastoreFormDialogProps = {
|
|
10
11
|
target: DatastoreFormTarget;
|
|
11
12
|
onSubmit: (values: {
|
|
12
13
|
name: string;
|
|
13
14
|
}) => void;
|
|
14
15
|
onCancel: () => void;
|
|
15
16
|
isSubmitting?: boolean;
|
|
17
|
+
onNameChange?: (name: string) => void;
|
|
18
|
+
nameCheck?: TenantOrganizationCheck;
|
|
16
19
|
};
|
|
17
20
|
export declare function provisioningNotice(target: DatastoreFormTarget): string;
|
|
18
21
|
export declare function DatastoreFormDialog(props: DatastoreFormDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
-
export {};
|
|
20
22
|
//# sourceMappingURL=DatastoreFormDialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatastoreFormDialog.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/components/DatastoreFormDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DatastoreFormDialog.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/components/DatastoreFormDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAahE,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEN,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAKtE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,2CAsElE"}
|
|
@@ -11,10 +11,10 @@ export function provisioningNotice(target) {
|
|
|
11
11
|
.exhaustive();
|
|
12
12
|
}
|
|
13
13
|
export function DatastoreFormDialog(props) {
|
|
14
|
-
const { target, onSubmit, onCancel, isSubmitting = false } = props;
|
|
14
|
+
const { target, onSubmit, onCancel, isSubmitting = false, onNameChange, nameCheck } = props;
|
|
15
15
|
const [name, setName] = useState("");
|
|
16
16
|
const isOrganization = target.kind === "organization";
|
|
17
|
-
const canSubmit = !!name.trim() && !isSubmitting;
|
|
17
|
+
const canSubmit = !!name.trim() && !isSubmitting && nameCheck?.blocked !== true;
|
|
18
18
|
function submit() {
|
|
19
19
|
if (!canSubmit)
|
|
20
20
|
return;
|
|
@@ -24,10 +24,13 @@ export function DatastoreFormDialog(props) {
|
|
|
24
24
|
.with({ kind: "organization" }, () => "Sets up a new top-level organization with its own datastore and a fresh Manta you can build on.")
|
|
25
25
|
.with({ kind: "datastore", parentPath: "/" }, (datastore) => `Adds a top-level datastore in ${datastore.organizationName}.`)
|
|
26
26
|
.with({ kind: "datastore" }, (datastore) => `Adds a datastore nested under ${datastore.parentName}, in ${datastore.organizationName}.`)
|
|
27
|
-
.exhaustive() })] }), _jsx(Input, { autoFocus: true, label: isOrganization ? "Organization name" : "Datastore name", placeholder: isOrganization ? "e.g. Other Reseller Co" : "e.g. Acme Corp", value: name, disabled: isSubmitting, onChange: (event) =>
|
|
27
|
+
.exhaustive() })] }), _jsx(Input, { autoFocus: true, label: isOrganization ? "Organization name" : "Datastore name", placeholder: isOrganization ? "e.g. Other Reseller Co" : "e.g. Acme Corp", value: name, disabled: isSubmitting, onChange: (event) => {
|
|
28
|
+
setName(event.target.value);
|
|
29
|
+
onNameChange?.(event.target.value);
|
|
30
|
+
}, onKeyDown: (event) => {
|
|
28
31
|
if (event.key === "Enter")
|
|
29
32
|
submit();
|
|
30
33
|
if (event.key === "Escape")
|
|
31
34
|
onCancel();
|
|
32
|
-
} }), _jsx("p", { role: "status", "aria-live": "polite", className: "typography-caption text-muted-foreground min-h-5", children: isSubmitting ? provisioningNotice(target) : "" }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "tertiary", onClick: onCancel, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { onClick: submit, disabled: !canSubmit, isLoading: isSubmitting, label: isOrganization ? "Add organization" : "Add datastore" })] })] }) }));
|
|
35
|
+
} }), _jsx("p", { role: "status", "aria-live": "polite", className: "typography-caption text-muted-foreground min-h-5", children: isSubmitting ? provisioningNotice(target) : (nameCheck?.hint ?? "") }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "tertiary", onClick: onCancel, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { onClick: submit, disabled: !canSubmit, isLoading: isSubmitting, label: isOrganization ? "Add organization" : "Add datastore" })] })] }) }));
|
|
33
36
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Table } from "@tanstack/react-table";
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
|
-
import type { DatastoreRow } from "../flatten.js";
|
|
3
|
+
import type { DatastoreRow, ProviderFilter } from "../flatten.js";
|
|
4
4
|
import type { StatusFilter } from "../hooks/useDatastoreTable.js";
|
|
5
5
|
type DatastoresToolbarProps = {
|
|
6
6
|
tabs?: ReactNode;
|
|
@@ -9,6 +9,8 @@ type DatastoresToolbarProps = {
|
|
|
9
9
|
searchPlaceholder?: string;
|
|
10
10
|
statusFilter: StatusFilter;
|
|
11
11
|
onStatusFilterChange: (status: StatusFilter) => void;
|
|
12
|
+
providerFilter?: ProviderFilter;
|
|
13
|
+
onProviderFilterChange?: (filter: ProviderFilter) => void;
|
|
12
14
|
table: Table<DatastoreRow>;
|
|
13
15
|
columnLabels?: Record<string, string>;
|
|
14
16
|
columnDefaultOrder?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatastoresToolbar.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/components/DatastoresToolbar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/
|
|
1
|
+
{"version":3,"file":"DatastoresToolbar.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/components/DatastoresToolbar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAc/D,KAAK,sBAAsB,GAAG;IAC5B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,oBAAoB,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACrD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAC1D,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,2CAuI9D"}
|
|
@@ -8,22 +8,35 @@ import { Dropdown, DropdownContent, DropdownGroup, DropdownItem, DropdownTrigger
|
|
|
8
8
|
import { FilterSection, FilterSheet } from "#components/filter-sheet/index";
|
|
9
9
|
import { Input } from "#components/input/index";
|
|
10
10
|
import { TableColumnRearrangePopover } from "#components/table/index";
|
|
11
|
+
const providerFilterOptions = [
|
|
12
|
+
{ id: "ALL", label: "All" },
|
|
13
|
+
{ id: "mirrored", label: "Linked to identity provider" },
|
|
14
|
+
{ id: "unmirrored", label: "Not linked to identity provider" },
|
|
15
|
+
];
|
|
11
16
|
export function DatastoresToolbar(props) {
|
|
12
|
-
const { tabs, searchQuery, onSearchQueryChange, searchPlaceholder = "Search by name or ID...", statusFilter, onStatusFilterChange, table, columnLabels = datastoreColumnLabels, columnDefaultOrder = defaultColumnOrder, } = props;
|
|
17
|
+
const { tabs, searchQuery, onSearchQueryChange, searchPlaceholder = "Search by name or ID...", statusFilter, onStatusFilterChange, providerFilter, onProviderFilterChange, table, columnLabels = datastoreColumnLabels, columnDefaultOrder = defaultColumnOrder, } = props;
|
|
13
18
|
const allStatusesSelected = statusFilter === "ALL";
|
|
14
19
|
const selectedStatusLabel = datastoreStatusFilterOptions.find((option) => option.id === statusFilter)?.label;
|
|
15
|
-
const
|
|
16
|
-
const
|
|
20
|
+
const providerFiltered = isPresent(providerFilter) && providerFilter !== "ALL";
|
|
21
|
+
const selectedProviderLabel = providerFilterOptions.find((option) => option.id === providerFilter)?.label;
|
|
22
|
+
const hasActiveFilters = isPresent(searchQuery) || !allStatusesSelected || providerFiltered;
|
|
23
|
+
const activeFilterCount = (isPresent(searchQuery) ? 1 : 0) + (allStatusesSelected ? 0 : 1) + (providerFiltered ? 1 : 0);
|
|
17
24
|
function handleClearFilters() {
|
|
18
25
|
onSearchQueryChange("");
|
|
19
26
|
onStatusFilterChange("ALL");
|
|
27
|
+
onProviderFilterChange?.("ALL");
|
|
20
28
|
}
|
|
21
29
|
function statusDropdown(className) {
|
|
22
30
|
return (_jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { asChild: true, children: _jsxs(Button, { variant: "tertiary", size: "base", rounded: "lg", className: className, children: [_jsx("span", { children: allStatusesSelected ? "Status" : selectedStatusLabel }), _jsx(ChevronDown, { className: "size-4" })] }) }), _jsx(DropdownContent, { align: "start", className: "w-48", children: _jsx(DropdownGroup, { label: "Filter by status", children: datastoreStatusFilterOptions.map((option) => (_jsx(DropdownItem, { selected: option.id === statusFilter, onClick: () => onStatusFilterChange(option.id), children: option.label }, option.id))) }) })] }));
|
|
23
31
|
}
|
|
32
|
+
function providerDropdown(className) {
|
|
33
|
+
if (!isPresent(providerFilter) || !onProviderFilterChange)
|
|
34
|
+
return null;
|
|
35
|
+
return (_jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { asChild: true, children: _jsxs(Button, { variant: "tertiary", size: "base", rounded: "lg", className: className, children: [_jsx("span", { children: providerFiltered ? selectedProviderLabel : "Identity provider" }), _jsx(ChevronDown, { className: "size-4" })] }) }), _jsx(DropdownContent, { align: "start", className: "w-64", children: _jsx(DropdownGroup, { label: "Filter by identity provider", children: providerFilterOptions.map((option) => (_jsx(DropdownItem, { selected: option.id === providerFilter, onClick: () => onProviderFilterChange(option.id), children: option.label }, option.id))) }) })] }));
|
|
36
|
+
}
|
|
24
37
|
function filterControls() {
|
|
25
|
-
return (_jsxs(_Fragment, { children: [statusDropdown(), hasActiveFilters && (_jsx(Button, { variant: "ghost", size: "base", rounded: "lg", onClick: handleClearFilters, icon: X, children: "Clear filters" }))] }));
|
|
38
|
+
return (_jsxs(_Fragment, { children: [statusDropdown(), providerDropdown(), hasActiveFilters && (_jsx(Button, { variant: "ghost", size: "base", rounded: "lg", onClick: handleClearFilters, icon: X, children: "Clear filters" }))] }));
|
|
26
39
|
}
|
|
27
|
-
const filterSheetContent = _jsx(FilterSection, { title: "Status", children: statusDropdown("w-full justify-between") });
|
|
40
|
+
const filterSheetContent = (_jsxs(_Fragment, { children: [_jsx(FilterSection, { title: "Status", children: statusDropdown("w-full justify-between") }), isPresent(providerFilter) && (_jsx(FilterSection, { title: "Identity provider", children: providerDropdown("w-full justify-between") }))] }));
|
|
28
41
|
return (_jsxs("div", { className: "flex min-w-0 flex-col gap-3 3xl:flex-row 3xl:items-center", children: [isPresent(tabs) && _jsx("div", { className: "min-w-0", children: tabs }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 flex-1 min-w-0", children: [_jsx(Input, { containerClassName: "min-w-0 flex-1 sm:w-64 sm:flex-none", type: "search", variant: "search", placeholder: searchPlaceholder, value: searchQuery, onChange: (event) => onSearchQueryChange(event.target.value) }), _jsx("div", { className: "sm:hidden", children: _jsx(FilterSheet, { activeCount: activeFilterCount, onReset: handleClearFilters, children: filterSheetContent }) }), _jsx("div", { className: "hidden sm:contents", children: filterControls() }), _jsx("div", { className: "ml-auto hidden shrink-0 sm:block", children: _jsx(TableColumnRearrangePopover, { enableReset: true, table: table, columnLabels: columnLabels, defaultOrder: columnDefaultOrder }) })] })] }));
|
|
29
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkUnlinkedDatastoreDialog.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/components/LinkUnlinkedDatastoreDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LinkUnlinkedDatastoreDialog.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/components/LinkUnlinkedDatastoreDialog.tsx"],"names":[],"mappings":"AAuBA,MAAM,MAAM,mBAAmB,GAAG;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAIF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,gCAAgC,2CA0IlF"}
|
|
@@ -6,6 +6,8 @@ import { useQueryClient } from "@tanstack/react-query";
|
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import { toast } from "sonner";
|
|
8
8
|
import { organizationNameKey } from "../flatten.js";
|
|
9
|
+
import { useTenantOrganizationCheck } from "../hooks/useTenantOrganizationCheck.js";
|
|
10
|
+
import { toastProviderWarning } from "../link-provider.js";
|
|
9
11
|
import { Button } from "#components/button/index";
|
|
10
12
|
import { Input } from "#components/input/index";
|
|
11
13
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "#components/modal/index";
|
|
@@ -27,6 +29,7 @@ export function LinkUnlinkedDatastoreDialog(props) {
|
|
|
27
29
|
void queryClient.invalidateQueries({ queryKey: useUnlinkedDatastoresQuery.getKey() });
|
|
28
30
|
void queryClient.invalidateQueries({ queryKey: ["DatastoreProvisioningStatuses"] });
|
|
29
31
|
toast.success(`Linked to the existing datastore '${datastoreId}'`);
|
|
32
|
+
toastProviderWarning(result.linkUnlinkedDatastore.providerWarning);
|
|
30
33
|
onClose();
|
|
31
34
|
}
|
|
32
35
|
else {
|
|
@@ -40,7 +43,8 @@ export function LinkUnlinkedDatastoreDialog(props) {
|
|
|
40
43
|
toast.error(info.message, { description: info.description });
|
|
41
44
|
},
|
|
42
45
|
});
|
|
43
|
-
const
|
|
46
|
+
const tenantCheck = useTenantOrganizationCheck(mode === "new" ? organizationName : "", existingOrganizationNames);
|
|
47
|
+
const canSubmit = mode === "new" ? !!organizationName.trim() && !tenantCheck.blocked : !!existingOrganizationName;
|
|
44
48
|
const atExistingOrganizationRoot = mode === "existing" && !name.trim();
|
|
45
49
|
const suggestedParentPath = suggestedMatch &&
|
|
46
50
|
existingOrganizationName === suggestedMatch.organizationName &&
|
|
@@ -79,5 +83,5 @@ export function LinkUnlinkedDatastoreDialog(props) {
|
|
|
79
83
|
};
|
|
80
84
|
linkMutation.mutate({ input });
|
|
81
85
|
}
|
|
82
|
-
return (_jsx(Dialog, { open: true, onOpenChange: (nextOpen) => !nextOpen && onClose(), children: _jsxs(DialogContent, { className: "flex flex-col overflow-hidden", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { text: "Link datastore" }), _jsx(DialogDescription, { children: `Link the existing datastore '${datastoreId}' to an organization or group.` })] }), _jsxs(RadioGroup, { value: mode, onValueChange: (v) => setMode(v), className: "flex gap-4 items-center", children: [_jsx(RadioGroupItem, { value: "new", label: "New organization" }), _jsx(RadioGroupItem, { value: "existing", label: "Existing organization", disabled: !isPresent(organizationNames) })] }), mode === "new" ? (_jsx(Input, { autoFocus: true, label: "Organization name", placeholder: "e.g. Acme Corp", value: organizationName, onChange: (event) => setOrganizationName(event.target.value) })) : (_jsxs(_Fragment, { children: [_jsxs(Select, { value: existingOrganizationName, onValueChange: setExistingOrganizationName, children: [_jsx(SelectTrigger, { label: "Organization", id: "link-organization", children: _jsx(SelectValue, { placeholder: "Select an organization\u2026" }) }), _jsx(SelectContent, { children: organizationNames.map((orgName) => (_jsx(SelectItem, { value: orgName, children: orgName }, orgName))) })] }), _jsx(Input, { label: "Datastore name", placeholder: "Leave empty to link to the organization root", value: name, onChange: (event) => setName(event.target.value) })] })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: "Cancel" }), _jsx(Button, { onClick: submit, disabled: !canSubmit || linkMutation.isPending, children: "Link" })] })] }) }));
|
|
86
|
+
return (_jsx(Dialog, { open: true, onOpenChange: (nextOpen) => !nextOpen && onClose(), children: _jsxs(DialogContent, { className: "flex flex-col overflow-hidden", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { text: "Link datastore" }), _jsx(DialogDescription, { children: `Link the existing datastore '${datastoreId}' to an organization or group.` })] }), _jsxs(RadioGroup, { value: mode, onValueChange: (v) => setMode(v), className: "flex gap-4 items-center", children: [_jsx(RadioGroupItem, { value: "new", label: "New organization" }), _jsx(RadioGroupItem, { value: "existing", label: "Existing organization", disabled: !isPresent(organizationNames) })] }), mode === "new" ? (_jsxs(_Fragment, { children: [_jsx(Input, { autoFocus: true, label: "Organization name", placeholder: "e.g. Acme Corp", value: organizationName, onChange: (event) => setOrganizationName(event.target.value) }), isPresent(tenantCheck.hint) ? (_jsx("span", { className: "typography-caption text-muted-foreground", children: tenantCheck.hint })) : null] })) : (_jsxs(_Fragment, { children: [_jsxs(Select, { value: existingOrganizationName, onValueChange: setExistingOrganizationName, children: [_jsx(SelectTrigger, { label: "Organization", id: "link-organization", children: _jsx(SelectValue, { placeholder: "Select an organization\u2026" }) }), _jsx(SelectContent, { children: organizationNames.map((orgName) => (_jsx(SelectItem, { value: orgName, children: orgName }, orgName))) })] }), _jsx(Input, { label: "Datastore name", placeholder: "Leave empty to link to the organization root", value: name, onChange: (event) => setName(event.target.value) })] })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: "Cancel" }), _jsx(Button, { onClick: submit, disabled: !canSubmit || linkMutation.isPending, children: "Link" })] })] }) }));
|
|
83
87
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type DatastoreFormDialogProps } from "./DatastoreFormDialog.js";
|
|
2
|
+
type ProvisionDatastoreDialogProps = Omit<DatastoreFormDialogProps, "onNameChange" | "nameCheck"> & {
|
|
3
|
+
existingOrganizationNames: Set<string>;
|
|
4
|
+
};
|
|
5
|
+
export declare function ProvisionDatastoreDialog(props: ProvisionDatastoreDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=ProvisionDatastoreDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProvisionDatastoreDialog.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/components/ProvisionDatastoreDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAE3F,KAAK,6BAA6B,GAAG,IAAI,CAAC,wBAAwB,EAAE,cAAc,GAAG,WAAW,CAAC,GAAG;IAClG,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,2CAS5E"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useTenantOrganizationCheck } from "../hooks/useTenantOrganizationCheck.js";
|
|
4
|
+
import { DatastoreFormDialog } from "./DatastoreFormDialog.js";
|
|
5
|
+
export function ProvisionDatastoreDialog(props) {
|
|
6
|
+
const { existingOrganizationNames, ...dialogProps } = props;
|
|
7
|
+
const [name, setName] = useState("");
|
|
8
|
+
const nameCheck = useTenantOrganizationCheck(dialogProps.target.kind === "organization" ? name : "", existingOrganizationNames);
|
|
9
|
+
return _jsx(DatastoreFormDialog, { ...dialogProps, onNameChange: setName, nameCheck: nameCheck });
|
|
10
|
+
}
|
|
@@ -14,10 +14,14 @@ export type DatastoreRow = {
|
|
|
14
14
|
provisionedAt?: string;
|
|
15
15
|
provisionedBy?: string;
|
|
16
16
|
isOrganization: boolean;
|
|
17
|
+
mirrored?: boolean;
|
|
17
18
|
isRealmDefault?: boolean;
|
|
18
19
|
isUnlinked?: boolean;
|
|
19
20
|
};
|
|
20
21
|
export declare function realmDefaultRow(datastoreId: Realm): DatastoreRow;
|
|
22
|
+
export declare function isUnmirroredOrganization(row: DatastoreRow): boolean;
|
|
23
|
+
export type ProviderFilter = "ALL" | "mirrored" | "unmirrored";
|
|
24
|
+
export declare function matchesProviderFilter(row: DatastoreRow, filter: ProviderFilter): boolean;
|
|
21
25
|
export type DatastoreRowVisibility = {
|
|
22
26
|
showArchived: boolean;
|
|
23
27
|
showUnprovisioned: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flatten.d.ts","sourceRoot":"","sources":["../../../src/routes/datastores/flatten.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAmB,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAGlE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAG3E,MAAM,MAAM,YAAY,GAAG;IAEzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,cAAc,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"flatten.d.ts","sourceRoot":"","sources":["../../../src/routes/datastores/flatten.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAmB,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAGlE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAG3E,MAAM,MAAM,YAAY,GAAG;IAEzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,eAAe,CAAC,WAAW,EAAE,KAAK,GAAG,YAAY,CAchE;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAEnE;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,UAAU,GAAG,YAAY,CAAC;AAE/D,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAMxF;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAcF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,UAAU,EAAE,sBAAsB,GAAG,YAAY,EAAE,CAG7G;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAAE,EACpB,UAAU,EAAE,sBAAsB,EAClC,GAAG,EAAE,MAAM,sBAAsB,EACjC,UAAU,EAAE,MAAM,GACjB,MAAM,CAIR;AAGD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAE9E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAEhE;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,sBAAsB,EAClC,MAAM,EAAE,0BAA0B,GAAG,KAAK,GACzC,sBAAsB,CAMxB;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CActE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,YAAY,EAAE,CAgB7E"}
|
|
@@ -16,6 +16,16 @@ export function realmDefaultRow(datastoreId) {
|
|
|
16
16
|
isRealmDefault: true,
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
+
export function isUnmirroredOrganization(row) {
|
|
20
|
+
return row.isOrganization && row.mirrored === false;
|
|
21
|
+
}
|
|
22
|
+
export function matchesProviderFilter(row, filter) {
|
|
23
|
+
return match(filter)
|
|
24
|
+
.with("ALL", () => true)
|
|
25
|
+
.with("mirrored", () => row.isOrganization && row.mirrored === true)
|
|
26
|
+
.with("unmirrored", () => isUnmirroredOrganization(row))
|
|
27
|
+
.exhaustive();
|
|
28
|
+
}
|
|
19
29
|
function matchesVisibility(row, visibility) {
|
|
20
30
|
return (visibility.showArchived || !row.removed) && (visibility.showUnprovisioned || isPresent(row.datastoreId));
|
|
21
31
|
}
|
|
@@ -82,5 +92,6 @@ export function toDatastoreRows(nodes) {
|
|
|
82
92
|
provisionedAt: node.provisionedAt ?? undefined,
|
|
83
93
|
provisionedBy: node.provisionedBy ?? undefined,
|
|
84
94
|
isOrganization: node.isOrganization,
|
|
95
|
+
mirrored: node.mirrored ?? undefined,
|
|
85
96
|
}));
|
|
86
97
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ColumnDef } from "@tanstack/react-table";
|
|
2
|
-
import type
|
|
2
|
+
import { type DatastoreRow } from "../flatten.js";
|
|
3
3
|
import { type DatastoreStatus } from "#components/datastore-management/tree";
|
|
4
4
|
export declare const datastoreColumnIds: {
|
|
5
5
|
readonly name: "name";
|
|
@@ -41,6 +41,9 @@ type UseDatastoreColumnsArgs = {
|
|
|
41
41
|
onManageUsers: (row: DatastoreRow) => void;
|
|
42
42
|
onBringOnline: (row: DatastoreRow) => void;
|
|
43
43
|
isBringingOnline?: boolean;
|
|
44
|
+
onLinkProvider: (row: DatastoreRow) => void;
|
|
45
|
+
isLinkingProvider?: boolean;
|
|
46
|
+
providerLinkEnabled?: boolean;
|
|
44
47
|
};
|
|
45
48
|
export declare function useDatastoreColumns(args: UseDatastoreColumnsArgs): ColumnDef<DatastoreRow>[];
|
|
46
49
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDatastoreColumns.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/hooks/useDatastoreColumns.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAuBvD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"useDatastoreColumns.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/hooks/useDatastoreColumns.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAuBvD,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAGzE,OAAO,EAA4C,KAAK,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAYvH,eAAO,MAAM,kBAAkB;;;;;;;;;CASrB,CAAC;AASX,eAAO,MAAM,qBAAqB;;;;;;;CAOkB,CAAC;AAErD,eAAO,MAAM,kBAAkB,+HAAoC,CAAC;AAEpE,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGvD,CAAC;AAEF,eAAO,MAAM,mBAAmB,6DAK/B,CAAC;AAcF,KAAK,uBAAuB,GAAG;IAC7B,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3D,QAAQ,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,MAAM,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACzC,cAAc,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,aAAa,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,SAAS,CAAC,YAAY,CAAC,EAAE,CA4V5F"}
|
|
@@ -6,6 +6,7 @@ import { Check, DatabaseZap, Link2, MoreHorizontal, Pencil, Plus, Power, Refresh
|
|
|
6
6
|
import { useMemo } from "react";
|
|
7
7
|
import { match } from "ts-pattern";
|
|
8
8
|
import { DatastoreStatusBadge, datastoreStatusFilterValue, } from "../components/StatusBadge.js";
|
|
9
|
+
import { isUnmirroredOrganization } from "../flatten.js";
|
|
9
10
|
import { Badge } from "#components/badge/index";
|
|
10
11
|
import { Button } from "#components/button/index";
|
|
11
12
|
import { datastoreStatusCategory, isMaterializing } from "#components/datastore-management/tree";
|
|
@@ -54,7 +55,7 @@ const columnMinWidths = {
|
|
|
54
55
|
[datastoreColumnIds.actions]: "min-w-[140px]",
|
|
55
56
|
};
|
|
56
57
|
export function useDatastoreColumns(args) {
|
|
57
|
-
const { statusByDatastoreId, currentDatastoreId, isSwitching, indented, matchableRowIds, suggestedMatchByDatastoreId, onSelect, onAddChild, onLink, onProvision, onLinkExisting, onRemove, onRestore, onRename, onRegister, onManageUsers, onBringOnline, isBringingOnline, } = args;
|
|
58
|
+
const { statusByDatastoreId, currentDatastoreId, isSwitching, indented, matchableRowIds, suggestedMatchByDatastoreId, onSelect, onAddChild, onLink, onProvision, onLinkExisting, onRemove, onRestore, onRename, onRegister, onManageUsers, onBringOnline, isBringingOnline, onLinkProvider, isLinkingProvider, providerLinkEnabled, } = args;
|
|
58
59
|
return useMemo(() => [
|
|
59
60
|
{
|
|
60
61
|
id: datastoreColumnIds.name,
|
|
@@ -136,7 +137,7 @@ export function useDatastoreColumns(args) {
|
|
|
136
137
|
.with({ materializing: true }, () => "Still materializing - this can take a few minutes.")
|
|
137
138
|
.otherwise(() => undefined);
|
|
138
139
|
const canSelect = hasDatastore && !reason && !current && !isSwitching;
|
|
139
|
-
return (_jsxs("div", { className: cn(columnMinWidths[datastoreColumnIds.actions], "flex items-center justify-end gap-1.5"), children: [isUnlinked && (_jsx(Button, { "data-testid": `datastore-link-${datastoreRow.id}`, size: "sm", variant: "secondary", icon: Link2, onClick: () => onLink(datastoreRow), children: "Link" })), hasDatastore && !removed && category === "offline" && (_jsx(Button, { "data-testid": `datastore-bring-online-${datastoreRow.id}`, size: "sm", variant: "secondary", icon: Power, disabled: isBringingOnline, onClick: () => onBringOnline(datastoreRow), children: "Bring online" })), !isUnlinked && hasDatastore && !removed && notRegistered && (_jsx(Button, { "data-testid": `datastore-register-${datastoreRow.id}`, size: "sm", variant: "secondary", icon: RefreshCw, onClick: () => onRegister(datastoreRow), children: "Register" })), !isUnlinked && hasDatastore && current && (_jsx(Button, { "data-testid": `datastore-select-${datastoreRow.id}`, size: "sm", variant: "secondary", disabled: true, children: "Selected" })), !isUnlinked && hasDatastore && !current && !removed && (_jsx(Button, { "data-testid": `datastore-select-${datastoreRow.id}`, size: "sm", variant: "secondary", disabled: !canSelect, title: reason, onClick: () => onSelect(datastoreRow), children: "Select" })), isRealmDefault || isUnlinked ? (
|
|
140
|
+
return (_jsxs("div", { className: cn(columnMinWidths[datastoreColumnIds.actions], "flex items-center justify-end gap-1.5"), children: [providerLinkEnabled === true && isUnmirroredOrganization(datastoreRow) && !removed && (_jsx(Button, { "data-testid": `datastore-link-provider-${datastoreRow.id}`, size: "sm", variant: "secondary", icon: Link2, disabled: isLinkingProvider, onClick: () => onLinkProvider(datastoreRow), children: "Link to identity provider" })), isUnlinked && (_jsx(Button, { "data-testid": `datastore-link-${datastoreRow.id}`, size: "sm", variant: "secondary", icon: Link2, onClick: () => onLink(datastoreRow), children: "Link" })), hasDatastore && !removed && category === "offline" && (_jsx(Button, { "data-testid": `datastore-bring-online-${datastoreRow.id}`, size: "sm", variant: "secondary", icon: Power, disabled: isBringingOnline, onClick: () => onBringOnline(datastoreRow), children: "Bring online" })), !isUnlinked && hasDatastore && !removed && notRegistered && (_jsx(Button, { "data-testid": `datastore-register-${datastoreRow.id}`, size: "sm", variant: "secondary", icon: RefreshCw, onClick: () => onRegister(datastoreRow), children: "Register" })), !isUnlinked && hasDatastore && current && (_jsx(Button, { "data-testid": `datastore-select-${datastoreRow.id}`, size: "sm", variant: "secondary", disabled: true, children: "Selected" })), !isUnlinked && hasDatastore && !current && !removed && (_jsx(Button, { "data-testid": `datastore-select-${datastoreRow.id}`, size: "sm", variant: "secondary", disabled: !canSelect, title: reason, onClick: () => onSelect(datastoreRow), children: "Select" })), isRealmDefault || isUnlinked ? (
|
|
140
141
|
// Same-sized spacer keeps Select/Selected aligned with rows that have the ellipsis.
|
|
141
142
|
_jsx("div", { className: "size-6", "aria-hidden": "true" })) : (_jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": `Actions for ${name}`, className: "shrink-0 rounded-sm-v4 p-1 text-muted-foreground hover:bg-faint hover:text-default-foreground", children: _jsx(MoreHorizontal, { className: "size-4" }) }) }), _jsxs(DropdownContent, { align: "end", className: "min-w-52", children: [_jsx(DropdownItem, { icon: _jsx(Pencil, { className: "size-4" }), onSelect: () => onRename(datastoreRow), children: "Rename" }), isPresent(datastoreRow.organizationAlias) && (_jsx(DropdownItem, { icon: _jsx(Users, { className: "size-4" }), onSelect: () => onManageUsers(datastoreRow), children: "Manage users" })), !hasDatastore &&
|
|
142
143
|
(matchableRowIds.has(datastoreRow.id) ? (_jsx(DropdownItem, { icon: _jsx(Link2, { className: "size-4" }), onSelect: () => onLinkExisting(datastoreRow), children: "Link existing datastore" })) : (_jsx(DropdownItem, { icon: _jsx(DatabaseZap, { className: "size-4" }), onSelect: () => onProvision(datastoreRow), children: "Provision datastore" }))), _jsx(DropdownItem, { icon: _jsx(Plus, { className: "size-4" }), onSelect: () => onAddChild(datastoreRow), children: "Add datastore" }), enableDatastoreRemoval && hasDatastore && !removed && (_jsxs(_Fragment, { children: [_jsx(DropdownSeparator, {}), _jsx(DropdownItem, { className: "text-error-foreground", icon: _jsx(Trash2, { className: "size-4" }), onSelect: () => onRemove(datastoreRow), children: "Remove datastore" })] })), enableDatastoreRemoval && hasDatastore && removed && (_jsxs(_Fragment, { children: [_jsx(DropdownSeparator, {}), _jsx(DropdownItem, { icon: _jsx(RotateCcw, { className: "size-4" }), onSelect: () => onRestore(datastoreRow), children: "Restore datastore" })] }))] })] }))] }));
|
|
@@ -161,5 +162,8 @@ export function useDatastoreColumns(args) {
|
|
|
161
162
|
onManageUsers,
|
|
162
163
|
onBringOnline,
|
|
163
164
|
isBringingOnline,
|
|
165
|
+
onLinkProvider,
|
|
166
|
+
isLinkingProvider,
|
|
167
|
+
providerLinkEnabled,
|
|
164
168
|
]);
|
|
165
169
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTenantOrganizationCheck.d.ts","sourceRoot":"","sources":["../../../../src/routes/datastores/hooks/useTenantOrganizationCheck.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,KAAK,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAKzF,wBAAgB,0BAA0B,CACxC,gBAAgB,EAAE,MAAM,EACxB,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,GACrC,uBAAuB,CAgBzB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useOrganizationLinkingQuery, useTenantOrganizationQuery } from "@manta-eu/client";
|
|
2
|
+
import { isPresent } from "@manta-eu/lib/present";
|
|
3
|
+
import { useDebounceValue } from "usehooks-ts";
|
|
4
|
+
import { organizationNameKey } from "../flatten.js";
|
|
5
|
+
import { tenantOrganizationCheck } from "../link-provider.js";
|
|
6
|
+
import { useAuthContext } from "#providers/AuthContext";
|
|
7
|
+
import { useMantaClient } from "#providers/index";
|
|
8
|
+
// An empty name checks nothing, so a dialog passes "" while it is not creating an organization.
|
|
9
|
+
export function useTenantOrganizationCheck(organizationName, existingOrganizationNames) {
|
|
10
|
+
const { mantaClient } = useMantaClient();
|
|
11
|
+
const { isOperator } = useAuthContext();
|
|
12
|
+
const linkingQuery = useOrganizationLinkingQuery(mantaClient, undefined, { enabled: !!isOperator });
|
|
13
|
+
const linking = linkingQuery.data?.organizationLinking;
|
|
14
|
+
const trimmed = organizationName.trim();
|
|
15
|
+
const [debounced] = useDebounceValue(trimmed, 300);
|
|
16
|
+
const knownName = existingOrganizationNames.has(organizationNameKey(debounced));
|
|
17
|
+
const lookupName = linking?.linkEnabled === true && !knownName ? debounced : "";
|
|
18
|
+
const lookup = useTenantOrganizationQuery(mantaClient, { organizationName: lookupName }, { enabled: isPresent(lookupName), retry: false });
|
|
19
|
+
const tenant = isPresent(lookupName) && lookupName === trimmed ? lookup.data?.tenantOrganization : undefined;
|
|
20
|
+
return tenantOrganizationCheck(tenant, linking?.pushEnabled === true);
|
|
21
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/datastores/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/datastores/index.tsx"],"names":[],"mappings":"AA4FA,wBAAgB,eAAe,4CA4tB9B"}
|