@agent-native/core 0.80.10 → 0.81.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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +53 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +108 -15
- package/corpus/core/src/cli/design-connect.ts +419 -19
- package/corpus/core/src/client/AssistantChat.tsx +123 -26
- package/corpus/core/src/client/ConnectBuilderCard.tsx +1 -0
- package/corpus/core/src/client/chat/index.ts +1 -0
- package/corpus/core/src/client/chat/run-recovery.tsx +9 -7
- package/corpus/core/src/client/chat-view-transition.ts +33 -2
- package/corpus/core/src/client/composer/PromptComposer.tsx +21 -2
- package/corpus/core/src/client/index.ts +1 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -4
- package/corpus/core/src/client/sharing/ShareButton.tsx +3 -3
- package/corpus/core/src/client/sse-event-processor.ts +9 -0
- package/corpus/core/src/client/use-agent-chat-home-handoff.ts +31 -3
- package/corpus/core/src/db/client.ts +29 -2
- package/corpus/core/src/provider-api/index.ts +29 -0
- package/corpus/core/src/server/core-routes-plugin.ts +58 -20
- package/corpus/core/src/styles/agent-native.css +54 -0
- package/corpus/core/src/usage/store.ts +2 -2
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +118 -10
- package/corpus/templates/analytics/app/components/layout/layout-route-policy.ts +7 -0
- package/corpus/templates/analytics/app/global.css +8 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +7 -1
- package/corpus/templates/analytics/app/lib/chat-handoff.ts +34 -0
- package/corpus/templates/analytics/app/pages/Ask.tsx +9 -18
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +109 -21
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -6
- package/corpus/templates/analytics/changelog/2026-06-30-ask-opens-a-fresh-chat-unless-you-were-just-chatting-and-das.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-dashboard-email-reports-are-more-reliable-and-use-cleaner.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-dashboard-toolbar-controls-use-a-quieter-share-button-and-ve.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-session-replay-rows-show-whole-minute-durations-in-the-playl.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-session-replays-now-render-captured-styling-and-keep-the-eve.md +6 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +16 -3
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +31 -14
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +9 -2
- package/corpus/templates/assets/AGENTS.md +4 -0
- package/corpus/templates/assets/actions/_tool-activity.ts +46 -0
- package/corpus/templates/assets/actions/generate-image-batch.ts +26 -5
- package/corpus/templates/assets/actions/generate-image.ts +118 -67
- package/corpus/templates/assets/actions/list-draft-assets.ts +50 -0
- package/corpus/templates/assets/actions/open-asset-picker.ts +9 -0
- package/corpus/templates/assets/actions/rerun-generation-run.ts +52 -31
- package/corpus/templates/assets/app/components/create/RecentDraftsSection.tsx +100 -0
- package/corpus/templates/assets/app/global.css +15 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +4 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +7 -0
- package/corpus/templates/assets/app/i18n-data.ts +61 -0
- package/corpus/templates/assets/app/routes/_index.tsx +4 -0
- package/corpus/templates/assets/app/routes/library.tsx +233 -52
- package/corpus/templates/assets/changelog/2026-06-29-image-generation-can-now-render-requested-text-and-respect-b.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-image-generation-no-longer-looks-stuck-while-the-provider-is-still-working.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-tagged-presets-now-control-the-image-aspect-ratio.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-the-assets-picker-now-supports-a-vertical-embedded-layout-fo.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +135 -11
- package/corpus/templates/assets/shared/api.ts +4 -0
- package/corpus/templates/clips/actions/finalize-recording.ts +1 -12
- package/corpus/templates/clips/actions/list-ai-requests.ts +60 -0
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +24 -25
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +10 -5
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -8
- package/corpus/templates/clips/changelog/2026-06-30-extension-save-recovery-avoids-false-upload-failures.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-30-longer-chrome-extension-recordings-now-keep-saving-reliably-.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/chrome-extension/src/background.ts +19 -10
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +38 -12
- package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +224 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +119 -16
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +16 -0
- package/corpus/templates/clips/server/lib/recording-upload-state.ts +48 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +9 -1
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +63 -13
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +74 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +32 -0
- package/corpus/templates/design/AGENTS.md +27 -0
- package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +1 -1
- package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +5 -5
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +76 -25
- package/corpus/templates/design/actions/apply-design-state.ts +17 -4
- package/corpus/templates/design/actions/apply-motion-edit.ts +76 -115
- package/corpus/templates/design/actions/apply-shader-fill.ts +148 -56
- package/corpus/templates/design/actions/capture-design-state.ts +27 -4
- package/corpus/templates/design/actions/connect-localhost.ts +59 -22
- package/corpus/templates/design/actions/delete-design.ts +20 -0
- package/corpus/templates/design/actions/export-zip.ts +23 -8
- package/corpus/templates/design/actions/generate-design.ts +53 -1
- package/corpus/templates/design/actions/get-component-details.ts +21 -26
- package/corpus/templates/design/actions/get-motion-timeline.ts +135 -10
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +116 -0
- package/corpus/templates/design/actions/import-design-tokens.ts +521 -0
- package/corpus/templates/design/actions/index-design-tokens.ts +18 -5
- package/corpus/templates/design/actions/insert-design-native-asset.ts +268 -0
- package/corpus/templates/design/actions/insert-figma-library-asset.ts +233 -0
- package/corpus/templates/design/actions/list-design-extensions.ts +32 -10
- package/corpus/templates/design/actions/list-design-native-assets.ts +105 -0
- package/corpus/templates/design/actions/list-design-states.ts +19 -1
- package/corpus/templates/design/actions/list-figma-library-assets.ts +292 -0
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +238 -0
- package/corpus/templates/design/actions/navigate.ts +18 -3
- package/corpus/templates/design/actions/open-component-source.ts +7 -2
- package/corpus/templates/design/actions/preview-component-prop-edit.ts +32 -26
- package/corpus/templates/design/actions/preview-shader-fill.ts +9 -11
- package/corpus/templates/design/actions/provider-api-catalog.ts +2 -2
- package/corpus/templates/design/actions/provider-api-docs.ts +1 -1
- package/corpus/templates/design/actions/provider-api-request.ts +3 -3
- package/corpus/templates/design/actions/revoke-localhost-write-consent.ts +48 -0
- package/corpus/templates/design/actions/run-design-audit.ts +74 -10
- package/corpus/templates/design/actions/run-design-extension-action.ts +1 -1
- package/corpus/templates/design/actions/view-screen.ts +1 -1
- package/corpus/templates/design/actions/write-local-file.ts +213 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +244 -3197
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +30 -20
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +795 -289
- package/corpus/templates/design/app/components/design/EditPanel.tsx +635 -234
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +124 -32
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +161 -0
- package/corpus/templates/design/app/components/design/MotionDock.tsx +244 -266
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +491 -56
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +55 -67
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +38 -63
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +264 -8
- package/corpus/templates/design/app/components/design/bridge/codegen.ts +125 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +4037 -0
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +62 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +272 -0
- package/corpus/templates/design/app/components/design/bridge/nav.bridge.ts +116 -0
- package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +24 -0
- package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +78 -0
- package/corpus/templates/design/app/components/design/bridge/tsconfig.json +17 -0
- package/corpus/templates/design/app/components/design/bridge/tweak.bridge.ts +28 -0
- package/corpus/templates/design/app/components/design/bridge/zoom.bridge.ts +43 -0
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +45 -16
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +88 -9
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +94 -9
- package/corpus/templates/design/app/components/layout/Layout.tsx +19 -3
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/design/app/global.css +7 -0
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +23 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +22 -0
- package/corpus/templates/design/app/i18n-data.ts +369 -0
- package/corpus/templates/design/app/lib/pending-generation.ts +1 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +3024 -616
- package/corpus/templates/design/app/pages/Index.tsx +5 -1
- package/corpus/templates/design/changelog/2026-06-30-applying-the-one-click-fix-for-a-small-tap-target-accessibil.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-canvas-creation-screen-dragging-undo-redo-and-image-fill-edi.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-component-prop-edits-and-shader-fills-now-preserve-rapid-sam.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-can-browse-figma-library-components-and-insert-them-i.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-now-has-a-figma-style-left-rail-for-file-agent-assets.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-now-has-native-components-embedded-media-and-figma-im.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-preview-now-includes-a-publish-app-waitlist-option-fr.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-s-left-rail-now-matches-the-sidebar-chrome-and-uses-t.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-s-tools-create-menu-now-stays-compact-instead-of-rend.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-starter-prompts-now-begin-generating-immediately-and-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-token-edits-now-stay-visible-in-previews-and-token-li.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-tools-now-use-a-quieter-figma-style-list-layout.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-drawing-rectangles-on-the-all-screens-canvas-no-longer-flash.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-fixed-code-native-design-studio-edits-so-component-props-mot.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-fixed-visual-editing-hover-overlays-and-spacing-handles-so-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-motion-edits-now-save-automatically-without-a-separate-css-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-motion-timelines-now-reopen-as-editable-tracks-after-writing.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-new-design-prompts-with-uploaded-screenshots-work-reliably-o.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-screen-previews-in-all-screens-view-now-keep-rounded-outline.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-selection-outlines-now-sit-flush-on-rectangles-drawn-directl.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-share-options-use-a-tighter-design-editor-popover-with-compa.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-collapsed-motion-panel-now-stays-tucked-under-the-left-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-now-shows-states-and-review-in-a-tighte.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-sidebar-keeps-the-organization-picker-space-stable-while.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-tokens-can-now-be-imported-from-pasted-notes-code-files-fold.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +94 -2
- package/corpus/templates/design/e2e/helpers.ts +168 -65
- package/corpus/templates/design/package.json +3 -1
- package/corpus/templates/design/server/db/schema.ts +23 -0
- package/corpus/templates/design/server/handlers/uploads.ts +22 -1
- package/corpus/templates/design/server/lib/provider-api.ts +7 -4
- package/corpus/templates/design/server/lib/verify-write-grant.ts +108 -0
- package/corpus/templates/design/server/plugins/db.ts +39 -0
- package/corpus/templates/design/server/register-secrets.ts +38 -0
- package/corpus/templates/design/shared/board-file.ts +228 -0
- package/corpus/templates/design/shared/board-objects.ts +288 -0
- package/corpus/templates/design/shared/code-layer.ts +52 -0
- package/corpus/templates/design/shared/component-model.ts +35 -0
- package/corpus/templates/design/shared/motion-compiler.ts +137 -15
- package/corpus/templates/design/shared/motion-timeline.ts +2 -2
- package/corpus/templates/design/shared/resolve-tweaks.ts +32 -9
- package/corpus/templates/design/tsconfig.json +2 -1
- package/corpus/templates/slides/AGENTS.md +9 -0
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +4 -0
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +4 -24
- package/corpus/templates/slides/app/lib/export-pdf-client.ts +29 -20
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +365 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +12 -9
- package/corpus/templates/slides/app/vite-env.d.ts +18 -0
- package/corpus/templates/slides/changelog/2026-06-30-powerpoint-downloads-now-preserve-the-rendered-slide-layout-.md +6 -0
- package/corpus/templates/slides/changelog/2026-06-30-unavailable-decks-open-in-a-cleaner-full-height-centered-sta.md +6 -0
- package/corpus/templates/slides/package.json +1 -0
- package/corpus/templates/slides/vite.config.ts +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +94 -10
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/design-connect.d.ts +25 -0
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +357 -18
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +115 -22
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +1 -0
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +5 -5
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/chat-view-transition.d.ts +6 -0
- package/dist/client/chat-view-transition.d.ts.map +1 -1
- package/dist/client/chat-view-transition.js +23 -2
- package/dist/client/chat-view-transition.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +3 -2
- package/dist/client/composer/PromptComposer.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/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +11 -4
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/sharing/ShareButton.js +3 -3
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +10 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.d.ts +8 -2
- package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.js +20 -6
- package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/db/client.d.ts +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +28 -2
- package/dist/db/client.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/index.d.ts +5 -4
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +28 -0
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +25 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +43 -18
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-native.css +54 -0
- package/dist/usage/store.js +2 -2
- package/dist/usage/store.js.map +1 -1
- package/package.json +1 -1
|
@@ -826,6 +826,13 @@ const enUS = {
|
|
|
826
826
|
noMatchingAssets: "No matching assets across your kits.",
|
|
827
827
|
noMatchingLibraryAssets:
|
|
828
828
|
"No matching {{mediaLabel}} assets in this library.",
|
|
829
|
+
drafts: "Drafts",
|
|
830
|
+
allLibraries: "All libraries",
|
|
831
|
+
noDrafts: "No drafts yet.",
|
|
832
|
+
noMatchingDrafts: "No matching drafts.",
|
|
833
|
+
recentDrafts: "Recent Drafts",
|
|
834
|
+
viewAllDrafts: "View all drafts",
|
|
835
|
+
draftAsset: "Draft asset",
|
|
829
836
|
noReusableAssets:
|
|
830
837
|
"No reusable assets yet. Select a kit to upload references or generate assets.",
|
|
831
838
|
noNewAssetsUploaded: "No new assets were uploaded.",
|
|
@@ -2762,6 +2769,12 @@ export const messagesByLocale = {
|
|
|
2762
2769
|
"zh-TW": mergeMessages(zhTW),
|
|
2763
2770
|
"zh-CN": mergeMessages({
|
|
2764
2771
|
library: {
|
|
2772
|
+
allLibraries: "所有库",
|
|
2773
|
+
noDrafts: "暂无草稿。",
|
|
2774
|
+
noMatchingDrafts: "没有匹配的草稿。",
|
|
2775
|
+
recentDrafts: "最近草稿",
|
|
2776
|
+
viewAllDrafts: "查看所有草稿",
|
|
2777
|
+
draftAsset: "草稿资产",
|
|
2765
2778
|
addAssets: "添加资产",
|
|
2766
2779
|
addAssetsDescription:
|
|
2767
2780
|
"上传源素材或生成候选项,然后只将应指导未来生成的资产标记为参考。",
|
|
@@ -3500,6 +3513,12 @@ export const messagesByLocale = {
|
|
|
3500
3513
|
}),
|
|
3501
3514
|
"es-ES": mergeMessages({
|
|
3502
3515
|
library: {
|
|
3516
|
+
allLibraries: "Todas las bibliotecas",
|
|
3517
|
+
noDrafts: "Aún no hay borradores.",
|
|
3518
|
+
noMatchingDrafts: "No hay borradores coincidentes.",
|
|
3519
|
+
recentDrafts: "Borradores recientes",
|
|
3520
|
+
viewAllDrafts: "Ver todos los borradores",
|
|
3521
|
+
draftAsset: "Borrador",
|
|
3503
3522
|
addAssets: "Agregar activos",
|
|
3504
3523
|
addAssetsDescription:
|
|
3505
3524
|
"Cargue material fuente o genere candidatos, luego marque solo los activos que deberían guiar a las generaciones futuras como referencias.",
|
|
@@ -3963,6 +3982,12 @@ export const messagesByLocale = {
|
|
|
3963
3982
|
}),
|
|
3964
3983
|
"fr-FR": mergeMessages({
|
|
3965
3984
|
library: {
|
|
3985
|
+
allLibraries: "Toutes les bibliothèques",
|
|
3986
|
+
noDrafts: "Aucun brouillon pour l'instant.",
|
|
3987
|
+
noMatchingDrafts: "Aucun brouillon correspondant.",
|
|
3988
|
+
recentDrafts: "Brouillons récents",
|
|
3989
|
+
viewAllDrafts: "Voir tous les brouillons",
|
|
3990
|
+
draftAsset: "Brouillon",
|
|
3966
3991
|
addAssets: "Ajouter des éléments",
|
|
3967
3992
|
addAssetsDescription:
|
|
3968
3993
|
"Téléchargez le matériel source ou générez des candidats, puis marquez uniquement les atouts qui devraient guider les générations futures comme références.",
|
|
@@ -4404,6 +4429,12 @@ export const messagesByLocale = {
|
|
|
4404
4429
|
}),
|
|
4405
4430
|
"de-DE": mergeMessages({
|
|
4406
4431
|
library: {
|
|
4432
|
+
allLibraries: "Alle Bibliotheken",
|
|
4433
|
+
noDrafts: "Noch keine Entwürfe.",
|
|
4434
|
+
noMatchingDrafts: "Keine passenden Entwürfe.",
|
|
4435
|
+
recentDrafts: "Letzte Entwürfe",
|
|
4436
|
+
viewAllDrafts: "Alle Entwürfe anzeigen",
|
|
4437
|
+
draftAsset: "Entwurf",
|
|
4407
4438
|
addAssets: "Assets hinzufügen",
|
|
4408
4439
|
addAssetsDescription:
|
|
4409
4440
|
"Laden Sie Quellmaterial hoch oder generieren Sie Kandidaten und markieren Sie dann nur die Assets, die künftigen Generationen als Referenz dienen sollen.",
|
|
@@ -4753,6 +4784,12 @@ export const messagesByLocale = {
|
|
|
4753
4784
|
}),
|
|
4754
4785
|
"ja-JP": mergeMessages({
|
|
4755
4786
|
library: {
|
|
4787
|
+
allLibraries: "すべてのライブラリ",
|
|
4788
|
+
noDrafts: "下書きはまだありません。",
|
|
4789
|
+
noMatchingDrafts: "一致する下書きはありません。",
|
|
4790
|
+
recentDrafts: "最近の下書き",
|
|
4791
|
+
viewAllDrafts: "すべての下書きを表示",
|
|
4792
|
+
draftAsset: "下書きアセット",
|
|
4756
4793
|
addAssets: "アセットの追加",
|
|
4757
4794
|
addAssetsDescription:
|
|
4758
4795
|
"ソース素材をアップロードするか候補を生成し、将来の世代を導く必要がある資産のみを参照としてマークします。",
|
|
@@ -5092,6 +5129,12 @@ export const messagesByLocale = {
|
|
|
5092
5129
|
}),
|
|
5093
5130
|
"ko-KR": mergeMessages({
|
|
5094
5131
|
library: {
|
|
5132
|
+
allLibraries: "모든 라이브러리",
|
|
5133
|
+
noDrafts: "아직 초안이 없습니다.",
|
|
5134
|
+
noMatchingDrafts: "일치하는 초안이 없습니다.",
|
|
5135
|
+
recentDrafts: "최근 초안",
|
|
5136
|
+
viewAllDrafts: "모든 초안 보기",
|
|
5137
|
+
draftAsset: "초안 자산",
|
|
5095
5138
|
addAssets: "자산 추가",
|
|
5096
5139
|
addAssetsDescription:
|
|
5097
5140
|
"원본 자료를 업로드하거나 후보를 생성한 후, 미래 세대를 이끌어야 할 자산만 참고 자료로 표시하세요.",
|
|
@@ -5430,6 +5473,12 @@ export const messagesByLocale = {
|
|
|
5430
5473
|
}),
|
|
5431
5474
|
"pt-BR": mergeMessages({
|
|
5432
5475
|
library: {
|
|
5476
|
+
allLibraries: "Todas as bibliotecas",
|
|
5477
|
+
noDrafts: "Ainda não há rascunhos.",
|
|
5478
|
+
noMatchingDrafts: "Nenhum rascunho correspondente.",
|
|
5479
|
+
recentDrafts: "Rascunhos recentes",
|
|
5480
|
+
viewAllDrafts: "Ver todos os rascunhos",
|
|
5481
|
+
draftAsset: "Rascunho",
|
|
5433
5482
|
addAssets: "Adicionar recursos",
|
|
5434
5483
|
addAssetsDescription:
|
|
5435
5484
|
"Carregue o material de origem ou gere candidatos e marque apenas os ativos que devem orientar as gerações futuras como referências.",
|
|
@@ -5870,6 +5919,12 @@ export const messagesByLocale = {
|
|
|
5870
5919
|
}),
|
|
5871
5920
|
"hi-IN": mergeMessages({
|
|
5872
5921
|
library: {
|
|
5922
|
+
allLibraries: "सभी लाइब्रेरी",
|
|
5923
|
+
noDrafts: "अभी तक कोई ड्राफ़्ट नहीं।",
|
|
5924
|
+
noMatchingDrafts: "कोई मिलान वाला ड्राफ़्ट नहीं।",
|
|
5925
|
+
recentDrafts: "हाल के ड्राफ़्ट",
|
|
5926
|
+
viewAllDrafts: "सभी ड्राफ़्ट देखें",
|
|
5927
|
+
draftAsset: "ड्राफ़्ट एसेट",
|
|
5873
5928
|
addAssets: "संपत्तियां जोड़ें",
|
|
5874
5929
|
addAssetsDescription:
|
|
5875
5930
|
"स्रोत सामग्री अपलोड करें या उम्मीदवार तैयार करें, फिर केवल उन संपत्तियों को चिह्नित करें जो भविष्य की पीढ़ियों को संदर्भ के रूप में मार्गदर्शन करें।",
|
|
@@ -6206,6 +6261,12 @@ export const messagesByLocale = {
|
|
|
6206
6261
|
}),
|
|
6207
6262
|
"ar-SA": mergeMessages({
|
|
6208
6263
|
library: {
|
|
6264
|
+
allLibraries: "جميع المكتبات",
|
|
6265
|
+
noDrafts: "لا توجد مسودات بعد.",
|
|
6266
|
+
noMatchingDrafts: "لا توجد مسودات مطابقة.",
|
|
6267
|
+
recentDrafts: "المسودات الأخيرة",
|
|
6268
|
+
viewAllDrafts: "عرض جميع المسودات",
|
|
6269
|
+
draftAsset: "مسودة",
|
|
6209
6270
|
addAssets: "أضف الأصول",
|
|
6210
6271
|
addAssetsDescription:
|
|
6211
6272
|
"قم بتحميل المواد المصدرية أو قم بإنشاء مرشحين، ثم حدد فقط الأصول التي يجب أن توجه الأجيال القادمة كمراجع.",
|
|
@@ -9,6 +9,7 @@ import { IconPhoto, IconSparkles, IconVideo } from "@tabler/icons-react";
|
|
|
9
9
|
import { useEffect } from "react";
|
|
10
10
|
import { useNavigate, useParams } from "react-router";
|
|
11
11
|
|
|
12
|
+
import { RecentDraftsSection } from "@/components/create/RecentDraftsSection";
|
|
12
13
|
import { GenerationResults } from "@/components/generation/GenerationResults";
|
|
13
14
|
import { useImageModelMenu } from "@/hooks/use-image-model-menu";
|
|
14
15
|
import { ASSETS_CHAT_STORAGE_KEY } from "@/lib/chat";
|
|
@@ -122,6 +123,9 @@ export default function CreatePage() {
|
|
|
122
123
|
</button>
|
|
123
124
|
))}
|
|
124
125
|
</div>
|
|
126
|
+
<div className="mt-8 w-full text-left">
|
|
127
|
+
<RecentDraftsSection />
|
|
128
|
+
</div>
|
|
125
129
|
</div>
|
|
126
130
|
}
|
|
127
131
|
/>
|
|
@@ -102,16 +102,22 @@ import {
|
|
|
102
102
|
type VariantSlot,
|
|
103
103
|
} from "./brand-kits.$id";
|
|
104
104
|
|
|
105
|
-
type AssetTab = "all" | "generated" | "references";
|
|
105
|
+
type AssetTab = "all" | "generated" | "drafts" | "references";
|
|
106
106
|
|
|
107
107
|
function isGeneratedAsset(asset: Asset) {
|
|
108
108
|
const role = asset.role ?? "";
|
|
109
109
|
return role === "generated" || role === "active" || role === "candidate";
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
function isDraftAsset(asset: Asset) {
|
|
113
|
+
return asset.role === "generated" && asset.status === "candidate";
|
|
114
|
+
}
|
|
115
|
+
|
|
112
116
|
function assetMatchesTab(asset: Asset, tab: AssetTab) {
|
|
113
117
|
if (tab === "all") return true;
|
|
114
|
-
if (tab === "
|
|
118
|
+
if (tab === "drafts") return isDraftAsset(asset);
|
|
119
|
+
if (tab === "generated")
|
|
120
|
+
return isGeneratedAsset(asset) && !isDraftAsset(asset);
|
|
115
121
|
return !isGeneratedAsset(asset);
|
|
116
122
|
}
|
|
117
123
|
|
|
@@ -123,6 +129,7 @@ const MCP_APP_CHAT_BRIDGE_QUERY_PARAM = "__an_mcp_chat_bridge";
|
|
|
123
129
|
const PICKER_INLINE_SELECT_CLASS =
|
|
124
130
|
"h-7 w-auto min-w-0 max-w-full rounded-md border-0 bg-transparent px-1.5 py-1 text-xs font-medium text-muted-foreground shadow-none ring-offset-transparent transition hover:bg-accent/50 hover:text-foreground focus:ring-0 focus:ring-offset-0 sm:px-2 [&>svg]:ms-1 [&>svg]:size-3.5 [&>svg]:opacity-60";
|
|
125
131
|
type PickerMediaType = "image" | "video";
|
|
132
|
+
type PickerLayout = "default" | "vertical";
|
|
126
133
|
|
|
127
134
|
type Asset = {
|
|
128
135
|
id: string;
|
|
@@ -187,6 +194,7 @@ type HostConfig = {
|
|
|
187
194
|
styleStrength?: StyleStrength;
|
|
188
195
|
includeLogo?: boolean;
|
|
189
196
|
callerAppId?: string;
|
|
197
|
+
layout?: PickerLayout;
|
|
190
198
|
autoGenerate?: boolean;
|
|
191
199
|
candidateRunIds?: string[];
|
|
192
200
|
};
|
|
@@ -238,6 +246,10 @@ function normalizeMediaType(value: unknown): PickerMediaType {
|
|
|
238
246
|
return value === "video" ? "video" : "image";
|
|
239
247
|
}
|
|
240
248
|
|
|
249
|
+
function normalizePickerLayout(value: unknown): PickerLayout | undefined {
|
|
250
|
+
return value === "vertical" ? "vertical" : undefined;
|
|
251
|
+
}
|
|
252
|
+
|
|
241
253
|
function normalizeBoolean(value: unknown): boolean | undefined {
|
|
242
254
|
if (typeof value === "boolean") return value;
|
|
243
255
|
if (typeof value !== "string") return undefined;
|
|
@@ -314,6 +326,7 @@ function normalizeHostConfig(value: unknown): HostConfig {
|
|
|
314
326
|
includeLogo: normalizeBoolean(record.includeLogo),
|
|
315
327
|
callerAppId:
|
|
316
328
|
typeof record.callerAppId === "string" ? record.callerAppId : undefined,
|
|
329
|
+
layout: normalizePickerLayout(record.layout),
|
|
317
330
|
candidateRunIds: normalizeCandidateRunIds(record.candidateRunIds),
|
|
318
331
|
};
|
|
319
332
|
if (Object.prototype.hasOwnProperty.call(record, "autoGenerate")) {
|
|
@@ -1957,12 +1970,29 @@ export function LibraryWorkspace({
|
|
|
1957
1970
|
|
|
1958
1971
|
export function AssetPickerSurface() {
|
|
1959
1972
|
const t = useT();
|
|
1960
|
-
const [searchParams] = useSearchParams();
|
|
1973
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
1961
1974
|
const searchParamsKey = searchParams.toString();
|
|
1975
|
+
const urlAssetTab = useMemo<AssetTab | null>(() => {
|
|
1976
|
+
const tab = new URLSearchParams(searchParamsKey).get("tab");
|
|
1977
|
+
return tab === "all" ||
|
|
1978
|
+
tab === "generated" ||
|
|
1979
|
+
tab === "drafts" ||
|
|
1980
|
+
tab === "references"
|
|
1981
|
+
? tab
|
|
1982
|
+
: null;
|
|
1983
|
+
}, [searchParamsKey]);
|
|
1984
|
+
// The active tab is the only host-irrelevant search param. Exclude it from the
|
|
1985
|
+
// host-config key so toggling tabs (which writes `?tab=`) doesn't retrigger the
|
|
1986
|
+
// effect that resets media type / query / library from the URL.
|
|
1987
|
+
const hostParamsKey = useMemo(() => {
|
|
1988
|
+
const params = new URLSearchParams(searchParamsKey);
|
|
1989
|
+
params.delete("tab");
|
|
1990
|
+
return params.toString();
|
|
1991
|
+
}, [searchParamsKey]);
|
|
1962
1992
|
const mcpChatBridgeActive =
|
|
1963
1993
|
searchParamsRequestPicker(searchParams) || isEmbedMcpChatBridgeActive();
|
|
1964
1994
|
const urlHostConfig = useMemo(() => {
|
|
1965
|
-
const params = new URLSearchParams(
|
|
1995
|
+
const params = new URLSearchParams(hostParamsKey);
|
|
1966
1996
|
return {
|
|
1967
1997
|
mediaType: normalizeMediaType(params.get("mediaType")),
|
|
1968
1998
|
prompt: params.get("prompt") ?? undefined,
|
|
@@ -1976,6 +2006,7 @@ export function AssetPickerSurface() {
|
|
|
1976
2006
|
styleStrength: normalizeStyleStrength(params.get("styleStrength")),
|
|
1977
2007
|
includeLogo: normalizeBoolean(params.get("includeLogo")),
|
|
1978
2008
|
callerAppId: params.get("callerAppId") ?? undefined,
|
|
2009
|
+
layout: normalizePickerLayout(params.get("layout")),
|
|
1979
2010
|
candidateRunIds: normalizeCandidateRunIds(
|
|
1980
2011
|
params.getAll("candidateRunIds").length > 0
|
|
1981
2012
|
? params.getAll("candidateRunIds")
|
|
@@ -1983,7 +2014,7 @@ export function AssetPickerSurface() {
|
|
|
1983
2014
|
),
|
|
1984
2015
|
autoGenerate: normalizeBoolean(params.get("autoGenerate")) ?? false,
|
|
1985
2016
|
} satisfies HostConfig;
|
|
1986
|
-
}, [
|
|
2017
|
+
}, [hostParamsKey]);
|
|
1987
2018
|
const bridgeRef = useRef<EmbeddedAppBridge | null>(null);
|
|
1988
2019
|
const embedded = useMemo(
|
|
1989
2020
|
() =>
|
|
@@ -2001,6 +2032,9 @@ export function AssetPickerSurface() {
|
|
|
2001
2032
|
const [mediaType, setMediaType] = useState<PickerMediaType>(
|
|
2002
2033
|
() => hostConfig.mediaType ?? "image",
|
|
2003
2034
|
);
|
|
2035
|
+
const [pickerLayout, setPickerLayout] = useState<PickerLayout>(
|
|
2036
|
+
() => hostConfig.layout ?? "default",
|
|
2037
|
+
);
|
|
2004
2038
|
const [query, setQuery] = useState(() => hostConfig.query ?? "");
|
|
2005
2039
|
const [prompt, setPrompt] = useState(() => hostConfig.prompt ?? "");
|
|
2006
2040
|
const [aspectRatio, setAspectRatio] = useState<string>(
|
|
@@ -2008,7 +2042,7 @@ export function AssetPickerSurface() {
|
|
|
2008
2042
|
);
|
|
2009
2043
|
const [presetId, setPresetId] = useState(() => hostConfig.presetId ?? "none");
|
|
2010
2044
|
const [count, setCount] = useState(() => hostConfig.count ?? 3);
|
|
2011
|
-
const [assetTab, setAssetTab] = useState<AssetTab>("all");
|
|
2045
|
+
const [assetTab, setAssetTab] = useState<AssetTab>(urlAssetTab ?? "all");
|
|
2012
2046
|
const [selectedLibraryId, setSelectedLibraryId] = useState(
|
|
2013
2047
|
() => hostConfig.libraryId ?? "",
|
|
2014
2048
|
);
|
|
@@ -2023,6 +2057,7 @@ export function AssetPickerSurface() {
|
|
|
2023
2057
|
useEffect(() => {
|
|
2024
2058
|
setHostConfig((current) => ({ ...current, ...urlHostConfig }));
|
|
2025
2059
|
setMediaType(urlHostConfig.mediaType ?? "image");
|
|
2060
|
+
setPickerLayout(urlHostConfig.layout ?? "default");
|
|
2026
2061
|
setQuery(urlHostConfig.query ?? "");
|
|
2027
2062
|
setPrompt(urlHostConfig.prompt ?? "");
|
|
2028
2063
|
setSelectedLibraryId(urlHostConfig.libraryId ?? "");
|
|
@@ -2032,6 +2067,30 @@ export function AssetPickerSurface() {
|
|
|
2032
2067
|
setVisibleCandidateRunIds(urlHostConfig.candidateRunIds ?? []);
|
|
2033
2068
|
}, [urlHostConfig]);
|
|
2034
2069
|
|
|
2070
|
+
useEffect(() => {
|
|
2071
|
+
// Reset to "all" when the tab param is removed (e.g. back/forward nav)
|
|
2072
|
+
// since the component stays mounted across search-param changes.
|
|
2073
|
+
setAssetTab(urlAssetTab ?? "all");
|
|
2074
|
+
}, [urlAssetTab]);
|
|
2075
|
+
|
|
2076
|
+
const handleAssetTabChange = useCallback(
|
|
2077
|
+
(value: AssetTab) => {
|
|
2078
|
+
setAssetTab(value);
|
|
2079
|
+
// Keep the tab reflected in the URL so it survives refresh/share and
|
|
2080
|
+
// stays consistent with the `?tab=` deep link from the home page.
|
|
2081
|
+
setSearchParams(
|
|
2082
|
+
(prev) => {
|
|
2083
|
+
const next = new URLSearchParams(prev);
|
|
2084
|
+
if (value === "all") next.delete("tab");
|
|
2085
|
+
else next.set("tab", value);
|
|
2086
|
+
return next;
|
|
2087
|
+
},
|
|
2088
|
+
{ replace: true },
|
|
2089
|
+
);
|
|
2090
|
+
},
|
|
2091
|
+
[setSearchParams],
|
|
2092
|
+
);
|
|
2093
|
+
|
|
2035
2094
|
const librariesQuery = useActionQuery("list-libraries", {
|
|
2036
2095
|
compact: true,
|
|
2037
2096
|
} as any) as {
|
|
@@ -2116,23 +2175,54 @@ export function AssetPickerSurface() {
|
|
|
2116
2175
|
!selectedPreset &&
|
|
2117
2176
|
Boolean(waitingForPresetData);
|
|
2118
2177
|
const mediaLabel = mediaType === "video" ? "video" : "image";
|
|
2178
|
+
const viewingDrafts = assetTab === "drafts";
|
|
2179
|
+
// The standalone Library "Drafts" tab mirrors the home Recent Drafts section:
|
|
2180
|
+
// every unsaved draft across all accessible libraries, regardless of media
|
|
2181
|
+
// type. The embedded picker keeps its library + media-type scope so an
|
|
2182
|
+
// image-only picker never surfaces video drafts.
|
|
2183
|
+
const draftsGlobalView = viewingDrafts && !embedded;
|
|
2119
2184
|
const assetsParams = useMemo(
|
|
2120
2185
|
() => ({
|
|
2121
2186
|
libraryId: selectedLibraryId,
|
|
2122
2187
|
mediaType,
|
|
2188
|
+
// Drafts are exactly generated candidates — filter them server-side
|
|
2189
|
+
// instead of fetching the whole library and filtering on the client.
|
|
2190
|
+
role: viewingDrafts ? "generated" : undefined,
|
|
2191
|
+
status: viewingDrafts ? "candidate" : undefined,
|
|
2123
2192
|
query: query.trim() || undefined,
|
|
2124
2193
|
includeCandidates:
|
|
2125
|
-
|
|
2194
|
+
viewingDrafts ||
|
|
2195
|
+
(mediaType === "image" && visibleCandidateRunIds.length > 0),
|
|
2196
|
+
// The Drafts tab shows every unsaved draft, not just the latest run batch.
|
|
2126
2197
|
candidateRunIds:
|
|
2127
|
-
visibleCandidateRunIds.length > 0
|
|
2198
|
+
!viewingDrafts && visibleCandidateRunIds.length > 0
|
|
2199
|
+
? visibleCandidateRunIds
|
|
2200
|
+
: undefined,
|
|
2128
2201
|
}),
|
|
2129
|
-
[
|
|
2202
|
+
[
|
|
2203
|
+
viewingDrafts,
|
|
2204
|
+
mediaType,
|
|
2205
|
+
query,
|
|
2206
|
+
selectedLibraryId,
|
|
2207
|
+
visibleCandidateRunIds,
|
|
2208
|
+
],
|
|
2130
2209
|
);
|
|
2131
2210
|
const { data: assetData, isLoading: assetsLoading } = useActionQuery(
|
|
2132
2211
|
"list-assets",
|
|
2133
2212
|
assetsParams as any,
|
|
2134
|
-
{
|
|
2213
|
+
{
|
|
2214
|
+
enabled:
|
|
2215
|
+
Boolean(selectedLibraryId) && !usingStarterLibrary && !draftsGlobalView,
|
|
2216
|
+
} as any,
|
|
2135
2217
|
) as { data?: { assets?: Asset[] }; isLoading: boolean };
|
|
2218
|
+
const { data: globalDraftsData, isLoading: globalDraftsLoading } =
|
|
2219
|
+
useActionQuery(
|
|
2220
|
+
"list-draft-assets",
|
|
2221
|
+
{ limit: 500 } as any,
|
|
2222
|
+
{
|
|
2223
|
+
enabled: draftsGlobalView,
|
|
2224
|
+
} as any,
|
|
2225
|
+
) as { data?: { assets?: Asset[] }; isLoading: boolean };
|
|
2136
2226
|
const starterAssets: Asset[] = useMemo(
|
|
2137
2227
|
() =>
|
|
2138
2228
|
STARTER_PRESET.referenceImages.map((reference) => ({
|
|
@@ -2159,11 +2249,23 @@ export function AssetPickerSurface() {
|
|
|
2159
2249
|
.some((value) => String(value).toLowerCase().includes(needle)),
|
|
2160
2250
|
);
|
|
2161
2251
|
}, [query, starterAssets]);
|
|
2162
|
-
const
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2252
|
+
const globalDrafts = useMemo(() => {
|
|
2253
|
+
const drafts = globalDraftsData?.assets ?? [];
|
|
2254
|
+
const needle = query.trim().toLowerCase();
|
|
2255
|
+
if (!needle) return drafts;
|
|
2256
|
+
return drafts.filter((asset) =>
|
|
2257
|
+
[asset.title, asset.description, asset.prompt]
|
|
2258
|
+
.filter(Boolean)
|
|
2259
|
+
.some((value) => String(value).toLowerCase().includes(needle)),
|
|
2260
|
+
);
|
|
2261
|
+
}, [globalDraftsData, query]);
|
|
2262
|
+
const allAssets = draftsGlobalView
|
|
2263
|
+
? globalDrafts
|
|
2264
|
+
: usingStarterLibrary
|
|
2265
|
+
? mediaType === "image"
|
|
2266
|
+
? visibleStarterAssets
|
|
2267
|
+
: []
|
|
2268
|
+
: (assetData?.assets ?? []);
|
|
2167
2269
|
const currentLibrary = useMemo(
|
|
2168
2270
|
() =>
|
|
2169
2271
|
displayLibraries.find((library) => library.id === selectedLibraryId) ??
|
|
@@ -2174,6 +2276,7 @@ export function AssetPickerSurface() {
|
|
|
2174
2276
|
() => allAssets.filter((asset) => assetMatchesTab(asset, assetTab)),
|
|
2175
2277
|
[allAssets, assetTab],
|
|
2176
2278
|
);
|
|
2279
|
+
const listLoading = draftsGlobalView ? globalDraftsLoading : assetsLoading;
|
|
2177
2280
|
const [previewAsset, setPreviewAsset] = useState<Asset | null>(null);
|
|
2178
2281
|
const [standaloneSelection, setStandaloneSelection] = useState<ReturnType<
|
|
2179
2282
|
typeof assetPayload
|
|
@@ -2413,6 +2516,7 @@ export function AssetPickerSurface() {
|
|
|
2413
2516
|
const next = normalizeHostConfig(payload);
|
|
2414
2517
|
setHostConfig((current) => ({ ...current, ...next }));
|
|
2415
2518
|
if (next.mediaType !== undefined) setMediaType(next.mediaType);
|
|
2519
|
+
if (next.layout !== undefined) setPickerLayout(next.layout);
|
|
2416
2520
|
if (next.query !== undefined) setQuery(next.query);
|
|
2417
2521
|
if (next.prompt !== undefined) setPrompt(next.prompt);
|
|
2418
2522
|
if (next.libraryId !== undefined) setSelectedLibraryId(next.libraryId);
|
|
@@ -2442,10 +2546,11 @@ export function AssetPickerSurface() {
|
|
|
2442
2546
|
query,
|
|
2443
2547
|
prompt,
|
|
2444
2548
|
aspectRatio,
|
|
2549
|
+
layout: pickerLayout,
|
|
2445
2550
|
},
|
|
2446
2551
|
{ requestSource: "assets-picker-ui" },
|
|
2447
2552
|
).catch(() => {});
|
|
2448
|
-
}, [aspectRatio, mediaType, prompt, query, selectedLibraryId]);
|
|
2553
|
+
}, [aspectRatio, mediaType, pickerLayout, prompt, query, selectedLibraryId]);
|
|
2449
2554
|
|
|
2450
2555
|
const canGenerate =
|
|
2451
2556
|
mediaType === "image" &&
|
|
@@ -2561,14 +2666,22 @@ export function AssetPickerSurface() {
|
|
|
2561
2666
|
waitingForRequestedPreset,
|
|
2562
2667
|
]);
|
|
2563
2668
|
|
|
2669
|
+
const verticalLayout = pickerLayout === "vertical";
|
|
2670
|
+
|
|
2564
2671
|
return (
|
|
2565
2672
|
<div
|
|
2566
2673
|
className={cn(
|
|
2567
2674
|
"flex flex-col overflow-hidden bg-background text-foreground",
|
|
2568
2675
|
embedded ? "h-screen w-screen" : "h-full w-full",
|
|
2676
|
+
verticalLayout && "assets-picker-vertical",
|
|
2569
2677
|
)}
|
|
2570
2678
|
>
|
|
2571
|
-
<header
|
|
2679
|
+
<header
|
|
2680
|
+
className={cn(
|
|
2681
|
+
"flex shrink-0 items-center justify-between gap-3 border-b border-border",
|
|
2682
|
+
verticalLayout ? "h-10 px-2" : "h-12 px-3",
|
|
2683
|
+
)}
|
|
2684
|
+
>
|
|
2572
2685
|
<div className="min-w-0 truncate text-sm font-semibold">
|
|
2573
2686
|
{embedded ? t("navigation.brand") : t("library.library")}
|
|
2574
2687
|
</div>
|
|
@@ -2577,7 +2690,7 @@ export function AssetPickerSurface() {
|
|
|
2577
2690
|
<Button
|
|
2578
2691
|
variant={showCreatePane ? "secondary" : "default"}
|
|
2579
2692
|
size="sm"
|
|
2580
|
-
className="
|
|
2693
|
+
className={cn("gap-1.5", verticalLayout ? "h-7 px-2" : "h-8")}
|
|
2581
2694
|
onClick={() => setShowCreatePane((open) => !open)}
|
|
2582
2695
|
>
|
|
2583
2696
|
{showCreatePane ? (
|
|
@@ -2585,7 +2698,9 @@ export function AssetPickerSurface() {
|
|
|
2585
2698
|
) : (
|
|
2586
2699
|
<IconPhotoPlus className="h-3.5 w-3.5" />
|
|
2587
2700
|
)}
|
|
2588
|
-
{
|
|
2701
|
+
<span className={verticalLayout ? "sr-only" : undefined}>
|
|
2702
|
+
{showCreatePane ? t("library.close") : t("library.createPane")}
|
|
2703
|
+
</span>
|
|
2589
2704
|
</Button>
|
|
2590
2705
|
)}
|
|
2591
2706
|
{embedded && (
|
|
@@ -2614,9 +2729,14 @@ export function AssetPickerSurface() {
|
|
|
2614
2729
|
</header>
|
|
2615
2730
|
|
|
2616
2731
|
{showCreatePane && mediaType === "image" && (
|
|
2617
|
-
<section
|
|
2732
|
+
<section
|
|
2733
|
+
className={cn(
|
|
2734
|
+
"shrink-0 border-b border-border",
|
|
2735
|
+
verticalLayout ? "px-2 py-2" : "px-3 py-3",
|
|
2736
|
+
)}
|
|
2737
|
+
>
|
|
2618
2738
|
{mediaType === "image" ? (
|
|
2619
|
-
<div className="
|
|
2739
|
+
<div className="rounded-lg border border-border/80 bg-background focus-within:ring-1 focus-within:ring-ring">
|
|
2620
2740
|
<Input
|
|
2621
2741
|
type="text"
|
|
2622
2742
|
value={prompt}
|
|
@@ -2633,10 +2753,23 @@ export function AssetPickerSurface() {
|
|
|
2633
2753
|
if (canGenerate) runGenerate();
|
|
2634
2754
|
}}
|
|
2635
2755
|
placeholder={t("library.generateImagePlaceholder")}
|
|
2636
|
-
className=
|
|
2756
|
+
className={cn(
|
|
2757
|
+
"border-0 bg-transparent px-3 leading-6 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0",
|
|
2758
|
+
verticalLayout ? "h-9 py-2 text-xs" : "h-11 py-2.5",
|
|
2759
|
+
)}
|
|
2637
2760
|
/>
|
|
2638
|
-
<div
|
|
2639
|
-
|
|
2761
|
+
<div
|
|
2762
|
+
className={cn(
|
|
2763
|
+
"flex gap-1 px-2 pb-2",
|
|
2764
|
+
verticalLayout ? "flex-col items-stretch" : "items-center",
|
|
2765
|
+
)}
|
|
2766
|
+
>
|
|
2767
|
+
<div
|
|
2768
|
+
className={cn(
|
|
2769
|
+
"flex min-w-0 flex-1 items-center gap-0.5 sm:gap-1",
|
|
2770
|
+
verticalLayout ? "justify-between" : "justify-end",
|
|
2771
|
+
)}
|
|
2772
|
+
>
|
|
2640
2773
|
<Select value={aspectRatio} onValueChange={setAspectRatio}>
|
|
2641
2774
|
<SelectTrigger
|
|
2642
2775
|
aria-label={t("brandKitDetail.aspectRatio")}
|
|
@@ -2701,7 +2834,10 @@ export function AssetPickerSurface() {
|
|
|
2701
2834
|
) : null}
|
|
2702
2835
|
</div>
|
|
2703
2836
|
<Button
|
|
2704
|
-
className=
|
|
2837
|
+
className={cn(
|
|
2838
|
+
"h-7 shrink-0 px-3 text-xs",
|
|
2839
|
+
!verticalLayout && "min-w-[5.75rem]",
|
|
2840
|
+
)}
|
|
2705
2841
|
disabled={!canGenerate}
|
|
2706
2842
|
onClick={runGenerate}
|
|
2707
2843
|
>
|
|
@@ -2841,31 +2977,65 @@ export function AssetPickerSurface() {
|
|
|
2841
2977
|
</section>
|
|
2842
2978
|
)}
|
|
2843
2979
|
|
|
2844
|
-
<main
|
|
2980
|
+
<main
|
|
2981
|
+
className={cn(
|
|
2982
|
+
"min-h-0 flex-1 overflow-y-auto",
|
|
2983
|
+
verticalLayout ? "p-2" : "p-3",
|
|
2984
|
+
)}
|
|
2985
|
+
>
|
|
2845
2986
|
{displayLibraries.length > 0 && (
|
|
2846
|
-
<div
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2987
|
+
<div
|
|
2988
|
+
className={cn(
|
|
2989
|
+
"mb-3 flex flex-col gap-2",
|
|
2990
|
+
!verticalLayout &&
|
|
2991
|
+
"sm:flex-row sm:items-center sm:justify-between",
|
|
2992
|
+
)}
|
|
2993
|
+
>
|
|
2994
|
+
<div
|
|
2995
|
+
className={cn(
|
|
2996
|
+
"flex flex-col gap-2",
|
|
2997
|
+
!verticalLayout && "sm:flex-row sm:items-center",
|
|
2998
|
+
)}
|
|
2999
|
+
>
|
|
3000
|
+
{draftsGlobalView ? (
|
|
3001
|
+
<div
|
|
3002
|
+
className={cn(
|
|
3003
|
+
"flex h-9 items-center rounded-md border border-border/70 bg-background px-3 text-sm text-muted-foreground",
|
|
3004
|
+
!verticalLayout && "sm:w-48",
|
|
3005
|
+
)}
|
|
3006
|
+
>
|
|
3007
|
+
{t("library.allLibraries")}
|
|
3008
|
+
</div>
|
|
3009
|
+
) : (
|
|
3010
|
+
<Select
|
|
3011
|
+
value={selectedLibraryId}
|
|
3012
|
+
onValueChange={setSelectedLibraryId}
|
|
3013
|
+
>
|
|
3014
|
+
<SelectTrigger
|
|
3015
|
+
className={cn(
|
|
3016
|
+
"h-9 w-full border-border/70 bg-background",
|
|
3017
|
+
!verticalLayout && "sm:w-48",
|
|
3018
|
+
)}
|
|
3019
|
+
>
|
|
3020
|
+
<SelectValue placeholder={t("library.library")} />
|
|
3021
|
+
</SelectTrigger>
|
|
3022
|
+
<SelectContent>
|
|
3023
|
+
<SelectGroup>
|
|
3024
|
+
{displayLibraries.map((library) => (
|
|
3025
|
+
<SelectItem key={library.id} value={library.id}>
|
|
3026
|
+
{library.title}
|
|
3027
|
+
</SelectItem>
|
|
3028
|
+
))}
|
|
3029
|
+
</SelectGroup>
|
|
3030
|
+
</SelectContent>
|
|
3031
|
+
</Select>
|
|
3032
|
+
)}
|
|
2865
3033
|
{selectedLibraryId && (
|
|
2866
3034
|
<Tabs
|
|
2867
3035
|
value={assetTab}
|
|
2868
|
-
onValueChange={(value) =>
|
|
3036
|
+
onValueChange={(value) =>
|
|
3037
|
+
handleAssetTabChange(value as AssetTab)
|
|
3038
|
+
}
|
|
2869
3039
|
>
|
|
2870
3040
|
<TabsList>
|
|
2871
3041
|
<TabsTrigger value="all">
|
|
@@ -2874,6 +3044,9 @@ export function AssetPickerSurface() {
|
|
|
2874
3044
|
<TabsTrigger value="generated">
|
|
2875
3045
|
{t("library.generated")}
|
|
2876
3046
|
</TabsTrigger>
|
|
3047
|
+
<TabsTrigger value="drafts">
|
|
3048
|
+
{t("library.drafts")}
|
|
3049
|
+
</TabsTrigger>
|
|
2877
3050
|
<TabsTrigger value="references">
|
|
2878
3051
|
{t("library.references")}
|
|
2879
3052
|
</TabsTrigger>
|
|
@@ -2888,7 +3061,10 @@ export function AssetPickerSurface() {
|
|
|
2888
3061
|
onInput={(event) => setQuery(event.currentTarget.value)}
|
|
2889
3062
|
onChange={(event) => setQuery(event.target.value)}
|
|
2890
3063
|
placeholder={t("library.searchMedia", { mediaLabel })}
|
|
2891
|
-
className=
|
|
3064
|
+
className={cn(
|
|
3065
|
+
"h-9 border-border/70 bg-background",
|
|
3066
|
+
!verticalLayout && "sm:max-w-xs",
|
|
3067
|
+
)}
|
|
2892
3068
|
/>
|
|
2893
3069
|
)}
|
|
2894
3070
|
</div>
|
|
@@ -2897,6 +3073,7 @@ export function AssetPickerSurface() {
|
|
|
2897
3073
|
{mediaType === "image" &&
|
|
2898
3074
|
selectedLibraryId &&
|
|
2899
3075
|
!usingStarterLibrary &&
|
|
3076
|
+
!viewingDrafts &&
|
|
2900
3077
|
pickerVariantScopeId && (
|
|
2901
3078
|
<LibraryCandidateStage
|
|
2902
3079
|
activeLibraryId={selectedLibraryId}
|
|
@@ -2914,7 +3091,7 @@ export function AssetPickerSurface() {
|
|
|
2914
3091
|
</div>
|
|
2915
3092
|
)}
|
|
2916
3093
|
|
|
2917
|
-
{selectedLibraryId &&
|
|
3094
|
+
{selectedLibraryId && listLoading && (
|
|
2918
3095
|
<div className="assets-library-dense-grid grid grid-cols-2 gap-3">
|
|
2919
3096
|
{Array.from({ length: 8 }).map((_, index) => (
|
|
2920
3097
|
<Skeleton key={index} className="aspect-square rounded-md" />
|
|
@@ -2922,12 +3099,16 @@ export function AssetPickerSurface() {
|
|
|
2922
3099
|
</div>
|
|
2923
3100
|
)}
|
|
2924
3101
|
|
|
2925
|
-
{selectedLibraryId && !
|
|
3102
|
+
{selectedLibraryId && !listLoading && assets.length === 0 && (
|
|
2926
3103
|
<div className="flex h-full items-center justify-center text-center">
|
|
2927
3104
|
<div className="max-w-sm text-sm text-muted-foreground">
|
|
2928
|
-
{
|
|
2929
|
-
?
|
|
2930
|
-
|
|
3105
|
+
{draftsGlobalView
|
|
3106
|
+
? query
|
|
3107
|
+
? t("library.noMatchingDrafts")
|
|
3108
|
+
: t("library.noDrafts")
|
|
3109
|
+
: query
|
|
3110
|
+
? t("library.noMatchingLibraryAssets", { mediaLabel })
|
|
3111
|
+
: t("library.noAssetsInLibrary", { mediaLabel })}
|
|
2931
3112
|
</div>
|
|
2932
3113
|
</div>
|
|
2933
3114
|
)}
|