@agent-native/core 0.92.7 → 0.92.8
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/docs/content/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/ar-SA/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/ar-SA/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/ar-SA/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/de-DE/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/de-DE/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/es-ES/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/es-ES/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/es-ES/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/fr-FR/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/fr-FR/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/fr-FR/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/hi-IN/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/hi-IN/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/hi-IN/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/ja-JP/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/ja-JP/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/ja-JP/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/ko-KR/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/ko-KR/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/ko-KR/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/pt-BR/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/pt-BR/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/pt-BR/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/zh-CN/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/zh-CN/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-CN/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/locales/zh-TW/a2a-protocol.mdx +12 -0
- package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-TW/pure-agent-apps.mdx +4 -0
- package/corpus/core/docs/content/pr-visual-recap.mdx +3 -3
- package/corpus/core/docs/content/pure-agent-apps.mdx +22 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/engine/builtin.ts +1 -1
- package/corpus/core/src/agent/model-config.ts +30 -30
- package/corpus/core/src/agent/production-agent.ts +129 -7
- package/corpus/core/src/cli/design-connect.ts +438 -83
- package/corpus/core/src/cli/recap.ts +2 -2
- package/corpus/core/src/client/AgentPanel.tsx +8 -1
- package/corpus/core/src/client/agent-chat-adapter.ts +12 -7
- package/corpus/core/src/client/composer/TiptapComposer.tsx +1 -1
- package/corpus/core/src/client/index.ts +4 -0
- package/corpus/core/src/client/org/TeamPage.tsx +41 -26
- package/corpus/core/src/client/use-action.ts +113 -1
- package/corpus/core/src/db/client.ts +12 -2
- package/corpus/core/src/db/create-get-db.ts +4 -1
- package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
- package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
- package/corpus/core/src/server/transcribe-voice.ts +1 -1
- package/corpus/core/src/usage/store.ts +13 -4
- package/corpus/core/src/vite/client.ts +38 -1
- package/corpus/templates/analytics/AGENTS.md +3 -0
- package/corpus/templates/analytics/actions/get-data-program.ts +78 -0
- package/corpus/templates/analytics/actions/list-data-programs.ts +49 -0
- package/corpus/templates/analytics/app/global.css +11 -0
- package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +163 -17
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/analytics/app/i18n-data.ts +20 -0
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +96 -3
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +61 -4
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +40 -2
- package/corpus/templates/analytics/changelog/2026-07-09-analytics-no-longer-forgets-successful-data-queries-when-a-l.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-09-dashboard-charts-keep-consistent-spacing-when-they-stack-ver.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-09-dashboard-charts-tables-and-extensions-can-be-selected-and-d.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-09-long-running-analytics-requests-now-recover-automatically-wh.md +6 -0
- package/corpus/templates/analytics/server/db/index.ts +6 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +1 -7
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +102 -15
- package/corpus/templates/content/app/hooks/use-content-database.ts +52 -0
- package/corpus/templates/content/app/hooks/use-document-properties.ts +50 -6
- package/corpus/templates/content/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/content/app/i18n-data.ts +28 -0
- package/corpus/templates/content/changelog/2026-07-09-notion-conflict-warnings-no-longer-flash-during-normal-synce.md +6 -0
- package/corpus/templates/content/changelog/2026-07-09-property-menus-and-delete-confirmations-now-open-visibly-and.md +6 -0
- package/corpus/templates/content/server/lib/notion-sync.ts +130 -28
- package/corpus/templates/design/actions/add-breakpoint.ts +48 -68
- package/corpus/templates/design/actions/add-localhost-screens.ts +496 -61
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +2 -18
- package/corpus/templates/design/actions/apply-design-token-edit.ts +51 -82
- package/corpus/templates/design/actions/apply-tweaks.ts +63 -41
- package/corpus/templates/design/actions/capture-design-state.ts +2 -2
- package/corpus/templates/design/actions/connect-localhost.ts +58 -12
- package/corpus/templates/design/actions/create-component.ts +2 -18
- package/corpus/templates/design/actions/create-design-branch.ts +38 -18
- package/corpus/templates/design/actions/create-fusion-app.ts +15 -11
- package/corpus/templates/design/actions/delete-file.ts +19 -34
- package/corpus/templates/design/actions/deploy-design-preview.ts +59 -27
- package/corpus/templates/design/actions/deploy-fusion-app.ts +22 -15
- package/corpus/templates/design/actions/export-pdf.ts +2 -1
- package/corpus/templates/design/actions/export-zip.ts +9 -3
- package/corpus/templates/design/actions/generate-design.ts +107 -70
- package/corpus/templates/design/actions/get-component-details.ts +2 -18
- package/corpus/templates/design/actions/get-design-branch-diff.ts +2 -3
- package/corpus/templates/design/actions/get-design-surface-index.ts +2 -18
- package/corpus/templates/design/actions/get-design.ts +2 -1
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +7 -1
- package/corpus/templates/design/actions/import-design-tokens.ts +114 -76
- package/corpus/templates/design/actions/index-components.ts +2 -18
- package/corpus/templates/design/actions/list-design-source-capabilities.ts +23 -28
- package/corpus/templates/design/actions/list-local-files.ts +9 -2
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +82 -98
- package/corpus/templates/design/actions/open-component-source.ts +2 -18
- package/corpus/templates/design/actions/open-visual-edit.ts +19 -1
- package/corpus/templates/design/actions/present-design-variants.ts +70 -70
- package/corpus/templates/design/actions/preview-component-prop-edit.ts +4 -14
- package/corpus/templates/design/actions/read-local-file.ts +9 -2
- package/corpus/templates/design/actions/remove-breakpoint.ts +40 -61
- package/corpus/templates/design/actions/rename-screen.ts +425 -0
- package/corpus/templates/design/actions/request-localhost-write-consent.ts +12 -2
- package/corpus/templates/design/actions/revoke-localhost-write-consent.ts +9 -2
- package/corpus/templates/design/actions/sync-fusion-app.ts +56 -39
- package/corpus/templates/design/actions/update-design.ts +376 -61
- package/corpus/templates/design/actions/update-file.ts +455 -188
- package/corpus/templates/design/actions/write-local-file.ts +10 -2
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +685 -608
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +43 -15
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +576 -2015
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +62 -14
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +263 -25
- package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +34 -0
- package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +40 -0
- package/corpus/templates/design/app/components/design/design-canvas/creation.ts +47 -0
- package/corpus/templates/design/app/components/design/design-canvas/element-payload.ts +27 -0
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +62 -0
- package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +137 -0
- package/corpus/templates/design/app/components/design/design-canvas/file-drop.ts +10 -0
- package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +23 -0
- package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +23 -0
- package/corpus/templates/design/app/components/design/design-canvas/iframe-pan.ts +177 -0
- package/corpus/templates/design/app/components/design/design-canvas/motion-types.ts +7 -0
- package/corpus/templates/design/app/components/design/design-canvas/pending-text-edit.ts +62 -0
- package/corpus/templates/design/app/components/design/index.ts +2 -2
- package/corpus/templates/design/app/components/design/multi-screen/canvas-tools.ts +100 -0
- package/corpus/templates/design/app/components/design/multi-screen/coordinate-transforms.ts +81 -0
- package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +23 -13
- package/corpus/templates/design/app/components/design/multi-screen/culling.ts +238 -19
- package/corpus/templates/design/app/components/design/multi-screen/draft-primitives.ts +424 -0
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +341 -0
- package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +52 -0
- package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +62 -0
- package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +283 -0
- package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +272 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +5 -1
- package/corpus/templates/design/app/components/design/multi-screen/wheel-gesture-state.ts +12 -0
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +325 -84
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +15 -1
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +119 -47
- package/corpus/templates/design/app/i18n/zh-TW.ts +9 -0
- package/corpus/templates/design/app/i18n-data.ts +223 -0
- package/corpus/templates/design/app/lib/design-save-outbox.ts +379 -0
- package/corpus/templates/design/app/lib/png-clipboard.ts +113 -0
- package/corpus/templates/design/app/pages/design-editor/canvas-primitives.ts +229 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +918 -0
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +43 -0
- package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +336 -0
- package/corpus/templates/design/app/pages/design-editor/data-operations.ts +270 -0
- package/corpus/templates/design/app/pages/design-editor/dom-guards.ts +24 -0
- package/corpus/templates/design/app/pages/design-editor/dom-utils.ts +11 -0
- package/corpus/templates/design/app/pages/design-editor/editor-session.ts +20 -0
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +408 -0
- package/corpus/templates/design/app/pages/design-editor/export-capture.ts +115 -0
- package/corpus/templates/design/app/pages/design-editor/geometry-persistence.ts +93 -0
- package/corpus/templates/design/app/pages/design-editor/history.ts +169 -0
- package/corpus/templates/design/app/pages/design-editor/layout-operations.ts +185 -0
- package/corpus/templates/design/app/pages/design-editor/motion-state.ts +309 -0
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +438 -0
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +510 -0
- package/corpus/templates/design/app/pages/design-editor/portable-style.ts +115 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +337 -0
- package/corpus/templates/design/app/pages/design-editor/style-utils.ts +5 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +92 -0
- package/corpus/templates/design/app/pages/design-editor/tweak-save.ts +87 -0
- package/corpus/templates/design/app/pages/design-editor/types.ts +36 -0
- package/corpus/templates/design/app/routes/design.$id.tsx +11 -1
- package/corpus/templates/design/changelog/2026-07-09-design-edits-canvas-positions-tools-and-tab-context-now-pers.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-figma-style-shortcuts-drawing-annotations-and-cross-screen-d.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-hand-and-scale-tools-now-keep-their-active-toolbar-identity-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-large-multi-screen-designs-now-stay-responsive-during-long-c.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layer-drags-now-land-exactly-where-the-insertion-indicator-s.md +6 -0
- package/corpus/templates/design/server/db/index.ts +2 -52
- package/corpus/templates/design/server/db/schema.ts +16 -0
- package/corpus/templates/design/server/lib/design-data-access.ts +70 -0
- package/corpus/templates/design/server/lib/design-data-mutation.ts +249 -0
- package/corpus/templates/design/server/lib/fusion-screens.ts +89 -76
- package/corpus/templates/design/server/lib/import-design-files.ts +76 -35
- package/corpus/templates/design/server/lib/verify-write-grant.ts +7 -2
- package/corpus/templates/design/server/plugins/db.ts +19 -0
- package/corpus/templates/design/server/source-workspace.ts +12 -13
- package/corpus/templates/design/shared/resolve-tweaks.ts +15 -0
- package/corpus/templates/design/shared/screen-rename.ts +42 -0
- package/corpus/templates/design/shared/source-mode.ts +84 -4
- package/dist/agent/engine/builder-engine.d.ts +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builtin.js +1 -1
- package/dist/agent/engine/builtin.js.map +1 -1
- package/dist/agent/model-config.d.ts +9 -9
- package/dist/agent/model-config.d.ts.map +1 -1
- package/dist/agent/model-config.js +30 -30
- package/dist/agent/model-config.js.map +1 -1
- package/dist/agent/production-agent.d.ts +60 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +106 -7
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/design-connect.d.ts +30 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +359 -75
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/recap.js +2 -2
- package/dist/cli/recap.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +10 -5
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/TiptapComposer.js +1 -1
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +6 -5
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/use-action.d.ts +32 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +68 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts +3 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +7 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +2 -2
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
- package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
- package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
- package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.js +1 -1
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/usage/store.d.ts.map +1 -1
- package/dist/usage/store.js +13 -4
- package/dist/usage/store.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +36 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/a2a-protocol.mdx +12 -0
- package/docs/content/locales/ar-SA/a2a-protocol.mdx +12 -0
- package/docs/content/locales/ar-SA/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/ar-SA/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/de-DE/a2a-protocol.mdx +12 -0
- package/docs/content/locales/de-DE/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/de-DE/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/es-ES/a2a-protocol.mdx +12 -0
- package/docs/content/locales/es-ES/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/es-ES/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/fr-FR/a2a-protocol.mdx +12 -0
- package/docs/content/locales/fr-FR/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/fr-FR/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/hi-IN/a2a-protocol.mdx +12 -0
- package/docs/content/locales/hi-IN/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/hi-IN/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/ja-JP/a2a-protocol.mdx +12 -0
- package/docs/content/locales/ja-JP/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/ja-JP/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/ko-KR/a2a-protocol.mdx +12 -0
- package/docs/content/locales/ko-KR/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/ko-KR/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/pt-BR/a2a-protocol.mdx +12 -0
- package/docs/content/locales/pt-BR/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/pt-BR/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/zh-CN/a2a-protocol.mdx +12 -0
- package/docs/content/locales/zh-CN/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/zh-CN/pure-agent-apps.mdx +4 -0
- package/docs/content/locales/zh-TW/a2a-protocol.mdx +12 -0
- package/docs/content/locales/zh-TW/pr-visual-recap.mdx +3 -3
- package/docs/content/locales/zh-TW/pure-agent-apps.mdx +4 -0
- package/docs/content/pr-visual-recap.mdx +3 -3
- package/docs/content/pure-agent-apps.mdx +22 -0
- package/package.json +2 -2
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
IconTrash,
|
|
11
11
|
IconCode,
|
|
12
12
|
IconDownload,
|
|
13
|
+
IconMessageCircle,
|
|
13
14
|
} from "@tabler/icons-react";
|
|
14
15
|
import { useIsFetching, useQueryClient } from "@tanstack/react-query";
|
|
15
16
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
@@ -46,6 +47,8 @@ import {
|
|
|
46
47
|
TooltipContent,
|
|
47
48
|
TooltipTrigger,
|
|
48
49
|
} from "@/components/ui/tooltip";
|
|
50
|
+
import type { SelectDashboardPanelOptions } from "@/hooks/use-dashboard-chat-context";
|
|
51
|
+
import { cn } from "@/lib/utils";
|
|
49
52
|
|
|
50
53
|
import { serializePanelSql } from "./panel-sql";
|
|
51
54
|
import type { SqlPanel } from "./types";
|
|
@@ -62,6 +65,8 @@ interface SqlChartCardProps {
|
|
|
62
65
|
editable?: boolean;
|
|
63
66
|
eagerLoad?: boolean;
|
|
64
67
|
isDragSource?: boolean;
|
|
68
|
+
selectedForChat?: boolean;
|
|
69
|
+
onSelectForChat?: (options?: SelectDashboardPanelOptions) => void;
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
const PanelDragHandle = memo(function PanelDragHandle({
|
|
@@ -115,6 +120,8 @@ export function SqlChartCard({
|
|
|
115
120
|
editable = true,
|
|
116
121
|
eagerLoad = false,
|
|
117
122
|
isDragSource = false,
|
|
123
|
+
selectedForChat = false,
|
|
124
|
+
onSelectForChat,
|
|
118
125
|
}: SqlChartCardProps) {
|
|
119
126
|
const t = useT();
|
|
120
127
|
const queryClient = useQueryClient();
|
|
@@ -144,6 +151,12 @@ export function SqlChartCard({
|
|
|
144
151
|
const chartHasCachedData =
|
|
145
152
|
queryClient.getQueryData(chartQueryKey) !== undefined;
|
|
146
153
|
const isChartRefreshing = chartHasCachedData && chartFetchCount > 0;
|
|
154
|
+
const extensionId =
|
|
155
|
+
panel.chartType === "extension"
|
|
156
|
+
? ((panel.config as Record<string, unknown> | undefined)?.extensionId as
|
|
157
|
+
| string
|
|
158
|
+
| undefined)
|
|
159
|
+
: undefined;
|
|
147
160
|
|
|
148
161
|
const setCardNodeRef = useCallback((node: HTMLDivElement | null) => {
|
|
149
162
|
cardRef.current = node;
|
|
@@ -160,6 +173,22 @@ export function SqlChartCard({
|
|
|
160
173
|
});
|
|
161
174
|
}, [chartQueryKey, queryClient]);
|
|
162
175
|
|
|
176
|
+
const handleCardClick = useCallback(
|
|
177
|
+
(event: React.MouseEvent<HTMLDivElement>) => {
|
|
178
|
+
const target = event.target;
|
|
179
|
+
if (
|
|
180
|
+
target instanceof Element &&
|
|
181
|
+
target.closest(
|
|
182
|
+
"button, a, input, textarea, select, [role='menuitem'], [data-no-panel-chat-select]",
|
|
183
|
+
)
|
|
184
|
+
) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
onSelectForChat?.({ focus: false });
|
|
188
|
+
},
|
|
189
|
+
[onSelectForChat],
|
|
190
|
+
);
|
|
191
|
+
|
|
163
192
|
useEffect(() => {
|
|
164
193
|
if (eagerLoad) {
|
|
165
194
|
setShouldLoadData(true);
|
|
@@ -299,14 +328,17 @@ export function SqlChartCard({
|
|
|
299
328
|
// actions (full screen, refresh, open embedded extension); editable
|
|
300
329
|
// dashboards also get delete and drag.
|
|
301
330
|
if (panel.chartType === "extension") {
|
|
302
|
-
const extensionId = (panel.config as Record<string, unknown> | undefined)
|
|
303
|
-
?.extensionId as string | undefined;
|
|
304
331
|
return (
|
|
305
332
|
<div
|
|
306
333
|
ref={setCardNodeRef}
|
|
334
|
+
onClick={handleCardClick}
|
|
307
335
|
style={isDragSource ? { zIndex: 50 } : undefined}
|
|
308
336
|
data-dragging={isDragSource ? "true" : undefined}
|
|
309
|
-
|
|
337
|
+
data-chat-selected={selectedForChat ? "true" : undefined}
|
|
338
|
+
className={cn(
|
|
339
|
+
"dashboard-extension-card group relative h-full rounded-lg border border-transparent transition-colors",
|
|
340
|
+
selectedForChat && "border-foreground/35 ring-1 ring-foreground/10",
|
|
341
|
+
)}
|
|
310
342
|
>
|
|
311
343
|
{!expanded && (
|
|
312
344
|
<SqlChart
|
|
@@ -332,6 +364,15 @@ export function SqlChartCard({
|
|
|
332
364
|
<TooltipContent>{t("sqlDashboard.panelOptions")}</TooltipContent>
|
|
333
365
|
</Tooltip>
|
|
334
366
|
<DropdownMenuContent align="end" className="w-44">
|
|
367
|
+
<DropdownMenuItem
|
|
368
|
+
onSelect={() =>
|
|
369
|
+
onSelectForChat?.({ openSidebar: true, focus: true })
|
|
370
|
+
}
|
|
371
|
+
>
|
|
372
|
+
<IconMessageCircle className="h-4 w-4 mr-2" />
|
|
373
|
+
{t("sqlDashboard.chatWithPanel")}
|
|
374
|
+
</DropdownMenuItem>
|
|
375
|
+
<DropdownMenuSeparator />
|
|
335
376
|
<DropdownMenuItem onSelect={() => setExpanded(true)}>
|
|
336
377
|
<IconMaximize className="h-4 w-4 mr-2" />
|
|
337
378
|
{t("sqlDashboard.fullScreen")}
|
|
@@ -437,11 +478,18 @@ export function SqlChartCard({
|
|
|
437
478
|
return (
|
|
438
479
|
<div
|
|
439
480
|
ref={setCardNodeRef}
|
|
481
|
+
onClick={handleCardClick}
|
|
440
482
|
style={isDragSource ? { zIndex: 50 } : undefined}
|
|
441
483
|
data-dragging={isDragSource ? "true" : undefined}
|
|
484
|
+
data-chat-selected={selectedForChat ? "true" : undefined}
|
|
442
485
|
className="dashboard-chart-card group relative h-full hover:z-20 focus-within:z-20"
|
|
443
486
|
>
|
|
444
|
-
<Card
|
|
487
|
+
<Card
|
|
488
|
+
className={cn(
|
|
489
|
+
"flex h-full flex-col overflow-visible transition-colors",
|
|
490
|
+
selectedForChat && "border-foreground/35 ring-1 ring-foreground/10",
|
|
491
|
+
)}
|
|
492
|
+
>
|
|
445
493
|
<CardHeader className="pb-2 flex flex-row items-center gap-2 shrink-0">
|
|
446
494
|
<CardTitle className="text-sm font-medium flex-1 truncate">
|
|
447
495
|
{panel.title}
|
|
@@ -499,6 +547,15 @@ export function SqlChartCard({
|
|
|
499
547
|
</TooltipContent>
|
|
500
548
|
</Tooltip>
|
|
501
549
|
<DropdownMenuContent align="end" className="w-44">
|
|
550
|
+
<DropdownMenuItem
|
|
551
|
+
onSelect={() =>
|
|
552
|
+
onSelectForChat?.({ openSidebar: true, focus: true })
|
|
553
|
+
}
|
|
554
|
+
>
|
|
555
|
+
<IconMessageCircle className="h-4 w-4 mr-2" />
|
|
556
|
+
{t("sqlDashboard.chatWithPanel")}
|
|
557
|
+
</DropdownMenuItem>
|
|
558
|
+
<DropdownMenuSeparator />
|
|
502
559
|
<DropdownMenuItem onSelect={() => setExpanded(true)}>
|
|
503
560
|
<IconMaximize className="h-4 w-4 mr-2" />
|
|
504
561
|
{t("sqlDashboard.fullScreen")}
|
|
@@ -92,7 +92,11 @@ import {
|
|
|
92
92
|
TooltipContent,
|
|
93
93
|
TooltipTrigger,
|
|
94
94
|
} from "@/components/ui/tooltip";
|
|
95
|
-
import {
|
|
95
|
+
import {
|
|
96
|
+
useDashboardChatContext,
|
|
97
|
+
type DashboardPanelChatContextArgs,
|
|
98
|
+
type SelectDashboardPanelOptions,
|
|
99
|
+
} from "@/hooks/use-dashboard-chat-context";
|
|
96
100
|
import { useDashboardViews } from "@/hooks/use-dashboard-views";
|
|
97
101
|
import { useUserPref } from "@/hooks/use-user-pref";
|
|
98
102
|
import { incrementItemView } from "@/lib/item-popularity";
|
|
@@ -258,6 +262,8 @@ const PanelCell = memo(function PanelCell({
|
|
|
258
262
|
editable,
|
|
259
263
|
eagerLoad,
|
|
260
264
|
isDragSource,
|
|
265
|
+
selectedForChat,
|
|
266
|
+
selectPanelForChat,
|
|
261
267
|
onRemovePanel,
|
|
262
268
|
onEditPanel,
|
|
263
269
|
onSavePanel,
|
|
@@ -268,6 +274,11 @@ const PanelCell = memo(function PanelCell({
|
|
|
268
274
|
editable: boolean;
|
|
269
275
|
eagerLoad: boolean;
|
|
270
276
|
isDragSource: boolean;
|
|
277
|
+
selectedForChat: boolean;
|
|
278
|
+
selectPanelForChat: (
|
|
279
|
+
panel: DashboardPanelChatContextArgs,
|
|
280
|
+
options?: SelectDashboardPanelOptions,
|
|
281
|
+
) => void;
|
|
271
282
|
onRemovePanel: (panelId: string) => void;
|
|
272
283
|
onEditPanel: (panel: SqlPanel) => void;
|
|
273
284
|
onSavePanel: (panel: SqlPanel) => Promise<void>;
|
|
@@ -289,6 +300,29 @@ const PanelCell = memo(function PanelCell({
|
|
|
289
300
|
() => interpolate(serializePanelSql(panel.sql), vars),
|
|
290
301
|
[panel.sql, vars],
|
|
291
302
|
);
|
|
303
|
+
const handleSelectForChat = useCallback(
|
|
304
|
+
(options?: SelectDashboardPanelOptions) => {
|
|
305
|
+
const extensionId =
|
|
306
|
+
panel.chartType === "extension" ? panel.config?.extensionId : undefined;
|
|
307
|
+
selectPanelForChat(
|
|
308
|
+
{
|
|
309
|
+
panelId: panel.id,
|
|
310
|
+
panelTitle: panel.title,
|
|
311
|
+
panelKind:
|
|
312
|
+
panel.chartType === "table"
|
|
313
|
+
? "table"
|
|
314
|
+
: panel.chartType === "extension"
|
|
315
|
+
? "extension"
|
|
316
|
+
: "chart",
|
|
317
|
+
chartType: panel.chartType,
|
|
318
|
+
source: panel.source,
|
|
319
|
+
extensionId,
|
|
320
|
+
},
|
|
321
|
+
options,
|
|
322
|
+
);
|
|
323
|
+
},
|
|
324
|
+
[panel, selectPanelForChat],
|
|
325
|
+
);
|
|
292
326
|
|
|
293
327
|
return (
|
|
294
328
|
<div
|
|
@@ -323,6 +357,8 @@ const PanelCell = memo(function PanelCell({
|
|
|
323
357
|
editable={editable}
|
|
324
358
|
eagerLoad={eagerLoad}
|
|
325
359
|
isDragSource={isDragSource}
|
|
360
|
+
selectedForChat={selectedForChat}
|
|
361
|
+
onSelectForChat={handleSelectForChat}
|
|
326
362
|
/>
|
|
327
363
|
</div>
|
|
328
364
|
);
|
|
@@ -477,7 +513,7 @@ export default function SqlDashboardPage() {
|
|
|
477
513
|
const dashboardColumns = clampDashboardColumns(
|
|
478
514
|
dashboard?.columns ?? DEFAULT_DASHBOARD_COLUMNS,
|
|
479
515
|
);
|
|
480
|
-
useDashboardChatContext({
|
|
516
|
+
const { selectedPanelId, selectPanelForChat } = useDashboardChatContext({
|
|
481
517
|
id: reportScreenshot ? null : dashboardId,
|
|
482
518
|
kind: "sql",
|
|
483
519
|
title: dashboard?.name,
|
|
@@ -1859,6 +1895,8 @@ export default function SqlDashboardPage() {
|
|
|
1859
1895
|
editable={canEdit}
|
|
1860
1896
|
eagerLoad={reportScreenshot}
|
|
1861
1897
|
isDragSource={activeDragPanelId === panel.id}
|
|
1898
|
+
selectedForChat={selectedPanelId === panel.id}
|
|
1899
|
+
selectPanelForChat={selectPanelForChat}
|
|
1862
1900
|
onRemovePanel={removePanel}
|
|
1863
1901
|
onEditPanel={openEditPanel}
|
|
1864
1902
|
onSavePanel={handleSavePanel}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { registerDataProgramsShareable } from "@agent-native/core/data-programs";
|
|
1
2
|
import { createGetDb } from "@agent-native/core/db";
|
|
2
3
|
import { registerShareableResource } from "@agent-native/core/sharing";
|
|
3
4
|
|
|
@@ -12,6 +13,11 @@ import * as schema from "./schema.js";
|
|
|
12
13
|
export const getDb = createGetDb(schema);
|
|
13
14
|
export { schema };
|
|
14
15
|
|
|
16
|
+
// Core data-program tables live outside analytics/schema.ts; register the
|
|
17
|
+
// sharing type here so get-data-program / resolveAccess work in dev, CLI, and
|
|
18
|
+
// extension iframes (same side-effect pattern as dashboard/analysis below).
|
|
19
|
+
registerDataProgramsShareable();
|
|
20
|
+
|
|
15
21
|
registerShareableResource({
|
|
16
22
|
type: "dashboard",
|
|
17
23
|
resourceTable: schema.dashboards,
|
|
@@ -377,9 +377,7 @@ export function useMeetingTranscription({
|
|
|
377
377
|
};
|
|
378
378
|
|
|
379
379
|
// Resume the engine that initial start settled on (no fallback here —
|
|
380
|
-
// the engine choice was already made below).
|
|
381
|
-
// off: AEC/ducking on the shared mic can make Zoom/Meet callers hear
|
|
382
|
-
// the local user at a whisper while Clips is transcribed.
|
|
380
|
+
// the engine choice was already made below).
|
|
383
381
|
const startAudio = async () => {
|
|
384
382
|
await restartTranscriptionEngine(
|
|
385
383
|
session.engine,
|
|
@@ -388,7 +386,6 @@ export function useMeetingTranscription({
|
|
|
388
386
|
label: selectedMicLabel,
|
|
389
387
|
},
|
|
390
388
|
true,
|
|
391
|
-
false,
|
|
392
389
|
);
|
|
393
390
|
};
|
|
394
391
|
|
|
@@ -559,9 +556,6 @@ export function useMeetingTranscription({
|
|
|
559
556
|
|
|
560
557
|
session.engine = await startTranscriptionEngine({
|
|
561
558
|
mic: { deviceId: selectedMicId, label: selectedMicLabel },
|
|
562
|
-
// Match clip recordings: VoiceProcessingIO AEC/ducking on the shared
|
|
563
|
-
// mic can tank live meeting volume for remote participants.
|
|
564
|
-
voiceProcessing: false,
|
|
565
559
|
});
|
|
566
560
|
|
|
567
561
|
await invoke("silence_detector_start", {
|
|
@@ -69,6 +69,8 @@ import {
|
|
|
69
69
|
useMemo,
|
|
70
70
|
useRef,
|
|
71
71
|
useState,
|
|
72
|
+
type KeyboardEvent as ReactKeyboardEvent,
|
|
73
|
+
type MouseEvent as ReactMouseEvent,
|
|
72
74
|
type PointerEvent as ReactPointerEvent,
|
|
73
75
|
type ReactNode,
|
|
74
76
|
} from "react";
|
|
@@ -1110,7 +1112,11 @@ export function PropertyManagementPopover({
|
|
|
1110
1112
|
{triggerTrailing}
|
|
1111
1113
|
</button>
|
|
1112
1114
|
</DropdownMenuTrigger>
|
|
1113
|
-
<DropdownMenuContent
|
|
1115
|
+
<DropdownMenuContent
|
|
1116
|
+
align="start"
|
|
1117
|
+
collisionPadding={12}
|
|
1118
|
+
className="relative z-[300] w-72"
|
|
1119
|
+
>
|
|
1114
1120
|
<div
|
|
1115
1121
|
className="flex items-center gap-2 p-1"
|
|
1116
1122
|
onKeyDown={(event) => event.stopPropagation()}
|
|
@@ -1379,15 +1385,17 @@ export function PropertyManagementPopover({
|
|
|
1379
1385
|
</DropdownMenu>
|
|
1380
1386
|
|
|
1381
1387
|
<AlertDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>
|
|
1382
|
-
<AlertDialogContent>
|
|
1383
|
-
<AlertDialogHeader>
|
|
1384
|
-
<AlertDialogTitle>
|
|
1388
|
+
<AlertDialogContent className="max-w-sm gap-0 rounded-lg p-5">
|
|
1389
|
+
<AlertDialogHeader className="space-y-0 gap-1.5 text-start">
|
|
1390
|
+
<AlertDialogTitle className="text-base leading-tight tracking-tight">
|
|
1385
1391
|
{t("editor.properties.deletePropertyQuestion")}
|
|
1386
1392
|
</AlertDialogTitle>
|
|
1387
|
-
<AlertDialogDescription>
|
|
1388
|
-
{t("editor.properties.
|
|
1389
|
-
|
|
1390
|
-
|
|
1393
|
+
<AlertDialogDescription className="leading-normal [text-wrap:pretty]">
|
|
1394
|
+
{t("editor.properties.deletePropertyDescriptionPrefix")}
|
|
1395
|
+
<span className="font-medium text-foreground">
|
|
1396
|
+
{property.definition.name}
|
|
1397
|
+
</span>
|
|
1398
|
+
{t("editor.properties.deletePropertyDescriptionSuffix")}
|
|
1391
1399
|
</AlertDialogDescription>
|
|
1392
1400
|
</AlertDialogHeader>
|
|
1393
1401
|
{isOnlyBlocksField ? (
|
|
@@ -1395,12 +1403,12 @@ export function PropertyManagementPopover({
|
|
|
1395
1403
|
{t("editor.properties.onlyBlocksPropertyWarning")}
|
|
1396
1404
|
</div>
|
|
1397
1405
|
) : null}
|
|
1398
|
-
<AlertDialogFooter>
|
|
1399
|
-
<AlertDialogCancel>
|
|
1406
|
+
<AlertDialogFooter className="mt-4 flex-row items-center justify-end gap-2 sm:space-x-0">
|
|
1407
|
+
<AlertDialogCancel className="mt-0 h-8 px-3 focus-visible:ring-1 focus-visible:ring-muted-foreground/40 focus-visible:ring-offset-1">
|
|
1400
1408
|
{t("editor.properties.cancel")}
|
|
1401
1409
|
</AlertDialogCancel>
|
|
1402
1410
|
<AlertDialogAction
|
|
1403
|
-
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
1411
|
+
className="h-8 bg-destructive px-3 text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-1 focus-visible:ring-muted-foreground/40 focus-visible:ring-offset-1"
|
|
1404
1412
|
onClick={() => void deleteProperty()}
|
|
1405
1413
|
>
|
|
1406
1414
|
{t("editor.properties.deleteProperty")}
|
|
@@ -2651,6 +2659,7 @@ export function AddProperty({
|
|
|
2651
2659
|
}))
|
|
2652
2660
|
.filter((group) => group.fields.length > 0);
|
|
2653
2661
|
const addPropertySearchInputRef = useRef<HTMLInputElement>(null);
|
|
2662
|
+
const addActivationRef = useRef<{ key: string; at: number } | null>(null);
|
|
2654
2663
|
const [pendingPropertyType, setPendingPropertyType] =
|
|
2655
2664
|
useState<DocumentPropertyType | null>(null);
|
|
2656
2665
|
const [pendingSourceFieldId, setPendingSourceFieldId] = useState<
|
|
@@ -2718,6 +2727,39 @@ export function AddProperty({
|
|
|
2718
2727
|
}
|
|
2719
2728
|
}
|
|
2720
2729
|
|
|
2730
|
+
function runAddPropertyActivation(key: string, action: () => void) {
|
|
2731
|
+
const now = Date.now();
|
|
2732
|
+
const previous = addActivationRef.current;
|
|
2733
|
+
if (previous?.key === key && now - previous.at < 750) return;
|
|
2734
|
+
addActivationRef.current = { key, at: now };
|
|
2735
|
+
action();
|
|
2736
|
+
}
|
|
2737
|
+
|
|
2738
|
+
function activateAddPropertyItem(
|
|
2739
|
+
event: Pick<
|
|
2740
|
+
ReactMouseEvent<HTMLButtonElement>,
|
|
2741
|
+
"button" | "preventDefault" | "stopPropagation"
|
|
2742
|
+
>,
|
|
2743
|
+
key: string,
|
|
2744
|
+
action: () => void,
|
|
2745
|
+
) {
|
|
2746
|
+
if (event.button !== 0) return;
|
|
2747
|
+
event.preventDefault();
|
|
2748
|
+
event.stopPropagation();
|
|
2749
|
+
runAddPropertyActivation(key, action);
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
function activateAddPropertyItemFromKeyboard(
|
|
2753
|
+
event: ReactKeyboardEvent<HTMLButtonElement>,
|
|
2754
|
+
key: string,
|
|
2755
|
+
action: () => void,
|
|
2756
|
+
) {
|
|
2757
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
2758
|
+
event.preventDefault();
|
|
2759
|
+
event.stopPropagation();
|
|
2760
|
+
runAddPropertyActivation(key, action);
|
|
2761
|
+
}
|
|
2762
|
+
|
|
2721
2763
|
return (
|
|
2722
2764
|
<Popover
|
|
2723
2765
|
open={open}
|
|
@@ -2747,9 +2789,10 @@ export function AddProperty({
|
|
|
2747
2789
|
</button>
|
|
2748
2790
|
</PopoverTrigger>
|
|
2749
2791
|
<PopoverContent
|
|
2750
|
-
align="start"
|
|
2792
|
+
align={variant === "default" ? "start" : "end"}
|
|
2793
|
+
collisionPadding={12}
|
|
2751
2794
|
portalled={popoversPortalled}
|
|
2752
|
-
className="w-80 p-2"
|
|
2795
|
+
className="relative z-[300] w-80 p-2"
|
|
2753
2796
|
>
|
|
2754
2797
|
<div className="grid gap-2">
|
|
2755
2798
|
<div className="flex h-8 items-center gap-1 rounded border border-border bg-background px-2">
|
|
@@ -2800,7 +2843,33 @@ export function AddProperty({
|
|
|
2800
2843
|
disabled={isAddingProperty}
|
|
2801
2844
|
aria-busy={pendingSourceFieldId === field.id}
|
|
2802
2845
|
className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-accent disabled:opacity-50"
|
|
2803
|
-
|
|
2846
|
+
onPointerDownCapture={(event) =>
|
|
2847
|
+
activateAddPropertyItem(
|
|
2848
|
+
event,
|
|
2849
|
+
`source:${field.id}`,
|
|
2850
|
+
() => {
|
|
2851
|
+
void addFromSourceField(field.id);
|
|
2852
|
+
},
|
|
2853
|
+
)
|
|
2854
|
+
}
|
|
2855
|
+
onClick={(event) =>
|
|
2856
|
+
activateAddPropertyItem(
|
|
2857
|
+
event,
|
|
2858
|
+
`source:${field.id}`,
|
|
2859
|
+
() => {
|
|
2860
|
+
void addFromSourceField(field.id);
|
|
2861
|
+
},
|
|
2862
|
+
)
|
|
2863
|
+
}
|
|
2864
|
+
onKeyDown={(event) =>
|
|
2865
|
+
activateAddPropertyItemFromKeyboard(
|
|
2866
|
+
event,
|
|
2867
|
+
`source:${field.id}`,
|
|
2868
|
+
() => {
|
|
2869
|
+
void addFromSourceField(field.id);
|
|
2870
|
+
},
|
|
2871
|
+
)
|
|
2872
|
+
}
|
|
2804
2873
|
>
|
|
2805
2874
|
{pendingSourceFieldId === field.id ? (
|
|
2806
2875
|
<Spinner className="size-4 shrink-0 text-muted-foreground" />
|
|
@@ -2837,7 +2906,25 @@ export function AddProperty({
|
|
|
2837
2906
|
className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-accent"
|
|
2838
2907
|
disabled={isAddingProperty}
|
|
2839
2908
|
aria-busy={pendingPropertyType === type}
|
|
2840
|
-
|
|
2909
|
+
onPointerDownCapture={(event) =>
|
|
2910
|
+
activateAddPropertyItem(event, `type:${type}`, () => {
|
|
2911
|
+
void add(type);
|
|
2912
|
+
})
|
|
2913
|
+
}
|
|
2914
|
+
onClick={(event) =>
|
|
2915
|
+
activateAddPropertyItem(event, `type:${type}`, () => {
|
|
2916
|
+
void add(type);
|
|
2917
|
+
})
|
|
2918
|
+
}
|
|
2919
|
+
onKeyDown={(event) =>
|
|
2920
|
+
activateAddPropertyItemFromKeyboard(
|
|
2921
|
+
event,
|
|
2922
|
+
`type:${type}`,
|
|
2923
|
+
() => {
|
|
2924
|
+
void add(type);
|
|
2925
|
+
},
|
|
2926
|
+
)
|
|
2927
|
+
}
|
|
2841
2928
|
>
|
|
2842
2929
|
{pendingPropertyType === type ? (
|
|
2843
2930
|
<Spinner className="size-4 text-muted-foreground" />
|
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
CreateDatabaseRequest,
|
|
19
19
|
DatabaseItemsBatchRequest,
|
|
20
20
|
DisconnectContentDatabaseSourceRequest,
|
|
21
|
+
DocumentPropertiesResponse,
|
|
21
22
|
ExecuteBuilderSourceBatchRequest,
|
|
22
23
|
ExecuteBuilderSourceBatchResponse,
|
|
23
24
|
DuplicateDatabaseItemRequest,
|
|
@@ -131,6 +132,57 @@ export function applyDocumentPropertyValueToDatabaseResponse(
|
|
|
131
132
|
return changed ? { ...current, items } : current;
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
export function applyDocumentPropertiesToDatabaseResponse(
|
|
136
|
+
current: ContentDatabaseResponse | undefined,
|
|
137
|
+
response: Pick<DocumentPropertiesResponse, "databaseId" | "properties">,
|
|
138
|
+
): ContentDatabaseResponse | undefined {
|
|
139
|
+
if (!current) return current;
|
|
140
|
+
if (response.databaseId && current.database.id !== response.databaseId) {
|
|
141
|
+
return current;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const sortedProperties = [...response.properties].sort(
|
|
145
|
+
(a, b) => a.definition.position - b.definition.position,
|
|
146
|
+
);
|
|
147
|
+
const propertyById = new Map(
|
|
148
|
+
sortedProperties.map((property) => [property.definition.id, property]),
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
...current,
|
|
153
|
+
properties: sortedProperties,
|
|
154
|
+
items: current.items.map((item) => ({
|
|
155
|
+
...item,
|
|
156
|
+
properties: item.properties
|
|
157
|
+
.filter((property) => propertyById.has(property.definition.id))
|
|
158
|
+
.map((property) => ({
|
|
159
|
+
...propertyById.get(property.definition.id)!,
|
|
160
|
+
value: property.value,
|
|
161
|
+
})),
|
|
162
|
+
})),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function removeDocumentPropertyFromDatabaseResponse(
|
|
167
|
+
current: ContentDatabaseResponse | undefined,
|
|
168
|
+
propertyId: string,
|
|
169
|
+
): ContentDatabaseResponse | undefined {
|
|
170
|
+
if (!current) return current;
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
...current,
|
|
174
|
+
properties: current.properties.filter(
|
|
175
|
+
(property) => property.definition.id !== propertyId,
|
|
176
|
+
),
|
|
177
|
+
items: current.items.map((item) => ({
|
|
178
|
+
...item,
|
|
179
|
+
properties: item.properties.filter(
|
|
180
|
+
(property) => property.definition.id !== propertyId,
|
|
181
|
+
),
|
|
182
|
+
})),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
134
186
|
// `get-content-database` returns a union at runtime: the full response, or an
|
|
135
187
|
// unavailable payload (`{ available: false, reason: "deleted" | "not_found" }`)
|
|
136
188
|
// with no `database` field. Consumers typed against ContentDatabaseResponse
|
|
@@ -12,9 +12,11 @@ import type {
|
|
|
12
12
|
import { useQueryClient } from "@tanstack/react-query";
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
|
+
applyDocumentPropertiesToDatabaseResponse,
|
|
15
16
|
applyDocumentPropertyValueToDatabaseResponse,
|
|
16
17
|
contentDatabaseQueryFilter,
|
|
17
18
|
contentDatabaseQueryKey,
|
|
19
|
+
removeDocumentPropertyFromDatabaseResponse,
|
|
18
20
|
} from "./use-content-database";
|
|
19
21
|
|
|
20
22
|
export function useDocumentProperties(documentId: string | null) {
|
|
@@ -37,7 +39,12 @@ export function useConfigureDocumentProperty(
|
|
|
37
39
|
DocumentPropertiesResponse,
|
|
38
40
|
ConfigureDocumentPropertyRequest
|
|
39
41
|
>("configure-document-property", {
|
|
40
|
-
|
|
42
|
+
skipActionQueryInvalidation: true,
|
|
43
|
+
onSuccess: (data) => {
|
|
44
|
+
queryClient.setQueriesData<ContentDatabaseResponse>(
|
|
45
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
46
|
+
(current) => applyDocumentPropertiesToDatabaseResponse(current, data),
|
|
47
|
+
);
|
|
41
48
|
queryClient.invalidateQueries({
|
|
42
49
|
queryKey: ["action", "list-document-properties", { documentId }],
|
|
43
50
|
});
|
|
@@ -45,7 +52,7 @@ export function useConfigureDocumentProperty(
|
|
|
45
52
|
queryKey: ["action", "get-document", { id: documentId }],
|
|
46
53
|
});
|
|
47
54
|
queryClient.invalidateQueries({
|
|
48
|
-
|
|
55
|
+
...contentDatabaseQueryFilter(databaseDocumentId),
|
|
49
56
|
});
|
|
50
57
|
},
|
|
51
58
|
});
|
|
@@ -135,7 +142,12 @@ export function useDuplicateDocumentProperty(
|
|
|
135
142
|
DocumentPropertiesResponse,
|
|
136
143
|
DuplicateDocumentPropertyRequest
|
|
137
144
|
>("duplicate-document-property", {
|
|
138
|
-
|
|
145
|
+
skipActionQueryInvalidation: true,
|
|
146
|
+
onSuccess: (data) => {
|
|
147
|
+
queryClient.setQueriesData<ContentDatabaseResponse>(
|
|
148
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
149
|
+
(current) => applyDocumentPropertiesToDatabaseResponse(current, data),
|
|
150
|
+
);
|
|
139
151
|
queryClient.invalidateQueries({
|
|
140
152
|
queryKey: ["action", "list-document-properties", { documentId }],
|
|
141
153
|
});
|
|
@@ -143,7 +155,7 @@ export function useDuplicateDocumentProperty(
|
|
|
143
155
|
queryKey: ["action", "get-document", { id: documentId }],
|
|
144
156
|
});
|
|
145
157
|
queryClient.invalidateQueries({
|
|
146
|
-
|
|
158
|
+
...contentDatabaseQueryFilter(databaseDocumentId),
|
|
147
159
|
});
|
|
148
160
|
},
|
|
149
161
|
});
|
|
@@ -181,7 +193,39 @@ export function useDeleteDocumentProperty(
|
|
|
181
193
|
DocumentPropertiesResponse,
|
|
182
194
|
DeleteDocumentPropertyRequest
|
|
183
195
|
>("delete-document-property", {
|
|
184
|
-
|
|
196
|
+
skipActionQueryInvalidation: true,
|
|
197
|
+
onMutate: async (variables) => {
|
|
198
|
+
await queryClient.cancelQueries(
|
|
199
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
200
|
+
);
|
|
201
|
+
const previous = queryClient.getQueriesData<ContentDatabaseResponse>(
|
|
202
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
203
|
+
);
|
|
204
|
+
queryClient.setQueriesData<ContentDatabaseResponse>(
|
|
205
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
206
|
+
(current) =>
|
|
207
|
+
removeDocumentPropertyFromDatabaseResponse(
|
|
208
|
+
current,
|
|
209
|
+
variables.propertyId,
|
|
210
|
+
),
|
|
211
|
+
);
|
|
212
|
+
return { previous };
|
|
213
|
+
},
|
|
214
|
+
onError: (_error, _variables, context) => {
|
|
215
|
+
const rollback = context as
|
|
216
|
+
| {
|
|
217
|
+
previous?: Array<[readonly unknown[], unknown]>;
|
|
218
|
+
}
|
|
219
|
+
| undefined;
|
|
220
|
+
for (const [queryKey, data] of rollback?.previous ?? []) {
|
|
221
|
+
queryClient.setQueryData(queryKey, data);
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
onSuccess: (data) => {
|
|
225
|
+
queryClient.setQueriesData<ContentDatabaseResponse>(
|
|
226
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
227
|
+
(current) => applyDocumentPropertiesToDatabaseResponse(current, data),
|
|
228
|
+
);
|
|
185
229
|
queryClient.invalidateQueries({
|
|
186
230
|
queryKey: ["action", "list-document-properties", { documentId }],
|
|
187
231
|
});
|
|
@@ -189,7 +233,7 @@ export function useDeleteDocumentProperty(
|
|
|
189
233
|
queryKey: ["action", "get-document", { id: documentId }],
|
|
190
234
|
});
|
|
191
235
|
queryClient.invalidateQueries({
|
|
192
|
-
|
|
236
|
+
...contentDatabaseQueryFilter(databaseDocumentId),
|
|
193
237
|
});
|
|
194
238
|
},
|
|
195
239
|
});
|
|
@@ -307,6 +307,8 @@ const messages = {
|
|
|
307
307
|
deleteProperty: "刪除屬性",
|
|
308
308
|
deletePropertyDescription:
|
|
309
309
|
'這將從該工作區中的每個檔案中刪除"{{name}}"及其值。',
|
|
310
|
+
deletePropertyDescriptionPrefix: '這將從該工作區中的每個檔案中刪除"',
|
|
311
|
+
deletePropertyDescriptionSuffix: '"及其值。',
|
|
310
312
|
deletePropertyQuestion: "刪除屬性?",
|
|
311
313
|
duplicateProperty: "重複的屬性",
|
|
312
314
|
editEndDate: "編輯 {{name}} 結束日期",
|