@agent-native/core 0.102.1 → 0.103.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 +2 -2
- package/corpus/core/CHANGELOG.md +15 -0
- package/corpus/core/docs/content/local-file-mode.mdx +99 -489
- package/corpus/core/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/corpus/core/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/corpus/core/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/corpus/core/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/corpus/core/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/corpus/core/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/corpus/core/docs/content/template-content.mdx +26 -42
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/content-local.ts +86 -18
- package/corpus/core/src/cli/index.ts +2 -2
- package/corpus/core/src/cli/skills-content/content-skill.ts +36 -25
- package/corpus/core/src/cli/skills.ts +47 -13
- package/corpus/core/src/client/AgentPanel.tsx +7 -0
- package/corpus/core/src/client/AssistantChat.tsx +7 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +7 -1
- package/corpus/core/src/client/chat/message-components.tsx +17 -3
- package/corpus/core/src/client/composer/ComposerPlusMenu.tsx +96 -6
- package/corpus/core/src/client/composer/asset-picker-url.ts +80 -0
- package/corpus/core/src/client/error-format.ts +24 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +8 -1
- package/corpus/core/src/local-artifacts/index.ts +65 -0
- package/corpus/templates/assets/app/components/library/GenerationPresetsPanel.tsx +325 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +12 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +21 -0
- package/corpus/templates/assets/app/i18n-data.ts +215 -0
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +19 -479
- package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id_.settings.tsx +446 -0
- package/corpus/templates/assets/app/routes/library.tsx +69 -0
- package/corpus/templates/assets/changelog/2026-07-15-fixed-top-level-image-picker-selections-returning-to-the-com.md +6 -0
- package/corpus/templates/clips/actions/disconnect-calendar.ts +57 -9
- package/corpus/templates/clips/actions/generate-workflow.ts +102 -59
- package/corpus/templates/clips/actions/get-recording-player-data.ts +64 -1
- package/corpus/templates/clips/actions/regenerate-summary.ts +7 -0
- package/corpus/templates/clips/actions/regenerate-title.ts +29 -11
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +34 -13
- package/corpus/templates/clips/app/components/editor/thumbnail-picker.tsx +87 -9
- package/corpus/templates/clips/app/components/editor/trim-handles.tsx +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +21 -8
- package/corpus/templates/clips/app/components/library/folder-tree.tsx +52 -0
- package/corpus/templates/clips/app/components/player/settings-panel.tsx +116 -58
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +43 -37
- package/corpus/templates/clips/app/components/player/video-player.tsx +50 -2
- package/corpus/templates/clips/app/components/recorder/microphone-visualizer.tsx +22 -3
- package/corpus/templates/clips/app/i18n/ar-SA.ts +5 -2
- package/corpus/templates/clips/app/i18n/de-DE.ts +6 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +5 -2
- package/corpus/templates/clips/app/i18n/es-ES.ts +6 -2
- package/corpus/templates/clips/app/i18n/fr-FR.ts +5 -2
- package/corpus/templates/clips/app/i18n/hi-IN.ts +5 -2
- package/corpus/templates/clips/app/i18n/ja-JP.ts +6 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +5 -2
- package/corpus/templates/clips/app/i18n/pt-BR.ts +6 -2
- package/corpus/templates/clips/app/i18n/zh-CN.ts +5 -2
- package/corpus/templates/clips/app/i18n/zh-TW.ts +5 -2
- package/corpus/templates/clips/app/lib/timestamp-mapping.ts +14 -0
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -2
- package/corpus/templates/clips/app/routes/_index.tsx +1 -2
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +98 -32
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +4 -1
- package/corpus/templates/clips/changelog/2026-07-15-ai-workflow-generation-now-stays-visible-avoids-duplicate-re.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-clip-playback-and-cta-controls-remain-interactive-through-ed.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-clip-titles-no-longer-describe-the-product-as-a-loom-alterna.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-description-regeneration-now-opens-the-agent-chat-so-progres.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-direct-recording-urls-now-respect-share-link-and-password-ac.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-disconnecting-a-calendar-now-clears-unrecorded-synced-meetin.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-folders-now-expose-rename-and-delete-actions-directly-in-the.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-recording-pages-now-explain-sign-in-access-and-avoid-showing.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-the-clips-extension-quick-actions-toolbar-can-be-moved-out-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-the-editor-now-skips-cut-sections-during-preview-and-keeps-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-thumbnail-capture-now-updates-previews-while-scrubbing-and-l.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-windows-permission-links-open-the-matching-settings-page.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +117 -2
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +27 -0
- package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +139 -101
- package/corpus/templates/clips/server/lib/recording-page-access.ts +35 -0
- package/corpus/templates/clips/server/lib/share-password.ts +6 -3
- package/corpus/templates/content/.agents/skills/content/SKILL.md +26 -39
- package/corpus/templates/content/AGENTS.md +25 -30
- package/corpus/templates/content/actions/_builder-docs-client.ts +23 -0
- package/corpus/templates/content/actions/_content-database-source-adapters.ts +21 -3
- package/corpus/templates/content/actions/_content-files.ts +338 -0
- package/corpus/templates/content/actions/_content-space-access.ts +135 -0
- package/corpus/templates/content/actions/_content-spaces.ts +640 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +90 -7
- package/corpus/templates/content/actions/_database-utils.ts +7 -1
- package/corpus/templates/content/actions/_local-file-documents.ts +0 -9
- package/corpus/templates/content/actions/_local-folder-source.ts +53 -0
- package/corpus/templates/content/actions/_property-utils.ts +9 -4
- package/corpus/templates/content/actions/add-database-item.ts +108 -65
- package/corpus/templates/content/actions/backfill-content-files.ts +22 -0
- package/corpus/templates/content/actions/connect-local-folder-source.ts +221 -0
- package/corpus/templates/content/actions/create-content-database.ts +129 -3
- package/corpus/templates/content/actions/create-document.ts +65 -55
- package/corpus/templates/content/actions/create-inline-content-database.ts +6 -1
- package/corpus/templates/content/actions/delete-content-database.ts +3 -0
- package/corpus/templates/content/actions/delete-document.ts +7 -11
- package/corpus/templates/content/actions/disconnect-local-folder-source.ts +175 -0
- package/corpus/templates/content/actions/duplicate-database-item.ts +10 -0
- package/corpus/templates/content/actions/duplicate-database-items.ts +13 -0
- package/corpus/templates/content/actions/edit-document.ts +2 -28
- package/corpus/templates/content/actions/ensure-content-spaces.ts +26 -0
- package/corpus/templates/content/actions/export-content-source.ts +47 -9
- package/corpus/templates/content/actions/get-document.ts +0 -14
- package/corpus/templates/content/actions/import-content-source.ts +43 -3
- package/corpus/templates/content/actions/list-content-spaces.ts +103 -0
- package/corpus/templates/content/actions/list-documents.ts +12 -9
- package/corpus/templates/content/actions/move-document.ts +3 -14
- package/corpus/templates/content/actions/pull-document.ts +0 -23
- package/corpus/templates/content/actions/remove-local-file-source.ts +50 -29
- package/corpus/templates/content/actions/resolve-local-folder-conflict.ts +442 -0
- package/corpus/templates/content/actions/reveal-local-source-file.ts +6 -17
- package/corpus/templates/content/actions/search-documents.ts +0 -34
- package/corpus/templates/content/actions/share-local-file-document.ts +25 -1
- package/corpus/templates/content/actions/submit-content-database-form.ts +12 -0
- package/corpus/templates/content/actions/sync-local-folder-source.ts +731 -0
- package/corpus/templates/content/actions/sync-manifest-local-folder-source.ts +123 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +10 -1
- package/corpus/templates/content/actions/update-document.ts +0 -15
- package/corpus/templates/content/actions/view-screen.ts +2 -50
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +76 -62
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +70 -22
- package/corpus/templates/content/app/components/editor/database/grouping.ts +2 -1
- package/corpus/templates/content/app/components/editor/database/settings.tsx +23 -20
- package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +330 -0
- package/corpus/templates/content/app/components/editor/database/types.ts +1 -0
- package/corpus/templates/content/app/components/editor/database/view-config.ts +3 -1
- package/corpus/templates/content/app/components/layout/Layout.tsx +25 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +209 -113
- package/corpus/templates/content/app/components/sidebar/select-content-space.ts +31 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +16 -0
- package/corpus/templates/content/app/hooks/use-content-spaces.ts +39 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +11 -0
- package/corpus/templates/content/app/i18n-data.ts +75 -0
- package/corpus/templates/content/app/routes/_app.local-files.tsx +174 -65
- package/corpus/templates/content/changelog/2026-07-16-content-callouts-can-now-be-reviewed-and-published-to-builder.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-heading-5-and-heading-6-are-available-from-the-editor-slash-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-organize-every-workspace-through-a-customizable-files-databa.md +6 -0
- package/corpus/templates/content/parity/matrix.md +2 -1
- package/corpus/templates/content/parity/matrix.ts +37 -1
- package/corpus/templates/content/scripts/dev-database.mjs +7 -5
- package/corpus/templates/content/server/db/schema.ts +113 -40
- package/corpus/templates/content/server/lib/document-context.ts +15 -1
- package/corpus/templates/content/server/lib/notion-sync.ts +6 -0
- package/corpus/templates/content/server/plugins/db.ts +153 -0
- package/corpus/templates/content/shared/api.ts +17 -3
- package/corpus/templates/content/shared/builder-mdx.ts +163 -16
- package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +59 -0
- package/corpus/templates/design/AGENTS.md +6 -1
- package/corpus/templates/design/actions/create-design-from-template.ts +19 -7
- package/corpus/templates/design/actions/list-design-templates.ts +69 -21
- package/corpus/templates/design/actions/navigate.ts +2 -2
- package/corpus/templates/design/actions/view-screen.ts +15 -2
- package/corpus/templates/design/agent-native.app-skill.json +5 -0
- package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +7 -3
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +281 -56
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +14 -2
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +3 -3
- package/corpus/templates/design/app/i18n-data.ts +21 -2
- package/corpus/templates/design/app/i18n-template-feature.ts +218 -10
- package/corpus/templates/design/app/pages/Index.tsx +195 -24
- package/corpus/templates/design/app/pages/Templates.tsx +144 -55
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +12 -1
- package/corpus/templates/design/changelog/2026-07-14-templates-now-appear-in-the-new-design-picker-with-previews-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-prototype-print-and-download-buttons-now-work-in-preview.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-templates-now-open-immediately-after-copying-even-while-the-.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/mail/AGENTS.md +23 -18
- package/corpus/templates/mail/actions/bulk-archive.ts +32 -28
- package/corpus/templates/mail/actions/mark-read.ts +131 -20
- package/corpus/templates/mail/actions/mark-thread-read.ts +1 -1
- package/corpus/templates/mail/actions/move-email.ts +30 -24
- package/corpus/templates/mail/actions/send-email.ts +73 -68
- package/corpus/templates/mail/changelog/2026-07-15-unread-inbox-cleanup-now-completes-reliably.md +6 -0
- package/corpus/templates/mail/server/handlers/emails.ts +218 -209
- package/corpus/templates/mail/server/lib/bulk-mark-read.ts +30 -0
- package/corpus/templates/mail/server/lib/email-state.ts +198 -113
- package/corpus/templates/mail/server/lib/google-auth.ts +218 -25
- package/corpus/templates/mail/server/lib/jobs.ts +69 -74
- package/corpus/templates/mail/server/lib/local-email-store.ts +265 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/slides/actions/extract-pdf.ts +1 -1
- package/corpus/templates/slides/actions/import-file.ts +4 -1
- package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +9 -12
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +29 -21
- package/corpus/templates/slides/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/slides/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/slides/changelog/2026-07-15-image-search-and-generation-controls-now-use-the-registered-.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-15-pdf-deck-references-can-be-imported-for-slide-inspiration-ag.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-15-stable-style-inspector-dock.md +6 -0
- package/dist/cli/content-local.d.ts +1 -0
- package/dist/cli/content-local.d.ts.map +1 -1
- package/dist/cli/content-local.js +75 -17
- package/dist/cli/content-local.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills-content/content-skill.d.ts +1 -1
- package/dist/cli/skills-content/content-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/content-skill.js +36 -25
- package/dist/cli/skills-content/content-skill.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +47 -14
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +5 -0
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +7 -0
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +8 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +4 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +10 -3
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +58 -6
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/asset-picker-url.d.ts +16 -0
- package/dist/client/composer/asset-picker-url.d.ts.map +1 -0
- package/dist/client/composer/asset-picker-url.js +64 -0
- package/dist/client/composer/asset-picker-url.js.map +1 -0
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +17 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +6 -1
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/local-artifacts/index.d.ts +10 -0
- package/dist/local-artifacts/index.d.ts.map +1 -1
- package/dist/local-artifacts/index.js +39 -0
- package/dist/local-artifacts/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/docs/content/local-file-mode.mdx +99 -489
- package/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/docs/content/template-content.mdx +26 -42
- package/package.json +1 -1
- package/corpus/templates/assets/app/components/library/EditLibraryDialog.tsx +0 -126
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
IconPhotoPlus,
|
|
27
27
|
IconRefresh,
|
|
28
28
|
IconSearch,
|
|
29
|
+
IconSettings,
|
|
29
30
|
IconTrash,
|
|
30
31
|
IconUpload,
|
|
31
32
|
IconVideo,
|
|
@@ -57,7 +58,6 @@ import {
|
|
|
57
58
|
} from "react-router";
|
|
58
59
|
import { toast } from "sonner";
|
|
59
60
|
|
|
60
|
-
import { EditLibraryDialog } from "@/components/library/EditLibraryDialog";
|
|
61
61
|
import {
|
|
62
62
|
AlertDialog,
|
|
63
63
|
AlertDialogAction,
|
|
@@ -98,10 +98,8 @@ import {
|
|
|
98
98
|
SelectTrigger,
|
|
99
99
|
SelectValue,
|
|
100
100
|
} from "@/components/ui/select";
|
|
101
|
-
import { Separator } from "@/components/ui/separator";
|
|
102
101
|
import { Spinner } from "@/components/ui/spinner";
|
|
103
102
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
104
|
-
import { Textarea } from "@/components/ui/textarea";
|
|
105
103
|
import {
|
|
106
104
|
Tooltip,
|
|
107
105
|
TooltipContent,
|
|
@@ -110,7 +108,6 @@ import {
|
|
|
110
108
|
} from "@/components/ui/tooltip";
|
|
111
109
|
import { assetPreviewSources } from "@/lib/asset-preview-sources";
|
|
112
110
|
import { assetMediaUrl } from "@/lib/asset-urls";
|
|
113
|
-
import { getLibraryCustomInstructions } from "@/lib/libraries";
|
|
114
111
|
import {
|
|
115
112
|
chunkAssetUploads,
|
|
116
113
|
getFailedUploadCount,
|
|
@@ -119,14 +116,7 @@ import {
|
|
|
119
116
|
type AssetUploadResult,
|
|
120
117
|
} from "@/lib/upload-results";
|
|
121
118
|
|
|
122
|
-
import {
|
|
123
|
-
IMAGE_CATEGORIES,
|
|
124
|
-
ASPECT_RATIOS,
|
|
125
|
-
type AssetVariantState,
|
|
126
|
-
type AspectRatio,
|
|
127
|
-
type ImageCategory,
|
|
128
|
-
type ImageRole,
|
|
129
|
-
} from "../../shared/api";
|
|
119
|
+
import { type AssetVariantState, type ImageRole } from "../../shared/api";
|
|
130
120
|
|
|
131
121
|
export type VariantSlot = AssetVariantState["slots"][number];
|
|
132
122
|
|
|
@@ -288,12 +278,6 @@ function removeVariantSlotsByScopeFromCache(
|
|
|
288
278
|
);
|
|
289
279
|
}
|
|
290
280
|
|
|
291
|
-
function paletteDraftFromColors(colors: unknown): string {
|
|
292
|
-
return Array.isArray(colors)
|
|
293
|
-
? colors.filter((color) => typeof color === "string").join(", ")
|
|
294
|
-
: "";
|
|
295
|
-
}
|
|
296
|
-
|
|
297
281
|
function referenceRoleForAsset(asset: any): ImageRole {
|
|
298
282
|
if (asset?.mediaType === "video" || asset?.mimeType?.startsWith("video/")) {
|
|
299
283
|
return "video_reference";
|
|
@@ -317,22 +301,6 @@ function assetUpdatedTime(asset: any): number {
|
|
|
317
301
|
return Number.isNaN(time) ? 0 : time;
|
|
318
302
|
}
|
|
319
303
|
|
|
320
|
-
function parsePaletteDraft(value: string): string[] {
|
|
321
|
-
const seen = new Set<string>();
|
|
322
|
-
const colors: string[] = [];
|
|
323
|
-
for (const raw of value.split(/[\s,]+/)) {
|
|
324
|
-
const trimmed = raw.trim();
|
|
325
|
-
if (!trimmed) continue;
|
|
326
|
-
const color = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
|
|
327
|
-
if (!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.test(color)) continue;
|
|
328
|
-
const normalized = color.toLowerCase();
|
|
329
|
-
if (seen.has(normalized)) continue;
|
|
330
|
-
seen.add(normalized);
|
|
331
|
-
colors.push(normalized);
|
|
332
|
-
}
|
|
333
|
-
return colors;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
304
|
export function loader({ params, request }: LoaderFunctionArgs) {
|
|
337
305
|
const url = new URL(request.url);
|
|
338
306
|
return redirect(`/library/${params.id}${url.search}`);
|
|
@@ -386,7 +354,6 @@ export function BrandKitDetailRoute({
|
|
|
386
354
|
const [folderOpen, setFolderOpen] = useState(false);
|
|
387
355
|
const [uploading, setUploading] = useState(false);
|
|
388
356
|
const [pendingUploads, setPendingUploads] = useState<PendingUpload[]>([]);
|
|
389
|
-
const [editOpen, setEditOpen] = useState(false);
|
|
390
357
|
const [archiveOpen, setArchiveOpen] = useState(false);
|
|
391
358
|
const [headerPrimaryActionsTarget, setHeaderPrimaryActionsTarget] =
|
|
392
359
|
useState<HTMLElement | null>(null);
|
|
@@ -415,9 +382,6 @@ export function BrandKitDetailRoute({
|
|
|
415
382
|
"all",
|
|
416
383
|
);
|
|
417
384
|
const [search, setSearch] = useState("");
|
|
418
|
-
const [styleDescriptionDraft, setStyleDescriptionDraft] = useState("");
|
|
419
|
-
const [customInstructionsDraft, setCustomInstructionsDraft] = useState("");
|
|
420
|
-
const [paletteDraft, setPaletteDraft] = useState("");
|
|
421
385
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
422
386
|
const dragCounterRef = useRef(0);
|
|
423
387
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
@@ -432,9 +396,13 @@ export function BrandKitDetailRoute({
|
|
|
432
396
|
});
|
|
433
397
|
|
|
434
398
|
useEffect(() => {
|
|
399
|
+
if (urlTab === "settings") {
|
|
400
|
+
navigate(`/brand-kits/${libraryId}/settings`, { replace: true });
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
435
403
|
if (!urlTab) return;
|
|
436
404
|
setActiveTab((current) => (current === urlTab ? current : urlTab));
|
|
437
|
-
}, [urlTab]);
|
|
405
|
+
}, [urlTab, libraryId, navigate]);
|
|
438
406
|
|
|
439
407
|
useEffect(() => {
|
|
440
408
|
if (headerMode !== "actions" || typeof document === "undefined") {
|
|
@@ -502,11 +470,6 @@ export function BrandKitDetailRoute({
|
|
|
502
470
|
(asset.status === "reference" && !isContentOnlyReference(asset)),
|
|
503
471
|
);
|
|
504
472
|
const unfiledCount = libraryAssets.filter((asset) => !asset.folderId).length;
|
|
505
|
-
const customInstructions = getLibraryCustomInstructions(library);
|
|
506
|
-
const libraryStyleDescription = library?.styleBrief?.description ?? "";
|
|
507
|
-
const libraryPaletteDraft = paletteDraftFromColors(
|
|
508
|
-
library?.styleBrief?.palette,
|
|
509
|
-
);
|
|
510
473
|
const liveVariantsForLibrary =
|
|
511
474
|
liveVariants?.libraryId === libraryId ? liveVariants : null;
|
|
512
475
|
const liveCandidateSlots = useMemo(
|
|
@@ -547,17 +510,6 @@ export function BrandKitDetailRoute({
|
|
|
547
510
|
);
|
|
548
511
|
}, [assets, liveCandidateSlots]);
|
|
549
512
|
|
|
550
|
-
useEffect(() => {
|
|
551
|
-
setStyleDescriptionDraft(libraryStyleDescription);
|
|
552
|
-
}, [library?.id, libraryStyleDescription]);
|
|
553
|
-
|
|
554
|
-
useEffect(() => {
|
|
555
|
-
setCustomInstructionsDraft(customInstructions ?? "");
|
|
556
|
-
}, [library?.id, customInstructions]);
|
|
557
|
-
|
|
558
|
-
useEffect(() => {
|
|
559
|
-
setPaletteDraft(libraryPaletteDraft);
|
|
560
|
-
}, [library?.id, libraryPaletteDraft]);
|
|
561
513
|
const pendingVisibleUploads = pendingUploads.filter((upload) => {
|
|
562
514
|
if (mediaFilter !== "all" && upload.mediaType !== mediaFilter) return false;
|
|
563
515
|
if (activeFolderId === "all") return true;
|
|
@@ -841,37 +793,6 @@ export function BrandKitDetailRoute({
|
|
|
841
793
|
);
|
|
842
794
|
}
|
|
843
795
|
|
|
844
|
-
function analyzeBrand() {
|
|
845
|
-
if (!library) return;
|
|
846
|
-
const anchorIds = assets
|
|
847
|
-
.filter(
|
|
848
|
-
(asset) =>
|
|
849
|
-
asset.metadata?.isStyleAnchor ||
|
|
850
|
-
library.settings?.canonicalStyleAssetIds?.includes(asset.id),
|
|
851
|
-
)
|
|
852
|
-
.map((asset) => asset.id);
|
|
853
|
-
sendToAgentChat({
|
|
854
|
-
message: [
|
|
855
|
-
"Analyze this Assets library brand.",
|
|
856
|
-
`Call analyze-collection-style with libraryId: ${library.id}.`,
|
|
857
|
-
"Update the reusable style brief with palette and visual traits, then summarize what changed.",
|
|
858
|
-
].join("\n"),
|
|
859
|
-
context: [
|
|
860
|
-
"## Assets library context",
|
|
861
|
-
`Library: ${library.title} (${library.id})`,
|
|
862
|
-
`Description: ${library.description || ""}`,
|
|
863
|
-
`Reference assets: ${references.length}`,
|
|
864
|
-
`Anchor assets: ${anchorIds.length ? anchorIds.join(", ") : "none"}`,
|
|
865
|
-
`Current style brief: ${JSON.stringify(library.styleBrief ?? {})}`,
|
|
866
|
-
customInstructions
|
|
867
|
-
? `Custom instructions: ${customInstructions}`
|
|
868
|
-
: "Custom instructions: none",
|
|
869
|
-
].join("\n"),
|
|
870
|
-
submit: true,
|
|
871
|
-
newTab: true,
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
|
|
875
796
|
async function upload(files: FileList | null, category = "style-only") {
|
|
876
797
|
if (!files?.length || uploading) return;
|
|
877
798
|
const selectedFiles = Array.from(files);
|
|
@@ -1107,8 +1028,7 @@ export function BrandKitDetailRoute({
|
|
|
1107
1028
|
);
|
|
1108
1029
|
}
|
|
1109
1030
|
const assetById = new Map(assets.map((asset) => [asset.id, asset]));
|
|
1110
|
-
const activeSurfaceTab =
|
|
1111
|
-
activeTab === "runs" || activeTab === "settings" ? activeTab : "assets";
|
|
1031
|
+
const activeSurfaceTab = activeTab === "runs" ? activeTab : "assets";
|
|
1112
1032
|
const hideEmptyLanes =
|
|
1113
1033
|
activeFolderId !== "all" || mediaFilter !== "all" || search.trim() !== "";
|
|
1114
1034
|
const uploadAction = (
|
|
@@ -1141,6 +1061,13 @@ export function BrandKitDetailRoute({
|
|
|
1141
1061
|
</Button>
|
|
1142
1062
|
</DropdownMenuTrigger>
|
|
1143
1063
|
<DropdownMenuContent align="end">
|
|
1064
|
+
<DropdownMenuItem asChild>
|
|
1065
|
+
<Link to={`/brand-kits/${libraryId}/settings`}>
|
|
1066
|
+
<IconSettings className="mr-2 h-4 w-4 shrink-0" />
|
|
1067
|
+
{t("library.settings")}
|
|
1068
|
+
</Link>
|
|
1069
|
+
</DropdownMenuItem>
|
|
1070
|
+
<DropdownMenuSeparator />
|
|
1144
1071
|
<DropdownMenuItem
|
|
1145
1072
|
onSelect={(event) => {
|
|
1146
1073
|
event.preventDefault();
|
|
@@ -1224,10 +1151,12 @@ export function BrandKitDetailRoute({
|
|
|
1224
1151
|
variant="ghost"
|
|
1225
1152
|
size="icon"
|
|
1226
1153
|
className="h-8 w-8 text-muted-foreground hover:text-foreground"
|
|
1227
|
-
|
|
1154
|
+
asChild
|
|
1228
1155
|
aria-label={t("library.editBrandKit")}
|
|
1229
1156
|
>
|
|
1230
|
-
<
|
|
1157
|
+
<Link to={`/brand-kits/${libraryId}/settings`}>
|
|
1158
|
+
<IconPencil className="h-4 w-4" />
|
|
1159
|
+
</Link>
|
|
1231
1160
|
</Button>
|
|
1232
1161
|
</div>
|
|
1233
1162
|
<p className="mt-1 max-w-3xl text-sm text-muted-foreground">
|
|
@@ -1248,11 +1177,6 @@ export function BrandKitDetailRoute({
|
|
|
1248
1177
|
onChange={(event) => upload(event.target.files)}
|
|
1249
1178
|
/>
|
|
1250
1179
|
|
|
1251
|
-
<EditLibraryDialog
|
|
1252
|
-
library={library}
|
|
1253
|
-
open={editOpen}
|
|
1254
|
-
onOpenChange={setEditOpen}
|
|
1255
|
-
/>
|
|
1256
1180
|
<AlertDialog open={archiveOpen} onOpenChange={setArchiveOpen}>
|
|
1257
1181
|
<AlertDialogContent>
|
|
1258
1182
|
<AlertDialogHeader>
|
|
@@ -1339,7 +1263,6 @@ export function BrandKitDetailRoute({
|
|
|
1339
1263
|
<TabsList>
|
|
1340
1264
|
<TabsTrigger value="assets">{t("library.assetsTab")}</TabsTrigger>
|
|
1341
1265
|
<TabsTrigger value="runs">{t("library.runs")}</TabsTrigger>
|
|
1342
|
-
<TabsTrigger value="settings">{t("library.settings")}</TabsTrigger>
|
|
1343
1266
|
</TabsList>
|
|
1344
1267
|
|
|
1345
1268
|
<TabsContent value="assets" className="space-y-5">
|
|
@@ -1502,107 +1425,6 @@ export function BrandKitDetailRoute({
|
|
|
1502
1425
|
</div>
|
|
1503
1426
|
)}
|
|
1504
1427
|
</TabsContent>
|
|
1505
|
-
|
|
1506
|
-
<TabsContent value="settings">
|
|
1507
|
-
<div className="assets-brand-kit-settings-grid grid gap-4">
|
|
1508
|
-
<div className="space-y-4 rounded-lg border border-border p-4">
|
|
1509
|
-
<Label>{t("brandKitDetail.styleDescription")}</Label>
|
|
1510
|
-
<Textarea
|
|
1511
|
-
value={styleDescriptionDraft}
|
|
1512
|
-
onChange={(event) =>
|
|
1513
|
-
setStyleDescriptionDraft(event.target.value)
|
|
1514
|
-
}
|
|
1515
|
-
onBlur={() =>
|
|
1516
|
-
updateLibrary.mutate({
|
|
1517
|
-
id: library.id,
|
|
1518
|
-
styleBrief: {
|
|
1519
|
-
...library.styleBrief,
|
|
1520
|
-
description: styleDescriptionDraft,
|
|
1521
|
-
},
|
|
1522
|
-
})
|
|
1523
|
-
}
|
|
1524
|
-
className="min-h-40"
|
|
1525
|
-
/>
|
|
1526
|
-
<Separator />
|
|
1527
|
-
<Label>{t("brandKitDetail.customInstructions")}</Label>
|
|
1528
|
-
<Textarea
|
|
1529
|
-
value={customInstructionsDraft}
|
|
1530
|
-
onChange={(event) =>
|
|
1531
|
-
setCustomInstructionsDraft(event.target.value)
|
|
1532
|
-
}
|
|
1533
|
-
onBlur={() =>
|
|
1534
|
-
updateLibrary.mutate({
|
|
1535
|
-
id: library.id,
|
|
1536
|
-
customInstructions: customInstructionsDraft,
|
|
1537
|
-
})
|
|
1538
|
-
}
|
|
1539
|
-
placeholder={t(
|
|
1540
|
-
"brandKitDetail.customInstructionsPlaceholder",
|
|
1541
|
-
)}
|
|
1542
|
-
className="min-h-28"
|
|
1543
|
-
/>
|
|
1544
|
-
<Separator />
|
|
1545
|
-
<div className="flex items-center justify-between">
|
|
1546
|
-
<div>
|
|
1547
|
-
<div className="text-sm font-medium">
|
|
1548
|
-
{t("brandKitDetail.palette")}
|
|
1549
|
-
</div>
|
|
1550
|
-
<div className="mt-2 flex flex-wrap gap-2">
|
|
1551
|
-
{(library.styleBrief?.palette ?? []).map(
|
|
1552
|
-
(color: string) => (
|
|
1553
|
-
<span
|
|
1554
|
-
key={color}
|
|
1555
|
-
className="h-7 w-7 rounded-md border border-border"
|
|
1556
|
-
style={{ backgroundColor: color }}
|
|
1557
|
-
title={color}
|
|
1558
|
-
/>
|
|
1559
|
-
),
|
|
1560
|
-
)}
|
|
1561
|
-
</div>
|
|
1562
|
-
<Input
|
|
1563
|
-
value={paletteDraft}
|
|
1564
|
-
onChange={(event) => setPaletteDraft(event.target.value)}
|
|
1565
|
-
onBlur={() => {
|
|
1566
|
-
const palette = parsePaletteDraft(paletteDraft);
|
|
1567
|
-
setPaletteDraft(palette.join(", "));
|
|
1568
|
-
updateLibrary.mutate({
|
|
1569
|
-
id: library.id,
|
|
1570
|
-
styleBrief: {
|
|
1571
|
-
...library.styleBrief,
|
|
1572
|
-
palette,
|
|
1573
|
-
},
|
|
1574
|
-
});
|
|
1575
|
-
}}
|
|
1576
|
-
placeholder={"#111827, #f8fafc, #2563eb"}
|
|
1577
|
-
className="mt-3 h-9 max-w-md text-xs"
|
|
1578
|
-
/>
|
|
1579
|
-
</div>
|
|
1580
|
-
<Button variant="outline" onClick={analyzeBrand}>
|
|
1581
|
-
{library.settings?.brandAnalysis?.analyzedAt
|
|
1582
|
-
? t("brandKitDetail.refreshBrand")
|
|
1583
|
-
: t("brandKitDetail.analyzeBrand")}
|
|
1584
|
-
</Button>
|
|
1585
|
-
</div>
|
|
1586
|
-
</div>
|
|
1587
|
-
<div className="space-y-4">
|
|
1588
|
-
<GenerationPresetsPanel
|
|
1589
|
-
libraryId={libraryId}
|
|
1590
|
-
presets={generationPresets}
|
|
1591
|
-
/>
|
|
1592
|
-
<div className="rounded-lg border border-border p-4">
|
|
1593
|
-
<h3 className="text-sm font-semibold">
|
|
1594
|
-
{t("brandKitDetail.agentUsage")}
|
|
1595
|
-
</h3>
|
|
1596
|
-
<p className="mt-2 text-sm text-muted-foreground">
|
|
1597
|
-
{t("brandKitDetail.agentUsageDescription")}
|
|
1598
|
-
</p>
|
|
1599
|
-
<code className="mt-3 block rounded-md bg-muted p-3 text-xs">
|
|
1600
|
-
{library.id}
|
|
1601
|
-
</code>
|
|
1602
|
-
</div>
|
|
1603
|
-
</div>
|
|
1604
|
-
</div>
|
|
1605
|
-
</TabsContent>
|
|
1606
1428
|
</Tabs>
|
|
1607
1429
|
</div>
|
|
1608
1430
|
</div>
|
|
@@ -2084,288 +1906,6 @@ function SessionCard({
|
|
|
2084
1906
|
);
|
|
2085
1907
|
}
|
|
2086
1908
|
|
|
2087
|
-
function GenerationPresetsPanel({
|
|
2088
|
-
libraryId,
|
|
2089
|
-
presets,
|
|
2090
|
-
}: {
|
|
2091
|
-
libraryId: string;
|
|
2092
|
-
presets: any[];
|
|
2093
|
-
}) {
|
|
2094
|
-
const t = useT();
|
|
2095
|
-
const createPreset = useActionMutation("create-generation-preset");
|
|
2096
|
-
const deletePreset = useActionMutation("delete-generation-preset");
|
|
2097
|
-
const [open, setOpen] = useState(false);
|
|
2098
|
-
const [confirmPresetId, setConfirmPresetId] = useState<string | null>(null);
|
|
2099
|
-
const [title, setTitle] = useState("");
|
|
2100
|
-
const [category, setCategory] = useState<ImageCategory>("social");
|
|
2101
|
-
const [aspectRatio, setAspectRatio] = useState<AspectRatio>("1:1");
|
|
2102
|
-
const [promptTemplate, setPromptTemplate] = useState("");
|
|
2103
|
-
const [textPolicy, setTextPolicy] = useState(t("library.defaultTextPolicy"));
|
|
2104
|
-
const [includeLogo, setIncludeLogo] = useState(false);
|
|
2105
|
-
|
|
2106
|
-
function reset() {
|
|
2107
|
-
setTitle("");
|
|
2108
|
-
setCategory("social");
|
|
2109
|
-
setAspectRatio("1:1");
|
|
2110
|
-
setPromptTemplate("");
|
|
2111
|
-
setTextPolicy(t("library.defaultTextPolicy"));
|
|
2112
|
-
setIncludeLogo(false);
|
|
2113
|
-
}
|
|
2114
|
-
|
|
2115
|
-
function submit() {
|
|
2116
|
-
const trimmed = title.trim();
|
|
2117
|
-
if (!trimmed) return;
|
|
2118
|
-
createPreset.mutate(
|
|
2119
|
-
{
|
|
2120
|
-
libraryId,
|
|
2121
|
-
title: trimmed,
|
|
2122
|
-
category,
|
|
2123
|
-
aspectRatio,
|
|
2124
|
-
imageSize: "2K",
|
|
2125
|
-
promptTemplate: promptTemplate.trim() || undefined,
|
|
2126
|
-
textPolicy,
|
|
2127
|
-
referencePolicy: "auto",
|
|
2128
|
-
includeLogo,
|
|
2129
|
-
},
|
|
2130
|
-
{
|
|
2131
|
-
onSuccess: () => {
|
|
2132
|
-
toast.success(t("brandKitDetail.generationPresetCreated"));
|
|
2133
|
-
reset();
|
|
2134
|
-
setOpen(false);
|
|
2135
|
-
},
|
|
2136
|
-
onError: (error: Error) => {
|
|
2137
|
-
toast.error(
|
|
2138
|
-
error.message || t("brandKitDetail.couldNotCreatePreset"),
|
|
2139
|
-
);
|
|
2140
|
-
},
|
|
2141
|
-
},
|
|
2142
|
-
);
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
return (
|
|
2146
|
-
<div className="rounded-lg border border-border p-4">
|
|
2147
|
-
<div className="flex items-center justify-between gap-3">
|
|
2148
|
-
<div>
|
|
2149
|
-
<h3 className="text-sm font-semibold">
|
|
2150
|
-
{t("brandKitDetail.generationPresets")}
|
|
2151
|
-
</h3>
|
|
2152
|
-
<p className="mt-1 text-sm text-muted-foreground">
|
|
2153
|
-
{t("brandKitDetail.generationPresetsDescription")}
|
|
2154
|
-
</p>
|
|
2155
|
-
</div>
|
|
2156
|
-
<Button variant="outline" size="sm" onClick={() => setOpen(true)}>
|
|
2157
|
-
{t("brandKitDetail.new")}
|
|
2158
|
-
</Button>
|
|
2159
|
-
</div>
|
|
2160
|
-
<div className="mt-3 space-y-2">
|
|
2161
|
-
{presets.slice(0, 5).map((preset) => (
|
|
2162
|
-
<div
|
|
2163
|
-
key={preset.id}
|
|
2164
|
-
className="flex items-start justify-between gap-3 rounded-md border border-border bg-background p-3"
|
|
2165
|
-
>
|
|
2166
|
-
<div className="min-w-0">
|
|
2167
|
-
<div className="flex flex-wrap items-center gap-2">
|
|
2168
|
-
<Link
|
|
2169
|
-
to={`/brand-kits/${libraryId}/presets/${preset.id}`}
|
|
2170
|
-
className="truncate text-sm font-medium underline-offset-4 hover:underline"
|
|
2171
|
-
>
|
|
2172
|
-
{preset.title}
|
|
2173
|
-
</Link>
|
|
2174
|
-
<Badge variant="outline">{preset.aspectRatio}</Badge>
|
|
2175
|
-
{preset.includeLogo ? (
|
|
2176
|
-
<Badge variant="secondary">{t("brandKitDetail.logo")}</Badge>
|
|
2177
|
-
) : null}
|
|
2178
|
-
</div>
|
|
2179
|
-
<p className="mt-1 line-clamp-2 text-xs text-muted-foreground">
|
|
2180
|
-
{preset.textPolicy || preset.description || preset.category}
|
|
2181
|
-
</p>
|
|
2182
|
-
</div>
|
|
2183
|
-
<div className="flex shrink-0 items-center gap-1">
|
|
2184
|
-
<Button variant="ghost" size="sm" asChild>
|
|
2185
|
-
<Link to={`/brand-kits/${libraryId}/presets/${preset.id}`}>
|
|
2186
|
-
{t("brandKitDetail.edit")}
|
|
2187
|
-
</Link>
|
|
2188
|
-
</Button>
|
|
2189
|
-
<Button
|
|
2190
|
-
variant="ghost"
|
|
2191
|
-
size="icon"
|
|
2192
|
-
className="h-8 w-8 text-muted-foreground hover:text-destructive"
|
|
2193
|
-
aria-label={`${t("brandKitDetail.delete")} ${preset.title}`}
|
|
2194
|
-
onClick={() => setConfirmPresetId(preset.id)}
|
|
2195
|
-
>
|
|
2196
|
-
<IconTrash className="h-4 w-4" />
|
|
2197
|
-
</Button>
|
|
2198
|
-
</div>
|
|
2199
|
-
</div>
|
|
2200
|
-
))}
|
|
2201
|
-
{!presets.length ? (
|
|
2202
|
-
<p className="rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground">
|
|
2203
|
-
{t("brandKitDetail.noPresetsYet")}
|
|
2204
|
-
</p>
|
|
2205
|
-
) : null}
|
|
2206
|
-
</div>
|
|
2207
|
-
|
|
2208
|
-
<AlertDialog
|
|
2209
|
-
open={confirmPresetId !== null}
|
|
2210
|
-
onOpenChange={(isOpen) => {
|
|
2211
|
-
if (!isOpen) setConfirmPresetId(null);
|
|
2212
|
-
}}
|
|
2213
|
-
>
|
|
2214
|
-
<AlertDialogContent>
|
|
2215
|
-
<AlertDialogHeader>
|
|
2216
|
-
<AlertDialogTitle>
|
|
2217
|
-
{t("brandKitDetail.deleteGenerationPreset")}
|
|
2218
|
-
</AlertDialogTitle>
|
|
2219
|
-
<AlertDialogDescription>
|
|
2220
|
-
{t("brandKitDetail.deleteGenerationPresetDescription")}
|
|
2221
|
-
</AlertDialogDescription>
|
|
2222
|
-
</AlertDialogHeader>
|
|
2223
|
-
<AlertDialogFooter>
|
|
2224
|
-
<AlertDialogCancel>{t("brandKitDetail.cancel")}</AlertDialogCancel>
|
|
2225
|
-
<AlertDialogAction
|
|
2226
|
-
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
2227
|
-
disabled={!confirmPresetId || deletePreset.isPending}
|
|
2228
|
-
onClick={(event) => {
|
|
2229
|
-
event.preventDefault();
|
|
2230
|
-
if (!confirmPresetId) return;
|
|
2231
|
-
deletePreset.mutate(
|
|
2232
|
-
{ id: confirmPresetId },
|
|
2233
|
-
{
|
|
2234
|
-
onSuccess: () => {
|
|
2235
|
-
setConfirmPresetId(null);
|
|
2236
|
-
toast.success(
|
|
2237
|
-
t("brandKitDetail.generationPresetDeleted"),
|
|
2238
|
-
);
|
|
2239
|
-
},
|
|
2240
|
-
onError: (error: Error) => {
|
|
2241
|
-
toast.error(
|
|
2242
|
-
error.message ||
|
|
2243
|
-
t("brandKitDetail.couldNotDeletePreset"),
|
|
2244
|
-
);
|
|
2245
|
-
},
|
|
2246
|
-
},
|
|
2247
|
-
);
|
|
2248
|
-
}}
|
|
2249
|
-
>
|
|
2250
|
-
{t("assetDetail.delete")}
|
|
2251
|
-
</AlertDialogAction>
|
|
2252
|
-
</AlertDialogFooter>
|
|
2253
|
-
</AlertDialogContent>
|
|
2254
|
-
</AlertDialog>
|
|
2255
|
-
|
|
2256
|
-
<Dialog open={open} onOpenChange={setOpen}>
|
|
2257
|
-
<DialogContent className="sm:max-w-lg">
|
|
2258
|
-
<DialogHeader>
|
|
2259
|
-
<DialogTitle>{t("brandKitDetail.newGenerationPreset")}</DialogTitle>
|
|
2260
|
-
<DialogDescription>
|
|
2261
|
-
{t("brandKitDetail.newGenerationPresetDescription")}
|
|
2262
|
-
</DialogDescription>
|
|
2263
|
-
</DialogHeader>
|
|
2264
|
-
<div className="grid gap-4">
|
|
2265
|
-
<div className="grid gap-2">
|
|
2266
|
-
<Label htmlFor="preset-title">{t("brandKitDetail.name")}</Label>
|
|
2267
|
-
<Input
|
|
2268
|
-
id="preset-title"
|
|
2269
|
-
value={title}
|
|
2270
|
-
onChange={(event) => setTitle(event.target.value)}
|
|
2271
|
-
placeholder={t("brandKitDetail.campaignLaunch")}
|
|
2272
|
-
/>
|
|
2273
|
-
</div>
|
|
2274
|
-
<div className="grid grid-cols-2 gap-3">
|
|
2275
|
-
<div className="grid gap-2">
|
|
2276
|
-
<Label>{t("brandKitDetail.category")}</Label>
|
|
2277
|
-
<Select
|
|
2278
|
-
value={category}
|
|
2279
|
-
onValueChange={(value) => setCategory(value as ImageCategory)}
|
|
2280
|
-
>
|
|
2281
|
-
<SelectTrigger>
|
|
2282
|
-
<SelectValue />
|
|
2283
|
-
</SelectTrigger>
|
|
2284
|
-
<SelectContent>
|
|
2285
|
-
{IMAGE_CATEGORIES.map((item) => (
|
|
2286
|
-
<SelectItem key={item} value={item}>
|
|
2287
|
-
{item}
|
|
2288
|
-
</SelectItem>
|
|
2289
|
-
))}
|
|
2290
|
-
</SelectContent>
|
|
2291
|
-
</Select>
|
|
2292
|
-
</div>
|
|
2293
|
-
<div className="grid gap-2">
|
|
2294
|
-
<Label>{t("brandKitDetail.aspectRatio")}</Label>
|
|
2295
|
-
<Select
|
|
2296
|
-
value={aspectRatio}
|
|
2297
|
-
onValueChange={(value) =>
|
|
2298
|
-
setAspectRatio(value as AspectRatio)
|
|
2299
|
-
}
|
|
2300
|
-
>
|
|
2301
|
-
<SelectTrigger>
|
|
2302
|
-
<SelectValue />
|
|
2303
|
-
</SelectTrigger>
|
|
2304
|
-
<SelectContent>
|
|
2305
|
-
{ASPECT_RATIOS.map((ratio) => (
|
|
2306
|
-
<SelectItem key={ratio} value={ratio}>
|
|
2307
|
-
{ratio}
|
|
2308
|
-
</SelectItem>
|
|
2309
|
-
))}
|
|
2310
|
-
</SelectContent>
|
|
2311
|
-
</Select>
|
|
2312
|
-
</div>
|
|
2313
|
-
</div>
|
|
2314
|
-
<div className="grid gap-2">
|
|
2315
|
-
<Label htmlFor="preset-template">
|
|
2316
|
-
{t("brandKitDetail.promptTemplate")}
|
|
2317
|
-
</Label>
|
|
2318
|
-
<Textarea
|
|
2319
|
-
id="preset-template"
|
|
2320
|
-
value={promptTemplate}
|
|
2321
|
-
onChange={(event) => setPromptTemplate(event.target.value)}
|
|
2322
|
-
placeholder={t("library.promptTemplatePlaceholder")}
|
|
2323
|
-
/>
|
|
2324
|
-
</div>
|
|
2325
|
-
<div className="grid gap-2">
|
|
2326
|
-
<Label htmlFor="preset-text-policy">
|
|
2327
|
-
{t("brandKitDetail.textPolicy")}
|
|
2328
|
-
</Label>
|
|
2329
|
-
<Textarea
|
|
2330
|
-
id="preset-text-policy"
|
|
2331
|
-
value={textPolicy}
|
|
2332
|
-
onChange={(event) => setTextPolicy(event.target.value)}
|
|
2333
|
-
/>
|
|
2334
|
-
</div>
|
|
2335
|
-
<label
|
|
2336
|
-
htmlFor="preset-include-logo"
|
|
2337
|
-
className="flex items-start gap-3 rounded-md border border-border p-3"
|
|
2338
|
-
>
|
|
2339
|
-
<Checkbox
|
|
2340
|
-
id="preset-include-logo"
|
|
2341
|
-
checked={includeLogo}
|
|
2342
|
-
onCheckedChange={(checked) => setIncludeLogo(checked === true)}
|
|
2343
|
-
className="mt-0.5"
|
|
2344
|
-
/>
|
|
2345
|
-
<span className="grid gap-1">
|
|
2346
|
-
<span className="text-sm font-medium leading-none">
|
|
2347
|
-
{t("brandKitDetail.compositeCanonicalLogo")}
|
|
2348
|
-
</span>
|
|
2349
|
-
<span className="text-xs text-muted-foreground">
|
|
2350
|
-
{t("brandKitDetail.compositeCanonicalLogoHint")}
|
|
2351
|
-
</span>
|
|
2352
|
-
</span>
|
|
2353
|
-
</label>
|
|
2354
|
-
</div>
|
|
2355
|
-
<DialogFooter>
|
|
2356
|
-
<Button variant="outline" onClick={() => setOpen(false)}>
|
|
2357
|
-
{t("brandKitDetail.cancel")}
|
|
2358
|
-
</Button>
|
|
2359
|
-
<Button disabled={!title.trim()} onClick={submit}>
|
|
2360
|
-
{t("brandKitDetail.create")}
|
|
2361
|
-
</Button>
|
|
2362
|
-
</DialogFooter>
|
|
2363
|
-
</DialogContent>
|
|
2364
|
-
</Dialog>
|
|
2365
|
-
</div>
|
|
2366
|
-
);
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
1909
|
function FolderChip({
|
|
2370
1910
|
active,
|
|
2371
1911
|
label,
|
|
@@ -642,7 +642,7 @@ export default function GenerationPresetEditorRoute() {
|
|
|
642
642
|
);
|
|
643
643
|
}, [referenceAssetSearch, skeletonBackgroundAssets]);
|
|
644
644
|
const settingsHref = libraryId
|
|
645
|
-
? `/
|
|
645
|
+
? `/brand-kits/${encodeURIComponent(libraryId)}/settings`
|
|
646
646
|
: "/library";
|
|
647
647
|
|
|
648
648
|
function updateForm(patch: Partial<PresetFormState>) {
|