@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useBringDatastoreOnlineMutation, useLinkUnlinkedDatastoreMutation, useDatastoreTreeQuery, useProvisionDatastoreMutation, useRegisterDatastoreMutation, useRemoveDatastoreMutation, useRenameDatastoreGroupMutation, useRestoreDatastoreMutation, useUnlinkedDatastoresQuery, } from "@manta-eu/client";
|
|
2
|
+
import { useBringDatastoreOnlineMutation, useOrganizationLinkingQuery, useLinkOrganizationToProviderMutation, useLinkUnlinkedDatastoreMutation, useDatastoreTreeQuery, useProvisionDatastoreMutation, useRegisterDatastoreMutation, useRemoveDatastoreMutation, useRenameDatastoreGroupMutation, useRestoreDatastoreMutation, useUnlinkedDatastoresQuery, } from "@manta-eu/client";
|
|
3
3
|
import { enableDatastoreRemoval } from "@manta-eu/client/shared/constants";
|
|
4
4
|
import { deriveDatastoreId } from "@manta-eu/client/shared/datastore-id";
|
|
5
5
|
import { parseError } from "@manta-eu/client/shared/error-utils";
|
|
@@ -11,15 +11,17 @@ import { Archive, Database, EyeOff, Plus, RefreshCcw, TriangleAlert } from "luci
|
|
|
11
11
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
12
12
|
import { useNavigate, useSearchParams } from "react-router";
|
|
13
13
|
import { toast } from "sonner";
|
|
14
|
-
import { DatastoreFormDialog } from "./components/DatastoreFormDialog.js";
|
|
15
14
|
import { DatastoresToolbar } from "./components/DatastoresToolbar.js";
|
|
16
15
|
import { DatastoreTableSkeleton } from "./components/DatastoreTableSkeleton.js";
|
|
17
16
|
import { LinkUnlinkedDatastoreDialog } from "./components/LinkUnlinkedDatastoreDialog.js";
|
|
17
|
+
import { ProvisionDatastoreDialog } from "./components/ProvisionDatastoreDialog.js";
|
|
18
18
|
import { RenameDatastoreGroupDialog } from "./components/RenameDatastoreGroupDialog.js";
|
|
19
19
|
import { UnlinkedDatastoresPanel } from "./components/UnlinkedDatastoresPanel.js";
|
|
20
|
-
import { existingOrganizationNameKeys, hiddenRowCount, organizationNameKey, organizationNames, realmDefaultRow, toDatastoreRows, unlinkedDatastoreRow, visibilityForStatusFilter, visibleDatastoreRows, } from "./flatten.js";
|
|
20
|
+
import { existingOrganizationNameKeys, hiddenRowCount, matchesProviderFilter, organizationNameKey, organizationNames, realmDefaultRow, toDatastoreRows, unlinkedDatastoreRow, visibilityForStatusFilter, visibleDatastoreRows, } from "./flatten.js";
|
|
21
21
|
import { datastoreColumnIds, unlinkedColumnLabels, unlinkedColumnOrder, useDatastoreColumns, } from "./hooks/useDatastoreColumns.js";
|
|
22
22
|
import { useDatastoreTable } from "./hooks/useDatastoreTable.js";
|
|
23
|
+
import { linkProviderOutcome, toastProviderWarning } from "./link-provider.js";
|
|
24
|
+
import { Banner } from "#components/banner/index";
|
|
23
25
|
import { Button } from "#components/button/index";
|
|
24
26
|
import { collectDatastoreIds } from "#components/datastore-management/tree";
|
|
25
27
|
import { useDatastoreStatusByDatastoreId } from "#components/datastore-management/use-datastore-status";
|
|
@@ -60,6 +62,7 @@ export function DatastoresRoute() {
|
|
|
60
62
|
showUnprovisioned: false,
|
|
61
63
|
});
|
|
62
64
|
const { showArchived, showUnprovisioned } = visibility;
|
|
65
|
+
const [providerFilter, setProviderFilter] = useState("ALL");
|
|
63
66
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
64
67
|
const tabParam = searchParams.get("tab");
|
|
65
68
|
const activeTab = tabParam && activeTabs.includes(tabParam) ? tabParam : "organizations";
|
|
@@ -112,6 +115,7 @@ export function DatastoresRoute() {
|
|
|
112
115
|
else {
|
|
113
116
|
toast.success(`Datastore "${name}" is ready`);
|
|
114
117
|
}
|
|
118
|
+
toastProviderWarning(result.provisionDatastore.providerWarning);
|
|
115
119
|
},
|
|
116
120
|
onError: (error) => {
|
|
117
121
|
const info = parseError(error, "Couldn't create the datastore");
|
|
@@ -190,6 +194,30 @@ export function DatastoresRoute() {
|
|
|
190
194
|
toast.error(info.message, { description: info.description });
|
|
191
195
|
},
|
|
192
196
|
});
|
|
197
|
+
const linkingQuery = useOrganizationLinkingQuery(mantaClient, undefined, { enabled: !!isOperator });
|
|
198
|
+
const linkProviderMutation = useLinkOrganizationToProviderMutation(mantaClient, {
|
|
199
|
+
onSuccess: (result) => {
|
|
200
|
+
const { reason } = result.linkOrganizationToProvider;
|
|
201
|
+
const outcome = linkProviderOutcome(result.linkOrganizationToProvider);
|
|
202
|
+
if (outcome === "linkDisabled") {
|
|
203
|
+
void queryClient.invalidateQueries({ queryKey: useOrganizationLinkingQuery.getKey() });
|
|
204
|
+
toast.error("Organizations can't be linked to the identity provider on this realm", {
|
|
205
|
+
description: reason ?? "Ask an administrator to enable organization linking.",
|
|
206
|
+
});
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
invalidateTree();
|
|
210
|
+
if (outcome === "failed") {
|
|
211
|
+
toast.error("Couldn't link the organization", { description: reason ?? undefined });
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
toast.success("Organization linked to the identity provider");
|
|
215
|
+
},
|
|
216
|
+
onError: (error) => {
|
|
217
|
+
const info = parseError(error, "Couldn't link the organization");
|
|
218
|
+
toast.error(info.message, { description: info.description });
|
|
219
|
+
},
|
|
220
|
+
});
|
|
193
221
|
const treeRows = useMemo(() => [
|
|
194
222
|
...(realmDatastoreId ? [realmDefaultRow(realmDatastoreId)] : []),
|
|
195
223
|
...toDatastoreRows(data?.datastoreTree ?? []),
|
|
@@ -198,6 +226,9 @@ export function DatastoresRoute() {
|
|
|
198
226
|
const allRows = useMemo(() => [...treeRows, ...unlinkedRows], [treeRows, unlinkedRows]);
|
|
199
227
|
const rows = useMemo(() => visibleDatastoreRows(treeRows, visibility), [treeRows, visibility]);
|
|
200
228
|
const unprovisionedCount = useMemo(() => hiddenRowCount(treeRows, visibility, "showUnprovisioned", rows.length), [treeRows, visibility, rows.length]);
|
|
229
|
+
const providerLinkEnabled = linkingQuery.data?.organizationLinking?.linkEnabled;
|
|
230
|
+
const linkingUnreadable = linkingQuery.isError || linkingQuery.data?.organizationLinking === null;
|
|
231
|
+
const tableRows = useMemo(() => (providerLinkEnabled === true ? rows.filter((row) => matchesProviderFilter(row, providerFilter)) : rows), [rows, providerFilter, providerLinkEnabled]);
|
|
201
232
|
const unlinkedCount = unlinkedRows.length;
|
|
202
233
|
const existingOrganizationNames = useMemo(() => existingOrganizationNameKeys(allRows), [allRows]);
|
|
203
234
|
const organizationNameOptions = useMemo(() => organizationNames(allRows), [allRows]);
|
|
@@ -259,6 +290,7 @@ export function DatastoresRoute() {
|
|
|
259
290
|
void queryClient.invalidateQueries({ queryKey: ["DatastoreProvisioningStatuses"] });
|
|
260
291
|
if (result.linkUnlinkedDatastore.success) {
|
|
261
292
|
toast.success(`Linked to the existing datastore "${result.linkUnlinkedDatastore.datastoreId}"`);
|
|
293
|
+
toastProviderWarning(result.linkUnlinkedDatastore.providerWarning);
|
|
262
294
|
}
|
|
263
295
|
else {
|
|
264
296
|
toast.error("Couldn't link the existing datastore", {
|
|
@@ -316,6 +348,9 @@ export function DatastoresRoute() {
|
|
|
316
348
|
if (isPresent(row.datastoreId))
|
|
317
349
|
bringOnlineMutation.mutate({ datastoreId: row.datastoreId });
|
|
318
350
|
}, [bringOnlineMutation.mutate]);
|
|
351
|
+
const onLinkProvider = useCallback((row) => {
|
|
352
|
+
linkProviderMutation.mutate({ organizationId: row.organizationId });
|
|
353
|
+
}, [linkProviderMutation.mutate]);
|
|
319
354
|
const columns = useDatastoreColumns({
|
|
320
355
|
statusByDatastoreId,
|
|
321
356
|
currentDatastoreId: datastore?.id ?? realmDatastoreId,
|
|
@@ -335,6 +370,9 @@ export function DatastoresRoute() {
|
|
|
335
370
|
onManageUsers,
|
|
336
371
|
onBringOnline,
|
|
337
372
|
isBringingOnline: bringOnlineMutation.isPending,
|
|
373
|
+
onLinkProvider,
|
|
374
|
+
isLinkingProvider: linkProviderMutation.isPending,
|
|
375
|
+
providerLinkEnabled,
|
|
338
376
|
});
|
|
339
377
|
const filterToggles = [
|
|
340
378
|
...(enableDatastoreRemoval
|
|
@@ -363,7 +401,7 @@ export function DatastoresRoute() {
|
|
|
363
401
|
: []),
|
|
364
402
|
];
|
|
365
403
|
const treeColumns = useMemo(() => columns.filter((column) => column.id !== datastoreColumnIds.suggestedMatch), [columns]);
|
|
366
|
-
const { table, searchQuery, onSearchQueryChange, statusFilter, onStatusFilterChange } = useDatastoreTable("datastores",
|
|
404
|
+
const { table, searchQuery, onSearchQueryChange, statusFilter, onStatusFilterChange } = useDatastoreTable("datastores", tableRows, treeColumns, sorting, setSorting);
|
|
367
405
|
const unlinkedColumns = useMemo(() => unlinkedColumnOrder.flatMap((id) => columns.filter((column) => column.id === id)), [columns]);
|
|
368
406
|
const { table: unlinkedTable, searchQuery: unlinkedSearchQuery, onSearchQueryChange: onUnlinkedSearchQueryChange, statusFilter: unlinkedStatusFilter, onStatusFilterChange: onUnlinkedStatusFilterChange, } = useDatastoreTable("datastores-unlinked", unlinkedRows, unlinkedColumns, unlinkedSorting, setUnlinkedSorting);
|
|
369
407
|
const scopeTabs = activeTabs.map((tab) => ({
|
|
@@ -449,10 +487,10 @@ export function DatastoresRoute() {
|
|
|
449
487
|
};
|
|
450
488
|
provisionMutation.mutate({ input }, { onSuccess: (result) => result.provisionDatastore.success && setFormTarget(null) });
|
|
451
489
|
}
|
|
452
|
-
return (_jsxs(RouteLayout, { user: user, datastore: datastore, datastores: datastores, isOperator: isOperator, canSwitchDatastore: canSwitchDatastore, logout: logout, children: [_jsx(PageHeader, { title: "Datastores", icon: Database, actions: _jsxs(_Fragment, { children: [_jsx(Button, { iconOnly: true, variant: "tertiary", onClick: handleRefresh, disabled: isFetching, icon: RefreshCcw, "aria-label": "Refresh datastores" }), activeTab === "organizations" && (_jsxs(_Fragment, { children: [filterToggles.map((toggle) => (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "secondary", "aria-pressed": toggle.active, onClick: toggle.onToggle, icon: toggle.icon, children: toggle.label }) }), _jsx(TooltipContent, { children: toggle.description })] }, toggle.key))), _jsx(Button, { icon: Plus, onClick: () => setFormTarget({ kind: "organization" }), children: "Add organization" })] }))] }) }), _jsxs(Tabs, { value: activeTab, onValueChange: (tab) => setSearchParams({ tab }, { replace: true }), className: "flex flex-col flex-1 min-h-0 overflow-hidden", children: [_jsxs(TabsContent, { value: "organizations", className: "flex flex-col flex-1 min-h-0 overflow-hidden", children: [_jsx("div", { className: "border-b border-muted-border px-5 py-3 shrink-0", children: _jsx(DatastoresToolbar, { tabs: tabsList, searchQuery: searchQuery, onSearchQueryChange: onSearchQueryChange, statusFilter: statusFilter, onStatusFilterChange: handleStatusFilterChange, table: table }) }), _jsxs("div", { className: "flex-1 overflow-auto p-4", children: [isLoading && _jsx(DatastoreTableSkeleton, {}), !isLoading && !isPresent(rows) && (_jsx(EmptyState, { icon: Database, title: "No organizations yet", description: "Provision an organization to give it its first datastore.", children: _jsx(Button, { icon: Plus, onClick: () => setFormTarget({ kind: "organization" }), children: "Add organization" }) })), !isLoading && isPresent(rows) && (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("div", { className: "rounded-xl border border-muted-border bg-card overflow-hidden", children: _jsx(DataTable, { table: table, noResultsMessage: "No datastores match your filters." }) }), _jsx(TablePagination, { table: table, total: rows.length })] }))] })] }), _jsx(TabsContent, { value: "unlinked", className: "flex flex-col flex-1 min-h-0 overflow-hidden", children: _jsx(UnlinkedDatastoresPanel, { tabs: tabsList, table: unlinkedTable, rows: unlinkedRows, searchQuery: unlinkedSearchQuery, onSearchQueryChange: onUnlinkedSearchQueryChange, statusFilter: unlinkedStatusFilter, onStatusFilterChange: onUnlinkedStatusFilterChange, columnLabels: unlinkedColumnLabels, columnDefaultOrder: unlinkedColumnOrder, isLoading: isUnlinkedLoading, errorMessage: unlinkedError != null
|
|
490
|
+
return (_jsxs(RouteLayout, { user: user, datastore: datastore, datastores: datastores, isOperator: isOperator, canSwitchDatastore: canSwitchDatastore, logout: logout, children: [_jsx(PageHeader, { title: "Datastores", icon: Database, actions: _jsxs(_Fragment, { children: [_jsx(Button, { iconOnly: true, variant: "tertiary", onClick: handleRefresh, disabled: isFetching, icon: RefreshCcw, "aria-label": "Refresh datastores" }), activeTab === "organizations" && (_jsxs(_Fragment, { children: [filterToggles.map((toggle) => (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "secondary", "aria-pressed": toggle.active, onClick: toggle.onToggle, icon: toggle.icon, children: toggle.label }) }), _jsx(TooltipContent, { children: toggle.description })] }, toggle.key))), _jsx(Button, { icon: Plus, onClick: () => setFormTarget({ kind: "organization" }), children: "Add organization" })] }))] }) }), _jsxs(Tabs, { value: activeTab, onValueChange: (tab) => setSearchParams({ tab }, { replace: true }), className: "flex flex-col flex-1 min-h-0 overflow-hidden", children: [_jsxs(TabsContent, { value: "organizations", className: "flex flex-col flex-1 min-h-0 overflow-hidden", children: [_jsx("div", { className: "border-b border-muted-border px-5 py-3 shrink-0", children: _jsx(DatastoresToolbar, { tabs: tabsList, searchQuery: searchQuery, onSearchQueryChange: onSearchQueryChange, statusFilter: statusFilter, onStatusFilterChange: handleStatusFilterChange, ...(providerLinkEnabled === true ? { providerFilter, onProviderFilterChange: setProviderFilter } : {}), table: table }) }), _jsxs("div", { className: "flex-1 overflow-auto p-4", children: [linkingUnreadable && (_jsx(Banner, { className: "mb-3", label: "Couldn't read whether organizations link to the identity provider, so linking is hidden until it can be." })), isLoading && _jsx(DatastoreTableSkeleton, {}), !isLoading && !isPresent(rows) && (_jsx(EmptyState, { icon: Database, title: "No organizations yet", description: "Provision an organization to give it its first datastore.", children: _jsx(Button, { icon: Plus, onClick: () => setFormTarget({ kind: "organization" }), children: "Add organization" }) })), !isLoading && isPresent(rows) && (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("div", { className: "rounded-xl border border-muted-border bg-card overflow-hidden", children: _jsx(DataTable, { table: table, noResultsMessage: "No datastores match your filters." }) }), _jsx(TablePagination, { table: table, total: rows.length })] }))] })] }), _jsx(TabsContent, { value: "unlinked", className: "flex flex-col flex-1 min-h-0 overflow-hidden", children: _jsx(UnlinkedDatastoresPanel, { tabs: tabsList, table: unlinkedTable, rows: unlinkedRows, searchQuery: unlinkedSearchQuery, onSearchQueryChange: onUnlinkedSearchQueryChange, statusFilter: unlinkedStatusFilter, onStatusFilterChange: onUnlinkedStatusFilterChange, columnLabels: unlinkedColumnLabels, columnDefaultOrder: unlinkedColumnOrder, isLoading: isUnlinkedLoading, errorMessage: unlinkedError != null
|
|
453
491
|
? (parseError(unlinkedError, "Couldn't list unlinked datastores").description ??
|
|
454
492
|
"Couldn't list unlinked datastores")
|
|
455
|
-
: null }) })] }), formTarget && (_jsx(
|
|
493
|
+
: null }) })] }), formTarget && (_jsx(ProvisionDatastoreDialog, { target: formTarget, existingOrganizationNames: existingOrganizationNames, onSubmit: submitForm, onCancel: () => setFormTarget(null), isSubmitting: provisionMutation.isPending })), linkDialogTarget && (_jsx(LinkUnlinkedDatastoreDialog, { datastoreId: linkDialogTarget, suggestedMatch: suggestedLinkTarget(linkDialogTarget), organizationNames: organizationNameOptions, existingOrganizationNames: existingOrganizationNames, onClose: () => setLinkDialogTarget(null) })), renameTarget && (_jsx(RenameDatastoreGroupDialog, { target: renameTarget, onSubmit: (name) => {
|
|
456
494
|
renameMutation.mutate({
|
|
457
495
|
input: {
|
|
458
496
|
id: renameTarget.id,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GQLLinkOrganizationResponse, GQLTenantOrganization } from "@manta-eu/client";
|
|
2
|
+
export type LinkProviderOutcome = "linkDisabled" | "failed" | "linked";
|
|
3
|
+
export declare function linkProviderOutcome(response: Pick<GQLLinkOrganizationResponse, "linkEnabled" | "linked" | "mirrored">): LinkProviderOutcome;
|
|
4
|
+
export declare function tenantOrganizationHint(tenant: Pick<GQLTenantOrganization, "slug" | "exists" | "mirroredBy">, pushEnabled: boolean): string;
|
|
5
|
+
export type TenantOrganizationCheck = {
|
|
6
|
+
hint?: string;
|
|
7
|
+
blocked: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function tenantOrganizationCheck(tenant: Pick<GQLTenantOrganization, "slug" | "exists" | "mirroredBy"> | null | undefined, pushEnabled: boolean): TenantOrganizationCheck;
|
|
10
|
+
export declare function toastProviderWarning(providerWarning: string | null | undefined): void;
|
|
11
|
+
//# sourceMappingURL=link-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-provider.d.ts","sourceRoot":"","sources":["../../../src/routes/datastores/link-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAI3F,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAGvE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,IAAI,CAAC,2BAA2B,EAAE,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC,GACjF,mBAAmB,CAGrB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,CAAC,EACrE,WAAW,EAAE,OAAO,GACnB,MAAM,CAeR;AAED,MAAM,MAAM,uBAAuB,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1E,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EACxF,WAAW,EAAE,OAAO,GACnB,uBAAuB,CAGzB;AAED,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,QAG9E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isPresent } from "@manta-eu/lib/present";
|
|
2
|
+
import { toast } from "sonner";
|
|
3
|
+
// Only an explicit false means the realm links nothing; null is a call that never reached the provider.
|
|
4
|
+
export function linkProviderOutcome(response) {
|
|
5
|
+
if (response.linkEnabled === false)
|
|
6
|
+
return "linkDisabled";
|
|
7
|
+
return response.linked || response.mirrored === true ? "linked" : "failed";
|
|
8
|
+
}
|
|
9
|
+
export function tenantOrganizationHint(tenant, pushEnabled) {
|
|
10
|
+
if (!isPresent(tenant.slug)) {
|
|
11
|
+
return "This name carries no character the identity provider accepts, so no organization can be created there for it.";
|
|
12
|
+
}
|
|
13
|
+
if (isPresent(tenant.mirroredBy)) {
|
|
14
|
+
return `The identity provider's "${tenant.slug}" already belongs to "${tenant.mirroredBy}", so this organization can't be linked to it — choose another name.`;
|
|
15
|
+
}
|
|
16
|
+
if (pushEnabled) {
|
|
17
|
+
return tenant.exists
|
|
18
|
+
? `The identity provider already has "${tenant.slug}" — creating this organization links to it rather than creating another.`
|
|
19
|
+
: `The identity provider has no "${tenant.slug}" yet; creating this organization creates it there too.`;
|
|
20
|
+
}
|
|
21
|
+
return tenant.exists
|
|
22
|
+
? `The identity provider already has "${tenant.slug}" — once this organization exists, "Link to identity provider" reuses it.`
|
|
23
|
+
: `The identity provider has no "${tenant.slug}" yet; once this organization exists, "Link to identity provider" creates it.`;
|
|
24
|
+
}
|
|
25
|
+
export function tenantOrganizationCheck(tenant, pushEnabled) {
|
|
26
|
+
if (!tenant)
|
|
27
|
+
return { blocked: false };
|
|
28
|
+
return { hint: tenantOrganizationHint(tenant, pushEnabled), blocked: isPresent(tenant.mirroredBy) };
|
|
29
|
+
}
|
|
30
|
+
export function toastProviderWarning(providerWarning) {
|
|
31
|
+
if (!isPresent(providerWarning))
|
|
32
|
+
return;
|
|
33
|
+
toast.warning("The organization isn't linked to the identity provider", { description: providerWarning });
|
|
34
|
+
}
|
|
@@ -7,6 +7,7 @@ import type { ProviderPresentation } from "#routes/integrations/types";
|
|
|
7
7
|
export type ProviderSetupInstructions = Readonly<{
|
|
8
8
|
identifier?: FieldInstruction;
|
|
9
9
|
apiKey?: FieldInstruction;
|
|
10
|
+
settings?: FieldInstruction;
|
|
10
11
|
}>;
|
|
11
12
|
export type InferalConnectFormConfig = {
|
|
12
13
|
setupInstructions?: ProviderSetupInstructions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,MAAM,CAAC,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/routes/integrations/components/connect-forms/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG;IACrC,iBAAiB,CAAC,EAAE,yBAAyB,CAAC;IAC9C,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,UAAU,CAAC,MAAM,SAAS,WAAW,IAAI;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;IACrB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC;CACpD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Status } from "./components/StatusChip.js";
|
|
2
|
-
import type { ProviderConnection } from "./types.js";
|
|
2
|
+
import type { OAuthConnection, ProviderConnection } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* The display projection of a `ProviderConnection`. It retains the source only so
|
|
5
5
|
* row-level actions can dispatch correctly; rendering otherwise uses normalized fields.
|
|
@@ -24,5 +24,8 @@ export type ConnectionView = {
|
|
|
24
24
|
syncedLabel?: string;
|
|
25
25
|
namedAccount?: NamedAccount;
|
|
26
26
|
};
|
|
27
|
+
export type GrantFacts = Pick<OAuthConnection, "revokedAt" | "grantExpiresAt">;
|
|
28
|
+
/** The accounts whose grant a person has to renew: revoked, expired, or inside the warning window. */
|
|
29
|
+
export declare function connectionProblems<T extends GrantFacts>(connections: readonly T[]): T[];
|
|
27
30
|
export declare function toConnectionView(connection: ProviderConnection): ConnectionView;
|
|
28
31
|
//# sourceMappingURL=connection-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-view.d.ts","sourceRoot":"","sources":["../../../src/routes/integrations/connection-view.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"connection-view.d.ts","sourceRoot":"","sources":["../../../src/routes/integrations/connection-view.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAsC,eAAe,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEvG;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAiDF,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,gBAAgB,CAAC,CAAC;AAY/E,sGAAsG;AACtG,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAEvF;AA8BD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,GAAG,cAAc,CAoB/E"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GQLGmailIntegrationStatus, GQLIntegration, GQLRelayIntegrationStatus } from "@manta-eu/client";
|
|
2
2
|
import { isPresent } from "@manta-eu/lib/present";
|
|
3
|
-
import { formatDistanceToNow } from "date-fns";
|
|
3
|
+
import { addDays, formatDistanceToNow, isAfter, isValid } from "date-fns";
|
|
4
4
|
import { match } from "ts-pattern";
|
|
5
5
|
// Fallback nouns shown until the ontology carries rdfs:labels for these classes (MNT-503).
|
|
6
6
|
// https://linear.app/manta-eu/issue/MNT-503/add-rdfslabel-to-provider-entity-classes-in-the-ontology
|
|
@@ -30,18 +30,50 @@ const statusMap = {
|
|
|
30
30
|
[GQLRelayIntegrationStatus.Deleted]: { label: "Deleted", tone: "neutral" },
|
|
31
31
|
};
|
|
32
32
|
const oauthConnectedStatus = { label: "Connected", tone: "success" };
|
|
33
|
+
const oauthRevokedStatus = { label: "Reconnect needed", tone: "error" };
|
|
34
|
+
const oauthExpiredStatus = { label: "Expired", tone: "error" };
|
|
35
|
+
const grantExpiryWarningDays = 14;
|
|
33
36
|
// Integrations whose account is limited to what was picked at connect time, so an empty pick reads nothing.
|
|
34
37
|
const oauthIncludedResourcesLabels = {
|
|
35
38
|
[GQLIntegration.Dash]: { label: "Folders", noneLabel: "No folders selected" },
|
|
36
39
|
};
|
|
37
|
-
function
|
|
40
|
+
function connectedLabel(connectedAt) {
|
|
41
|
+
if (!isPresent(connectedAt))
|
|
42
|
+
return undefined;
|
|
43
|
+
const connected = new Date(connectedAt);
|
|
44
|
+
if (!isValid(connected))
|
|
45
|
+
return undefined;
|
|
46
|
+
return `Connected ${formatDistanceToNow(connected, { addSuffix: true })}`;
|
|
47
|
+
}
|
|
48
|
+
function grantStatus({ revokedAt, grantExpiresAt }) {
|
|
49
|
+
if (isPresent(revokedAt))
|
|
50
|
+
return oauthRevokedStatus;
|
|
51
|
+
if (!isPresent(grantExpiresAt))
|
|
52
|
+
return undefined;
|
|
53
|
+
const expiresAt = new Date(grantExpiresAt);
|
|
54
|
+
const now = new Date();
|
|
55
|
+
if (!isValid(expiresAt) || isAfter(expiresAt, addDays(now, grantExpiryWarningDays)))
|
|
56
|
+
return undefined;
|
|
57
|
+
if (!isAfter(expiresAt, now))
|
|
58
|
+
return oauthExpiredStatus;
|
|
59
|
+
return { label: `Expires ${formatDistanceToNow(expiresAt, { addSuffix: true })}`, tone: "warning" };
|
|
60
|
+
}
|
|
61
|
+
/** The accounts whose grant a person has to renew: revoked, expired, or inside the warning window. */
|
|
62
|
+
export function connectionProblems(connections) {
|
|
63
|
+
return connections.filter((connection) => isPresent(grantStatus(connection)));
|
|
64
|
+
}
|
|
65
|
+
function oauthScope(connection) {
|
|
66
|
+
const { integration, includedResources } = connection;
|
|
67
|
+
const grant = grantStatus(connection);
|
|
68
|
+
const status = grant ?? oauthConnectedStatus;
|
|
38
69
|
const labels = oauthIncludedResourcesLabels[integration];
|
|
39
70
|
if (!labels || !includedResources)
|
|
40
|
-
return { status
|
|
41
|
-
if (!isPresent(includedResources))
|
|
42
|
-
return { status: { label: labels.noneLabel, tone: "warning" } };
|
|
71
|
+
return { status };
|
|
72
|
+
if (!isPresent(includedResources)) {
|
|
73
|
+
return { status: grant ?? { label: labels.noneLabel, tone: "warning" } };
|
|
74
|
+
}
|
|
43
75
|
return {
|
|
44
|
-
status
|
|
76
|
+
status,
|
|
45
77
|
secondaryLabel: `${labels.label}: ${includedResources.map(({ id, name }) => name ?? id).join(", ")}`,
|
|
46
78
|
};
|
|
47
79
|
}
|
|
@@ -67,6 +99,7 @@ export function toConnectionView(connection) {
|
|
|
67
99
|
id: c.id,
|
|
68
100
|
primaryLabel: isPresent(c.name) ? c.name : `${oauthAccountNoun[c.integration]} ${c.externalId}`,
|
|
69
101
|
...oauthScope(c),
|
|
102
|
+
syncedLabel: connectedLabel(c.connectedAt),
|
|
70
103
|
namedAccount: {
|
|
71
104
|
name: isPresent(c.name) ? c.name : oauthAccountNoun[c.integration],
|
|
72
105
|
noun: isPresent(c.name) ? oauthAccountNoun[c.integration] : undefined,
|
|
@@ -34,6 +34,9 @@ export type OAuthConnection = {
|
|
|
34
34
|
entityIri?: string;
|
|
35
35
|
typeIri?: string;
|
|
36
36
|
includedResources?: GQLIncludedResource[];
|
|
37
|
+
connectedAt?: string | null;
|
|
38
|
+
revokedAt?: string | null;
|
|
39
|
+
grantExpiresAt?: string | null;
|
|
37
40
|
};
|
|
38
41
|
export type GmailConnection = {
|
|
39
42
|
kind: "gmail";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/routes/integrations/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,EAC7B,cAAc,EACd,yBAAyB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,cAAc,SAAS,CAAC;AAErC,MAAM,MAAM,UAAU,GAClB,GAAG,6BAA6B,EAAE,GAClC,OAAO,eAAe,GACtB,OAAO,eAAe,GACtB,OAAO,cAAc,CAAC;AAC1B,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAC7D,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAE3E,MAAM,MAAM,oBAAoB,CAAC,EAAE,SAAS,MAAM,GAAG,UAAU,IAAI;IACjE,EAAE,EAAE,EAAE,CAAC;IACP,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,QAAQ,CAAC;IACrB,IAAI,EAAE,qBAAqB,CAAC;CAC7B,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,yBAAyB,CAAC;IAClC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC;AAEF,mGAAmG;AACnG,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,cAAc,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,mBAAmB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/routes/integrations/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,EAC7B,cAAc,EACd,yBAAyB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,cAAc,SAAS,CAAC;AAErC,MAAM,MAAM,UAAU,GAClB,GAAG,6BAA6B,EAAE,GAClC,OAAO,eAAe,GACtB,OAAO,eAAe,GACtB,OAAO,cAAc,CAAC;AAC1B,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAC7D,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAE3E,MAAM,MAAM,oBAAoB,CAAC,EAAE,SAAS,MAAM,GAAG,UAAU,IAAI;IACjE,EAAE,EAAE,EAAE,CAAC;IACP,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,QAAQ,CAAC;IACrB,IAAI,EAAE,qBAAqB,CAAC;CAC7B,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,yBAAyB,CAAC;IAClC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC;AAEF,mGAAmG;AACnG,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,cAAc,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,MAAM,EAAE,yBAAyB,CAAC;IAClC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEvF,MAAM,MAAM,iBAAiB,CAAC,EAAE,SAAS,MAAM,GAAG,UAAU,IAAI;IAC9D,EAAE,EAAE,EAAE,CAAC;IACP,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B,CAAC"}
|
|
@@ -3,7 +3,7 @@ export type ChangeScopeDialogProps = {
|
|
|
3
3
|
open: boolean;
|
|
4
4
|
onOpenChange: (open: boolean) => void;
|
|
5
5
|
memory: GQLMemory;
|
|
6
|
-
|
|
6
|
+
canManageSharedMemories?: boolean;
|
|
7
7
|
onSave: (newScope: GQLMemoryScope, newTeams: string[], supersedesMemoryIris: string[]) => Promise<void>;
|
|
8
8
|
isSaving: boolean;
|
|
9
9
|
currentUserId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChangeScopeDialog.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/ChangeScopeDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA6B,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAiB7F,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,SAAS,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"ChangeScopeDialog.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/ChangeScopeDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA6B,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAiB7F,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,SAAS,CAAC;IAClB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,MAAM,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxG,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAQF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,2CA6K9D"}
|
|
@@ -13,7 +13,7 @@ const scopeOptions = [
|
|
|
13
13
|
{ value: GQLMemoryScope.Team, label: "Team" },
|
|
14
14
|
];
|
|
15
15
|
export function ChangeScopeDialog(props) {
|
|
16
|
-
const { open, onOpenChange, memory,
|
|
16
|
+
const { open, onOpenChange, memory, canManageSharedMemories, onSave, isSaving, currentUserId } = props;
|
|
17
17
|
const [scope, setScope] = useState(memory.scope);
|
|
18
18
|
const [teams, setTeams] = useState(memory.teams);
|
|
19
19
|
const [pendingConflicts, setPendingConflicts] = useState([]);
|
|
@@ -75,10 +75,10 @@ export function ChangeScopeDialog(props) {
|
|
|
75
75
|
setPendingState(null);
|
|
76
76
|
}, []);
|
|
77
77
|
return (_jsxs(_Fragment, { children: [_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { text: "Change memory scope" }), _jsxs(DialogDescription, { children: ["Change the scope of \u201C", memory.label, "\u201D memory. All properties remain the same, but visibility changes."] })] }), _jsxs("div", { className: "flex flex-col gap-4 py-2", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("label", { className: "typography-small text-default-foreground", children: "Scope" }), _jsx("div", { className: "flex gap-2", children: scopeOptions
|
|
78
|
-
.filter(({ value }) => value !== GQLMemoryScope.Company ||
|
|
78
|
+
.filter(({ value }) => value !== GQLMemoryScope.Company || canManageSharedMemories)
|
|
79
79
|
.map(({ value, label }) => (_jsx("button", { type: "button", onClick: () => setScope(value), className: `px-3 py-1.5 rounded-lg typography-small-medium transition-colors ${scope === value
|
|
80
80
|
? "bg-primary text-primary-foreground"
|
|
81
|
-
: "bg-muted text-muted-foreground hover:bg-muted/80"}`, children: label }, value))) })] }), isTeam && _jsx(TeamPicker, { selected: teams, onChange: setTeams,
|
|
81
|
+
: "bg-muted text-muted-foreground hover:bg-muted/80"}`, children: label }, value))) })] }), isTeam && (_jsx(TeamPicker, { selected: teams, onChange: setTeams, canManageSharedMemories: canManageSharedMemories ?? false }))] }), _jsx(DialogFooter, { children: timedOut && pendingState ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "typography-small text-muted-foreground mr-auto", children: "Conflict check timed out. Move without checking?" }), _jsx(Button, { variant: "tertiary", onClick: () => {
|
|
82
82
|
setTimedOut(false);
|
|
83
83
|
setPendingState(null);
|
|
84
84
|
}, disabled: isSaving, children: "Cancel" }), _jsx(Button, { onClick: () => {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export type MemoriesEmptyStateProps = {
|
|
2
|
-
isOperator?: boolean;
|
|
3
2
|
onAdd: () => void;
|
|
4
3
|
};
|
|
5
4
|
export declare function MemoriesEmptyState(props: MemoriesEmptyStateProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,7 +9,7 @@ type CompanyMemoriesEmptyStateProps = {
|
|
|
10
9
|
export declare function CompanyMemoriesEmptyState(props: CompanyMemoriesEmptyStateProps): import("react/jsx-runtime").JSX.Element;
|
|
11
10
|
export declare function CapturedMemoriesEmptyState(): import("react/jsx-runtime").JSX.Element;
|
|
12
11
|
export type GroupMemoriesEmptyStateProps = {
|
|
13
|
-
|
|
12
|
+
canManageSharedMemories?: boolean;
|
|
14
13
|
onAdd?: () => void;
|
|
15
14
|
};
|
|
16
15
|
export declare function GroupMemoriesEmptyState(props: GroupMemoriesEmptyStateProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyStates.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/EmptyStates.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,uBAAuB,GAAG;IACpC,
|
|
1
|
+
{"version":3,"file":"EmptyStates.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/EmptyStates.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,2CAchE;AAED,KAAK,8BAA8B,GAAG;IACpC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,8BAA8B,2CAmB9E;AAED,wBAAgB,0BAA0B,4CAYzC;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,2CAoB1E"}
|
|
@@ -15,8 +15,8 @@ export function CapturedMemoriesEmptyState() {
|
|
|
15
15
|
return (_jsx(EmptyState, { icon: MessageSquare, title: "No captured memories yet", description: "Manta captures useful context from your conversations automatically. Start chatting and memories will appear here.", children: _jsx(Button, { asChild: true, children: _jsx(Link, { to: "/", children: "Start chatting" }) }) }));
|
|
16
16
|
}
|
|
17
17
|
export function GroupMemoriesEmptyState(props) {
|
|
18
|
-
const {
|
|
19
|
-
return (_jsx(EmptyState, { icon: Users, title: "No team memories yet", description:
|
|
18
|
+
const { canManageSharedMemories, onAdd } = props;
|
|
19
|
+
return (_jsx(EmptyState, { icon: Users, title: "No team memories yet", description: canManageSharedMemories
|
|
20
20
|
? "Add shared context that Manta uses for specific teams in the company."
|
|
21
21
|
: "Your team hasn't added any shared memories yet.", children: onAdd && (_jsx(Button, { onClick: onAdd, icon: Plus, children: "Add team memory" })) }));
|
|
22
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoriesPanel.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/MemoriesPanel.tsx"],"names":[],"mappings":"AA4BA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,
|
|
1
|
+
{"version":3,"file":"MemoriesPanel.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/MemoriesPanel.tsx"],"names":[],"mappings":"AA4BA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CA2KtD"}
|
|
@@ -17,7 +17,7 @@ import { Dropdown, DropdownContent, DropdownGroup, DropdownItem, DropdownTrigger
|
|
|
17
17
|
import { Skeleton } from "#components/skeleton/index";
|
|
18
18
|
import { useMantaClient } from "#providers/index";
|
|
19
19
|
export function MemoriesPanel(props) {
|
|
20
|
-
const {
|
|
20
|
+
const { canManageSharedMemories, onClose } = props;
|
|
21
21
|
const { mantaClient } = useMantaClient();
|
|
22
22
|
const queryClient = useQueryClient();
|
|
23
23
|
const { data, isLoading, error: queryError } = useMemoriesQuery(mantaClient);
|
|
@@ -36,7 +36,7 @@ export function MemoriesPanel(props) {
|
|
|
36
36
|
const handleCreate = useCallback(async (form, supersedesMemoryIris) => {
|
|
37
37
|
if (!addDialog)
|
|
38
38
|
return;
|
|
39
|
-
if (!
|
|
39
|
+
if (!canManageSharedMemories && addDialog.scope !== GQLMemoryScope.User)
|
|
40
40
|
return;
|
|
41
41
|
try {
|
|
42
42
|
const result = await createMutation.mutateAsync({
|
|
@@ -52,11 +52,11 @@ export function MemoriesPanel(props) {
|
|
|
52
52
|
const err = parseError(e, "Failed to add memory");
|
|
53
53
|
toast.error(err.message, { description: err.description });
|
|
54
54
|
}
|
|
55
|
-
}, [addDialog, createMutation, invalidate,
|
|
55
|
+
}, [addDialog, createMutation, invalidate, canManageSharedMemories]);
|
|
56
56
|
const handleUpdate = useCallback(async (form, supersedesMemoryIris) => {
|
|
57
57
|
if (!editingMemory)
|
|
58
58
|
return;
|
|
59
|
-
if (!
|
|
59
|
+
if (!canManageSharedMemories && editingMemory.scope !== GQLMemoryScope.User)
|
|
60
60
|
return;
|
|
61
61
|
try {
|
|
62
62
|
const result = await updateMutation.mutateAsync({
|
|
@@ -72,7 +72,7 @@ export function MemoriesPanel(props) {
|
|
|
72
72
|
const err = parseError(e, "Failed to update memory");
|
|
73
73
|
toast.error(err.message, { description: err.description });
|
|
74
74
|
}
|
|
75
|
-
}, [editingMemory, updateMutation, invalidate,
|
|
75
|
+
}, [editingMemory, updateMutation, invalidate, canManageSharedMemories]);
|
|
76
76
|
const handleDelete = useCallback(async (iri) => {
|
|
77
77
|
try {
|
|
78
78
|
await deleteMutation.mutateAsync({ memoryIri: iri });
|
|
@@ -84,7 +84,7 @@ export function MemoriesPanel(props) {
|
|
|
84
84
|
toast.error(err.message, { description: err.description });
|
|
85
85
|
}
|
|
86
86
|
}, [deleteMutation, invalidate]);
|
|
87
|
-
return (_jsxs("div", { className: "flex flex-col h-full", children: [_jsxs("div", { className: "shrink-0 flex items-center justify-between gap-2 px-4 py-3 border-b border-muted-border", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Brain, { className: "size-4 text-muted-foreground" }), _jsx("span", { className: "typography-small-medium text-default-foreground", children: "Memories" })] }), _jsxs("div", { className: "flex items-center gap-1", children: [
|
|
87
|
+
return (_jsxs("div", { className: "flex flex-col h-full", children: [_jsxs("div", { className: "shrink-0 flex items-center justify-between gap-2 px-4 py-3 border-b border-muted-border", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Brain, { className: "size-4 text-muted-foreground" }), _jsx("span", { className: "typography-small-medium text-default-foreground", children: "Memories" })] }), _jsxs("div", { className: "flex items-center gap-1", children: [canManageSharedMemories && (_jsx(Button, { variant: "ghost", size: "sm", icon: Building2, onClick: () => setAddDialog({ scope: GQLMemoryScope.Company }), children: "Add org" })), _jsx(Button, { size: "sm", icon: Plus, onClick: () => setAddDialog({ scope: GQLMemoryScope.User }), children: "Add" }), _jsx(Button, { variant: "ghost", size: "sm", iconOnly: true, icon: X, "aria-label": "Close memories panel", onClick: onClose })] })] }), _jsxs("div", { className: "flex-1 overflow-auto", children: [isLoading && (_jsx("ul", { className: "divide-y divide-muted-border", children: Array.from({ length: 4 }, (_, i) => (_jsxs("li", { className: "flex items-start gap-3 px-4 py-3", children: [_jsxs("div", { className: "flex-1 min-w-0 flex flex-col gap-1.5", children: [_jsx(Skeleton, { className: "h-4 w-2/3 rounded-md" }), _jsx(Skeleton, { className: "h-3.5 w-full rounded-md" })] }), _jsxs("div", { className: "shrink-0 flex items-center gap-2 pt-0.5", children: [_jsx(Skeleton, { className: "h-5 w-14 rounded-full" }), _jsx(Skeleton, { className: "size-7 rounded-md" })] })] }, `panel-skeleton-${i}`))) })), errorMessage && _jsx(Banner, { label: errorMessage, className: "m-4" }), !isLoading && !errorMessage && !isPresent(memories) && (_jsxs("div", { className: "flex flex-col items-center justify-center gap-3 p-8 text-center", children: [_jsx(Brain, { className: "size-8 text-muted-foreground" }), _jsx("p", { className: "typography-small text-muted-foreground", children: "No memories yet. Add something Manta should always keep in mind." })] })), !isLoading && isPresent(memories) && (_jsx("ul", { className: "divide-y divide-muted-border", children: memories.map((memory) => (_jsx(MemoryListItem, { memory: memory, canManageSharedMemories: canManageSharedMemories, onEdit: () => setEditingMemory(memory), onDelete: () => void handleDelete(memory.iri) }, memory.iri))) }))] }), addDialog && (_jsx(MemoryFormDialog, { open: true, onOpenChange: (open) => {
|
|
88
88
|
if (!open)
|
|
89
89
|
setAddDialog(null);
|
|
90
90
|
}, scope: addDialog.scope, onSave: handleCreate, isSaving: createMutation.isPending })), editingMemory && (_jsx(MemoryFormDialog, { open: true, onOpenChange: (open) => {
|
|
@@ -93,7 +93,7 @@ export function MemoriesPanel(props) {
|
|
|
93
93
|
}, scope: editingMemory.scope, initial: editingMemory, onSave: handleUpdate, isSaving: updateMutation.isPending }))] }));
|
|
94
94
|
}
|
|
95
95
|
function MemoryListItem(props) {
|
|
96
|
-
const { memory,
|
|
97
|
-
const canEdit = memory.scope !== GQLMemoryScope.Company ||
|
|
98
|
-
return (_jsxs("li", { className: "flex items-start gap-3 px-4 py-3", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "typography-caption-medium text-default-foreground truncate", children: memory.label }), _jsx("p", { className: "typography-small text-muted-foreground line-clamp-2 mt-0.5", children: memory.description })] }), _jsxs("div", { className: "shrink-0 flex items-center gap-2 pt-0.5", children: [
|
|
96
|
+
const { memory, canManageSharedMemories, onEdit, onDelete } = props;
|
|
97
|
+
const canEdit = memory.scope !== GQLMemoryScope.Company || canManageSharedMemories;
|
|
98
|
+
return (_jsxs("li", { className: "flex items-start gap-3 px-4 py-3", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "typography-caption-medium text-default-foreground truncate", children: memory.label }), _jsx("p", { className: "typography-small text-muted-foreground line-clamp-2 mt-0.5", children: memory.description })] }), _jsxs("div", { className: "shrink-0 flex items-center gap-2 pt-0.5", children: [canManageSharedMemories && _jsx(ScopeBadge, { scope: memory.scope }), _jsx(KindBadge, { kind: memory.kind }), canEdit && (_jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { asChild: true, children: _jsx(Button, { variant: "tertiary", size: "sm", iconOnly: true, icon: EllipsisIcon, "aria-label": "Memory actions" }) }), _jsx(DropdownContent, { align: "end", className: "z-60", children: _jsxs(DropdownGroup, { children: [_jsxs(DropdownItem, { onSelect: onEdit, children: [_jsx(Pencil, { size: 16 }), "Edit"] }), _jsxs(DropdownItem, { onSelect: onDelete, children: [_jsx(Trash2, { size: 16, className: "text-error-foreground" }), "Delete"] })] }) })] }))] })] }));
|
|
99
99
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type GQLMemory } from "@manta-eu/client";
|
|
2
2
|
export type MemoryActionsProps = {
|
|
3
3
|
memory: GQLMemory;
|
|
4
|
-
|
|
4
|
+
canManageSharedMemories?: boolean;
|
|
5
5
|
onEdit: (memory: GQLMemory) => void;
|
|
6
6
|
onDelete: (iri: string) => void;
|
|
7
7
|
onMove?: (memory: GQLMemory) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryActions.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/MemoryActions.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAkBlE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"MemoryActions.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/MemoryActions.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAkBlE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IACpC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,kDAsEtD"}
|
|
@@ -8,17 +8,17 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
|
|
|
8
8
|
import { Button } from "#components/button/index";
|
|
9
9
|
import { Dropdown, DropdownContent, DropdownGroup, DropdownItem, DropdownTrigger } from "#components/dropdown/index";
|
|
10
10
|
export function MemoryActions(props) {
|
|
11
|
-
const { memory,
|
|
11
|
+
const { memory, canManageSharedMemories, onEdit, onDelete, onMove, onRestore, onReconfirm } = props;
|
|
12
12
|
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
13
13
|
const isRealm = memory.scope === GQLMemoryScope.Company;
|
|
14
14
|
if (isPresent(memory.supersededBy)) {
|
|
15
|
-
const canRestore =
|
|
15
|
+
const canRestore = canManageSharedMemories || memory.scope === GQLMemoryScope.User;
|
|
16
16
|
if (!canRestore)
|
|
17
17
|
return null;
|
|
18
18
|
return (_jsx("div", { className: "text-right", onClick: (e) => e.stopPropagation(), children: _jsxs(Button, { variant: "tertiary", size: "sm", rounded: "lg", onClick: () => onRestore?.(memory.iri), className: "gap-1.5", children: [_jsx(Undo2, { size: 14 }), "Restore"] }) }));
|
|
19
19
|
}
|
|
20
|
-
if (!isRealm ||
|
|
21
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-right", onClick: (e) => e.stopPropagation(), children: _jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { asChild: true, children: _jsx(Button, { variant: "tertiary", iconOnly: true, icon: EllipsisIcon, "aria-label": "Actions" }) }), _jsx(DropdownContent, { align: "end", className: "z-60 w-44", children: _jsxs(DropdownGroup, { children: [_jsxs(DropdownItem, { onSelect: () => onEdit(memory), children: [_jsx(Pencil, { size: 16 }), "Edit"] }), onReconfirm && needsTrustReview(memory) && (_jsxs(DropdownItem, { onSelect: () => onReconfirm(memory.iri), children: [_jsx(BadgeCheck, { size: 16 }), "Reconfirm"] })), onMove &&
|
|
20
|
+
if (!isRealm || canManageSharedMemories) {
|
|
21
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-right", onClick: (e) => e.stopPropagation(), children: _jsxs(Dropdown, { children: [_jsx(DropdownTrigger, { asChild: true, children: _jsx(Button, { variant: "tertiary", iconOnly: true, icon: EllipsisIcon, "aria-label": "Actions" }) }), _jsx(DropdownContent, { align: "end", className: "z-60 w-44", children: _jsxs(DropdownGroup, { children: [_jsxs(DropdownItem, { onSelect: () => onEdit(memory), children: [_jsx(Pencil, { size: 16 }), "Edit"] }), onReconfirm && needsTrustReview(memory) && (_jsxs(DropdownItem, { onSelect: () => onReconfirm(memory.iri), children: [_jsx(BadgeCheck, { size: 16 }), "Reconfirm"] })), onMove && canManageSharedMemories && (_jsxs(DropdownItem, { onSelect: () => onMove(memory), children: [_jsx(MoveRight, { size: 16 }), "Move to\u2026"] })), _jsxs(DropdownItem, { onSelect: () => setConfirmOpen(true), children: [_jsx(Trash2, { size: 16, className: "text-error-foreground" }), "Delete"] })] }) })] }) }), _jsx(AlertDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete memory?" }), _jsxs(AlertDialogDescription, { children: ["\"", memory.label, "\" will be permanently deleted."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", onClick: () => onDelete(memory.iri), children: "Delete" })] })] }) })] }));
|
|
22
22
|
}
|
|
23
23
|
return null;
|
|
24
24
|
}
|
|
@@ -17,7 +17,7 @@ export type MemoryFieldsProps = {
|
|
|
17
17
|
form: MemoryFormState;
|
|
18
18
|
errors: FormErrors;
|
|
19
19
|
isTeam: boolean;
|
|
20
|
-
|
|
20
|
+
canManageSharedMemories?: boolean;
|
|
21
21
|
schemas?: GQLMemorySchema[];
|
|
22
22
|
onChange: (next: Partial<MemoryFormState>) => void;
|
|
23
23
|
descriptionPlaceholder?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryFields.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/MemoryFields.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAIvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAwBvC,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,aAAa,GAAG,OAAO,GAAG,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC;AAE3G,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAUvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,
|
|
1
|
+
{"version":3,"file":"MemoryFields.d.ts","sourceRoot":"","sources":["../../../../src/routes/memories/components/MemoryFields.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAIvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAwBvC,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,aAAa,GAAG,OAAO,GAAG,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC;AAE3G,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAUvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IACnD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CAyHpD"}
|
|
@@ -22,9 +22,9 @@ export const emptyForm = {
|
|
|
22
22
|
importance: 3,
|
|
23
23
|
};
|
|
24
24
|
export function MemoryFields(props) {
|
|
25
|
-
const { form, errors, isTeam,
|
|
25
|
+
const { form, errors, isTeam, canManageSharedMemories = false, schemas, onChange, descriptionPlaceholder, labelPlaceholder, autoFocus = false, onEditProperties, filledPropertyCount = 0, totalPropertyCount = 0, children, } = props;
|
|
26
26
|
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("label", { className: "typography-small", children: "Importance" }), _jsx(ImportanceSlider, { value: form.importance, onChange: (v) => onChange({ importance: v }) })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("label", { className: "typography-small", children: "Kind" }), _jsxs(Select, { value: form.kind, onValueChange: (v) => onChange({ kind: v }), children: [_jsx(SelectTrigger, { label: "Kind", id: "memory-kind", hiddenLabel: true, children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: GQLMemoryKind.Preference, children: "Preference" }), _jsx(SelectItem, { value: GQLMemoryKind.Fact, children: "Fact" }), _jsx(SelectItem, { value: GQLMemoryKind.Objective, children: "Objective" }), _jsx(SelectItem, { value: GQLMemoryKind.Context, children: "Context" })] })] })] }), isPresent(schemas) && (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("label", { className: "typography-small", children: "Schema" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Combobox, { children: [_jsx(ComboboxTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: cn(createSelectClassName({ size: "base" }), "flex-1 min-w-0"), children: [_jsx("span", { className: cn("flex-1 min-w-0 truncate text-left", !form.memorySubclass && "text-placeholder-foreground"), children: form.memorySubclass
|
|
27
27
|
? (schemas.find((s) => s.iri === form.memorySubclass)?.label ??
|
|
28
28
|
formatEntityName(form.memorySubclass))
|
|
29
|
-
: "Default" }), _jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground" })] }) }), _jsxs(ComboboxContent, { align: "start", className: "w-[var(--radix-popover-trigger-width,320px)]", children: [_jsx(ComboboxInput, { placeholder: "Search schemas\u2026" }), _jsxs(ComboboxList, { children: [_jsx(ComboboxEmpty, { children: "No schemas found" }), _jsx(ComboboxItem, { value: "none", selected: form.memorySubclass === null, onSelect: () => onChange({ memorySubclass: null, customProperties: {} }), children: "Default" }), schemas.map((schema) => (_jsx(ComboboxItem, { value: schema.label, selected: form.memorySubclass === schema.iri, onSelect: () => onChange({ memorySubclass: schema.iri, customProperties: {} }), children: schema.label }, schema.iri)))] })] })] }), onEditProperties && totalPropertyCount > 0 && (_jsxs(Button, { type: "button", variant: "tertiary", size: "base", onClick: onEditProperties, className: "shrink-0", children: [filledPropertyCount > 0 ? `${filledPropertyCount}/${totalPropertyCount} filled` : "Edit properties", _jsx(ChevronRight, { className: "size-3.5" })] }))] })] })), _jsx(Input, { id: "memory-label", label: "Label", placeholder: labelPlaceholder, value: form.label, onChange: (e) => onChange({ label: e.target.value }), error: errors.label }), _jsx(Textarea, { id: "memory-description", label: "Description", placeholder: descriptionPlaceholder, value: form.description ?? "", onChange: (e) => onChange({ description: e.target.value }), minRows: 3, maxRows: 8, autoFocus: autoFocus, error: errors.description }), children, isTeam && (_jsx(TeamPicker, { selected: form.teams, onChange: (teams) => onChange({ teams }),
|
|
29
|
+
: "Default" }), _jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground" })] }) }), _jsxs(ComboboxContent, { align: "start", className: "w-[var(--radix-popover-trigger-width,320px)]", children: [_jsx(ComboboxInput, { placeholder: "Search schemas\u2026" }), _jsxs(ComboboxList, { children: [_jsx(ComboboxEmpty, { children: "No schemas found" }), _jsx(ComboboxItem, { value: "none", selected: form.memorySubclass === null, onSelect: () => onChange({ memorySubclass: null, customProperties: {} }), children: "Default" }), schemas.map((schema) => (_jsx(ComboboxItem, { value: schema.label, selected: form.memorySubclass === schema.iri, onSelect: () => onChange({ memorySubclass: schema.iri, customProperties: {} }), children: schema.label }, schema.iri)))] })] })] }), onEditProperties && totalPropertyCount > 0 && (_jsxs(Button, { type: "button", variant: "tertiary", size: "base", onClick: onEditProperties, className: "shrink-0", children: [filledPropertyCount > 0 ? `${filledPropertyCount}/${totalPropertyCount} filled` : "Edit properties", _jsx(ChevronRight, { className: "size-3.5" })] }))] })] })), _jsx(Input, { id: "memory-label", label: "Label", placeholder: labelPlaceholder, value: form.label, onChange: (e) => onChange({ label: e.target.value }), error: errors.label }), _jsx(Textarea, { id: "memory-description", label: "Description", placeholder: descriptionPlaceholder, value: form.description ?? "", onChange: (e) => onChange({ description: e.target.value }), minRows: 3, maxRows: 8, autoFocus: autoFocus, error: errors.description }), children, isTeam && (_jsx(TeamPicker, { selected: form.teams, onChange: (teams) => onChange({ teams }), canManageSharedMemories: canManageSharedMemories, error: errors.teams }))] }));
|
|
30
30
|
}
|