@agent-native/core 0.165.4 → 0.167.0

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.
Files changed (223) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +5 -1
  3. package/corpus/templates/analytics/.agents/skills/workspace-conventions/SKILL.md +4 -1
  4. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +93 -56
  5. package/corpus/templates/analytics/app/i18n-data.ts +23 -20
  6. package/corpus/templates/analytics/app/pages/Settings.tsx +0 -1
  7. package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +0 -1
  8. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +1 -1
  9. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +2 -1
  10. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +0 -1
  11. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +0 -32
  12. package/corpus/templates/analytics/server/lib/session-replay.ts +1 -5
  13. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +5 -1
  14. package/corpus/templates/assets/.agents/skills/workspace-conventions/SKILL.md +4 -1
  15. package/corpus/templates/assets/actions/navigate.ts +2 -2
  16. package/corpus/templates/assets/actions/save-generated-image.ts +0 -5
  17. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -262
  18. package/corpus/templates/assets/app/routes/library.tsx +1 -1
  19. package/corpus/templates/assets/app/routes/settings.tsx +0 -3
  20. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +5 -1
  21. package/corpus/templates/brain/.agents/skills/workspace-conventions/SKILL.md +4 -1
  22. package/corpus/templates/brain/actions/ask-brain.ts +0 -1
  23. package/corpus/templates/brain/actions/navigate.ts +2 -2
  24. package/corpus/templates/brain/app/routes/sources.tsx +0 -4
  25. package/corpus/templates/brain/server/lib/capture-sanitization.ts +0 -11
  26. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +5 -1
  27. package/corpus/templates/calendar/.agents/skills/workspace-conventions/SKILL.md +4 -1
  28. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -20
  29. package/corpus/templates/calendar/app/pages/CalendarView.tsx +0 -1
  30. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  31. package/corpus/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  32. package/corpus/templates/chat/actions/navigate.ts +2 -2
  33. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +5 -1
  34. package/corpus/templates/clips/.agents/skills/workspace-conventions/SKILL.md +4 -1
  35. package/corpus/templates/clips/CHANGELOG.md +1 -0
  36. package/corpus/templates/clips/actions/import-loom-recording.ts +16 -4
  37. package/corpus/templates/clips/actions/navigate.ts +2 -2
  38. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +0 -1
  39. package/corpus/templates/clips/app/components/library/space-dialogs.tsx +0 -1
  40. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +0 -1
  41. package/corpus/templates/clips/app/components/player/clips-share-trigger.tsx +17 -0
  42. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +3 -3
  43. package/corpus/templates/clips/app/components/player/video-player.tsx +2 -2
  44. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +0 -1
  45. package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +0 -1
  46. package/corpus/templates/clips/app/global.css +31 -0
  47. package/corpus/templates/clips/app/hooks/use-playback-position.ts +0 -2
  48. package/corpus/templates/clips/app/lib/download-release-channel.ts +10 -0
  49. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -3
  50. package/corpus/templates/clips/app/routes/download.tsx +67 -44
  51. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +7 -12
  52. package/corpus/templates/clips/app/routes/record.tsx +6 -6
  53. package/corpus/templates/clips/app/routes/share.$shareId.tsx +26 -29
  54. package/corpus/templates/clips/changelog/2026-08-20-clip-viewer-share-actions.md +6 -0
  55. package/corpus/templates/clips/changelog/2026-08-20-preparing-recording-countdown-overlay.md +1 -0
  56. package/corpus/templates/clips/chrome-extension/src/background.ts +0 -13
  57. package/corpus/templates/clips/chrome-extension/src/overlay.ts +0 -1
  58. package/corpus/templates/clips/chrome-extension/src/popup.ts +0 -20
  59. package/corpus/templates/clips/desktop/src/app.tsx +6 -18
  60. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +0 -1
  61. package/corpus/templates/clips/desktop/src/lib/recorder.ts +0 -8
  62. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +5 -1
  63. package/corpus/templates/content/.agents/skills/workspace-conventions/SKILL.md +4 -1
  64. package/corpus/templates/content/actions/_database-source-utils.ts +0 -3
  65. package/corpus/templates/content/actions/attach-content-database-source.ts +1 -4
  66. package/corpus/templates/content/actions/navigate.ts +2 -2
  67. package/corpus/templates/content/actions/prepare-builder-source-execution.ts +1 -1
  68. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +0 -6
  69. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +0 -580
  70. package/corpus/templates/content/app/components/editor/database/FormView.tsx +2 -2
  71. package/corpus/templates/content/app/components/editor/database/filter-sort.ts +1 -1
  72. package/corpus/templates/content/app/components/editor/database/settings.tsx +0 -23
  73. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +0 -1
  74. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +8 -304
  75. package/corpus/templates/content/app/hooks/use-documents.ts +0 -1
  76. package/corpus/templates/content/shared/api.ts +0 -1
  77. package/corpus/templates/content/shared/builder-mdx.ts +0 -1
  78. package/corpus/templates/content/shared/nfm.ts +1 -7
  79. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +5 -1
  80. package/corpus/templates/crm/.agents/skills/workspace-conventions/SKILL.md +4 -1
  81. package/corpus/templates/crm/actions/merge-crm-records.ts +0 -4
  82. package/corpus/templates/crm/app/components/crm/record/RecordLists.tsx +0 -1
  83. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1
  84. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1
  85. package/corpus/templates/crm/server/db/crm-store.ts +1 -1
  86. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +5 -1
  87. package/corpus/templates/design/.agents/skills/workspace-conventions/SKILL.md +4 -1
  88. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1 -14
  89. package/corpus/templates/design/AGENTS.md +2 -1
  90. package/corpus/templates/design/actions/apply-component-prop-edit.ts +1 -5
  91. package/corpus/templates/design/actions/generate-design.ts +0 -1
  92. package/corpus/templates/design/actions/generate-screens.ts +5 -2
  93. package/corpus/templates/design/actions/go-to-main-component.ts +2 -2
  94. package/corpus/templates/design/actions/list-design-systems.ts +10 -0
  95. package/corpus/templates/design/actions/navigate.ts +2 -2
  96. package/corpus/templates/design/actions/open-component-source.ts +4 -4
  97. package/corpus/templates/design/actions/present-design-variants.ts +1 -2
  98. package/corpus/templates/design/actions/run-design-audit.ts +0 -22
  99. package/corpus/templates/design/actions/show-design-questions.ts +5 -2
  100. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +19 -8
  101. package/corpus/templates/design/app/components/design/EditPanel.tsx +11 -183
  102. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +21 -4
  103. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -5
  104. package/corpus/templates/design/app/components/design/bridge/codegen.ts +1 -1
  105. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +10 -19
  106. package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +1 -1
  107. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +13 -3
  108. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +38 -32
  109. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +1 -4
  110. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +0 -4
  111. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +15 -6
  112. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +2 -2
  113. package/corpus/templates/design/app/components/visual-editor/NodeRewriteProposal.tsx +0 -1
  114. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1 -1
  115. package/corpus/templates/design/app/i18n-data.ts +122 -0
  116. package/corpus/templates/design/app/lib/clipboard-content-lineage.ts +11 -1
  117. package/corpus/templates/design/app/pages/DesignEditor.tsx +50 -254
  118. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +163 -8
  119. package/corpus/templates/design/app/pages/Index.tsx +17 -0
  120. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +44 -32
  121. package/corpus/templates/design/app/pages/design-editor/canvas-primitives.ts +10 -0
  122. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +49 -3
  123. package/corpus/templates/design/app/pages/design-editor/clone-idrefs.ts +31 -0
  124. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +28 -0
  125. package/corpus/templates/design/app/pages/design-editor/commands/add-auto-layout.ts +3 -3
  126. package/corpus/templates/design/app/pages/design-editor/commands/align-selection.ts +44 -14
  127. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +16 -5
  128. package/corpus/templates/design/app/pages/design-editor/commands/change-selected-z-index.ts +1 -1
  129. package/corpus/templates/design/app/pages/design-editor/commands/frame-selection.ts +1 -1
  130. package/corpus/templates/design/app/pages/design-editor/commands/group-selection.ts +1 -1
  131. package/corpus/templates/design/app/pages/design-editor/commands/nudge-selection.ts +1 -1
  132. package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +142 -17
  133. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +1 -0
  134. package/corpus/templates/design/app/pages/design-editor/commands/ungroup-selection.ts +1 -1
  135. package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +1 -0
  136. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +25 -9
  137. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +1 -0
  138. package/corpus/templates/design/app/pages/design-editor/measure-child-rects.ts +83 -0
  139. package/corpus/templates/design/app/pages/design-editor/paste-placement.ts +66 -0
  140. package/corpus/templates/design/server/routes/[...page].get.ts +0 -1
  141. package/corpus/templates/design/shared/code-layer.ts +120 -70
  142. package/corpus/templates/design/shared/design-surface-index.ts +0 -1
  143. package/corpus/templates/design/shared/pen-path.ts +0 -4
  144. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +5 -1
  145. package/corpus/templates/dispatch/.agents/skills/workspace-conventions/SKILL.md +4 -1
  146. package/corpus/templates/dispatch/app/routes/integrations.tsx +0 -109
  147. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +5 -1
  148. package/corpus/templates/factory/.agents/skills/workspace-conventions/SKILL.md +4 -1
  149. package/corpus/templates/factory/actions/navigate.ts +2 -2
  150. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +0 -13
  151. package/corpus/templates/factory/app/routes/factory.tsx +0 -1
  152. package/corpus/templates/factory/server/factory-graph/store.ts +0 -1
  153. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +5 -1
  154. package/corpus/templates/forms/.agents/skills/workspace-conventions/SKILL.md +4 -1
  155. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +5 -1
  156. package/corpus/templates/macros/.agents/skills/workspace-conventions/SKILL.md +4 -1
  157. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -1
  158. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +5 -1
  159. package/corpus/templates/mail/.agents/skills/workspace-conventions/SKILL.md +4 -1
  160. package/corpus/templates/mail/app/components/email/EmailList.tsx +0 -1
  161. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  162. package/corpus/templates/mail/shared/markdown.ts +3 -0
  163. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +5 -1
  164. package/corpus/templates/plan/.agents/skills/workspace-conventions/SKILL.md +4 -1
  165. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +5 -1
  166. package/corpus/templates/slides/.agents/skills/workspace-conventions/SKILL.md +4 -1
  167. package/corpus/templates/slides/actions/add-slide.ts +0 -1
  168. package/corpus/templates/slides/actions/list-decks.ts +1 -1
  169. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -4
  170. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +0 -1
  171. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
  172. package/corpus/templates/slides/app/pages/DeckEditor.tsx +1 -6
  173. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +5 -1
  174. package/corpus/templates/tasks/.agents/skills/workspace-conventions/SKILL.md +4 -1
  175. package/corpus/templates/tasks/app/components/layout/Layout.tsx +0 -1
  176. package/corpus/templates/tasks/app/hooks/use-visible-task-fields.ts +1 -4
  177. package/corpus/templates/tasks/server/custom-fields/store.ts +1 -6
  178. package/corpus/templates/tasks/shared/list-screen-snapshot.ts +2 -2
  179. package/dist/agent/engine/registry.js +27 -14
  180. package/dist/agent/index.d.ts +1 -1
  181. package/dist/agent/production-agent.d.ts +19 -6
  182. package/dist/agent/production-agent.js +57 -16
  183. package/dist/agent/types.d.ts +3 -0
  184. package/dist/client/EnvironmentBadge.d.ts +1 -0
  185. package/dist/client/EnvironmentBadge.js +7 -0
  186. package/dist/collab/awareness.d.ts +2 -2
  187. package/dist/collab/routes.d.ts +1 -1
  188. package/dist/config.d.ts +11 -0
  189. package/dist/config.js +248 -0
  190. package/dist/deploy/build.js +12 -1
  191. package/dist/index.d.ts +1 -1
  192. package/dist/notifications/routes.d.ts +3 -3
  193. package/dist/observability/routes.d.ts +2 -2
  194. package/dist/progress/routes.d.ts +1 -1
  195. package/dist/resources/handlers.d.ts +2 -2
  196. package/dist/server/agent-chat/plugin-options.d.ts +3 -2
  197. package/dist/server/agent-chat-plugin.js +5 -2
  198. package/dist/server/index.d.ts +1 -1
  199. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  200. package/dist/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  201. package/dist/templates/chat/actions/navigate.ts +2 -2
  202. package/dist/templates/default/.agents/skills/secrets/SKILL.md +5 -1
  203. package/dist/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
  204. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
  205. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
  206. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
  207. package/dist/vite/agent-native-config-loader.d.ts +1 -0
  208. package/dist/vite/agent-native-config-loader.js +3 -3
  209. package/dist/vite/agents-bundle-plugin.d.ts +1 -1
  210. package/dist/vite/agents-bundle-plugin.js +13 -1
  211. package/dist/vite/client.js +14 -14
  212. package/docs/content/agent-native-config.mdx +62 -11
  213. package/docs/content/agent-surfaces.mdx +6 -0
  214. package/docs/content/environment-variables.mdx +5 -2
  215. package/package.json +3 -3
  216. package/src/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
  217. package/src/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
  218. package/src/templates/chat/actions/navigate.ts +2 -2
  219. package/src/templates/default/.agents/skills/secrets/SKILL.md +5 -1
  220. package/src/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
  221. package/src/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
  222. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
  223. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
