@agent-native/core 0.102.2 → 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 +1 -1
- package/corpus/core/CHANGELOG.md +6 -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/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/clips/app/components/editor/editor-layout.tsx +12 -2
- package/corpus/templates/clips/app/components/player/settings-panel.tsx +30 -12
- package/corpus/templates/clips/app/components/player/video-player.tsx +5 -1
- package/corpus/templates/clips/app/components/recorder/microphone-visualizer.tsx +22 -3
- package/corpus/templates/clips/app/i18n/ar-SA.ts +3 -2
- package/corpus/templates/clips/app/i18n/de-DE.ts +4 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +3 -2
- package/corpus/templates/clips/app/i18n/es-ES.ts +4 -2
- package/corpus/templates/clips/app/i18n/fr-FR.ts +3 -2
- package/corpus/templates/clips/app/i18n/hi-IN.ts +3 -2
- package/corpus/templates/clips/app/i18n/ja-JP.ts +4 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +3 -2
- package/corpus/templates/clips/app/i18n/pt-BR.ts +4 -2
- package/corpus/templates/clips/app/i18n/zh-CN.ts +3 -2
- package/corpus/templates/clips/app/i18n/zh-TW.ts +3 -2
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +27 -1
- 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/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-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/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/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/observability/routes.d.ts +5 -5
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- 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>) {
|