@agent-native/core 0.90.4 → 0.90.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -7
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +21 -0
- package/corpus/core/docs/content/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +1 -1
- package/corpus/core/docs/content/toolkit-agent-ux.mdx +1 -1
- package/corpus/core/docs/content/toolkit-app-adapters.mdx +1 -1
- package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +1 -1
- package/corpus/core/docs/content/toolkit-collaboration.mdx +1 -1
- package/corpus/core/docs/content/toolkit-command-navigation.mdx +2 -2
- package/corpus/core/docs/content/toolkit-comments-review.mdx +1 -1
- package/corpus/core/docs/content/toolkit-history.mdx +1 -1
- package/corpus/core/docs/content/toolkit-observability.mdx +1 -1
- package/corpus/core/docs/content/toolkit-org-team.mdx +1 -1
- package/corpus/core/docs/content/toolkit-resources.mdx +1 -1
- package/corpus/core/docs/content/toolkit-settings.mdx +1 -1
- package/corpus/core/docs/content/toolkit-setup-connections.mdx +1 -1
- package/corpus/core/docs/content/toolkit-sharing-ui.mdx +1 -1
- package/corpus/core/docs/content/toolkit-sharing.mdx +1 -1
- package/corpus/core/docs/content/toolkit-shell-hooks.mdx +1 -1
- package/corpus/core/docs/content/toolkit-ui.mdx +1 -1
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +18 -18
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +8 -2
- package/corpus/core/src/agent/engine/anthropic-engine.ts +11 -1
- package/corpus/core/src/agent/production-agent.ts +22 -11
- package/corpus/core/src/agent/run-manager.ts +17 -6
- package/corpus/core/src/agent/run-store.ts +16 -11
- package/corpus/core/src/cli/design-connect.ts +16 -2
- package/corpus/core/src/client/KeepTabOpenNotice.tsx +20 -15
- package/corpus/core/src/client/RunStuckBanner.tsx +14 -13
- package/corpus/core/src/client/agent-chat-adapter.ts +28 -17
- package/corpus/core/src/client/use-db-sync.ts +99 -1
- package/corpus/core/src/client/use-run-stuck-detection.ts +8 -5
- package/corpus/core/src/collab/client.ts +49 -4
- package/corpus/core/src/deploy/build.ts +103 -0
- package/corpus/core/src/server/core-routes-plugin.ts +137 -8
- package/corpus/templates/clips/changelog/2026-07-07-faster-local-whisper-dictation-start.md +6 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +311 -31
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +2 -0
- package/corpus/templates/content/AGENTS.md +1 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +73 -8
- package/corpus/templates/content/actions/_database-utils.ts +2 -1
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +20 -1
- package/corpus/templates/content/actions/stage-builder-source-bulk-update.ts +663 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +33 -7
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +53 -4
- package/corpus/templates/content/app/components/editor/database/settings.tsx +24 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +70 -1
- package/corpus/templates/content/app/hooks/use-document-properties.ts +63 -5
- package/corpus/templates/content/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/content/app/i18n-data.ts +31 -0
- package/corpus/templates/content/changelog/2026-07-01-builder-source-rows-can-be-staged-in-bulk-with-a-reviewable.md +6 -0
- package/corpus/templates/content/changelog/2026-07-07-builder-backed-database-fields-now-edit-like-normal-content-fields.md +6 -0
- package/corpus/templates/content/parity/matrix.md +24 -24
- package/corpus/templates/content/parity/matrix.ts +2 -0
- package/corpus/templates/content/shared/api.ts +59 -4
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +9 -0
- package/corpus/templates/design/actions/connect-localhost.ts +26 -3
- package/corpus/templates/design/actions/open-visual-edit.ts +4 -37
- package/corpus/templates/design/actions/read-source-file.ts +28 -0
- package/corpus/templates/design/actions/update-file.ts +76 -7
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +207 -11
- package/corpus/templates/design/app/components/design/EditPanel.tsx +4 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +387 -25
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1110 -88
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +368 -16
- package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +24 -0
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +27 -6
- package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +18 -0
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +5 -4
- package/corpus/templates/design/app/components/design/multi-screen/handle-hit-zones.ts +124 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +23 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/design/app/i18n-data.ts +19 -0
- package/corpus/templates/design/changelog/2026-07-07-dragging-a-free-floating-element-into-a-layout-column-or-row.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-dragging-a-repeated-list-item-like-a-to-do-card-generated-fr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-dragging-an-element-onto-a-button-or-chip-s-middle-no-longer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-elements-dropped-into-another-board-shape-now-stay-exactly-w.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-fixed-drag-reordering-elements-within-a-screen-no-longer-sil.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-fixed-dragging-an-element-from-a-screen-onto-the-canvas-now-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-fixed-dragging-elements-between-screens-into-ai-generated-co.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-fixed-moving-elements-between-screens-no-longer-bakes-intern.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-fixed-the-cross-screen-drop-indicator-now-points-at-the-corr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-fixed-the-zoom-menu-no-longer-leaves-the-canvas-unresponsive.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-keeps-bridge-access-when-opening-previousl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-now-keeps-the-live-app-connection-authenti.md +6 -0
- package/corpus/templates/design/changelog/2026-07-07-text-drawn-on-the-canvas-is-now-readable-white-instead-of-in.md +6 -0
- package/corpus/templates/design/server/source-workspace.ts +27 -3
- package/corpus/templates/design/shared/board-file.ts +359 -0
- package/corpus/templates/design/shared/breakpoint-media.ts +21 -3
- package/corpus/templates/design/shared/code-layer.ts +145 -10
- package/dist/agent/durable-background.d.ts +12 -12
- package/dist/agent/durable-background.js +18 -18
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +8 -2
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +11 -1
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/production-agent.d.ts +2 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +18 -11
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +7 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +6 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +15 -10
- package/dist/agent/run-store.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +12 -2
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/client/KeepTabOpenNotice.d.ts +9 -10
- package/dist/client/KeepTabOpenNotice.d.ts.map +1 -1
- package/dist/client/KeepTabOpenNotice.js +8 -4
- package/dist/client/KeepTabOpenNotice.js.map +1 -1
- package/dist/client/RunStuckBanner.d.ts.map +1 -1
- package/dist/client/RunStuckBanner.js +14 -13
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +25 -17
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +18 -0
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +88 -1
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-run-stuck-detection.d.ts +1 -1
- package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
- package/dist/client/use-run-stuck-detection.js +6 -4
- package/dist/client/use-run-stuck-detection.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +43 -4
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.d.ts +1 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +57 -0
- package/dist/deploy/build.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +10 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +103 -9
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/docs/content/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/de-DE/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/es-ES/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +1 -1
- package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +1 -1
- package/docs/content/toolkit-agent-ux.mdx +1 -1
- package/docs/content/toolkit-app-adapters.mdx +1 -1
- package/docs/content/toolkit-collaboration-ui.mdx +1 -1
- package/docs/content/toolkit-collaboration.mdx +1 -1
- package/docs/content/toolkit-command-navigation.mdx +2 -2
- package/docs/content/toolkit-comments-review.mdx +1 -1
- package/docs/content/toolkit-history.mdx +1 -1
- package/docs/content/toolkit-observability.mdx +1 -1
- package/docs/content/toolkit-org-team.mdx +1 -1
- package/docs/content/toolkit-resources.mdx +1 -1
- package/docs/content/toolkit-settings.mdx +1 -1
- package/docs/content/toolkit-setup-connections.mdx +1 -1
- package/docs/content/toolkit-sharing-ui.mdx +1 -1
- package/docs/content/toolkit-sharing.mdx +1 -1
- package/docs/content/toolkit-shell-hooks.mdx +1 -1
- package/docs/content/toolkit-ui.mdx +1 -1
- package/package.json +1 -1
|
@@ -1523,11 +1523,13 @@ function PropertyOptionSettingsRow({
|
|
|
1523
1523
|
export function PropertyValuePopover({
|
|
1524
1524
|
property,
|
|
1525
1525
|
documentId,
|
|
1526
|
+
databaseDocumentId = documentId,
|
|
1526
1527
|
children,
|
|
1527
1528
|
portalled = true,
|
|
1528
1529
|
}: {
|
|
1529
1530
|
property: DocumentProperty;
|
|
1530
1531
|
documentId: string;
|
|
1532
|
+
databaseDocumentId?: string;
|
|
1531
1533
|
children: React.ReactNode;
|
|
1532
1534
|
portalled?: boolean;
|
|
1533
1535
|
}) {
|
|
@@ -1551,6 +1553,7 @@ export function PropertyValuePopover({
|
|
|
1551
1553
|
<PropertyValueEditor
|
|
1552
1554
|
property={property}
|
|
1553
1555
|
documentId={documentId}
|
|
1556
|
+
databaseDocumentId={databaseDocumentId}
|
|
1554
1557
|
onDone={() => setOpen(false)}
|
|
1555
1558
|
/>
|
|
1556
1559
|
</PopoverContent>
|
|
@@ -1561,10 +1564,12 @@ export function PropertyValuePopover({
|
|
|
1561
1564
|
function PropertyValueEditor({
|
|
1562
1565
|
property,
|
|
1563
1566
|
documentId,
|
|
1567
|
+
databaseDocumentId,
|
|
1564
1568
|
onDone,
|
|
1565
1569
|
}: {
|
|
1566
1570
|
property: DocumentProperty;
|
|
1567
1571
|
documentId: string;
|
|
1572
|
+
databaseDocumentId: string;
|
|
1568
1573
|
onDone: () => void;
|
|
1569
1574
|
}) {
|
|
1570
1575
|
const type = property.definition.type;
|
|
@@ -1573,6 +1578,7 @@ function PropertyValueEditor({
|
|
|
1573
1578
|
<OptionValueEditor
|
|
1574
1579
|
property={property}
|
|
1575
1580
|
documentId={documentId}
|
|
1581
|
+
databaseDocumentId={databaseDocumentId}
|
|
1576
1582
|
onDone={onDone}
|
|
1577
1583
|
/>
|
|
1578
1584
|
);
|
|
@@ -1583,6 +1589,7 @@ function PropertyValueEditor({
|
|
|
1583
1589
|
<CheckboxValueEditor
|
|
1584
1590
|
property={property}
|
|
1585
1591
|
documentId={documentId}
|
|
1592
|
+
databaseDocumentId={databaseDocumentId}
|
|
1586
1593
|
onDone={onDone}
|
|
1587
1594
|
/>
|
|
1588
1595
|
);
|
|
@@ -1593,6 +1600,7 @@ function PropertyValueEditor({
|
|
|
1593
1600
|
<DateValueEditor
|
|
1594
1601
|
property={property}
|
|
1595
1602
|
documentId={documentId}
|
|
1603
|
+
databaseDocumentId={databaseDocumentId}
|
|
1596
1604
|
onDone={onDone}
|
|
1597
1605
|
/>
|
|
1598
1606
|
);
|
|
@@ -1603,6 +1611,7 @@ function PropertyValueEditor({
|
|
|
1603
1611
|
<PersonValueEditor
|
|
1604
1612
|
property={property}
|
|
1605
1613
|
documentId={documentId}
|
|
1614
|
+
databaseDocumentId={databaseDocumentId}
|
|
1606
1615
|
onDone={onDone}
|
|
1607
1616
|
/>
|
|
1608
1617
|
);
|
|
@@ -1613,6 +1622,7 @@ function PropertyValueEditor({
|
|
|
1613
1622
|
<FilesMediaValueEditor
|
|
1614
1623
|
property={property}
|
|
1615
1624
|
documentId={documentId}
|
|
1625
|
+
databaseDocumentId={databaseDocumentId}
|
|
1616
1626
|
onDone={onDone}
|
|
1617
1627
|
/>
|
|
1618
1628
|
);
|
|
@@ -1622,6 +1632,7 @@ function PropertyValueEditor({
|
|
|
1622
1632
|
<ScalarValueEditor
|
|
1623
1633
|
property={property}
|
|
1624
1634
|
documentId={documentId}
|
|
1635
|
+
databaseDocumentId={databaseDocumentId}
|
|
1625
1636
|
onDone={onDone}
|
|
1626
1637
|
/>
|
|
1627
1638
|
);
|
|
@@ -1630,14 +1641,16 @@ function PropertyValueEditor({
|
|
|
1630
1641
|
function PersonValueEditor({
|
|
1631
1642
|
property,
|
|
1632
1643
|
documentId,
|
|
1644
|
+
databaseDocumentId,
|
|
1633
1645
|
onDone,
|
|
1634
1646
|
}: {
|
|
1635
1647
|
property: DocumentProperty;
|
|
1636
1648
|
documentId: string;
|
|
1649
|
+
databaseDocumentId: string;
|
|
1637
1650
|
onDone: () => void;
|
|
1638
1651
|
}) {
|
|
1639
1652
|
const t = useT();
|
|
1640
|
-
const mutation = useSetDocumentProperty(documentId);
|
|
1653
|
+
const mutation = useSetDocumentProperty(documentId, databaseDocumentId);
|
|
1641
1654
|
const { session } = useSession();
|
|
1642
1655
|
const [people, setPeople] = useState(() => personItems(property.value));
|
|
1643
1656
|
const [query, setQuery] = useState("");
|
|
@@ -1829,14 +1842,16 @@ function PersonValueEditor({
|
|
|
1829
1842
|
function FilesMediaValueEditor({
|
|
1830
1843
|
property,
|
|
1831
1844
|
documentId,
|
|
1845
|
+
databaseDocumentId,
|
|
1832
1846
|
onDone,
|
|
1833
1847
|
}: {
|
|
1834
1848
|
property: DocumentProperty;
|
|
1835
1849
|
documentId: string;
|
|
1850
|
+
databaseDocumentId: string;
|
|
1836
1851
|
onDone: () => void;
|
|
1837
1852
|
}) {
|
|
1838
1853
|
const t = useT();
|
|
1839
|
-
const mutation = useSetDocumentProperty(documentId);
|
|
1854
|
+
const mutation = useSetDocumentProperty(documentId, databaseDocumentId);
|
|
1840
1855
|
const [items, setItems] = useState(() => filesMediaItems(property.value));
|
|
1841
1856
|
const [linkValue, setLinkValue] = useState("");
|
|
1842
1857
|
const [uploading, setUploading] = useState(false);
|
|
@@ -2036,14 +2051,16 @@ function FilesMediaValueEditor({
|
|
|
2036
2051
|
function DateValueEditor({
|
|
2037
2052
|
property,
|
|
2038
2053
|
documentId,
|
|
2054
|
+
databaseDocumentId,
|
|
2039
2055
|
onDone,
|
|
2040
2056
|
}: {
|
|
2041
2057
|
property: DocumentProperty;
|
|
2042
2058
|
documentId: string;
|
|
2059
|
+
databaseDocumentId: string;
|
|
2043
2060
|
onDone: () => void;
|
|
2044
2061
|
}) {
|
|
2045
2062
|
const t = useT();
|
|
2046
|
-
const mutation = useSetDocumentProperty(documentId);
|
|
2063
|
+
const mutation = useSetDocumentProperty(documentId, databaseDocumentId);
|
|
2047
2064
|
const [includeTime, setIncludeTime] = useState(
|
|
2048
2065
|
documentPropertyDateIncludesTime(property.value),
|
|
2049
2066
|
);
|
|
@@ -2249,14 +2266,16 @@ function DateValueEditor({
|
|
|
2249
2266
|
function ScalarValueEditor({
|
|
2250
2267
|
property,
|
|
2251
2268
|
documentId,
|
|
2269
|
+
databaseDocumentId,
|
|
2252
2270
|
onDone,
|
|
2253
2271
|
}: {
|
|
2254
2272
|
property: DocumentProperty;
|
|
2255
2273
|
documentId: string;
|
|
2274
|
+
databaseDocumentId: string;
|
|
2256
2275
|
onDone: () => void;
|
|
2257
2276
|
}) {
|
|
2258
2277
|
const t = useT();
|
|
2259
|
-
const mutation = useSetDocumentProperty(documentId);
|
|
2278
|
+
const mutation = useSetDocumentProperty(documentId, databaseDocumentId);
|
|
2260
2279
|
const type = property.definition.type;
|
|
2261
2280
|
const inputType =
|
|
2262
2281
|
type === "number"
|
|
@@ -2357,14 +2376,16 @@ function ScalarValueEditor({
|
|
|
2357
2376
|
function CheckboxValueEditor({
|
|
2358
2377
|
property,
|
|
2359
2378
|
documentId,
|
|
2379
|
+
databaseDocumentId,
|
|
2360
2380
|
onDone,
|
|
2361
2381
|
}: {
|
|
2362
2382
|
property: DocumentProperty;
|
|
2363
2383
|
documentId: string;
|
|
2384
|
+
databaseDocumentId: string;
|
|
2364
2385
|
onDone: () => void;
|
|
2365
2386
|
}) {
|
|
2366
2387
|
const t = useT();
|
|
2367
|
-
const mutation = useSetDocumentProperty(documentId);
|
|
2388
|
+
const mutation = useSetDocumentProperty(documentId, databaseDocumentId);
|
|
2368
2389
|
const checked = Boolean(property.value);
|
|
2369
2390
|
|
|
2370
2391
|
return (
|
|
@@ -2396,15 +2417,20 @@ function CheckboxValueEditor({
|
|
|
2396
2417
|
function OptionValueEditor({
|
|
2397
2418
|
property,
|
|
2398
2419
|
documentId,
|
|
2420
|
+
databaseDocumentId,
|
|
2399
2421
|
onDone,
|
|
2400
2422
|
}: {
|
|
2401
2423
|
property: DocumentProperty;
|
|
2402
2424
|
documentId: string;
|
|
2425
|
+
databaseDocumentId: string;
|
|
2403
2426
|
onDone: () => void;
|
|
2404
2427
|
}) {
|
|
2405
2428
|
const t = useT();
|
|
2406
|
-
const setValue = useSetDocumentProperty(documentId);
|
|
2407
|
-
const configure = useConfigureDocumentProperty(
|
|
2429
|
+
const setValue = useSetDocumentProperty(documentId, databaseDocumentId);
|
|
2430
|
+
const configure = useConfigureDocumentProperty(
|
|
2431
|
+
documentId,
|
|
2432
|
+
databaseDocumentId,
|
|
2433
|
+
);
|
|
2408
2434
|
const options = property.definition.options.options ?? [];
|
|
2409
2435
|
const [optionQuery, setOptionQuery] = useState("");
|
|
2410
2436
|
const filteredOptions = filterPropertyOptions(options, optionQuery);
|
|
@@ -1223,9 +1223,15 @@ function DatabaseTable({
|
|
|
1223
1223
|
) {
|
|
1224
1224
|
setBuilderReviewResult(null);
|
|
1225
1225
|
setBuilderReviewCheckedAt(null);
|
|
1226
|
+
const scopedChangeSetIds =
|
|
1227
|
+
activeBuilderReview && activeBuilderReview.rows.length > 0
|
|
1228
|
+
? activeBuilderReview.rows.map((row) => row.changeSetId)
|
|
1229
|
+
: undefined;
|
|
1226
1230
|
try {
|
|
1227
1231
|
const prepared = await prepareBuilderReview.mutateAsync({
|
|
1228
1232
|
documentId: document.id,
|
|
1233
|
+
sourceId: source?.id,
|
|
1234
|
+
changeSetIds: scopedChangeSetIds,
|
|
1229
1235
|
pushModeConfirmation: "autosave",
|
|
1230
1236
|
});
|
|
1231
1237
|
let nextReview = prepared.review;
|
|
@@ -2243,6 +2249,25 @@ export function databaseBulkEditableProperties(properties: DocumentProperty[]) {
|
|
|
2243
2249
|
);
|
|
2244
2250
|
}
|
|
2245
2251
|
|
|
2252
|
+
export function databaseBuilderBulkUpdateSource(
|
|
2253
|
+
sources: ContentDatabaseSource[],
|
|
2254
|
+
primarySource: ContentDatabaseSource | null,
|
|
2255
|
+
selectedItems: ContentDatabaseItem[],
|
|
2256
|
+
) {
|
|
2257
|
+
if (selectedItems.length === 0) return null;
|
|
2258
|
+
const candidates =
|
|
2259
|
+
sources.length > 0 ? sources : primarySource ? [primarySource] : [];
|
|
2260
|
+
return (
|
|
2261
|
+
candidates.find(
|
|
2262
|
+
(candidate) =>
|
|
2263
|
+
candidate.sourceType === "builder-cms" &&
|
|
2264
|
+
selectedItems.every((item) =>
|
|
2265
|
+
candidate.rows.some((row) => row.documentId === item.document.id),
|
|
2266
|
+
),
|
|
2267
|
+
) ?? null
|
|
2268
|
+
);
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2246
2271
|
export function databaseBulkScalarInputState(
|
|
2247
2272
|
type: DocumentPropertyType,
|
|
2248
2273
|
input: string,
|
|
@@ -6068,6 +6093,30 @@ function BuilderSpaceModelsView({
|
|
|
6068
6093
|
const [query, setQuery] = useState("");
|
|
6069
6094
|
|
|
6070
6095
|
if (modelsQuery.isLoading) {
|
|
6096
|
+
if (attachedModelName) {
|
|
6097
|
+
return (
|
|
6098
|
+
<div className="grid min-w-0 gap-2">
|
|
6099
|
+
<div className="grid min-w-0 gap-1.5">
|
|
6100
|
+
<div className="px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
|
|
6101
|
+
{dbText("alreadyAttached")}
|
|
6102
|
+
</div>
|
|
6103
|
+
<div className="flex min-w-0 items-center justify-between gap-2 rounded-md px-2 py-1.5 text-left text-sm">
|
|
6104
|
+
<span className="flex min-w-0 items-center gap-2">
|
|
6105
|
+
<IconLayoutGrid className="size-4 shrink-0 text-muted-foreground" />
|
|
6106
|
+
<span className="min-w-0 truncate">{attachedModelName}</span>
|
|
6107
|
+
</span>
|
|
6108
|
+
<span className="shrink-0 rounded border border-border px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
6109
|
+
attached
|
|
6110
|
+
</span>
|
|
6111
|
+
</div>
|
|
6112
|
+
</div>
|
|
6113
|
+
<div className="flex min-w-0 items-center gap-2 px-2 text-xs text-muted-foreground">
|
|
6114
|
+
<Spinner className="size-3.5" />
|
|
6115
|
+
{dbText("loadingBuilderModels")}
|
|
6116
|
+
</div>
|
|
6117
|
+
</div>
|
|
6118
|
+
);
|
|
6119
|
+
}
|
|
6071
6120
|
return (
|
|
6072
6121
|
<div className="flex min-w-0 items-center gap-2 text-xs text-muted-foreground">
|
|
6073
6122
|
<Spinner className="size-3.5" />
|
|
@@ -12096,7 +12145,7 @@ function DatabaseBulkEditPopover({
|
|
|
12096
12145
|
disabled={disabled}
|
|
12097
12146
|
>
|
|
12098
12147
|
<IconPencil className="size-3.5" />
|
|
12099
|
-
|
|
12148
|
+
Edit
|
|
12100
12149
|
</Button>
|
|
12101
12150
|
</PopoverTrigger>
|
|
12102
12151
|
<PopoverContent align="start" className="w-[28rem] p-2">
|
|
@@ -12308,7 +12357,7 @@ function DatabaseBulkScalarValueEditor({
|
|
|
12308
12357
|
autoFocus
|
|
12309
12358
|
value={value}
|
|
12310
12359
|
type={inputType}
|
|
12311
|
-
aria-label={`
|
|
12360
|
+
aria-label={`Edit ${property.definition.name} for selected rows`}
|
|
12312
12361
|
placeholder="Value"
|
|
12313
12362
|
onChange={(event) => setValue(event.target.value)}
|
|
12314
12363
|
onKeyDown={(event) => {
|
|
@@ -12370,7 +12419,7 @@ function DatabaseBulkFilesValueEditor({
|
|
|
12370
12419
|
>
|
|
12371
12420
|
<textarea
|
|
12372
12421
|
autoFocus
|
|
12373
|
-
aria-label="
|
|
12422
|
+
aria-label={dbText("editFilesForSelectedRows")}
|
|
12374
12423
|
value={value}
|
|
12375
12424
|
placeholder={dbText("oneFileOrMediaLinkPerLine")}
|
|
12376
12425
|
rows={4}
|
|
@@ -14508,7 +14557,6 @@ function DatabaseTableRow({
|
|
|
14508
14557
|
item.properties.find(
|
|
14509
14558
|
(candidate) => candidate.definition.id === property.definition.id,
|
|
14510
14559
|
) ?? property;
|
|
14511
|
-
|
|
14512
14560
|
const value = (
|
|
14513
14561
|
<div
|
|
14514
14562
|
className={cn(
|
|
@@ -14555,6 +14603,7 @@ function DatabaseTableRow({
|
|
|
14555
14603
|
<PropertyValuePopover
|
|
14556
14604
|
property={itemProperty}
|
|
14557
14605
|
documentId={item.document.id}
|
|
14606
|
+
databaseDocumentId={databaseDocumentId}
|
|
14558
14607
|
>
|
|
14559
14608
|
{value}
|
|
14560
14609
|
</PropertyValuePopover>
|
|
@@ -2108,6 +2108,30 @@ function BuilderSpaceModelsView({
|
|
|
2108
2108
|
const [query, setQuery] = useState("");
|
|
2109
2109
|
|
|
2110
2110
|
if (modelsQuery.isLoading) {
|
|
2111
|
+
if (attachedModelName) {
|
|
2112
|
+
return (
|
|
2113
|
+
<div className="grid min-w-0 gap-2">
|
|
2114
|
+
<div className="grid min-w-0 gap-1.5">
|
|
2115
|
+
<div className="px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
|
|
2116
|
+
{dbText("alreadyAttached")}
|
|
2117
|
+
</div>
|
|
2118
|
+
<div className="flex min-w-0 items-center justify-between gap-2 rounded-md px-2 py-1.5 text-left text-sm">
|
|
2119
|
+
<span className="flex min-w-0 items-center gap-2">
|
|
2120
|
+
<IconLayoutGrid className="size-4 shrink-0 text-muted-foreground" />
|
|
2121
|
+
<span className="min-w-0 truncate">{attachedModelName}</span>
|
|
2122
|
+
</span>
|
|
2123
|
+
<span className="shrink-0 rounded border border-border px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
2124
|
+
attached
|
|
2125
|
+
</span>
|
|
2126
|
+
</div>
|
|
2127
|
+
</div>
|
|
2128
|
+
<div className="flex min-w-0 items-center gap-2 px-2 text-xs text-muted-foreground">
|
|
2129
|
+
<Spinner className="size-3.5" />
|
|
2130
|
+
{dbText("loadingBuilderModels")}
|
|
2131
|
+
</div>
|
|
2132
|
+
</div>
|
|
2133
|
+
);
|
|
2134
|
+
}
|
|
2111
2135
|
return (
|
|
2112
2136
|
<div className="flex min-w-0 items-center gap-2 text-xs text-muted-foreground">
|
|
2113
2137
|
<Spinner className="size-3.5" />
|
|
@@ -30,6 +30,8 @@ import type {
|
|
|
30
30
|
RefreshContentDatabaseSourceRequest,
|
|
31
31
|
ReviewContentDatabaseSourceChangeSetRequest,
|
|
32
32
|
SetContentDatabaseSourceWriteModeRequest,
|
|
33
|
+
StageBuilderSourceBulkUpdateRequest,
|
|
34
|
+
StageBuilderSourceBulkUpdateResponse,
|
|
33
35
|
StageBuilderRevisionRequest,
|
|
34
36
|
SuggestSourceJoinKeyResponse,
|
|
35
37
|
UpdateContentDatabaseViewRequest,
|
|
@@ -58,7 +60,7 @@ function isContentDatabaseQueryForDocument(
|
|
|
58
60
|
return params.documentId === documentId;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
function contentDatabaseQueryFilter(documentId: string) {
|
|
63
|
+
export function contentDatabaseQueryFilter(documentId: string) {
|
|
62
64
|
return {
|
|
63
65
|
queryKey: ["action", "get-content-database"],
|
|
64
66
|
predicate: (query: Query) =>
|
|
@@ -81,6 +83,52 @@ export function writeContentDatabaseResponseToCache(
|
|
|
81
83
|
);
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
export function applyDocumentPropertyValueToDatabaseResponse(
|
|
87
|
+
current: ContentDatabaseResponse | undefined,
|
|
88
|
+
patch: {
|
|
89
|
+
documentId: string;
|
|
90
|
+
propertyId: string;
|
|
91
|
+
value: ContentDatabaseResponse["properties"][number]["value"];
|
|
92
|
+
},
|
|
93
|
+
): ContentDatabaseResponse | undefined {
|
|
94
|
+
if (!current) return current;
|
|
95
|
+
const databaseProperty = current.properties.find(
|
|
96
|
+
(property) => property.definition.id === patch.propertyId,
|
|
97
|
+
);
|
|
98
|
+
if (!databaseProperty) return current;
|
|
99
|
+
|
|
100
|
+
let changed = false;
|
|
101
|
+
const items = current.items.map((item) => {
|
|
102
|
+
if (item.document.id !== patch.documentId) return item;
|
|
103
|
+
|
|
104
|
+
const existingIndex = item.properties.findIndex(
|
|
105
|
+
(property) => property.definition.id === patch.propertyId,
|
|
106
|
+
);
|
|
107
|
+
if (existingIndex >= 0) {
|
|
108
|
+
const properties = item.properties.map((property, index) =>
|
|
109
|
+
index === existingIndex
|
|
110
|
+
? { ...property, value: patch.value }
|
|
111
|
+
: property,
|
|
112
|
+
);
|
|
113
|
+
changed = true;
|
|
114
|
+
return { ...item, properties };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
changed = true;
|
|
118
|
+
return {
|
|
119
|
+
...item,
|
|
120
|
+
properties: [
|
|
121
|
+
...item.properties,
|
|
122
|
+
{ ...databaseProperty, value: patch.value },
|
|
123
|
+
]
|
|
124
|
+
.slice()
|
|
125
|
+
.sort((a, b) => a.definition.position - b.definition.position),
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return changed ? { ...current, items } : current;
|
|
130
|
+
}
|
|
131
|
+
|
|
84
132
|
// `get-content-database` returns a union at runtime: the full response, or an
|
|
85
133
|
// unavailable payload (`{ available: false, reason: "deleted" | "not_found" }`)
|
|
86
134
|
// with no `database` field. Consumers typed against ContentDatabaseResponse
|
|
@@ -668,6 +716,10 @@ export function useBuilderCmsModels(enabled: boolean) {
|
|
|
668
716
|
{
|
|
669
717
|
enabled,
|
|
670
718
|
retry: false,
|
|
719
|
+
placeholderData: (previous) => previous,
|
|
720
|
+
staleTime: 5 * 60 * 1000,
|
|
721
|
+
gcTime: 30 * 60 * 1000,
|
|
722
|
+
refetchOnWindowFocus: false,
|
|
671
723
|
},
|
|
672
724
|
);
|
|
673
725
|
}
|
|
@@ -923,3 +975,20 @@ export function usePrepareBuilderSourceReview(documentId: string) {
|
|
|
923
975
|
},
|
|
924
976
|
});
|
|
925
977
|
}
|
|
978
|
+
|
|
979
|
+
export function useStageBuilderSourceBulkUpdate(documentId: string) {
|
|
980
|
+
const queryClient = useQueryClient();
|
|
981
|
+
return useActionMutation<
|
|
982
|
+
StageBuilderSourceBulkUpdateResponse,
|
|
983
|
+
StageBuilderSourceBulkUpdateRequest
|
|
984
|
+
>("stage-builder-source-bulk-update", {
|
|
985
|
+
onSuccess: () => {
|
|
986
|
+
queryClient.invalidateQueries({
|
|
987
|
+
queryKey: contentDatabaseQueryKey(documentId),
|
|
988
|
+
});
|
|
989
|
+
queryClient.invalidateQueries({
|
|
990
|
+
queryKey: ["action", "get-content-database-source", { documentId }],
|
|
991
|
+
});
|
|
992
|
+
},
|
|
993
|
+
});
|
|
994
|
+
}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { useActionMutation, useActionQuery } from "@agent-native/core/client";
|
|
2
2
|
import type {
|
|
3
3
|
ConfigureDocumentPropertyRequest,
|
|
4
|
+
ContentDatabaseResponse,
|
|
4
5
|
DeleteDocumentPropertyRequest,
|
|
5
6
|
DocumentPropertiesResponse,
|
|
7
|
+
DocumentPropertyValue,
|
|
6
8
|
DuplicateDocumentPropertyRequest,
|
|
7
9
|
ReorderDocumentPropertyRequest,
|
|
8
10
|
SetDocumentPropertyRequest,
|
|
9
11
|
} from "@shared/api";
|
|
10
12
|
import { useQueryClient } from "@tanstack/react-query";
|
|
11
13
|
|
|
12
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
applyDocumentPropertyValueToDatabaseResponse,
|
|
16
|
+
contentDatabaseQueryFilter,
|
|
17
|
+
contentDatabaseQueryKey,
|
|
18
|
+
} from "./use-content-database";
|
|
13
19
|
|
|
14
20
|
export function useDocumentProperties(documentId: string | null) {
|
|
15
21
|
return useActionQuery<DocumentPropertiesResponse>(
|
|
@@ -54,15 +60,67 @@ export function useSetDocumentProperty(
|
|
|
54
60
|
DocumentPropertiesResponse,
|
|
55
61
|
SetDocumentPropertyRequest
|
|
56
62
|
>("set-document-property", {
|
|
57
|
-
|
|
63
|
+
onMutate: async (variables) => {
|
|
64
|
+
await queryClient.cancelQueries(
|
|
65
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
66
|
+
);
|
|
67
|
+
const previous = queryClient.getQueriesData<ContentDatabaseResponse>(
|
|
68
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
69
|
+
);
|
|
70
|
+
queryClient.setQueriesData<ContentDatabaseResponse>(
|
|
71
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
72
|
+
(current) =>
|
|
73
|
+
applyDocumentPropertyValueToDatabaseResponse(current, {
|
|
74
|
+
documentId: variables.documentId,
|
|
75
|
+
propertyId: variables.propertyId,
|
|
76
|
+
value: variables.value,
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
return { previous };
|
|
80
|
+
},
|
|
81
|
+
onError: (_error, _variables, context) => {
|
|
82
|
+
const rollback = context as
|
|
83
|
+
| {
|
|
84
|
+
previous?: Array<[readonly unknown[], unknown]>;
|
|
85
|
+
}
|
|
86
|
+
| undefined;
|
|
87
|
+
for (const [queryKey, data] of rollback?.previous ?? []) {
|
|
88
|
+
queryClient.setQueryData(queryKey, data);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
onSuccess: (data, variables) => {
|
|
92
|
+
const savedValue =
|
|
93
|
+
data.properties.find(
|
|
94
|
+
(property) => property.definition.id === variables.propertyId,
|
|
95
|
+
)?.value ?? variables.value;
|
|
96
|
+
queryClient.setQueriesData<ContentDatabaseResponse>(
|
|
97
|
+
contentDatabaseQueryFilter(databaseDocumentId),
|
|
98
|
+
(current) =>
|
|
99
|
+
applyDocumentPropertyValueToDatabaseResponse(current, {
|
|
100
|
+
documentId: variables.documentId,
|
|
101
|
+
propertyId: variables.propertyId,
|
|
102
|
+
value: savedValue as DocumentPropertyValue,
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
58
105
|
queryClient.invalidateQueries({
|
|
59
|
-
queryKey: [
|
|
106
|
+
queryKey: [
|
|
107
|
+
"action",
|
|
108
|
+
"list-document-properties",
|
|
109
|
+
{ documentId: variables.documentId },
|
|
110
|
+
],
|
|
60
111
|
});
|
|
61
112
|
queryClient.invalidateQueries({
|
|
62
|
-
queryKey: ["action", "get-document", { id: documentId }],
|
|
113
|
+
queryKey: ["action", "get-document", { id: variables.documentId }],
|
|
63
114
|
});
|
|
64
115
|
queryClient.invalidateQueries({
|
|
65
|
-
|
|
116
|
+
...contentDatabaseQueryFilter(databaseDocumentId),
|
|
117
|
+
});
|
|
118
|
+
queryClient.invalidateQueries({
|
|
119
|
+
queryKey: [
|
|
120
|
+
"action",
|
|
121
|
+
"get-content-database-source",
|
|
122
|
+
{ documentId: databaseDocumentId },
|
|
123
|
+
],
|
|
66
124
|
});
|
|
67
125
|
},
|
|
68
126
|
});
|
|
@@ -607,6 +607,8 @@ const messages = {
|
|
|
607
607
|
addProperty: "新增屬性",
|
|
608
608
|
back: "返回",
|
|
609
609
|
builderSpace: "Builder 空間",
|
|
610
|
+
builderBulkUpdateNotStaged: "Builder 批次更新未暫存",
|
|
611
|
+
builderBulkUpdateStaged: "Builder 批次更新已暫存",
|
|
610
612
|
builderUpdateFailed: "Builder 更新失敗",
|
|
611
613
|
builderWriteModeWasNotChanged: "Builder 寫入模式未更改",
|
|
612
614
|
builderBodiesReadyLocally: "Builder 文章正文已在本機準備好。",
|
|
@@ -687,6 +689,7 @@ const messages = {
|
|
|
687
689
|
nextMonth: "下個月",
|
|
688
690
|
nextTimelineRange: "下一個時間線範圍",
|
|
689
691
|
noRowsMatchThisView: "沒有行匹配此檢視",
|
|
692
|
+
editFilesForSelectedRows: "編輯所選行的檔案",
|
|
690
693
|
oneFileOrMediaLinkPerLine: "每行一個檔案或媒體連結",
|
|
691
694
|
previewPageTitle: "預覽頁面標題",
|
|
692
695
|
previousDatabasePage: "上一頁面資料庫頁面",
|