@@ -50,7 +50,6 @@ import {
50
50
  type DocumentPropertyOptionColor,
51
51
  countWords,
52
52
  documentPropertyDateKey,
53
- documentPropertyDatePart,
54
53
  evaluateNormalizationFormula,
55
54
  formatWordCount,
56
55
  formulaValueText,
@@ -10581,20 +10580,6 @@ function SourceChangeSetReviewCard({
10581
10580
  );
10582
10581
  }
10583
10582
 
10584
- function SourceMetadataRow({ label, value }: { label: string; value: string }) {
10585
- return (
10586
- <div className="flex min-w-0 items-start justify-between gap-3 text-xs">
10587
- <span className="shrink-0 text-muted-foreground">{label}</span>
10588
- <span
10589
- className="min-w-0 max-w-[65%] break-words text-right"
10590
- title={value}
10591
- >
10592
- {value}
10593
- </span>
10594
- </div>
10595
- );
10596
- }
10597
-
10598
10583
  function sourceRiskClass(risk: ContentDatabaseSourceChangeSet["riskLevel"]) {
10599
10584
  return cn(
10600
10585
  "rounded border px-1.5 py-0.5",
@@ -10764,14 +10749,6 @@ export function builderSourceContinuationWatchdogDelay(refires: number) {
10764
10749
  );
10765
10750
  }
10766
10751
 
10767
- function sourceBuilderReadModeSummary(source: ContentDatabaseSource) {
10768
- if (source.metadata.liveReadConfigured) return "Builder API read-only";
10769
- if (source.metadata.readMode === "fixture") {
10770
- return "Local fixture; Builder credentials unavailable";
10771
- }
10772
- return "Local fixture";
10773
- }
10774
-
10775
10752
  function sourcePushModeLabel(
10776
10753
  mode: ContentDatabaseSource["metadata"]["pushMode"] | null | undefined,
10777
10754
  ) {
@@ -11580,139 +11557,6 @@ function DatabasePropertyPickerSubContent({
11580
11557
  );
11581
11558
  }
11582
11559
 
11583
- function DatabaseGroupMenu({
11584
- activeView,
11585
- properties,
11586
- groupIds,
11587
- onGroupByChange,
11588
- onHideEmptyGroupsChange,
11589
- onGroupsCollapsedChange,
11590
- }: {
11591
- activeView: Pick<
11592
- ContentDatabaseView,
11593
- "type" | "groupByPropertyId" | "hideEmptyGroups"
11594
- >;
11595
- properties: DocumentProperty[];
11596
- groupIds: string[];
11597
- onGroupByChange: (propertyId: string | null) => void;
11598
- onHideEmptyGroupsChange: (hideEmptyGroups: boolean) => void;
11599
- onGroupsCollapsedChange: (groupIds: string[], collapsed: boolean) => void;
11600
- }) {
11601
- const groupableProperties = databaseViewGroupableProperties(properties);
11602
- const groupProperty = databaseViewGroupingProperty(activeView, properties);
11603
- const hideEmptyGroups = activeView.hideEmptyGroups === true;
11604
- const [propertyQuery, setPropertyQuery] = useState("");
11605
- const groupPropertyItems = databasePropertyPickerItems(
11606
- groupableProperties,
11607
- propertyQuery,
11608
- { includeName: false },
11609
- );
11610
- const canGroupView =
11611
- activeView.type === "table" ||
11612
- activeView.type === "list" ||
11613
- activeView.type === "gallery";
11614
-
11615
- return (
11616
- <DropdownMenu>
11617
- <DropdownMenuTrigger asChild>
11618
- <Button
11619
- type="button"
11620
- variant="ghost"
11621
- size="sm"
11622
- disabled={!canGroupView}
11623
- aria-label={
11624
- groupProperty
11625
- ? `Group by ${groupProperty.definition.name}`
11626
- : "Group"
11627
- }
11628
- title="Group"
11629
- className={cn(databaseToolbarIconButtonClass(Boolean(groupProperty)))}
11630
- >
11631
- <IconLayoutKanban className="size-3.5" />
11632
- </Button>
11633
- </DropdownMenuTrigger>
11634
- <DropdownMenuContent align="end" className="w-56">
11635
- <DropdownMenuLabel className="text-xs text-muted-foreground">
11636
- {dbText("groupBy")}
11637
- </DropdownMenuLabel>
11638
- <DropdownMenuItem
11639
- onSelect={(event) => {
11640
- event.preventDefault();
11641
- onGroupByChange(null);
11642
- }}
11643
- >
11644
- <span className="flex-1">None</span>
11645
- {!groupProperty ? (
11646
- <IconCheck className="size-4 text-muted-foreground" />
11647
- ) : null}
11648
- </DropdownMenuItem>
11649
- {groupableProperties.length > 0 ? <DropdownMenuSeparator /> : null}
11650
- {groupableProperties.length > 0 ? (
11651
- <DatabasePropertyPickerSearch
11652
- value={propertyQuery}
11653
- onChange={setPropertyQuery}
11654
- />
11655
- ) : null}
11656
- {groupPropertyItems.map((item) => (
11657
- <DatabasePropertyPickerItem
11658
- key={item.key}
11659
- item={item}
11660
- selected={groupProperty?.definition.id === item.key}
11661
- onSelect={(key) => onGroupByChange(key)}
11662
- />
11663
- ))}
11664
- {groupableProperties.length > 0 && groupPropertyItems.length === 0 ? (
11665
- <div className="px-2 py-1.5 text-xs text-muted-foreground">
11666
- {dbText("noPropertiesFound")}
11667
- </div>
11668
- ) : null}
11669
- {groupProperty ? (
11670
- <>
11671
- <DropdownMenuSeparator />
11672
- <DropdownMenuItem
11673
- onSelect={(event) => {
11674
- event.preventDefault();
11675
- onHideEmptyGroupsChange(!hideEmptyGroups);
11676
- }}
11677
- >
11678
- <IconEyeOff className="mr-2 size-4 text-muted-foreground" />
11679
- <span className="flex-1">{dbText("hideEmptyGroups")}</span>
11680
- {hideEmptyGroups ? (
11681
- <IconCheck className="size-4 text-muted-foreground" />
11682
- ) : null}
11683
- </DropdownMenuItem>
11684
- <DropdownMenuItem
11685
- disabled={groupIds.length === 0}
11686
- onSelect={(event) => {
11687
- event.preventDefault();
11688
- onGroupsCollapsedChange(groupIds, true);
11689
- }}
11690
- >
11691
- <IconChevronRight className="mr-2 size-4 text-muted-foreground" />
11692
- {dbText("collapseAllGroups")}
11693
- </DropdownMenuItem>
11694
- <DropdownMenuItem
11695
- disabled={groupIds.length === 0}
11696
- onSelect={(event) => {
11697
- event.preventDefault();
11698
- onGroupsCollapsedChange(groupIds, false);
11699
- }}
11700
- >
11701
- <IconChevronDown className="mr-2 size-4 text-muted-foreground" />
11702
- {dbText("expandAllGroups")}
11703
- </DropdownMenuItem>
11704
- </>
11705
- ) : null}
11706
- {groupableProperties.length === 0 ? (
11707
- <div className="px-2 py-1.5 text-xs text-muted-foreground">
11708
- {dbText("addAStatusSelectMultiSelectOrCheckboxPropertyToGroup")}
11709
- </div>
11710
- ) : null}
11711
- </DropdownMenuContent>
11712
- </DropdownMenu>
11713
- );
11714
- }
11715
-
11716
11560
  function databaseOpenPagesInLabel(value: ContentDatabaseOpenPagesIn) {
11717
11561
  return value === "full_page" ? "Full page" : "Side preview";
11718
11562
  }
@@ -16700,163 +16544,6 @@ function ColumnHeaderMenuContent({
16700
16544
  );
16701
16545
  }
16702
16546
 
16703
- function DatabasePropertiesMenu({
16704
- documentId,
16705
- databaseId,
16706
- properties,
16707
- hiddenCount,
16708
- activeView,
16709
- items,
16710
- onPropertyHiddenChange,
16711
- onPropertiesHiddenChange,
16712
- }: {
16713
- documentId: string;
16714
- databaseId: string;
16715
- properties: DocumentProperty[];
16716
- hiddenCount: number;
16717
- activeView: ContentDatabaseView;
16718
- items: ContentDatabaseItem[];
16719
- onPropertyHiddenChange: (propertyId: string, hidden: boolean) => void;
16720
- onPropertiesHiddenChange: (propertyIds: string[], hidden: boolean) => void;
16721
- }) {
16722
- const [query, setQuery] = useState("");
16723
- const normalizedQuery = query.trim().toLowerCase();
16724
- const filteredProperties = normalizedQuery
16725
- ? properties.filter((property) =>
16726
- property.definition.name.toLowerCase().includes(normalizedQuery),
16727
- )
16728
- : properties;
16729
- const visibleCount = properties.filter((property) =>
16730
- isDatabasePropertyVisibleInView(property, items, activeView),
16731
- ).length;
16732
- const propertyIds = properties.map((property) => property.definition.id);
16733
-
16734
- return (
16735
- <DropdownMenu>
16736
- <DropdownMenuTrigger asChild>
16737
- <Button
16738
- type="button"
16739
- variant="ghost"
16740
- size="sm"
16741
- aria-label={
16742
- hiddenCount > 0
16743
- ? `${hiddenCount} hidden properties`
16744
- : "Property visibility"
16745
- }
16746
- title={dbText("propertyVisibility")}
16747
- className={cn(
16748
- databaseToolbarIconButtonClass(hiddenCount > 0),
16749
- "relative",
16750
- )}
16751
- >
16752
- <IconEye className="size-3.5" />
16753
- {hiddenCount > 0 ? (
16754
- <span className="absolute -right-0.5 -top-0.5 flex h-3.5 min-w-3.5 shrink-0 items-center justify-center rounded-full bg-foreground px-1 text-[9px] leading-none text-background">
16755
- {formatCompactCountBadge(hiddenCount)}
16756
- </span>
16757
- ) : null}
16758
- </Button>
16759
- </DropdownMenuTrigger>
16760
- <DropdownMenuContent
16761
- align="end"
16762
- className="w-80"
16763
- onCloseAutoFocus={() => setQuery("")}
16764
- >
16765
- <DropdownMenuLabel className="text-xs text-muted-foreground">
16766
- Properties
16767
- </DropdownMenuLabel>
16768
- <div
16769
- className="grid gap-2 p-2 pt-1"
16770
- onKeyDown={(event) => event.stopPropagation()}
16771
- >
16772
- <div className="flex h-8 items-center gap-1 rounded border border-border bg-background px-2">
16773
- <IconSearch className="size-3.5 shrink-0 text-muted-foreground" />
16774
- <Input
16775
- value={query}
16776
- placeholder={dbText("searchProperties")}
16777
- aria-label={dbText("searchProperties")}
16778
- onChange={(event) => setQuery(event.target.value)}
16779
- className="h-7 border-0 bg-transparent px-0 text-xs shadow-none focus-visible:ring-0"
16780
- />
16781
- </div>
16782
- <div className="flex items-center justify-between gap-2 text-xs text-muted-foreground">
16783
- <span>
16784
- {visibleCount} shown, {properties.length - visibleCount} hidden
16785
- </span>
16786
- <div className="flex items-center gap-1">
16787
- <Button
16788
- type="button"
16789
- size="sm"
16790
- variant="ghost"
16791
- className="h-7 px-2 text-xs"
16792
- disabled={hiddenCount === 0}
16793
- onClick={() => onPropertiesHiddenChange(propertyIds, false)}
16794
- >
16795
- <IconEye className="mr-1 size-3.5" />
16796
- {dbText("showAll")}
16797
- </Button>
16798
- <Button
16799
- type="button"
16800
- size="sm"
16801
- variant="ghost"
16802
- className="h-7 px-2 text-xs"
16803
- disabled={visibleCount === 0}
16804
- onClick={() => onPropertiesHiddenChange(propertyIds, true)}
16805
- >
16806
- <IconEyeOff className="mr-1 size-3.5" />
16807
- {dbText("hideAll")}
16808
- </Button>
16809
- </div>
16810
- </div>
16811
- </div>
16812
- {filteredProperties.length === 0 ? (
16813
- <div className="px-3 py-4 text-sm text-muted-foreground">
16814
- {dbText("noMatchingProperties")}
16815
- </div>
16816
- ) : null}
16817
- {filteredProperties.map((property) => {
16818
- const Icon = TYPE_ICONS[property.definition.type];
16819
- const visible = isDatabasePropertyVisibleInView(
16820
- property,
16821
- items,
16822
- activeView,
16823
- );
16824
- return (
16825
- <DropdownMenuItem
16826
- key={property.definition.id}
16827
- onSelect={(event) => {
16828
- event.preventDefault();
16829
- onPropertyHiddenChange(property.definition.id, visible);
16830
- }}
16831
- >
16832
- <Icon className="mr-2 size-4 text-muted-foreground" />
16833
- <span className="min-w-0 flex-1 truncate">
16834
- {property.definition.name}
16835
- </span>
16836
- <span className="mr-2 text-xs text-muted-foreground">
16837
- {visible ? "Shown" : "Hidden"}
16838
- </span>
16839
- {visible ? (
16840
- <IconCheck className="size-4 text-muted-foreground" />
16841
- ) : null}
16842
- </DropdownMenuItem>
16843
- );
16844
- })}
16845
- <div
16846
- className="border-t border-border p-2"
16847
- onKeyDown={(event) => event.stopPropagation()}
16848
- >
16849
- <AddProperty
16850
- documentId={documentId}
16851
- databaseId={databaseId}
16852
- label={dbText("newProperty")}
16853
- />
16854
- </div>
16855
- </DropdownMenuContent>
16856
- </DropdownMenu>
16857
- );
16858
- }
16859
-
16860
16547
  export function applyDatabaseView(
16861
16548
  items: ContentDatabaseItem[],
16862
16549
  properties: DocumentProperty[],
@@ -16873,53 +16560,6 @@ export function applyDatabaseView(
16873
16560
  });
16874
16561
  }
16875
16562
 
16876
- function databaseItemMatchesFilterTree(
16877
- item: ContentDatabaseItem,
16878
- properties: DocumentProperty[],
16879
- filters: DatabaseFilter[],
16880
- filterMode: DatabaseFilterMode,
16881
- ) {
16882
- const rootFilters = filters.filter((filter) => !filter.parentFilterGroupId);
16883
- const nestedGroups = nestedDatabaseFilterGroups(filters);
16884
- const matches = [
16885
- ...rootFilters.map((filter) =>
16886
- databaseItemMatchesFilter(item, properties, filter),
16887
- ),
16888
- ...nestedGroups.map((group) =>
16889
- combineDatabaseFilterMatches(
16890
- group.map((filter) =>
16891
- databaseItemMatchesFilter(item, properties, filter),
16892
- ),
16893
- filterMode,
16894
- ),
16895
- ),
16896
- ];
16897
-
16898
- return combineDatabaseFilterMatches(matches, filterMode);
16899
- }
16900
-
16901
- function nestedDatabaseFilterGroups(filters: DatabaseFilter[]) {
16902
- const groups = new Map<string, DatabaseFilter[]>();
16903
- for (const filter of filters) {
16904
- if (!filter.parentFilterGroupId || !filter.filterGroupId) continue;
16905
- groups.set(filter.filterGroupId, [
16906
- ...(groups.get(filter.filterGroupId) ?? []),
16907
- filter,
16908
- ]);
16909
- }
16910
- return [...groups.values()].filter((group) => group.length > 0);
16911
- }
16912
-
16913
- function combineDatabaseFilterMatches(
16914
- matches: boolean[],
16915
- filterMode: DatabaseFilterMode,
16916
- ) {
16917
- if (matches.length === 0) return true;
16918
- return filterMode === "or"
16919
- ? matches.some((matched) => matched)
16920
- : matches.every((matched) => matched);
16921
- }
16922
-
16923
16563
  function defaultDatabaseSort(): DatabaseSort {
16924
16564
  return {
16925
16565
  key: "name",
@@ -17259,175 +16899,6 @@ function databasePropertyOptionIdForFilterValue(
17259
16899
  )?.id;
17260
16900
  }
17261
16901
 
17262
- function databaseItemMatchesFilter(
17263
- item: ContentDatabaseItem,
17264
- properties: DocumentProperty[],
17265
- filter: DatabaseFilter,
17266
- ) {
17267
- const value = databaseItemFilterValue(item, properties, filter.key);
17268
- const property = databaseItemFilterProperty(item, properties, filter.key);
17269
-
17270
- if (filter.operator === "is_empty") return !value.trim();
17271
- if (filter.operator === "is_not_empty") return !!value.trim();
17272
-
17273
- if (filter.operator === "is_checked") return property?.value === true;
17274
- if (filter.operator === "is_unchecked") return property?.value !== true;
17275
-
17276
- if (filter.operator === "greater_than" || filter.operator === "less_than") {
17277
- const current = propertyNumberValue(property);
17278
- const target = Number(filter.value.trim());
17279
- if (!Number.isFinite(current) || !Number.isFinite(target)) return false;
17280
- return filter.operator === "greater_than"
17281
- ? current > target
17282
- : current < target;
17283
- }
17284
-
17285
- if (
17286
- filter.operator === "before" ||
17287
- filter.operator === "after" ||
17288
- filter.operator === "between"
17289
- ) {
17290
- const current = propertyDateValue(property);
17291
- if (!Number.isFinite(current)) return false;
17292
- if (filter.operator === "between") {
17293
- const range = databaseFilterDateRangeValue(filter.value);
17294
- if (!range) return false;
17295
- return current >= range[0] && current <= range[1];
17296
- }
17297
- const target = new Date(filter.value.trim()).getTime();
17298
- if (!Number.isFinite(target)) return false;
17299
- return filter.operator === "before" ? current < target : current > target;
17300
- }
17301
-
17302
- const candidateValues = databaseItemFilterCandidateValues(
17303
- item,
17304
- properties,
17305
- filter.key,
17306
- ).map((candidate) => candidate.trim().toLowerCase());
17307
- const selectedFilterValues = databaseFilterSelectedValues(filter.value).map(
17308
- (candidate) => candidate.trim().toLowerCase(),
17309
- );
17310
- const normalizedValue = value.trim().toLowerCase();
17311
- const normalizedFilter = selectedFilterValues[0] ?? "";
17312
- const usesDiscreteValues =
17313
- property?.definition.type === "select" ||
17314
- property?.definition.type === "status" ||
17315
- property?.definition.type === "multi_select" ||
17316
- property?.definition.type === "person";
17317
-
17318
- if (
17319
- usesDiscreteValues &&
17320
- (filter.operator === "equals" || filter.operator === "contains")
17321
- ) {
17322
- return selectedFilterValues.some((filterValue) =>
17323
- candidateValues.includes(filterValue),
17324
- );
17325
- }
17326
- if (usesDiscreteValues && filter.operator === "does_not_equal") {
17327
- return selectedFilterValues.every(
17328
- (filterValue) => !candidateValues.includes(filterValue),
17329
- );
17330
- }
17331
-
17332
- if (filter.operator === "equals") {
17333
- return candidateValues.includes(normalizedFilter);
17334
- }
17335
- if (filter.operator === "does_not_equal") {
17336
- return !candidateValues.includes(normalizedFilter);
17337
- }
17338
- return normalizedValue.includes(normalizedFilter);
17339
- }
17340
-
17341
- function databaseItemSearchText(
17342
- item: ContentDatabaseItem,
17343
- properties: DocumentProperty[],
17344
- ) {
17345
- return [
17346
- item.document.title || "Untitled",
17347
- ...properties.map((property) =>
17348
- propertyValueText(
17349
- item.properties.find(
17350
- (candidate) => candidate.definition.id === property.definition.id,
17351
- ) ?? property,
17352
- ),
17353
- ),
17354
- ].join(" ");
17355
- }
17356
-
17357
- function databaseItemSortValue(
17358
- item: ContentDatabaseItem,
17359
- properties: DocumentProperty[],
17360
- key: string,
17361
- ) {
17362
- if (key === "name") return item.document.title || "";
17363
- const property = properties.find(
17364
- (candidate) => candidate.definition.id === key,
17365
- );
17366
- const itemProperty = item.properties.find(
17367
- (candidate) => candidate.definition.id === key,
17368
- );
17369
- return propertyValueText(itemProperty ?? property ?? null);
17370
- }
17371
-
17372
- function databaseItemFilterValue(
17373
- item: ContentDatabaseItem,
17374
- properties: DocumentProperty[],
17375
- key: string,
17376
- ) {
17377
- if (key === "name") return item.document.title || "";
17378
- return propertyValueText(databaseItemFilterProperty(item, properties, key));
17379
- }
17380
-
17381
- function databaseItemFilterProperty(
17382
- item: ContentDatabaseItem,
17383
- properties: DocumentProperty[],
17384
- key: string,
17385
- ) {
17386
- if (key === "name") return null;
17387
- const property = properties.find(
17388
- (candidate) => candidate.definition.id === key,
17389
- );
17390
- const itemProperty = item.properties.find(
17391
- (candidate) => candidate.definition.id === key,
17392
- );
17393
- return itemProperty ?? property ?? null;
17394
- }
17395
-
17396
- function databaseItemFilterCandidateValues(
17397
- item: ContentDatabaseItem,
17398
- properties: DocumentProperty[],
17399
- key: string,
17400
- ) {
17401
- if (key === "name") return [item.document.title || ""];
17402
- const property = databaseItemFilterProperty(item, properties, key);
17403
- if (!property) return [""];
17404
- const value = property.value;
17405
-
17406
- if (value === null || value === undefined || value === "") return [""];
17407
-
17408
- if (Array.isArray(value)) {
17409
- return value.flatMap((id) => {
17410
- const optionName =
17411
- property.definition.options.options?.find((option) => option.id === id)
17412
- ?.name ?? id;
17413
- return [id, optionName];
17414
- });
17415
- }
17416
-
17417
- if (
17418
- property.definition.type === "select" ||
17419
- property.definition.type === "status"
17420
- ) {
17421
- const id = String(value);
17422
- const optionName =
17423
- property.definition.options.options?.find((option) => option.id === id)
17424
- ?.name ?? id;
17425
- return [id, optionName];
17426
- }
17427
-
17428
- return [propertyValueText(property)];
17429
- }
17430
-
17431
16902
  function propertyValueText(property: DocumentProperty | null | undefined) {
17432
16903
  if (!property) return "";
17433
16904
  const value = property.value;
@@ -17461,23 +16932,6 @@ function propertyValueText(property: DocumentProperty | null | undefined) {
17461
16932
  return formulaValueText(value);
17462
16933
  }
17463
16934
 
17464
- function compareDatabaseSortValues(left: string, right: string) {
17465
- const leftNumber = Number(left);
17466
- const rightNumber = Number(right);
17467
- if (
17468
- left.trim() &&
17469
- right.trim() &&
17470
- Number.isFinite(leftNumber) &&
17471
- Number.isFinite(rightNumber)
17472
- ) {
17473
- return leftNumber - rightNumber;
17474
- }
17475
- return left.localeCompare(right, undefined, {
17476
- numeric: true,
17477
- sensitivity: "base",
17478
- });
17479
- }
17480
-
17481
16935
  function propertyNumberValue(property: DocumentProperty | null | undefined) {
17482
16936
  if (!property) return Number.NaN;
17483
16937
  if (
@@ -17494,14 +16948,6 @@ function propertyNumberValue(property: DocumentProperty | null | undefined) {
17494
16948
  return Number.isFinite(value) ? value : Number.NaN;
17495
16949
  }
17496
16950
 
17497
- function propertyDateValue(property: DocumentProperty | null | undefined) {
17498
- if (!property || !property.value) return Number.NaN;
17499
- const value = new Date(
17500
- documentPropertyDatePart(property.value, "start") || String(property.value),
17501
- ).getTime();
17502
- return Number.isFinite(value) ? value : Number.NaN;
17503
- }
17504
-
17505
16951
  function databaseSortDirectionLabel(direction: SortDirection) {
17506
16952
  return direction === "asc" ? "Ascending" : "Descending";
17507
16953
  }
@@ -18384,14 +17830,6 @@ function databaseFilterEncodeDateRangeValues(start: string, end: string) {
18384
17830
  return JSON.stringify([normalizedStart, normalizedEnd]);
18385
17831
  }
18386
17832
 
18387
- function databaseFilterDateRangeValue(value: string): [number, number] | null {
18388
- const [startValue, endValue] = databaseFilterDateRangeValues(value);
18389
- const start = new Date(startValue).getTime();
18390
- const end = new Date(endValue).getTime();
18391
- if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
18392
- return start <= end ? [start, end] : [end, start];
18393
- }
18394
-
18395
17833
  function databaseFilterEncodeSelectedValues(values: string[]) {
18396
17834
  const normalized = [
18397
17835
  ...new Set(values.map((value) => value.trim()).filter(Boolean)),
@@ -18413,24 +17851,6 @@ function databaseFilterOptionIsSelected(
18413
17851
  );
18414
17852
  }
18415
17853
 
18416
- function databaseFilterChipLabel(
18417
- filter: DatabaseFilter,
18418
- properties: DocumentProperty[],
18419
- ) {
18420
- const operator = databaseFilterOperatorLabel(
18421
- filter.operator,
18422
- filter.key,
18423
- properties,
18424
- );
18425
- if (!filterOperatorNeedsValue(filter.operator)) {
18426
- return `${filter.label} ${operator.toLowerCase()}`;
18427
- }
18428
- return `${filter.label} ${operator.toLowerCase()} ${databaseFilterValueLabel(
18429
- filter,
18430
- properties,
18431
- )}`;
18432
- }
18433
-
18434
17854
  export function databaseInlineFilterLabel(
18435
17855
  filter: DatabaseFilter,
18436
17856
  properties: DocumentProperty[],
@@ -12,7 +12,7 @@ import {
12
12
  IconExternalLink,
13
13
  } from "@tabler/icons-react";
14
14
  import { useMemo, useState } from "react";
15
- import { Link, useNavigate } from "react-router";
15
+ import { Link } from "react-router";
16
16
 
17
17
  import { Button } from "@/components/ui/button";
18
18
  import {
@@ -298,7 +298,7 @@ export function DatabaseFormView({
298
298
  canEdit,
299
299
  }: DatabaseFormViewProps) {
300
300
  const t = useT();
301
- const navigate = useNavigate();
301
+
302
302
  const submit = useSubmitContentDatabaseForm(databaseDocumentId);
303
303
  const questions = useMemo(
304
304
  () => contentDatabaseFormQuestions(view, properties),
@@ -9,7 +9,7 @@ import type {
9
9
  } from "@shared/api";
10
10
  import { formulaValueText, isComputedPropertyType } from "@shared/properties";
11
11
 
12
- import { calendarDateKey, propertyDateValue } from "./calendar-timeline";
12
+ import { propertyDateValue } from "./calendar-timeline";
13
13
  import {
14
14
  type ColumnKey,
15
15
  type DatabaseConditionMoveDirection,