@manta-eu/react 0.1.10 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/channel-icon/index.d.ts +1 -0
- package/dist/components/channel-icon/index.d.ts.map +1 -1
- package/dist/components/channel-icon/index.js +1 -1
- package/dist/components/channel-icon/index.js.map +1 -1
- package/dist/components/chat-view/ChatTurnErrorNotice.d.ts.map +1 -1
- package/dist/components/chat-view/ChatTurnErrorNotice.js +3 -1
- package/dist/components/chat-view/ChatTurnErrorNotice.js.map +1 -1
- package/dist/components/layouts/ConnectedCustomApp.d.ts +13 -0
- package/dist/components/layouts/ConnectedCustomApp.d.ts.map +1 -0
- package/dist/components/layouts/ConnectedCustomApp.js +37 -0
- package/dist/components/layouts/ConnectedCustomApp.js.map +1 -0
- package/dist/components/layouts/Sidebar.d.ts.map +1 -1
- package/dist/components/layouts/Sidebar.js +6 -3
- package/dist/components/layouts/Sidebar.js.map +1 -1
- package/dist/components/planning/ActioningView.d.ts +1 -2
- package/dist/components/planning/ActioningView.d.ts.map +1 -1
- package/dist/components/planning/ActioningView.js +19 -44
- package/dist/components/planning/ActioningView.js.map +1 -1
- package/dist/components/planning/ManualActionCard.d.ts +4 -0
- package/dist/components/planning/ManualActionCard.d.ts.map +1 -1
- package/dist/components/planning/ManualActionCard.js +7 -5
- package/dist/components/planning/ManualActionCard.js.map +1 -1
- package/dist/components/planning/ManualActionList.d.ts +4 -0
- package/dist/components/planning/ManualActionList.d.ts.map +1 -1
- package/dist/components/planning/ManualActionList.js +8 -2
- package/dist/components/planning/ManualActionList.js.map +1 -1
- package/dist/components/planning/actioning-view-utils.d.ts +9 -0
- package/dist/components/planning/actioning-view-utils.d.ts.map +1 -1
- package/dist/components/planning/actioning-view-utils.js +19 -1
- package/dist/components/planning/actioning-view-utils.js.map +1 -1
- package/dist/components/table-skeleton/index.d.ts +2 -0
- package/dist/components/table-skeleton/index.d.ts.map +1 -1
- package/dist/components/table-skeleton/index.js +2 -1
- package/dist/components/table-skeleton/index.js.map +1 -1
- package/dist/components/tooltip/index.d.ts +7 -0
- package/dist/components/tooltip/index.d.ts.map +1 -1
- package/dist/components/tooltip/index.js +10 -1
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/globals.css +19 -6
- package/dist/graph/createNodeRouter.js +3 -3
- package/dist/graph/createNodeRouter.js.map +1 -1
- package/dist/graph/entity-link.d.ts +14 -0
- package/dist/graph/entity-link.d.ts.map +1 -0
- package/dist/graph/entity-link.js +12 -0
- package/dist/graph/entity-link.js.map +1 -0
- package/dist/graph/graph-list-utils.d.ts +1 -0
- package/dist/graph/graph-list-utils.d.ts.map +1 -1
- package/dist/graph/graph-list-utils.js +1 -0
- package/dist/graph/graph-list-utils.js.map +1 -1
- package/dist/graph/graph-model.d.ts.map +1 -1
- package/dist/graph/graph-model.js +14 -5
- package/dist/graph/graph-model.js.map +1 -1
- package/dist/graph/nodes/BrandAssetAnalysisView.d.ts.map +1 -1
- package/dist/graph/nodes/BrandAssetAnalysisView.js +2 -1
- package/dist/graph/nodes/BrandAssetAnalysisView.js.map +1 -1
- package/dist/graph/nodes/BrandFontSuggestionView.d.ts +3 -0
- package/dist/graph/nodes/BrandFontSuggestionView.d.ts.map +1 -0
- package/dist/graph/nodes/{BrandFontFamilyView.js → BrandFontSuggestionView.js} +22 -13
- package/dist/graph/nodes/BrandFontSuggestionView.js.map +1 -0
- package/dist/graph/nodes/BrandGuidelinesView.js +1 -1
- package/dist/graph/nodes/BrandGuidelinesView.js.map +1 -1
- package/dist/graph/nodes/NodePropertyTable.d.ts +4 -2
- package/dist/graph/nodes/NodePropertyTable.d.ts.map +1 -1
- package/dist/graph/nodes/NodePropertyTable.js +12 -59
- package/dist/graph/nodes/NodePropertyTable.js.map +1 -1
- package/dist/graph/nodes/brand-font.d.ts +8 -0
- package/dist/graph/nodes/brand-font.d.ts.map +1 -1
- package/dist/graph/nodes/brand-font.js +6 -0
- package/dist/graph/nodes/brand-font.js.map +1 -1
- package/dist/graph/nodes/brand-shared.d.ts +0 -3
- package/dist/graph/nodes/brand-shared.d.ts.map +1 -1
- package/dist/graph/nodes/brand-shared.js +1 -4
- package/dist/graph/nodes/brand-shared.js.map +1 -1
- package/dist/graph/nodes/node-property-row.d.ts +30 -0
- package/dist/graph/nodes/node-property-row.d.ts.map +1 -0
- package/dist/graph/nodes/node-property-row.js +35 -0
- package/dist/graph/nodes/node-property-row.js.map +1 -0
- package/dist/graph/property-formatters.d.ts +1 -0
- package/dist/graph/property-formatters.d.ts.map +1 -1
- package/dist/graph/property-formatters.js +4 -1
- package/dist/graph/property-formatters.js.map +1 -1
- package/dist/graph/special-nodes/AttributeList.d.ts +27 -0
- package/dist/graph/special-nodes/AttributeList.d.ts.map +1 -0
- package/dist/graph/special-nodes/AttributeList.js +57 -0
- package/dist/graph/special-nodes/AttributeList.js.map +1 -0
- package/dist/graph/special-nodes/EntityPreview.d.ts +5 -0
- package/dist/graph/special-nodes/EntityPreview.d.ts.map +1 -0
- package/dist/graph/special-nodes/EntityPreview.js +19 -0
- package/dist/graph/special-nodes/EntityPreview.js.map +1 -0
- package/dist/graph/special-nodes/EntityValueChip.d.ts +11 -0
- package/dist/graph/special-nodes/EntityValueChip.d.ts.map +1 -0
- package/dist/graph/special-nodes/EntityValueChip.js +40 -0
- package/dist/graph/special-nodes/EntityValueChip.js.map +1 -0
- package/dist/graph/special-nodes/GenericView.d.ts +2 -1
- package/dist/graph/special-nodes/GenericView.d.ts.map +1 -1
- package/dist/graph/special-nodes/GenericView.js +23 -69
- package/dist/graph/special-nodes/GenericView.js.map +1 -1
- package/dist/graph/special-nodes/card-facts.d.ts +52 -0
- package/dist/graph/special-nodes/card-facts.d.ts.map +1 -0
- package/dist/graph/special-nodes/card-facts.js +189 -0
- package/dist/graph/special-nodes/card-facts.js.map +1 -0
- package/dist/graph/special-nodes/property-icons.d.ts +9 -0
- package/dist/graph/special-nodes/property-icons.d.ts.map +1 -0
- package/dist/graph/special-nodes/property-icons.js +39 -0
- package/dist/graph/special-nodes/property-icons.js.map +1 -0
- package/dist/graph/status-utils.d.ts +16 -0
- package/dist/graph/status-utils.d.ts.map +1 -1
- package/dist/graph/status-utils.js +35 -0
- package/dist/graph/status-utils.js.map +1 -1
- package/dist/graph/types.d.ts +5 -0
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/hooks/use-approve-anyway.d.ts +12 -0
- package/dist/hooks/use-approve-anyway.d.ts.map +1 -0
- package/dist/hooks/use-approve-anyway.js +81 -0
- package/dist/hooks/use-approve-anyway.js.map +1 -0
- package/dist/hooks/use-connection-problems.d.ts.map +1 -1
- package/dist/hooks/useAuth.d.ts +2 -2
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +2 -2
- package/dist/hooks/useAuth.js.map +1 -1
- package/dist/hooks/useOnboardingState.js +1 -1
- package/dist/hooks/useOnboardingState.js.map +1 -1
- package/dist/hooks/useValidateActionPlan.d.ts.map +1 -1
- package/dist/ldo-ui.d.ts +2 -1
- package/dist/ldo-ui.d.ts.map +1 -1
- package/dist/ldo-ui.js +1 -0
- package/dist/ldo-ui.js.map +1 -1
- package/dist/lib/datastore-route-table.d.ts +2 -1
- package/dist/lib/datastore-route-table.d.ts.map +1 -1
- package/dist/lib/datastore-route-table.js +2 -1
- package/dist/lib/datastore-route-table.js.map +1 -1
- package/dist/lib/manual-actions.d.ts +2 -1
- package/dist/lib/manual-actions.d.ts.map +1 -1
- package/dist/lib/manual-actions.js +3 -2
- package/dist/lib/manual-actions.js.map +1 -1
- package/dist/providers/ActiveChatProvider.js +3 -1
- package/dist/providers/ActiveChatProvider.js.map +1 -1
- package/dist/providers/AuthContext.d.ts +2 -1
- package/dist/providers/AuthContext.d.ts.map +1 -1
- package/dist/providers/AuthContext.js.map +1 -1
- package/dist/providers/ChatManagerProvider.d.ts.map +1 -1
- package/dist/providers/ChatManagerProvider.js +22 -9
- package/dist/providers/ChatManagerProvider.js.map +1 -1
- package/dist/providers/chat-socket-auth.d.ts +7 -2
- package/dist/providers/chat-socket-auth.d.ts.map +1 -1
- package/dist/providers/chat-socket-auth.js +87 -16
- package/dist/providers/chat-socket-auth.js.map +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +8 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/routes/activity/detail/ActivityChanges.d.ts +2 -0
- package/dist/routes/activity/detail/ActivityChanges.d.ts.map +1 -1
- package/dist/routes/activity/detail/ActivityChanges.js +8 -7
- package/dist/routes/activity/detail/ActivityChanges.js.map +1 -1
- package/dist/routes/activity/detail/ActivityDetail.d.ts +1 -0
- package/dist/routes/activity/detail/ActivityDetail.d.ts.map +1 -1
- package/dist/routes/activity/detail/ActivityDetail.js +5 -4
- package/dist/routes/activity/detail/ActivityDetail.js.map +1 -1
- package/dist/routes/activity/detail/ActivityStepsRail.d.ts +1 -0
- package/dist/routes/activity/detail/ActivityStepsRail.d.ts.map +1 -1
- package/dist/routes/activity/detail/ActivityStepsRail.js +3 -2
- package/dist/routes/activity/detail/ActivityStepsRail.js.map +1 -1
- package/dist/routes/activity/detail/ActivityTimeline.js +2 -2
- package/dist/routes/activity/detail/ActivityTimeline.js.map +1 -1
- package/dist/routes/activity/detail/NoChangesMessage.d.ts +6 -0
- package/dist/routes/activity/detail/NoChangesMessage.d.ts.map +1 -0
- package/dist/routes/activity/detail/NoChangesMessage.js +10 -0
- package/dist/routes/activity/detail/NoChangesMessage.js.map +1 -0
- package/dist/routes/data-explorer/components/RawTriples.js +1 -1
- package/dist/routes/data-explorer/components/RawTriples.js.map +1 -1
- package/dist/routes/data-explorer/components/RecentTypes.js +1 -1
- package/dist/routes/data-explorer/components/RecentTypes.js.map +1 -1
- package/dist/routes/data-explorer/components/class-detail/Instances.js +1 -1
- package/dist/routes/data-explorer/components/class-detail/Instances.js.map +1 -1
- package/dist/routes/data-explorer/components/namespace-detail/NamespaceClassRow.js +1 -1
- package/dist/routes/data-explorer/components/namespace-detail/NamespaceClassRow.js.map +1 -1
- package/dist/routes/data-explorer/components/ontology-coverage/CoverageTermColumns.js +1 -1
- package/dist/routes/data-explorer/components/ontology-coverage/CoverageTermColumns.js.map +1 -1
- package/dist/routes/data-explorer/components/ontology-coverage/UnobservedRuleVocabulary.js +1 -1
- package/dist/routes/data-explorer/components/ontology-coverage/UnobservedRuleVocabulary.js.map +1 -1
- package/dist/routes/data-explorer/components/record-detail/ChatPreview.js +2 -2
- package/dist/routes/data-explorer/components/record-detail/ChatPreview.js.map +1 -1
- package/dist/routes/data-explorer/declared-namespaces.d.ts +3 -0
- package/dist/routes/data-explorer/declared-namespaces.d.ts.map +1 -1
- package/dist/routes/data-explorer/declared-namespaces.js +21 -13
- package/dist/routes/data-explorer/declared-namespaces.js.map +1 -1
- package/dist/routes/data-explorer/namespaces.d.ts +1 -0
- package/dist/routes/data-explorer/namespaces.d.ts.map +1 -1
- package/dist/routes/data-explorer/namespaces.js +7 -6
- package/dist/routes/data-explorer/namespaces.js.map +1 -1
- package/dist/routes/datastores/components/DeleteDatastoreDialog.d.ts +10 -0
- package/dist/routes/datastores/components/DeleteDatastoreDialog.d.ts.map +1 -0
- package/dist/routes/datastores/components/DeleteDatastoreDialog.js +20 -0
- package/dist/routes/datastores/components/DeleteDatastoreDialog.js.map +1 -0
- package/dist/routes/datastores/flatten.d.ts +1 -0
- package/dist/routes/datastores/flatten.d.ts.map +1 -1
- package/dist/routes/datastores/flatten.js +17 -0
- package/dist/routes/datastores/flatten.js.map +1 -1
- package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts +3 -1
- package/dist/routes/datastores/hooks/useDatastoreColumns.d.ts.map +1 -1
- package/dist/routes/datastores/hooks/useDatastoreColumns.js +14 -6
- package/dist/routes/datastores/hooks/useDatastoreColumns.js.map +1 -1
- package/dist/routes/datastores/index.d.ts.map +1 -1
- package/dist/routes/datastores/index.js +31 -5
- package/dist/routes/datastores/index.js.map +1 -1
- package/dist/routes/integrations/components/ProviderGroup.js +2 -2
- package/dist/routes/integrations/components/ProviderGroup.js.map +1 -1
- package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.d.ts.map +1 -1
- package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.js +13 -6
- package/dist/routes/integrations/components/connect-forms/DataConnectionConnectForm.js.map +1 -1
- package/dist/routes/integrations/components/connect-forms/data-connection-fields.d.ts +3 -0
- package/dist/routes/integrations/components/connect-forms/data-connection-fields.d.ts.map +1 -1
- package/dist/routes/integrations/components/connect-forms/data-connection-fields.js +9 -2
- package/dist/routes/integrations/components/connect-forms/data-connection-fields.js.map +1 -1
- package/dist/routes/plans/components/ActionPlanPage.d.ts.map +1 -1
- package/dist/routes/plans/components/ActionPlanPage.js +4 -7
- package/dist/routes/plans/components/ActionPlanPage.js.map +1 -1
- package/dist/routes/plans/components/PlanDetailRouteContent.d.ts.map +1 -1
- package/dist/routes/plans/components/PlanDetailRouteContent.js +2 -1
- package/dist/routes/plans/components/PlanDetailRouteContent.js.map +1 -1
- package/package.json +12 -7
- package/src/app-subpaths.json +1 -0
- package/src/components/channel-icon/index.tsx +1 -1
- package/src/components/chat-view/ChatTurnErrorNotice.tsx +3 -1
- package/src/components/layouts/ConnectedCustomApp.tsx +63 -0
- package/src/components/layouts/Sidebar.tsx +9 -3
- package/src/components/planning/ActioningView.tsx +62 -70
- package/src/components/planning/ManualActionCard.tsx +66 -14
- package/src/components/planning/ManualActionList.tsx +30 -11
- package/src/components/planning/actioning-view-utils.ts +27 -1
- package/src/components/table-skeleton/index.tsx +7 -1
- package/src/components/tooltip/index.tsx +35 -2
- package/src/graph/createNodeRouter.tsx +3 -3
- package/src/graph/entity-link.tsx +20 -0
- package/src/graph/graph-list-utils.ts +2 -0
- package/src/graph/graph-model.ts +15 -6
- package/src/graph/nodes/BrandAssetAnalysisView.tsx +3 -1
- package/src/graph/nodes/{BrandFontFamilyView.tsx → BrandFontSuggestionView.tsx} +41 -27
- package/src/graph/nodes/BrandGuidelinesView.tsx +1 -1
- package/src/graph/nodes/NodePropertyTable.tsx +32 -143
- package/src/graph/nodes/brand-font.ts +17 -0
- package/src/graph/nodes/brand-shared.tsx +1 -4
- package/src/graph/nodes/node-property-row.tsx +154 -0
- package/src/graph/property-formatters.ts +5 -1
- package/src/graph/special-nodes/AttributeList.tsx +177 -0
- package/src/graph/special-nodes/EntityPreview.tsx +27 -0
- package/src/graph/special-nodes/EntityValueChip.tsx +85 -0
- package/src/graph/special-nodes/GenericView.tsx +49 -139
- package/src/graph/special-nodes/card-facts.ts +278 -0
- package/src/graph/special-nodes/property-icons.ts +59 -0
- package/src/graph/status-utils.ts +40 -0
- package/src/graph/types.ts +4 -0
- package/src/hooks/use-approve-anyway.ts +100 -0
- package/src/hooks/useAuth.ts +3 -3
- package/src/hooks/useOnboardingState.ts +1 -1
- package/src/ldo-ui.ts +8 -0
- package/src/lib/datastore-route-table.ts +4 -2
- package/src/lib/manual-actions.ts +3 -2
- package/src/providers/ActiveChatProvider.tsx +3 -1
- package/src/providers/AuthContext.ts +3 -1
- package/src/providers/ChatManagerProvider.tsx +19 -9
- package/src/providers/chat-socket-auth.ts +95 -16
- package/src/providers/index.tsx +16 -1
- package/src/routes/activity/detail/ActivityChanges.tsx +21 -5
- package/src/routes/activity/detail/ActivityDetail.tsx +24 -5
- package/src/routes/activity/detail/ActivityStepsRail.tsx +4 -2
- package/src/routes/activity/detail/ActivityTimeline.tsx +2 -2
- package/src/routes/activity/detail/NoChangesMessage.tsx +20 -0
- package/src/routes/data-explorer/components/RawTriples.tsx +1 -1
- package/src/routes/data-explorer/components/RecentTypes.tsx +1 -1
- package/src/routes/data-explorer/components/class-detail/Instances.tsx +1 -1
- package/src/routes/data-explorer/components/namespace-detail/NamespaceClassRow.tsx +1 -1
- package/src/routes/data-explorer/components/ontology-coverage/CoverageTermColumns.tsx +1 -1
- package/src/routes/data-explorer/components/ontology-coverage/UnobservedRuleVocabulary.tsx +1 -1
- package/src/routes/data-explorer/components/record-detail/ChatPreview.tsx +2 -2
- package/src/routes/data-explorer/declared-namespaces.ts +21 -13
- package/src/routes/data-explorer/namespaces.ts +7 -6
- package/src/routes/datastores/components/DeleteDatastoreDialog.tsx +78 -0
- package/src/routes/datastores/flatten.ts +15 -0
- package/src/routes/datastores/hooks/useDatastoreColumns.tsx +88 -49
- package/src/routes/datastores/index.tsx +41 -2
- package/src/routes/integrations/components/ProviderGroup.tsx +2 -2
- package/src/routes/integrations/components/connect-forms/DataConnectionConnectForm.tsx +38 -12
- package/src/routes/integrations/components/connect-forms/data-connection-fields.ts +11 -2
- package/src/routes/plans/components/ActionPlanPage.tsx +9 -8
- package/src/routes/plans/components/PlanDetailRouteContent.tsx +4 -3
- package/dist/components/planning/ExecutionActivityRow.d.ts +0 -9
- package/dist/components/planning/ExecutionActivityRow.d.ts.map +0 -1
- package/dist/components/planning/ExecutionActivityRow.js +0 -53
- package/dist/components/planning/ExecutionActivityRow.js.map +0 -1
- package/dist/components/planning/ExecutionSectionItem.d.ts +0 -20
- package/dist/components/planning/ExecutionSectionItem.d.ts.map +0 -1
- package/dist/components/planning/ExecutionSectionItem.js +0 -66
- package/dist/components/planning/ExecutionSectionItem.js.map +0 -1
- package/dist/components/planning/ExecutionSections.d.ts +0 -16
- package/dist/components/planning/ExecutionSections.d.ts.map +0 -1
- package/dist/components/planning/ExecutionSections.js +0 -32
- package/dist/components/planning/ExecutionSections.js.map +0 -1
- package/dist/components/planning/action-plan-icons.d.ts +0 -3
- package/dist/components/planning/action-plan-icons.d.ts.map +0 -1
- package/dist/components/planning/action-plan-icons.js +0 -25
- package/dist/components/planning/action-plan-icons.js.map +0 -1
- package/dist/components/planning/execution-section-model.d.ts +0 -24
- package/dist/components/planning/execution-section-model.d.ts.map +0 -1
- package/dist/components/planning/execution-section-model.js +0 -150
- package/dist/components/planning/execution-section-model.js.map +0 -1
- package/dist/graph/nodes/BrandFontFamilyView.d.ts +0 -3
- package/dist/graph/nodes/BrandFontFamilyView.d.ts.map +0 -1
- package/dist/graph/nodes/BrandFontFamilyView.js.map +0 -1
- package/dist/graph/nodes/BrandFontUploadButton.d.ts +0 -6
- package/dist/graph/nodes/BrandFontUploadButton.d.ts.map +0 -1
- package/dist/graph/nodes/BrandFontUploadButton.js +0 -69
- package/dist/graph/nodes/BrandFontUploadButton.js.map +0 -1
- package/dist/routes/data-explorer/components/TruncateTooltip.d.ts +0 -7
- package/dist/routes/data-explorer/components/TruncateTooltip.d.ts.map +0 -1
- package/dist/routes/data-explorer/components/TruncateTooltip.js +0 -9
- package/dist/routes/data-explorer/components/TruncateTooltip.js.map +0 -1
- package/src/components/planning/ExecutionActivityRow.tsx +0 -89
- package/src/components/planning/ExecutionSectionItem.tsx +0 -184
- package/src/components/planning/ExecutionSections.tsx +0 -97
- package/src/components/planning/action-plan-icons.tsx +0 -27
- package/src/components/planning/execution-section-model.ts +0 -190
- package/src/graph/nodes/BrandFontUploadButton.tsx +0 -95
- package/src/routes/data-explorer/components/TruncateTooltip.tsx +0 -25
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
import { GQLActionPlanState } from "@manta-eu/client";
|
|
2
|
+
import { isPresent } from "@manta-eu/lib/present";
|
|
2
3
|
import { match } from "ts-pattern";
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
export function parseTimestampMs(timestamp: string | null | undefined): number | null {
|
|
6
|
+
if (!timestamp) return null;
|
|
7
|
+
const value = new Date(timestamp).getTime();
|
|
8
|
+
return Number.isFinite(value) ? value : null;
|
|
9
|
+
}
|
|
4
10
|
|
|
5
11
|
export type ExecutionStatus = "idle" | "running" | "completed" | "failed" | "needs-approval";
|
|
6
12
|
|
|
13
|
+
export type RunSurface = "completed-changes" | "run" | "starting-run" | "loading" | "none";
|
|
14
|
+
|
|
15
|
+
export type DeriveRunSurfaceArgs = {
|
|
16
|
+
executionStatus: ExecutionStatus;
|
|
17
|
+
runIri: string | null;
|
|
18
|
+
hasCompletedChangesSlot: boolean;
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function deriveRunSurface(args: DeriveRunSurfaceArgs): RunSurface {
|
|
23
|
+
const { executionStatus, runIri, hasCompletedChangesSlot, isLoading } = args;
|
|
24
|
+
|
|
25
|
+
if (executionStatus === "completed" && hasCompletedChangesSlot) return "completed-changes";
|
|
26
|
+
if (isPresent(runIri)) return "run";
|
|
27
|
+
if (executionStatus === "running" || executionStatus === "needs-approval") return "starting-run";
|
|
28
|
+
if (isLoading) return "loading";
|
|
29
|
+
|
|
30
|
+
return "none";
|
|
31
|
+
}
|
|
32
|
+
|
|
7
33
|
export type DeriveExecutionStatusArgs = {
|
|
8
34
|
provenance: {
|
|
9
35
|
planErrorMessage: string | null;
|
|
@@ -9,14 +9,19 @@ export type TableSkeletonProps = {
|
|
|
9
9
|
renderRow: (rowIndex: number) => ReactNode;
|
|
10
10
|
withWrapper?: boolean;
|
|
11
11
|
className?: string;
|
|
12
|
+
headerClassName?: string;
|
|
13
|
+
rowClassName?: string;
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
export function TableSkeleton(props: TableSkeletonProps) {
|
|
15
17
|
const { gridColsClassName, headerColumnCount, rows = 8, renderRow, withWrapper = true, className } = props;
|
|
18
|
+
const { headerClassName, rowClassName } = props;
|
|
16
19
|
|
|
17
20
|
const content = (
|
|
18
21
|
<>
|
|
19
|
-
<div
|
|
22
|
+
<div
|
|
23
|
+
className={cn("grid gap-3 border-b border-muted-border bg-faint px-4 py-3", gridColsClassName, headerClassName)}
|
|
24
|
+
>
|
|
20
25
|
{Array.from({ length: headerColumnCount }, (_, index) => (
|
|
21
26
|
<Skeleton key={`table-skeleton-header-${index}`} className="h-4 w-2/3 rounded-md" />
|
|
22
27
|
))}
|
|
@@ -27,6 +32,7 @@ export function TableSkeleton(props: TableSkeletonProps) {
|
|
|
27
32
|
className={cn(
|
|
28
33
|
"grid items-center gap-3 border-b border-muted-border px-4 py-4 last:border-b-0",
|
|
29
34
|
gridColsClassName,
|
|
35
|
+
rowClassName,
|
|
30
36
|
)}
|
|
31
37
|
>
|
|
32
38
|
{renderRow(rowIndex)}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
4
|
-
import type { ComponentPropsWithoutRef, ElementRef } from "react";
|
|
5
|
-
import { forwardRef } from "react";
|
|
4
|
+
import type { ComponentPropsWithoutRef, ElementRef, ReactNode } from "react";
|
|
5
|
+
import { forwardRef, useState } from "react";
|
|
6
6
|
import { cn } from "#style";
|
|
7
7
|
|
|
8
8
|
export const TooltipProvider = TooltipPrimitive.Provider;
|
|
@@ -43,3 +43,36 @@ export const TooltipContent = forwardRef<ElementRef<typeof TooltipPrimitive.Cont
|
|
|
43
43
|
),
|
|
44
44
|
);
|
|
45
45
|
TooltipContent.displayName = "TooltipContent";
|
|
46
|
+
|
|
47
|
+
export type TruncateTooltipProps = { text: string; className: string; children?: ReactNode };
|
|
48
|
+
|
|
49
|
+
export function TruncateTooltip(props: TruncateTooltipProps) {
|
|
50
|
+
const { text, className, children } = props;
|
|
51
|
+
|
|
52
|
+
const [isTruncated, setIsTruncated] = useState(false);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Tooltip>
|
|
56
|
+
<TooltipTrigger asChild>
|
|
57
|
+
<span
|
|
58
|
+
className={className}
|
|
59
|
+
onMouseEnter={(event) => {
|
|
60
|
+
const element = event.currentTarget;
|
|
61
|
+
// Line height can round a single line 1px taller than its box, so only a real clamp counts.
|
|
62
|
+
setIsTruncated(
|
|
63
|
+
element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight + 1,
|
|
64
|
+
);
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{children ?? text}
|
|
68
|
+
</span>
|
|
69
|
+
</TooltipTrigger>
|
|
70
|
+
|
|
71
|
+
{isTruncated && (
|
|
72
|
+
<TooltipContent showArrow={false} className="max-h-64 max-w-sm overflow-y-auto break-words text-left">
|
|
73
|
+
<p className="typography-tiny">{text}</p>
|
|
74
|
+
</TooltipContent>
|
|
75
|
+
)}
|
|
76
|
+
</Tooltip>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -12,7 +12,7 @@ import { AttioNoteView } from "./nodes/AttioNoteView";
|
|
|
12
12
|
import { AttioTaskView } from "./nodes/AttioTaskView";
|
|
13
13
|
import { BrandAssetAnalysisActionView } from "./nodes/BrandAssetAnalysisActionView";
|
|
14
14
|
import { BrandAssetAnalysisView } from "./nodes/BrandAssetAnalysisView";
|
|
15
|
-
import {
|
|
15
|
+
import { BrandFontSuggestionView } from "./nodes/BrandFontSuggestionView";
|
|
16
16
|
import { BrandGuidelinesView } from "./nodes/BrandGuidelinesView";
|
|
17
17
|
import { CoresignalCompanyView } from "./nodes/CoresignalCompanyView";
|
|
18
18
|
import { CoresignalEmployeeView } from "./nodes/CoresignalEmployeeView";
|
|
@@ -123,7 +123,7 @@ const typedNodeEntries: ReadonlyArray<readonly [IRI, EntityView]> = [
|
|
|
123
123
|
// Asserted by a Datalog rule, not by a node shape, so codegen emits no class term for it.
|
|
124
124
|
[expandPrefix("brand:AssetAnalysis"), BrandAssetAnalysisView],
|
|
125
125
|
[brand.BrandGuidelines, BrandGuidelinesView],
|
|
126
|
-
[brand.
|
|
126
|
+
[brand.FontSuggestion, BrandFontSuggestionView],
|
|
127
127
|
];
|
|
128
128
|
|
|
129
129
|
export const typedEntityTypeIris: ReadonlySet<IRI> = new Set(typedNodeEntries.map(([type]) => type as IRI));
|
|
@@ -135,7 +135,7 @@ export const diffSubsumingViewIris: ReadonlySet<IRI> = new Set([
|
|
|
135
135
|
expandPrefix("brand:AssetAnalysisShape"),
|
|
136
136
|
expandPrefix("brand:AssetAnalysis"),
|
|
137
137
|
brand.BrandGuidelines,
|
|
138
|
-
brand.
|
|
138
|
+
brand.FontSuggestion,
|
|
139
139
|
]);
|
|
140
140
|
|
|
141
141
|
export const typedActionShapeIris: ReadonlySet<IRI> = new Set(actionShapeNodeEntries.map(([iri]) => iri));
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ComponentType, createContext, type ReactNode, useContext } from "react";
|
|
2
|
+
|
|
3
|
+
export type EntityLinkProps = { iri: string; className?: string; children: ReactNode };
|
|
4
|
+
|
|
5
|
+
export type EntityLinkComponent = ComponentType<EntityLinkProps>;
|
|
6
|
+
|
|
7
|
+
// The host app supplies how an entity opens (its router and record route); without one, entities render unlinked.
|
|
8
|
+
const EntityLinkContext = createContext<EntityLinkComponent | undefined>(undefined);
|
|
9
|
+
|
|
10
|
+
export type EntityLinkProviderProps = { component: EntityLinkComponent; children: ReactNode };
|
|
11
|
+
|
|
12
|
+
export function EntityLinkProvider(props: EntityLinkProviderProps) {
|
|
13
|
+
const { component, children } = props;
|
|
14
|
+
|
|
15
|
+
return <EntityLinkContext.Provider value={component}>{children}</EntityLinkContext.Provider>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function useEntityLink(): EntityLinkComponent | undefined {
|
|
19
|
+
return useContext(EntityLinkContext);
|
|
20
|
+
}
|
|
@@ -87,6 +87,7 @@ export type NodePropertyChange = {
|
|
|
87
87
|
|
|
88
88
|
export type NodePropertyPreview = {
|
|
89
89
|
id: string;
|
|
90
|
+
predicate?: string;
|
|
90
91
|
label: string;
|
|
91
92
|
value: string;
|
|
92
93
|
changeType?: PropertyChangeType;
|
|
@@ -162,6 +163,7 @@ export function selectPriorityPreviewFields(
|
|
|
162
163
|
|
|
163
164
|
return {
|
|
164
165
|
id: `${property.key}-${index}`,
|
|
166
|
+
predicate: property.iri,
|
|
165
167
|
label: property.label ?? propertyLabelFromKey(property.key),
|
|
166
168
|
value,
|
|
167
169
|
rawValue: String(property.value),
|
package/src/graph/graph-model.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isFullIri } from "@manta-eu/client/shared/rdf-namespaces";
|
|
1
2
|
import { labelPredicateSuffixes } from "@manta-eu/rdf-lib/detail-view-types";
|
|
2
3
|
import { expandPrefix, wellKnownPredicates } from "@manta-eu/rdf-lib/namespaces";
|
|
3
4
|
import type { RdfGraph } from "../lib/rdf-helpers";
|
|
@@ -10,7 +11,7 @@ import {
|
|
|
10
11
|
import { humanizePredicateName, type NodesAndEdges, type RDFEdge, shortenUri } from "./graph-utils";
|
|
11
12
|
import { readVocabValue } from "./nodes/typed-node-helpers";
|
|
12
13
|
import { mantaLightTheme } from "./themes";
|
|
13
|
-
import type { LayoutDirection, NodeProperty, RDFNode } from "./types";
|
|
14
|
+
import type { LayoutDirection, NodeProperty, NodeRelation, RDFNode } from "./types";
|
|
14
15
|
|
|
15
16
|
const labelPredicate = wellKnownPredicates.label;
|
|
16
17
|
const rdfType = wellKnownPredicates.type;
|
|
@@ -44,6 +45,7 @@ type NodeAccumulator = {
|
|
|
44
45
|
label?: string;
|
|
45
46
|
type?: string;
|
|
46
47
|
data: Record<string, unknown>;
|
|
48
|
+
relations: NodeRelation[];
|
|
47
49
|
};
|
|
48
50
|
|
|
49
51
|
type GraphEdgeRecord = {
|
|
@@ -60,7 +62,7 @@ function createOrGetNodeAccumulator(
|
|
|
60
62
|
): NodeAccumulator {
|
|
61
63
|
let node = nodeData.get(subjectId);
|
|
62
64
|
if (!node) {
|
|
63
|
-
node = { data: {} };
|
|
65
|
+
node = { data: {}, relations: [] };
|
|
64
66
|
nodeData.set(subjectId, node);
|
|
65
67
|
connectionCounts.set(subjectId, 0);
|
|
66
68
|
}
|
|
@@ -159,7 +161,7 @@ function buildNodesAndEdges(
|
|
|
159
161
|
const allNodeIds = new Set(nodeData.keys());
|
|
160
162
|
const hubThreshold = computeHubThreshold(connectionCounts);
|
|
161
163
|
|
|
162
|
-
const graphNodes: RDFNode[] = Array.from(nodeData).map(([id, { label, type, data }]) => {
|
|
164
|
+
const graphNodes: RDFNode[] = Array.from(nodeData).map(([id, { label, type, data, relations }]) => {
|
|
163
165
|
const childIds = (parentChildMap.get(id) || []).filter((childId) => allNodeIds.has(childId));
|
|
164
166
|
const parentId = childParentMap.get(id);
|
|
165
167
|
const depth = nodeDepths.get(id) || 0;
|
|
@@ -193,6 +195,7 @@ function buildNodesAndEdges(
|
|
|
193
195
|
isHub: connCount >= hubThreshold,
|
|
194
196
|
jsonLd: { "@id": id, "@type": type, ...data },
|
|
195
197
|
properties,
|
|
198
|
+
relations,
|
|
196
199
|
childIds,
|
|
197
200
|
parentId,
|
|
198
201
|
isCollapsed: false,
|
|
@@ -334,11 +337,15 @@ export function rdfGraphToNodesAndEdges(
|
|
|
334
337
|
const longNumericPattern = /\d{10,}/;
|
|
335
338
|
const leafValueSchemes = ["http://", "https://", "s3://"];
|
|
336
339
|
|
|
340
|
+
// A stored file or web address is a value to render, not a neighbor (without `s3:`, a long digit run reads as a ref).
|
|
341
|
+
function isLeafValue(targetId: string): boolean {
|
|
342
|
+
const isNamespacedIri = targetId.includes("#") || targetId.includes("vocab");
|
|
343
|
+
return !isNamespacedIri && leafValueSchemes.some((scheme) => targetId.startsWith(scheme));
|
|
344
|
+
}
|
|
345
|
+
|
|
337
346
|
function isEnumLikeRef(targetId: string): boolean {
|
|
338
347
|
if (definedSubjects.has(targetId)) return false;
|
|
339
|
-
|
|
340
|
-
// A stored file is a value to render, not a neighbor: without `s3:` a key with a long digit run reads as a ref.
|
|
341
|
-
if (!isNamespacedIri && leafValueSchemes.some((scheme) => targetId.startsWith(scheme))) return true;
|
|
348
|
+
if (isLeafValue(targetId)) return true;
|
|
342
349
|
const localName = targetId.split(/[#/]/).pop() ?? targetId;
|
|
343
350
|
if (uuidPattern.test(localName) || longNumericPattern.test(localName)) return false;
|
|
344
351
|
return true;
|
|
@@ -379,10 +386,12 @@ export function rdfGraphToNodesAndEdges(
|
|
|
379
386
|
|
|
380
387
|
if (isEnumLikeRef(targetId)) {
|
|
381
388
|
mergeNodeValue(node.data, predicate, targetId);
|
|
389
|
+
if (!isLeafValue(targetId) && isFullIri(targetId)) node.relations.push({ predicate, target: targetId });
|
|
382
390
|
continue;
|
|
383
391
|
}
|
|
384
392
|
|
|
385
393
|
createOrGetNodeAccumulator(nodeData, connectionCounts, targetId);
|
|
394
|
+
if (isFullIri(targetId)) node.relations.push({ predicate, target: targetId });
|
|
386
395
|
connectionCounts.set(subjectId, (connectionCounts.get(subjectId) || 0) + 1);
|
|
387
396
|
connectionCounts.set(targetId, (connectionCounts.get(targetId) || 0) + 1);
|
|
388
397
|
|
|
@@ -13,6 +13,7 @@ import { useRedirectEndpoint } from "#hooks/use-redirect-endpoint";
|
|
|
13
13
|
const filePredicate = `${namespaces.brand}file`;
|
|
14
14
|
const mimePredicate = `${namespaces.nmo}contentMimeType`;
|
|
15
15
|
const descriptionPredicate = `${namespaces.brand}assetDescription`;
|
|
16
|
+
const listedElsewhere = [filePredicate, mimePredicate, descriptionPredicate];
|
|
16
17
|
|
|
17
18
|
// The generated schema requires `m:file`, which only the planned request carries, so a lens read never matches.
|
|
18
19
|
export const BrandAssetAnalysisView = memo(function BrandAssetAnalysisView(props: EntityViewProps) {
|
|
@@ -46,8 +47,9 @@ export const BrandAssetAnalysisView = memo(function BrandAssetAnalysisView(props
|
|
|
46
47
|
|
|
47
48
|
<NodePropertyTable
|
|
48
49
|
properties={data.properties}
|
|
50
|
+
relations={data.relations}
|
|
49
51
|
jsonLd={data.jsonLd}
|
|
50
|
-
omitPredicates={
|
|
52
|
+
omitPredicates={listedElsewhere}
|
|
51
53
|
/>
|
|
52
54
|
</BrandNodeBody>
|
|
53
55
|
</EntityCardShell>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BrandFontFileSchema } from "@manta-eu/ldo";
|
|
1
|
+
import { BrandFontFileSchema, BrandSuggestedWeightSchema } from "@manta-eu/ldo";
|
|
2
2
|
import { redirectPath } from "@manta-eu/ldo/redirect-queries";
|
|
3
3
|
import { isPresent } from "@manta-eu/lib/present";
|
|
4
4
|
import { namespaces } from "@manta-eu/rdf-lib/namespaces";
|
|
@@ -8,11 +8,13 @@ import type { EntityViewProps } from "../types";
|
|
|
8
8
|
import {
|
|
9
9
|
fontFaceDescriptors,
|
|
10
10
|
preferredFontFile,
|
|
11
|
+
sortedWeights,
|
|
11
12
|
specimenWeight,
|
|
13
|
+
weightLabel,
|
|
12
14
|
type StoredFontFile,
|
|
15
|
+
type SuggestedWeight,
|
|
13
16
|
} from "./brand-font";
|
|
14
17
|
import { BrandNodeBody, BrandStatusBadge } from "./brand-shared";
|
|
15
|
-
import { BrandFontUploadButton } from "./BrandFontUploadButton";
|
|
16
18
|
import { EntityCardShell } from "./EntityCardShell";
|
|
17
19
|
import { NodePropertyTable } from "./NodePropertyTable";
|
|
18
20
|
import { readBrandString, toIriArray } from "./typed-node-helpers";
|
|
@@ -20,11 +22,27 @@ import { useEntitiesByIris } from "#hooks/use-entity";
|
|
|
20
22
|
import { useFontFace } from "#hooks/use-font-face";
|
|
21
23
|
import { useRedirectEndpoint } from "#hooks/use-redirect-endpoint";
|
|
22
24
|
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const fontFilePredicate = `${namespaces.brand}fontFile`;
|
|
25
|
+
const weightPredicate = `${namespaces.brand}hasSuggestedWeight`;
|
|
26
|
+
const listedElsewhere = [weightPredicate];
|
|
26
27
|
const specimenText = "Aa Bb Cc Qq Rr 0123456789 — The quick brown fox jumps over the lazy dog";
|
|
27
28
|
|
|
29
|
+
function useSuggestedWeights(iris: string[]): SuggestedWeight[] {
|
|
30
|
+
const { data } = useEntitiesByIris({ schema: BrandSuggestedWeightSchema, iris });
|
|
31
|
+
|
|
32
|
+
return (data ?? []).flatMap((weight) =>
|
|
33
|
+
weight
|
|
34
|
+
? [
|
|
35
|
+
{
|
|
36
|
+
weight: weight.fontWeight,
|
|
37
|
+
style: weight.fontStyle,
|
|
38
|
+
availability: weight.fontAvailability,
|
|
39
|
+
coveringFiles: weight.coveringFile ?? [],
|
|
40
|
+
},
|
|
41
|
+
]
|
|
42
|
+
: [],
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
28
46
|
function useStoredFontFiles(iris: string[]): StoredFontFile[] {
|
|
29
47
|
const { data } = useEntitiesByIris({ schema: BrandFontFileSchema, iris });
|
|
30
48
|
|
|
@@ -69,47 +87,43 @@ function FontSpecimen(props: FontSpecimenProps) {
|
|
|
69
87
|
);
|
|
70
88
|
}
|
|
71
89
|
|
|
72
|
-
export const
|
|
90
|
+
export const BrandFontSuggestionView = memo(function BrandFontSuggestionView(props: EntityViewProps) {
|
|
73
91
|
const { data, selected = false, ringColor, onContextMenu } = props;
|
|
74
92
|
|
|
75
93
|
const family = readBrandString(data.jsonLd, "family") ?? data.label;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const file = preferredFontFile(useStoredFontFiles(
|
|
94
|
+
const weights = sortedWeights(
|
|
95
|
+
useSuggestedWeights(toIriArray(data.jsonLd[weightPredicate] ?? data.jsonLd["brand:hasSuggestedWeight"])),
|
|
96
|
+
);
|
|
97
|
+
const file = preferredFontFile(useStoredFontFiles([...new Set(weights.flatMap((weight) => weight.coveringFiles))]));
|
|
80
98
|
|
|
81
99
|
return (
|
|
82
100
|
<EntityCardShell
|
|
83
101
|
icon={Type}
|
|
84
|
-
label={`Font
|
|
102
|
+
label={`Font Suggestion: ${family}`}
|
|
85
103
|
labelMaxWidth="max-w-140"
|
|
86
104
|
selected={selected}
|
|
87
105
|
ringColor={ringColor}
|
|
88
106
|
onContextMenu={onContextMenu}
|
|
89
107
|
>
|
|
90
|
-
<BrandNodeBody
|
|
91
|
-
right={
|
|
92
|
-
<div className="flex items-center gap-1">
|
|
93
|
-
<BrandStatusBadge status={availability} />
|
|
94
|
-
<BrandStatusBadge status={status} />
|
|
95
|
-
</div>
|
|
96
|
-
}
|
|
97
|
-
>
|
|
108
|
+
<BrandNodeBody>
|
|
98
109
|
{isPresent(file) && <FontSpecimen file={file} />}
|
|
99
110
|
|
|
100
|
-
{isPresent(
|
|
101
|
-
<
|
|
102
|
-
{
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
{isPresent(weights) && (
|
|
112
|
+
<ul className="flex flex-col gap-1">
|
|
113
|
+
{weights.map((weight) => (
|
|
114
|
+
<li key={weightLabel(weight)} className="flex items-center justify-between gap-2">
|
|
115
|
+
<span className="typography-tiny text-default-foreground">{weightLabel(weight)}</span>
|
|
116
|
+
<BrandStatusBadge status={weight.availability} />
|
|
117
|
+
</li>
|
|
118
|
+
))}
|
|
119
|
+
</ul>
|
|
107
120
|
)}
|
|
108
121
|
|
|
109
122
|
<NodePropertyTable
|
|
110
123
|
properties={data.properties}
|
|
111
124
|
jsonLd={data.jsonLd}
|
|
112
|
-
|
|
125
|
+
relations={data.relations}
|
|
126
|
+
omitPredicates={listedElsewhere}
|
|
113
127
|
/>
|
|
114
128
|
</BrandNodeBody>
|
|
115
129
|
</EntityCardShell>
|
|
@@ -18,7 +18,7 @@ export const BrandGuidelinesView = memo(function BrandGuidelinesView(props: Enti
|
|
|
18
18
|
onContextMenu={onContextMenu}
|
|
19
19
|
>
|
|
20
20
|
<BrandNodeBody>
|
|
21
|
-
<NodePropertyTable properties={data.properties} jsonLd={data.jsonLd} />
|
|
21
|
+
<NodePropertyTable properties={data.properties} jsonLd={data.jsonLd} relations={data.relations} />
|
|
22
22
|
</BrandNodeBody>
|
|
23
23
|
</EntityCardShell>
|
|
24
24
|
);
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Check, ChevronDown, ChevronRight, X } from "lucide-react";
|
|
3
|
-
import { useMemo, useState } from "react";
|
|
4
|
-
import { match, P } from "ts-pattern";
|
|
1
|
+
import { useCallback, useMemo } from "react";
|
|
5
2
|
import { shouldHidePreviewField } from "../graph-list-utils";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
import { AttributeList, useAttributeFacts } from "../special-nodes/AttributeList";
|
|
4
|
+
import type { NodeProperty, NodeRelation } from "../types";
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
NodePropertyExpander,
|
|
8
|
+
NodePropertyList,
|
|
9
|
+
NodePropertyRow,
|
|
10
|
+
PropertyValue,
|
|
11
|
+
type NodePropertyExpanderProps,
|
|
12
|
+
type NodePropertyRowProps,
|
|
13
|
+
} from "./node-property-row";
|
|
13
14
|
|
|
14
15
|
export type NodePropertyTableProps = {
|
|
15
16
|
properties: NodeProperty[];
|
|
@@ -17,145 +18,33 @@ export type NodePropertyTableProps = {
|
|
|
17
18
|
jsonLd?: Record<string, unknown>;
|
|
18
19
|
// Rendered above the table by the card itself, so the table skips them.
|
|
19
20
|
omitPredicates?: readonly string[];
|
|
21
|
+
relations?: NodeRelation[];
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<span className="rounded bg-faint px-1.5 py-[1px] typography-tiny text-default-foreground">{props.children}</span>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function PropertyValue(props: { display: PropertyDisplay }) {
|
|
29
|
-
return match(props.display)
|
|
30
|
-
.with({ kind: "tags" }, ({ values }) => (
|
|
31
|
-
<div className="flex flex-wrap gap-1">
|
|
32
|
-
{values.map((value) => (
|
|
33
|
-
<Tag key={value}>{value}</Tag>
|
|
34
|
-
))}
|
|
35
|
-
</div>
|
|
36
|
-
))
|
|
37
|
-
.with({ kind: "color" }, ({ hex }) => (
|
|
38
|
-
<span className="flex items-center gap-1.5">
|
|
39
|
-
<span
|
|
40
|
-
aria-hidden
|
|
41
|
-
className="size-3.5 shrink-0 rounded-sm border border-default-border"
|
|
42
|
-
style={{ backgroundColor: hex }}
|
|
43
|
-
/>
|
|
44
|
-
<span className="tabular-nums">{hex}</span>
|
|
45
|
-
</span>
|
|
46
|
-
))
|
|
47
|
-
.with({ kind: "ratio" }, ({ fraction, text }) => (
|
|
48
|
-
<span className="flex items-center gap-1.5">
|
|
49
|
-
<span aria-hidden className="h-1 w-12 shrink-0 overflow-hidden rounded-full bg-faint">
|
|
50
|
-
<span className="block h-full rounded-full bg-accent-foreground" style={{ width: `${fraction * 100}%` }} />
|
|
51
|
-
</span>
|
|
52
|
-
<span className="tabular-nums">{text}</span>
|
|
53
|
-
</span>
|
|
54
|
-
))
|
|
55
|
-
.with({ kind: "number" }, ({ text }) => <span className="tabular-nums">{text}</span>)
|
|
56
|
-
.with({ kind: "boolean" }, ({ value }) =>
|
|
57
|
-
value ? (
|
|
58
|
-
<span className="flex items-center gap-1">
|
|
59
|
-
<Check aria-hidden className="size-3.5 shrink-0 text-success-foreground" />
|
|
60
|
-
true
|
|
61
|
-
</span>
|
|
62
|
-
) : (
|
|
63
|
-
<span className="flex items-center gap-1">
|
|
64
|
-
<X aria-hidden className="size-3.5 shrink-0 text-muted-foreground" />
|
|
65
|
-
false
|
|
66
|
-
</span>
|
|
67
|
-
),
|
|
68
|
-
)
|
|
69
|
-
.with(P.union({ kind: "prose" }, { kind: "text" }), ({ text }) => <span>{text}</span>)
|
|
70
|
-
.exhaustive();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
type Row = { key: string; label: string; display: PropertyDisplay };
|
|
74
|
-
|
|
75
|
-
function PropertyRow(props: { row: Row }) {
|
|
76
|
-
const { row } = props;
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<div className="-mx-1 grid grid-cols-[minmax(0,7rem)_minmax(0,1fr)] items-baseline gap-x-3 gap-y-1 rounded-md border-t border-muted-border/50 px-1 py-1.5 transition-colors first:border-t-0 hover:bg-muted/30">
|
|
80
|
-
<span className="typography-tiny min-w-0 break-words text-muted-foreground first-letter:uppercase">
|
|
81
|
-
{row.label}
|
|
82
|
-
</span>
|
|
83
|
-
<div
|
|
84
|
-
className={cn(
|
|
85
|
-
"typography-tiny min-w-0 break-words text-default-foreground",
|
|
86
|
-
// A long description reads better as its own full-width block under the label.
|
|
87
|
-
row.display.kind === "prose" && "col-span-2",
|
|
88
|
-
)}
|
|
89
|
-
>
|
|
90
|
-
<PropertyValue display={row.display} />
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
);
|
|
94
|
-
}
|
|
24
|
+
const noJsonLd: Record<string, unknown> = {};
|
|
95
25
|
|
|
96
|
-
// Every property the node carries,
|
|
26
|
+
// Every property the node carries, in the same attribute list the fallback card uses. Rule-derived
|
|
97
27
|
// properties are included: they are real on the instance even though no shape declares them.
|
|
98
|
-
// Short values keep the compact two-column rhythm; prose paragraphs collapse behind the same
|
|
99
|
-
// "Show more" expander AttioNodeBody uses, so the card stays a summary until asked.
|
|
100
28
|
export function NodePropertyTable(props: NodePropertyTableProps) {
|
|
101
|
-
const { properties, jsonLd, omitPredicates
|
|
29
|
+
const { properties, jsonLd = noJsonLd, omitPredicates, relations } = props;
|
|
102
30
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return withOntologyLabels(properties, terms)
|
|
111
|
-
.filter(
|
|
112
|
-
(property) =>
|
|
113
|
-
!omitted.has(property.iri ?? "") && !shouldHidePreviewField(property.label ?? "", property.iri ?? ""),
|
|
114
|
-
)
|
|
115
|
-
.map((property): Row => {
|
|
116
|
-
const label = property.label || formatPropertyLabel(property.iri ?? property.key);
|
|
117
|
-
const formatted = formatDisplayValue(property.value, {
|
|
118
|
-
predicate: property.iri,
|
|
119
|
-
predicateLabel: property.label,
|
|
120
|
-
valueScale: property.valueScale,
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
key: property.iri ?? property.key,
|
|
125
|
-
label,
|
|
126
|
-
display: classifyPropertyDisplay({ label, formatted, raw: jsonLd?.[property.iri ?? ""] ?? property.value }),
|
|
127
|
-
};
|
|
128
|
-
});
|
|
129
|
-
}, [properties, terms, jsonLd, omitPredicates]);
|
|
130
|
-
|
|
131
|
-
const compactRows = rows.filter((row) => row.display.kind !== "prose");
|
|
132
|
-
const proseRows = rows.filter((row) => row.display.kind === "prose");
|
|
31
|
+
const include = useCallback(
|
|
32
|
+
(property: NodeProperty) =>
|
|
33
|
+
!(omitPredicates ?? []).includes(property.iri ?? "") &&
|
|
34
|
+
!shouldHidePreviewField(property.label ?? "", property.iri ?? ""),
|
|
35
|
+
[omitPredicates],
|
|
36
|
+
);
|
|
133
37
|
|
|
134
|
-
|
|
38
|
+
const visibleRelations = useMemo(
|
|
39
|
+
() =>
|
|
40
|
+
relations?.filter(
|
|
41
|
+
(relation) =>
|
|
42
|
+
!(omitPredicates ?? []).includes(relation.predicate) && !shouldHidePreviewField("", relation.predicate),
|
|
43
|
+
),
|
|
44
|
+
[relations, omitPredicates],
|
|
45
|
+
);
|
|
135
46
|
|
|
136
|
-
|
|
137
|
-
<div className="flex flex-col">
|
|
138
|
-
{compactRows.map((row) => (
|
|
139
|
-
<PropertyRow key={row.key} row={row} />
|
|
140
|
-
))}
|
|
47
|
+
const { facts, previewCount } = useAttributeFacts({ properties, relations: visibleRelations, jsonLd, include });
|
|
141
48
|
|
|
142
|
-
|
|
143
|
-
<>
|
|
144
|
-
{expanded && proseRows.map((row) => <PropertyRow key={row.key} row={row} />)}
|
|
145
|
-
<button
|
|
146
|
-
type="button"
|
|
147
|
-
onClick={() => setExpanded((value) => !value)}
|
|
148
|
-
className="nodrag flex items-center gap-1 pt-1.5 typography-tiny-medium text-muted-foreground hover:text-default-foreground"
|
|
149
|
-
>
|
|
150
|
-
{expanded ? (
|
|
151
|
-
<ChevronDown size={11} className="shrink-0" />
|
|
152
|
-
) : (
|
|
153
|
-
<ChevronRight size={11} className="shrink-0" />
|
|
154
|
-
)}
|
|
155
|
-
{expanded ? "Show less" : `Show ${proseRows.length} more`}
|
|
156
|
-
</button>
|
|
157
|
-
</>
|
|
158
|
-
)}
|
|
159
|
-
</div>
|
|
160
|
-
);
|
|
49
|
+
return <AttributeList facts={facts} previewCount={previewCount} showAll />;
|
|
161
50
|
}
|
|
@@ -27,3 +27,20 @@ export function fontFaceDescriptors(file: StoredFontFile): FontFaceDescriptors {
|
|
|
27
27
|
export function specimenWeight(file: StoredFontFile): number {
|
|
28
28
|
return Math.min(Math.max(400, file.weightMin), file.weightMax);
|
|
29
29
|
}
|
|
30
|
+
|
|
31
|
+
export type SuggestedWeight = {
|
|
32
|
+
weight: number;
|
|
33
|
+
style: "normal" | "italic";
|
|
34
|
+
availability: "available" | "looking-up" | "needs-upload";
|
|
35
|
+
coveringFiles: readonly string[];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function sortedWeights<W extends Pick<SuggestedWeight, "weight" | "style">>(weights: readonly W[]): W[] {
|
|
39
|
+
return [...weights].sort(
|
|
40
|
+
(a, b) => a.weight - b.weight || Number(a.style === "italic") - Number(b.style === "italic"),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function weightLabel(weight: Pick<SuggestedWeight, "weight" | "style">): string {
|
|
45
|
+
return weight.style === "italic" ? `${weight.weight} italic` : `${weight.weight}`;
|
|
46
|
+
}
|
|
@@ -11,14 +11,11 @@ import { cn } from "#style";
|
|
|
11
11
|
|
|
12
12
|
export const brandAmber = "#d97706";
|
|
13
13
|
|
|
14
|
-
// Every `sh:in` value
|
|
14
|
+
// Every `sh:in` value of brand:fontAvailability in kgc/shacl/shapes/brand-font-suggestion.ttl.
|
|
15
15
|
const toneByStatus = {
|
|
16
|
-
accepted: "positive",
|
|
17
16
|
available: "positive",
|
|
18
|
-
draft: "neutral",
|
|
19
17
|
"looking-up": "neutral",
|
|
20
18
|
"needs-upload": "caution",
|
|
21
|
-
rejected: "negative",
|
|
22
19
|
} as const satisfies Record<string, BadgeTone>;
|
|
23
20
|
|
|
24
21
|
export type BrandStatus = keyof typeof toneByStatus;
|