@smartcat/sanity-plugin 1.2.1 → 1.4.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/dist/_chunks-cjs/index.cjs +18 -5
- package/dist/_chunks-cjs/index.cjs.map +1 -1
- package/dist/_chunks-cjs/index2.cjs +8 -6
- package/dist/_chunks-cjs/index2.cjs.map +1 -1
- package/dist/_chunks-es/index.js +18 -5
- package/dist/_chunks-es/index.js.map +1 -1
- package/dist/_chunks-es/index2.js +8 -6
- package/dist/_chunks-es/index2.js.map +1 -1
- package/dist/export.cjs +21 -4
- package/dist/export.cjs.map +1 -1
- package/dist/export.d.cts +2 -0
- package/dist/export.d.ts +2 -0
- package/dist/export.js +22 -5
- package/dist/export.js.map +1 -1
- package/dist/index.cjs +477 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +482 -129
- package/dist/index.js.map +1 -1
- package/dist/locjson.d.cts +15 -0
- package/dist/locjson.d.ts +15 -0
- package/dist/progress.d.cts +0 -19
- package/dist/progress.d.ts +0 -19
- package/dist/smartcat.cjs +14 -2
- package/dist/smartcat.cjs.map +1 -1
- package/dist/smartcat.d.cts +10 -1
- package/dist/smartcat.d.ts +10 -1
- package/dist/smartcat.js +14 -2
- package/dist/smartcat.js.map +1 -1
- package/package.json +1 -1
- package/src/actions/AddToProjectAction.tsx +23 -2
- package/src/export/export.test.ts +42 -5
- package/src/export/index.ts +63 -8
- package/src/lib/locjson/filename.ts +7 -2
- package/src/lib/locjson/locjson.test.ts +64 -0
- package/src/lib/locjson/serialize.ts +38 -2
- package/src/progress/core.ts +44 -3
- package/src/progress/progress.test.ts +40 -0
- package/src/schema/translationProject.ts +19 -0
- package/src/smartcat/client.ts +15 -1
- package/src/tool/AddItemsSearch.tsx +462 -0
- package/src/tool/DocTitle.tsx +23 -0
- package/src/tool/ProjectView.tsx +29 -187
- package/src/tool/data.ts +7 -0
- package/src/tool/itemActions.tsx +216 -0
- package/src/tool/processing.test.ts +11 -1
- package/src/tool/processing.ts +116 -4
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/schema/translationProject.ts","../src/schema/settings.ts","../src/tool/WorkflowSelect.tsx","../src/tool/useTemplates.ts","../src/tool/useWorkflowSelection.ts","../src/lib/documentTitle.ts","../src/lib/linkedDocuments.ts","../src/actions/AddToProjectAction.tsx","../src/tool/data.ts","../src/tool/StatusBadge.tsx","../src/tool/ProjectsView.tsx","../src/tool/processing.ts","../src/tool/ItemProgress.tsx","../src/tool/LogPanel.tsx","../src/lib/log.ts","../src/tool/ProjectView.tsx","../src/tool/Dashboard.tsx","../src/tool/index.ts","../src/form/TranslationStatusInput.tsx","../src/tool/StudioInit.tsx","../src/lib/resolveConfig.ts","../src/index.ts"],"sourcesContent":["import {defineType, defineField, defineArrayMember, type SchemaTypeDefinition} from 'sanity'\nimport {TranslateIcon} from '@sanity/icons'\nimport {TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport type {TranslationProjectStatus} from '../types'\n\n/**\n * Single source of truth for status display titles, used by both the schema's\n * status dropdown (document editor) and the dashboard's StatusBadge. Titles are\n * kept terse so they read well in both places.\n */\nexport const STATUS_OPTIONS: {title: string; value: TranslationProjectStatus}[] = [\n {title: 'Draft', value: 'draft'},\n {title: 'Queued', value: 'queued'},\n {title: 'Sent', value: 'sent'},\n {title: 'In progress', value: 'translating'},\n {title: 'Importing', value: 'importing'},\n {title: 'Downloaded', value: 'downloaded'},\n {title: 'Completed', value: 'completed'},\n {title: 'Error', value: 'error'},\n]\n\n/**\n * Builds the translation-project document type.\n *\n * `items` holds `smartcat.projectItem` objects (a `docId`/`docType` pair), not\n * Sanity references, so any document type can be added — including ones linked\n * transitively — without the consumer having to enumerate every referenceable\n * type in a reference `to` list. Reads dereference `docId` manually via GROQ.\n */\nexport function createTranslationProjectType(): SchemaTypeDefinition {\n return defineType({\n name: TRANSLATION_PROJECT_TYPE,\n title: 'Translation project',\n type: 'document',\n icon: TranslateIcon,\n fields: [\n defineField({\n name: 'name',\n title: 'Project name',\n type: 'string',\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: 'status',\n type: 'string',\n // Driven by the dashboard and Functions, not edited by hand.\n readOnly: true,\n initialValue: 'draft',\n options: {list: STATUS_OPTIONS, layout: 'radio'},\n }),\n defineField({\n name: 'sourceLanguage',\n title: 'Source language',\n type: 'string',\n }),\n // Workflow chosen at creation: `template:<id>` or a standard preset.\n // Read by the export Function to build Smartcat's createProject params.\n defineField({name: 'workflow', type: 'string', readOnly: true, hidden: true}),\n defineField({\n name: 'targetLanguages',\n title: 'Target languages',\n type: 'array',\n of: [defineArrayMember({type: 'string'})],\n options: {layout: 'tags'},\n }),\n // Sanity-id → Smartcat-code mapping for this project's source + target\n // languages, stamped by the browser at export time so the thin Functions\n // (which can't see plugin config) can map to/from Smartcat codes.\n defineField({\n name: 'smartcatLanguages',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatLanguageMapping',\n fields: [\n defineField({name: 'sanityId', type: 'string'}),\n defineField({name: 'smartcatLanguage', type: 'string'}),\n ],\n }),\n ],\n }),\n defineField({\n name: 'items',\n title: 'Items',\n description: 'Content added to this project for translation.',\n // Populated by the \"Add to translation project\" action, not by hand.\n readOnly: true,\n type: 'array',\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcat.projectItem',\n title: 'Project item',\n fields: [\n defineField({name: 'docId', title: 'Document ID', type: 'string'}),\n defineField({name: 'docType', title: 'Document type', type: 'string'}),\n // Set when the item was added from the published perspective, so the\n // export translates the published document. Absent/false (incl. all\n // legacy items) prefers the draft — see itemDocDerefRespectingDraft.\n defineField({name: 'sourceIsPublished', title: 'Source is published', type: 'boolean'}),\n ],\n preview: {select: {title: 'docId', subtitle: 'docType'}},\n }),\n ],\n }),\n defineField({\n name: 'smartcatProjectId',\n title: 'Smartcat project ID',\n type: 'string',\n readOnly: true,\n description: 'GUID of the corresponding project in Smartcat.',\n }),\n defineField({\n name: 'smartcatProjectUrl',\n title: 'Smartcat project URL',\n type: 'url',\n readOnly: true,\n description: 'Link to the project in Smartcat (set by the export Function).',\n }),\n defineField({name: 'lastExportAt', type: 'datetime', readOnly: true}),\n defineField({name: 'lastImportAt', type: 'datetime', readOnly: true}),\n // Per-document, per-language, per-stage translation progress, mirrored from\n // Smartcat. The export captures the target document ids; the progress/import\n // Functions refresh the stage percentages; the browser sets `imported`.\n defineField({\n name: 'progress',\n title: 'Translation progress',\n type: 'array',\n readOnly: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatDocProgress',\n fields: [\n defineField({name: 'sourceDocId', type: 'string'}),\n defineField({name: 'title', type: 'string'}),\n defineField({\n name: 'targets',\n type: 'array',\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatTargetProgress',\n fields: [\n defineField({name: 'language', type: 'string'}),\n defineField({name: 'smartcatDocumentId', type: 'string'}),\n defineField({\n name: 'stages',\n type: 'array',\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatStageProgress',\n fields: [\n defineField({name: 'name', type: 'string'}),\n defineField({name: 'percent', type: 'number'}),\n ],\n }),\n ],\n }),\n // All stages at 100% (set by the progress/import Functions).\n defineField({name: 'complete', type: 'boolean'}),\n // A locale variant has been built from this target (set by the browser).\n defineField({name: 'imported', type: 'boolean'}),\n defineField({name: 'syncedAt', type: 'datetime'}),\n ],\n }),\n ],\n }),\n ],\n }),\n ],\n }),\n // Handshake fields for the on-demand progress refresh: the browser bumps\n // `progressRequestedAt`; the smartcat-progress Function reacts and writes\n // `progressSyncedAt`. Keeping them distinct stops the Function re-triggering\n // on its own write (filter is delta::changedAny(progressRequestedAt)).\n defineField({name: 'progressRequestedAt', type: 'datetime', readOnly: true, hidden: true}),\n defineField({name: 'progressSyncedAt', type: 'datetime', readOnly: true, hidden: true}),\n defineField({\n name: 'lastError',\n title: 'Last error',\n type: 'string',\n readOnly: true,\n description: 'Most recent export/import error, if any.',\n }),\n // JSON-encoded LogLine[] from the most recent Function run (export upload or\n // import download). Transient diagnostic data the browser merges into its\n // live Log panel; overwritten each run.\n defineField({\n name: 'functionLog',\n type: 'text',\n readOnly: true,\n hidden: true,\n }),\n // Transient transport buffers. The browser (plugin) serializes content into\n // `outbox`; the thin export Function uploads it. The thin import Function\n // downloads translated files into `inbox`; the browser turns them into\n // locale variants. Both are cleared after processing.\n defineField({\n name: 'outbox',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatOutboxItem',\n fields: [\n defineField({name: 'filename', type: 'string'}),\n defineField({name: 'locjson', type: 'text'}),\n ],\n }),\n ],\n }),\n defineField({\n name: 'inbox',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatInboxItem',\n fields: [\n defineField({name: 'sourceDocId', type: 'string'}),\n defineField({name: 'targetLanguage', type: 'string'}),\n defineField({name: 'smartcatDocumentId', type: 'string'}),\n defineField({name: 'locjson', type: 'text'}),\n ],\n }),\n ],\n }),\n // Transient: items the browser marked for deletion. On the next export the\n // Function deletes the Smartcat document and removes the item + its progress.\n defineField({\n name: 'pendingDeletions',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatPendingDeletion',\n fields: [\n defineField({name: 'itemKey', type: 'string'}),\n defineField({name: 'sourceDocId', type: 'string'}),\n defineField({name: 'smartcatDocumentId', type: 'string'}),\n ],\n }),\n ],\n }),\n ],\n preview: {\n select: {name: 'name', status: 'status', items: 'items'},\n prepare({name, status, items}) {\n const count = Array.isArray(items) ? items.length : 0\n return {\n title: name || 'Untitled project',\n subtitle: `${status || 'draft'} · ${count} item${count === 1 ? '' : 's'}`,\n }\n },\n },\n })\n}\n","import {defineType, defineField, defineArrayMember, type SchemaTypeDefinition} from 'sanity'\nimport {CogIcon} from '@sanity/icons'\nimport {SETTINGS_TYPE} from '../lib/constants'\n\n/**\n * Workspace-wide Smartcat settings, stored as a single fixed-id document.\n *\n * Holds the cached project-template list. The browser bumps `templatesRequestedAt`\n * (Studio init / create-dialog open); the `smartcat-templates` Function fetches\n * the list from Smartcat and writes `templates` + `templatesSyncedAt` back.\n * All fields are managed automatically — never hand-edited.\n */\nexport function createSettingsType(): SchemaTypeDefinition {\n return defineType({\n name: SETTINGS_TYPE,\n title: 'Smartcat settings',\n type: 'document',\n icon: CogIcon,\n fields: [\n defineField({\n name: 'templates',\n title: 'Project templates',\n type: 'array',\n readOnly: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatTemplate',\n fields: [\n defineField({name: 'id', type: 'string'}),\n defineField({name: 'name', type: 'string'}),\n ],\n preview: {select: {title: 'name', subtitle: 'id'}},\n }),\n ],\n }),\n // Handshake fields for the on-demand template refresh: the browser bumps\n // `templatesRequestedAt`; the smartcat-templates Function writes\n // `templatesSyncedAt`. Distinct fields stop the Function re-triggering on\n // its own write (filter is delta::changedAny(templatesRequestedAt)).\n defineField({name: 'templatesRequestedAt', type: 'datetime', readOnly: true, hidden: true}),\n defineField({name: 'templatesSyncedAt', type: 'datetime', readOnly: true, hidden: true}),\n ],\n preview: {\n select: {templates: 'templates', syncedAt: 'templatesSyncedAt'},\n prepare({templates, syncedAt}) {\n const count = Array.isArray(templates) ? templates.length : 0\n return {\n title: 'Smartcat settings',\n subtitle: syncedAt ? `${count} template${count === 1 ? '' : 's'} cached` : 'Not synced yet',\n }\n },\n },\n })\n}\n","import {Select} from '@sanity/ui'\nimport type {SmartcatTemplate} from '../smartcat/types'\nimport {STANDARD_WORKFLOW_OPTIONS, TEMPLATE_PREFIX} from '../lib/workflow'\n\ninterface WorkflowSelectProps {\n value: string\n onChange: (value: string) => void\n templates: SmartcatTemplate[]\n disabled?: boolean\n}\n\n/**\n * Workflow picker for new projects: cached Smartcat templates grouped under\n * \"Templates\", followed by the standard presets under \"Standard workflows\".\n * Templates are expected pre-sorted by name (see `useTemplates`).\n */\nexport function WorkflowSelect({value, onChange, templates, disabled}: WorkflowSelectProps) {\n return (\n <Select value={value} onChange={(e) => onChange(e.currentTarget.value)} disabled={disabled}>\n <option value=\"\" disabled>\n Select a workflow…\n </option>\n {templates.length > 0 && (\n <optgroup label=\"Templates\">\n {templates.map((t) => (\n <option key={t.id} value={`${TEMPLATE_PREFIX}${t.id}`}>\n {t.name}\n </option>\n ))}\n </optgroup>\n )}\n <optgroup label=\"Standard workflows\">\n {STANDARD_WORKFLOW_OPTIONS.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </optgroup>\n </Select>\n )\n}\n","import {useCallback, useEffect, useRef, useState} from 'react'\nimport {useClient} from 'sanity'\nimport {API_VERSION, SETTINGS_DOC_ID, SETTINGS_TYPE} from '../lib/constants'\nimport type {SmartcatTemplate} from '../smartcat/types'\n\ninterface SettingsDoc {\n templates?: SmartcatTemplate[]\n templatesRequestedAt?: string\n templatesSyncedAt?: string\n}\n\nconst SETTINGS_QUERY = `*[_id == $id][0]{templates, templatesRequestedAt, templatesSyncedAt}`\n\n/**\n * A request older than this is treated as failed/abandoned, so a fresh refresh\n * is allowed — self-heals a sync that never completed (e.g. a function error)\n * instead of wedging the cache in a perpetual \"in flight\" state.\n */\nexport const REQUEST_STALE_MS = 30_000\n\n/**\n * A refresh is in flight when a request is newer than the last sync *and* recent\n * enough that the function could still be working on it.\n */\nexport function isRefreshInFlight(\n s: {templatesRequestedAt?: string; templatesSyncedAt?: string} | null,\n): boolean {\n const requested = s?.templatesRequestedAt\n if (!requested) return false\n const pending = !s?.templatesSyncedAt || requested > s.templatesSyncedAt\n if (!pending) return false\n return Date.now() - Date.parse(requested) < REQUEST_STALE_MS\n}\n\n/**\n * Reads the cached Smartcat templates from the settings singleton and keeps them\n * live via `listen()`. `requestRefresh()` bumps the refresh trigger so the\n * `smartcat-templates` Function re-fetches — skipped while a request is already\n * in flight (debounce). Returns templates sorted by name.\n */\nexport function useTemplates(): {\n templates: SmartcatTemplate[]\n loaded: boolean\n requestRefresh: () => void\n} {\n const client = useClient({apiVersion: API_VERSION})\n const [settings, setSettings] = useState<SettingsDoc | null>(null)\n const [loaded, setLoaded] = useState(false)\n const settingsRef = useRef<SettingsDoc | null>(null)\n settingsRef.current = settings\n\n useEffect(() => {\n let cancelled = false\n const load = () =>\n client\n .fetch<SettingsDoc | null>(SETTINGS_QUERY, {id: SETTINGS_DOC_ID})\n .then((s) => {\n if (cancelled) return\n setSettings(s)\n setLoaded(true)\n })\n .catch(() => {})\n load()\n const sub = client\n .listen(SETTINGS_QUERY, {id: SETTINGS_DOC_ID}, {visibility: 'query'})\n .subscribe({next: load, error: () => {}})\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [client])\n\n const requestRefresh = useCallback(() => {\n if (isRefreshInFlight(settingsRef.current)) return\n client\n .transaction()\n .createIfNotExists({_id: SETTINGS_DOC_ID, _type: SETTINGS_TYPE})\n .patch(SETTINGS_DOC_ID, (p) => p.set({templatesRequestedAt: new Date().toISOString()}))\n .commit({visibility: 'async'})\n .catch(() => {})\n }, [client])\n\n return {templates: settings?.templates ?? [], loaded, requestRefresh}\n}\n","import {useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {isWorkflowValid} from '../lib/workflow'\nimport type {SmartcatTemplate} from '../smartcat/types'\n\nconst STORAGE_KEY = 'smartcat:lastWorkflow'\n\nfunction readLastWorkflow(): string {\n try {\n return localStorage.getItem(STORAGE_KEY) ?? ''\n } catch {\n return ''\n }\n}\n\nfunction writeLastWorkflow(value: string): void {\n try {\n localStorage.setItem(STORAGE_KEY, value)\n } catch {\n // Ignore unavailable / full storage; selection just won't persist.\n }\n}\n\n/**\n * Workflow selection for a create dialog. Starts with **no selection** so the\n * user must choose, then remembers the last pick per browser (localStorage).\n *\n * When `active` (the dialog is open) and the template cache is `loaded`, it\n * prefills the saved value — but only if it's still valid: a `template:<id>`\n * whose template no longer exists resets to no selection. It also clears the\n * selection live if the chosen template later disappears from the cache.\n */\nexport function useWorkflowSelection(\n active: boolean,\n templates: SmartcatTemplate[],\n loaded: boolean,\n): readonly [string, (value: string) => void] {\n const [workflow, setWorkflowState] = useState('')\n const initialized = useRef(false)\n const templateIds = useMemo(() => templates.map((t) => t.id), [templates])\n\n // Prefill the saved selection once per open, after the cache has loaded.\n useEffect(() => {\n if (!active) {\n initialized.current = false\n return\n }\n if (initialized.current || !loaded) return\n initialized.current = true\n const saved = readLastWorkflow()\n setWorkflowState(isWorkflowValid(saved, templateIds) ? saved : '')\n }, [active, loaded, templateIds])\n\n // If the selected template disappears from the cache, drop back to no selection.\n useEffect(() => {\n if (!active || !loaded || !workflow) return\n if (!isWorkflowValid(workflow, templateIds)) setWorkflowState('')\n }, [active, loaded, workflow, templateIds])\n\n const setWorkflow = useCallback((value: string) => {\n setWorkflowState(value)\n if (value) writeLastWorkflow(value)\n }, [])\n\n return [workflow, setWorkflow] as const\n}\n","import {prepareForPreview} from 'sanity'\n\n/** Fallback label for a document whose schema preview yields no title. */\nexport const UNTITLED = 'Untitled'\n\n/** Minimal schema shape: just enough to look a type up by name. */\nexport interface TitleSchema {\n get(typeName: string): unknown\n}\n\n/**\n * Document display title, resolved the Sanity-native way — by running the schema\n * type's `preview.prepare` (same as the Studio list/structure tree) — so types\n * without a literal `title` field (e.g. field-level i18n) get a real label. Always\n * returns a string or `undefined`, never a raw field value (an internationalized\n * array is an object that crashes React #31 if rendered as a child).\n */\nexport function resolveDocumentTitle(\n schema: TitleSchema,\n doc: Record<string, unknown> & {_type: string},\n): string | undefined {\n const type = schema.get(doc._type)\n if (!type) return undefined\n try {\n const preview = prepareForPreview(doc as never, type as never)\n return typeof preview?.title === 'string' ? preview.title : undefined\n } catch {\n return undefined\n }\n}\n","/** Minimal client surface the gather needs. */\nexport interface GatherClient {\n fetch<T>(query: string, params: Record<string, unknown>): Promise<T>\n}\n\nexport interface LinkedDocument {\n docId: string\n docType: string\n}\n\nexport interface GatherOptions {\n client: GatherClient\n /** Published id of the document to start from. */\n rootId: string\n /** Root/standalone types — traversal stops here (peer content, not pulled in). */\n isRoot: (type: string) => boolean\n /** Types with localizable content — added to the project and recursed into. */\n isTranslatable: (type: string) => boolean\n /** Documents fetched per round. */\n batchSize?: number\n}\n\nconst bareId = (id: string) => id.replace(/^drafts\\./, '')\n\n/** Every `_ref` string anywhere in a document's JSON, as bare (published) ids. */\nexport function collectRefs(node: unknown, out: Set<string> = new Set()): Set<string> {\n if (!node || typeof node !== 'object') return out\n if (Array.isArray(node)) {\n for (const item of node) collectRefs(item, out)\n return out\n }\n const obj = node as Record<string, unknown>\n if (typeof obj._ref === 'string') out.add(bareId(obj._ref))\n for (const [key, value] of Object.entries(obj)) {\n if (key === '_ref') continue\n collectRefs(value, out)\n }\n return out\n}\n\n// Prefer the draft copy (freshest refs) when both draft and published exist.\nfunction pickPreferDraft<T extends {_id: string}>(docs: T[] | null): Map<string, T> {\n const chosen = new Map<string, T>()\n for (const doc of docs ?? []) {\n const bare = bareId(doc._id)\n if (!chosen.has(bare) || doc._id.startsWith('drafts.')) chosen.set(bare, doc)\n }\n return chosen\n}\n\n/**\n * Breadth-first gather of documents linked (transitively) from `rootId`.\n *\n * Follows references only through translatable, non-root documents; stops at\n * root types (peer pages, translated on their own) and at non-localizable leaves\n * (assets, config). Cycle-safe. Returns the linked documents to add — excluding\n * the root itself.\n */\nexport async function gatherLinkedDocuments({\n client,\n rootId,\n isRoot,\n isTranslatable,\n batchSize = 50,\n}: GatherOptions): Promise<LinkedDocument[]> {\n const start = bareId(rootId)\n const seen = new Set<string>([start])\n const result: LinkedDocument[] = []\n let frontier: string[] = [start]\n\n while (frontier.length) {\n const batch = frontier.splice(0, batchSize)\n // Full bodies of the docs we're expanding — needed to read their outgoing refs.\n const bodies = await client.fetch<Array<Record<string, unknown> & {_id: string}>>(\n `*[_id in $ids]`,\n {ids: batch.flatMap((id) => [id, `drafts.${id}`])},\n )\n const candidates = new Set<string>()\n for (const doc of pickPreferDraft(bodies).values()) {\n for (const ref of collectRefs(doc)) candidates.add(ref)\n }\n const fresh = [...candidates].filter((id) => !seen.has(id))\n if (!fresh.length) continue\n fresh.forEach((id) => seen.add(id))\n\n // Classify fresh candidates by type (light query — avoids pulling full\n // bodies of peer pages and assets we won't recurse into).\n const typed = await client.fetch<Array<{_id: string; _type: string}>>(\n `*[_id in $ids]{_id, _type}`,\n {ids: fresh.flatMap((id) => [id, `drafts.${id}`])},\n )\n for (const [id, doc] of pickPreferDraft(typed)) {\n const type = doc._type\n if (!type || isRoot(type) || !isTranslatable(type)) continue\n result.push({docId: id, docType: type})\n frontier.push(id)\n }\n }\n return result\n}\n","import {useCallback, useEffect, useMemo, useState} from 'react'\nimport {useClient, usePerspective, useSchema, type DocumentActionComponent, type DocumentActionProps} from 'sanity'\nimport {Badge, Box, Button, Card, Flex, Inline, Label, Select, Spinner, Stack, Switch, Text, TextInput, useToast} from '@sanity/ui'\nimport {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {uuid} from '@sanity/uuid'\nimport {API_VERSION, TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {WorkflowSelect} from '../tool/WorkflowSelect'\nimport {useTemplates} from '../tool/useTemplates'\nimport {useWorkflowSelection} from '../tool/useWorkflowSelection'\nimport {resolveDocumentTitle, UNTITLED} from '../lib/documentTitle'\nimport {gatherLinkedDocuments} from '../lib/linkedDocuments'\nimport {ITEM_ID} from '../lib/projectItems'\nimport {getTranslatableFields} from '../lib/locjson/fields'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\ninterface ProjectOption {\n _id: string\n name: string\n count: number\n status: string\n}\n\nconst PROJECTS_QUERY = `*[_type == $type] | order(name asc){\n _id,\n name,\n status,\n \"count\": count(items)\n}`\n\nconst CREATE_NEW = '__create_new__'\n\n/**\n * Builds the \"Add to translation project\" document action, shown on the\n * configured translatable types. Lets the editor add the current document to an\n * existing project or create a new one — appending a weak reference to the\n * project's `items`.\n */\nexport function createAddToProjectAction(config: ResolvedSmartcatConfig): DocumentActionComponent {\n const sourceLanguage = config.sourceLanguage\n\n const AddToProjectAction: DocumentActionComponent = (props: DocumentActionProps) => {\n const {id, draft, published, onComplete} = props\n const client = useClient({apiVersion: API_VERSION})\n const schema = useSchema()\n const toast = useToast()\n // Which version is the translation source, decided here and stored on the\n // item (the pill and the export both read it — no re-resolving later): the\n // published document when the published perspective is selected or there is\n // no draft; otherwise the draft, which is what the editor sees and edits.\n const {selectedPerspectiveName} = usePerspective()\n const sourceIsPublished = selectedPerspectiveName === 'published' || !draft\n\n const [open, setOpen] = useState(false)\n const [projects, setProjects] = useState<ProjectOption[] | null>(null)\n const [selection, setSelection] = useState<string>(CREATE_NEW)\n const [newName, setNewName] = useState('')\n const [busy, setBusy] = useState(false)\n const [includeLinked, setIncludeLinked] = useState(true)\n const {templates, loaded, requestRefresh} = useTemplates()\n const [workflow, setWorkflow] = useWorkflowSelection(open, templates, loaded)\n\n const publishedId = id.replace(/^drafts\\./, '')\n const doc = draft ?? published\n // Resolve the title natively (preview.prepare) so field-level i18n types yield\n // a string, never the raw internationalized-array object (renders as React #31).\n const docTitle = (doc && resolveDocumentTitle(schema, doc)) || UNTITLED\n\n // Load existing projects when the dialog opens.\n useEffect(() => {\n if (!open) return\n // Refresh the template list each time the dialog opens.\n requestRefresh()\n let cancelled = false\n setProjects(null)\n client\n .fetch<ProjectOption[]>(PROJECTS_QUERY, {type: TRANSLATION_PROJECT_TYPE})\n .then((res) => {\n if (cancelled) return\n setProjects(res)\n // Default to the first existing project if there is one.\n setSelection(res.length > 0 ? res[0]._id : CREATE_NEW)\n })\n .catch((err) => {\n if (!cancelled) toast.push({status: 'error', title: 'Failed to load projects', description: String(err)})\n })\n return () => {\n cancelled = true\n }\n }, [open, client, toast, requestRefresh])\n\n const close = useCallback(() => {\n setOpen(false)\n setNewName('')\n onComplete()\n }, [onComplete])\n\n const handleConfirm = useCallback(async () => {\n setBusy(true)\n try {\n const makeItem = (docId: string, docType?: string) => ({\n _type: 'smartcat.projectItem',\n _key: uuid(),\n docId,\n docType,\n sourceIsPublished,\n })\n\n // The root document plus, optionally, everything it links to — de-duped by id.\n const collected = new Map<string, string | undefined>([[publishedId, doc?._type]])\n if (includeLinked) {\n const isRoot = (type: string) => config.rootTypes.includes(type)\n const isTranslatable = (type: string) =>\n getTranslatableFields(schema.get(type), {exclude: [config.documentI18nLanguageField]}).length > 0\n const linked = await gatherLinkedDocuments({client, rootId: publishedId, isRoot, isTranslatable})\n for (const {docId, docType} of linked) if (!collected.has(docId)) collected.set(docId, docType)\n }\n\n if (selection === CREATE_NEW) {\n const name = newName.trim() || `Translation project ${new Date().toISOString().slice(0, 10)}`\n const items = [...collected].map(([docId, docType]) => makeItem(docId, docType))\n await client.create({\n _type: TRANSLATION_PROJECT_TYPE,\n name,\n status: 'draft',\n sourceLanguage,\n workflow,\n items,\n })\n toast.push({\n status: 'success',\n title: `Created “${name}” with ${items.length} document${items.length === 1 ? '' : 's'}`,\n })\n } else {\n // Skip ids already in the project (normalized across old/new item shapes).\n const existing = await client.fetch<{id: string}[]>(\n `*[_id == $pid][0].items[]{\"id\": ${ITEM_ID}}`,\n {pid: selection},\n )\n const existingIds = new Set((existing ?? []).map((e) => e.id))\n const newItems = [...collected]\n .filter(([docId]) => !existingIds.has(docId))\n .map(([docId, docType]) => makeItem(docId, docType))\n const projName = projects?.find((p) => p._id === selection)?.name ?? 'project'\n if (newItems.length === 0) {\n toast.push({status: 'info', title: `Already in “${projName}”`})\n } else {\n await client.patch(selection).setIfMissing({items: []}).insert('after', 'items[-1]', newItems).commit()\n const skipped = collected.size - newItems.length\n toast.push({\n status: 'success',\n title: `Added ${newItems.length} document${newItems.length === 1 ? '' : 's'} to “${projName}”`,\n description: skipped > 0 ? `${skipped} already in the project` : undefined,\n })\n }\n }\n close()\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to add to project', description: String(err)})\n } finally {\n setBusy(false)\n }\n }, [selection, newName, workflow, publishedId, doc, includeLinked, sourceIsPublished, schema, client, projects, close])\n\n const content = useMemo(() => {\n if (projects === null) {\n return (\n <Flex align=\"center\" justify=\"center\" padding={4}>\n <Spinner muted />\n </Flex>\n )\n }\n return (\n <Stack space={4}>\n <Stack space={3}>\n <Label size={1}>Project</Label>\n <Select\n value={selection}\n onChange={(e) => setSelection(e.currentTarget.value)}\n disabled={busy}\n >\n {projects.map((p) => (\n <option key={p._id} value={p._id}>\n {p.name} ({p.count} item{p.count === 1 ? '' : 's'})\n </option>\n ))}\n <option value={CREATE_NEW}>➕ Create new project…</option>\n </Select>\n </Stack>\n\n {selection === CREATE_NEW && (\n <>\n <Stack space={3}>\n <Label size={1}>New project name</Label>\n <TextInput\n value={newName}\n placeholder=\"e.g. Spring campaign\"\n onChange={(e) => setNewName(e.currentTarget.value)}\n disabled={busy}\n />\n </Stack>\n <Stack space={3}>\n <Label size={1}>Workflow</Label>\n <WorkflowSelect\n value={workflow}\n onChange={setWorkflow}\n templates={templates}\n disabled={busy}\n />\n </Stack>\n </>\n )}\n\n <Card padding={3} radius={2} tone=\"transparent\" border>\n <Stack space={4}>\n <Text size={1} muted>\n Adding{' '}\n <Badge\n tone={sourceIsPublished ? 'positive' : 'caution'}\n fontSize={1}\n paddingX={2}\n style={{verticalAlign: 'middle'}}\n >\n {sourceIsPublished ? 'Published' : 'Draft'}\n </Badge>{' '}\n version of <strong>{docTitle}</strong> to the selected project.\n </Text>\n <Flex align=\"flex-start\" gap={3}>\n <Switch\n checked={includeLinked}\n onChange={(e) => setIncludeLinked(e.currentTarget.checked)}\n disabled={busy}\n />\n <Stack space={2}>\n <Text size={1} weight=\"medium\">\n Include linked content\n </Text>\n <Text size={1} muted>\n Also add documents this one references, recursively — skipping any already in the project.\n </Text>\n </Stack>\n </Flex>\n </Stack>\n </Card>\n\n <Flex justify=\"flex-end\" gap={2}>\n <Button mode=\"bleed\" text=\"Cancel\" onClick={close} disabled={busy} />\n <Button\n tone=\"primary\"\n text=\"Add to project\"\n icon={AddIcon}\n onClick={handleConfirm}\n loading={busy}\n disabled={selection === CREATE_NEW && !workflow}\n />\n </Flex>\n </Stack>\n )\n }, [projects, selection, newName, workflow, templates, busy, includeLinked, docTitle, sourceIsPublished, close, handleConfirm])\n\n return {\n label: 'Add to translation project',\n icon: TranslateIcon,\n onHandle: () => setOpen(true),\n dialog: open && {\n type: 'dialog',\n header: 'Add to translation project',\n onClose: close,\n content,\n },\n }\n }\n\n return AddToProjectAction\n}\n","import {TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {ITEM_ID, ITEM_ID_FROM_SUBQUERY, itemDocDeref} from '../lib/projectItems'\nimport type {TranslationProjectStatus} from '../types'\nimport type {DocProgress} from '../progress/core'\n\n/** A row in the projects list. */\nexport interface ProjectListItem {\n _id: string\n name: string\n status: TranslationProjectStatus\n count: number\n _createdAt: string\n _updatedAt: string\n}\n\n/** A resolved item inside a project. */\nexport interface ProjectItemRef {\n _key: string\n /** Published id of the added document, normalized across old (`_ref`) and new (`docId`) items. */\n docId: string\n /**\n * Whether the published version is the translation source (vs the draft),\n * decided and stored when the item was added. Drives the Draft/Published pill\n * and which version the export serializes. Null on legacy items (pre-flag).\n */\n sourceIsPublished: boolean | null\n doc: {_id: string; _type: string} | null\n /** Locale variants linked via translation.metadata: language -> variant doc id. */\n translations: {language: string; id: string}[] | null\n}\n\n/** A single project with its resolved items. */\nexport interface ProjectDetail {\n _id: string\n name: string\n status: TranslationProjectStatus\n sourceLanguage: string | null\n targetLanguages: string[] | null\n smartcatProjectId: string | null\n smartcatProjectUrl: string | null\n lastError: string | null\n /** JSON-encoded LogLine[] from the most recent Function run. */\n functionLog: string | null\n /** Targets the last download run deferred (size/time caps) — drives auto-continue. */\n importRemaining: number | null\n items: ProjectItemRef[] | null\n progress: DocProgress[] | null\n progressSyncedAt: string | null\n}\n\nexport const PROJECTS_QUERY = `*[_type == \"${TRANSLATION_PROJECT_TYPE}\"] | order(_createdAt desc){\n _id,\n name,\n status,\n _createdAt,\n _updatedAt,\n \"count\": count(items)\n}`\n\nexport const PROJECT_DETAIL_QUERY = `*[_id == $id][0]{\n _id,\n name,\n status,\n sourceLanguage,\n targetLanguages,\n smartcatProjectId,\n smartcatProjectUrl,\n lastError,\n functionLog,\n importRemaining,\n progressSyncedAt,\n items[]{\n _key,\n \"docId\": ${ITEM_ID},\n sourceIsPublished,\n \"doc\": ${itemDocDeref('{_id, _type}')},\n \"translations\": *[_type == \"translation.metadata\" && references(${ITEM_ID_FROM_SUBQUERY})][0]\n .translations[]{language, \"id\": value._ref}\n },\n progress[]{\n _key,\n sourceDocId,\n title,\n targets[]{_key, language, smartcatDocumentId, stages, complete, imported, syncedAt}\n }\n}`\n","import {Badge, type BadgeTone} from '@sanity/ui'\nimport type {TranslationProjectStatus} from '../types'\nimport {STATUS_OPTIONS} from '../schema/translationProject'\n\n// Badge color is a UI-only concern (no schema equivalent), so it lives here.\nconst TONES: Record<TranslationProjectStatus, BadgeTone> = {\n draft: 'default',\n queued: 'caution',\n sent: 'primary',\n translating: 'primary',\n importing: 'caution',\n downloaded: 'primary',\n completed: 'positive',\n error: 'critical',\n}\n\n// Display titles come from the schema's STATUS_OPTIONS — the single source.\nconst LABELS: Record<string, string> = Object.fromEntries(\n STATUS_OPTIONS.map((o) => [o.value, o.title]),\n)\n\n/** Display label for a project status (from the schema's status titles). */\nexport function statusLabel(status: TranslationProjectStatus): string {\n return LABELS[status] ?? status\n}\n\nexport function StatusBadge({status}: {status: TranslationProjectStatus}) {\n return (\n <Badge tone={TONES[status] ?? 'default'} fontSize={0} padding={2} radius={2}>\n {statusLabel(status)}\n </Badge>\n )\n}\n","import {useCallback, useEffect, useState} from 'react'\nimport {useClient, useRelativeTime} from 'sanity'\nimport {\n Box,\n Button,\n Card,\n Dialog,\n Flex,\n Heading,\n Label,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {API_VERSION, TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {PROJECTS_QUERY, type ProjectListItem} from './data'\nimport {StatusBadge} from './StatusBadge'\nimport {WorkflowSelect} from './WorkflowSelect'\nimport {useTemplates} from './useTemplates'\nimport {useWorkflowSelection} from './useWorkflowSelection'\n\ninterface ProjectsViewProps {\n sourceLanguage: string\n onOpenProject: (id: string) => void\n}\n\n/** A single project row. Extracted so `useRelativeTime` can run per row. */\nfunction ProjectRow({project: p, onOpen}: {project: ProjectListItem; onOpen: (id: string) => void}) {\n const createdAgo = useRelativeTime(p._createdAt, {useTemporalPhrase: true})\n return (\n <Card\n padding={3}\n radius={2}\n shadow={1}\n as=\"button\"\n onClick={() => onOpen(p._id)}\n style={{cursor: 'pointer', textAlign: 'left', width: '100%'}}\n >\n <Flex align=\"center\" gap={3}>\n <Box style={{width: 110}}>\n <Text size={1} muted title={new Date(p._createdAt).toLocaleString()}>\n {createdAgo}\n </Text>\n </Box>\n <Box style={{width: 100}}>\n <StatusBadge status={p.status} />\n </Box>\n <Box>\n <TranslateIcon />\n </Box>\n <Box flex={1}>\n <Text weight=\"semibold\">{p.name}</Text>\n </Box>\n <Text size={1} muted>\n {p.count} item{p.count === 1 ? '' : 's'}\n </Text>\n </Flex>\n </Card>\n )\n}\n\nexport function ProjectsView({sourceLanguage, onOpenProject}: ProjectsViewProps) {\n const client = useClient({apiVersion: API_VERSION})\n const toast = useToast()\n const [projects, setProjects] = useState<ProjectListItem[] | null>(null)\n const [creating, setCreating] = useState(false)\n const [newName, setNewName] = useState('')\n const [busy, setBusy] = useState(false)\n const {templates, loaded, requestRefresh} = useTemplates()\n const [workflow, setWorkflow] = useWorkflowSelection(creating, templates, loaded)\n\n // Refresh the template list each time the create dialog opens.\n useEffect(() => {\n if (creating) requestRefresh()\n }, [creating, requestRefresh])\n\n const load = useCallback(() => {\n return client\n .fetch<ProjectListItem[]>(PROJECTS_QUERY)\n .then(setProjects)\n .catch((err) => toast.push({status: 'error', title: 'Failed to load projects', description: String(err)}))\n }, [client, toast])\n\n // Initial load + live updates.\n useEffect(() => {\n load()\n const sub = client\n .listen(PROJECTS_QUERY, {}, {visibility: 'query'})\n .subscribe({next: () => load(), error: () => {}})\n return () => sub.unsubscribe()\n }, [client, load])\n\n const handleCreate = useCallback(async () => {\n const name = newName.trim()\n if (!name) return\n setBusy(true)\n try {\n const created = await client.create({\n _type: TRANSLATION_PROJECT_TYPE,\n name,\n status: 'draft',\n sourceLanguage,\n workflow,\n items: [],\n })\n toast.push({status: 'success', title: `Created “${name}”`})\n setCreating(false)\n setNewName('')\n onOpenProject(created._id)\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to create project', description: String(err)})\n } finally {\n setBusy(false)\n }\n }, [newName, workflow, client, sourceLanguage, toast, onOpenProject])\n\n return (\n <Stack space={4}>\n <Flex align=\"center\" justify=\"space-between\">\n <Heading size={2}>Translation projects</Heading>\n <Button icon={AddIcon} text=\"New project\" tone=\"primary\" onClick={() => setCreating(true)} />\n </Flex>\n\n {projects === null ? (\n <Flex align=\"center\" justify=\"center\" padding={5}>\n <Spinner muted />\n </Flex>\n ) : projects.length === 0 ? (\n <Card padding={5} radius={2} tone=\"transparent\" border>\n <Stack space={3}>\n <Text muted align=\"center\">\n No translation projects yet.\n </Text>\n <Flex justify=\"center\">\n <Button icon={AddIcon} text=\"Create your first project\" onClick={() => setCreating(true)} />\n </Flex>\n </Stack>\n </Card>\n ) : (\n <Stack space={2}>\n {projects.map((p) => (\n <ProjectRow key={p._id} project={p} onOpen={onOpenProject} />\n ))}\n </Stack>\n )}\n\n {creating && (\n <Dialog\n id=\"create-project\"\n header=\"New translation project\"\n onClose={() => {\n setCreating(false)\n setNewName('')\n }}\n width={1}\n >\n <Box padding={4}>\n <Stack space={4}>\n <Stack space={3}>\n <Label size={1}>Project name</Label>\n <TextInput\n value={newName}\n placeholder=\"e.g. Spring campaign\"\n autoFocus\n onChange={(e) => setNewName(e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleCreate()\n }}\n disabled={busy}\n />\n </Stack>\n <Stack space={3}>\n <Label size={1}>Workflow</Label>\n <WorkflowSelect\n value={workflow}\n onChange={setWorkflow}\n templates={templates}\n disabled={busy}\n />\n </Stack>\n <Flex justify=\"flex-end\" gap={2}>\n <Button\n mode=\"bleed\"\n text=\"Cancel\"\n onClick={() => {\n setCreating(false)\n setNewName('')\n }}\n disabled={busy}\n />\n <Button\n tone=\"primary\"\n text=\"Create\"\n onClick={handleCreate}\n loading={busy}\n disabled={!newName.trim() || !workflow}\n />\n </Flex>\n </Stack>\n </Box>\n </Dialog>\n )}\n </Stack>\n )\n}\n","import {uuid} from '@sanity/uuid'\nimport {resolveDocumentTitle} from '../lib/documentTitle'\nimport {ITEM_ID, itemDocDerefRespectingDraft} from '../lib/projectItems'\nimport {\n enumerateLeaves,\n getTranslatableFields,\n innerValueType,\n isInternationalizedArrayType,\n localizationMode,\n} from '../lib/locjson/fields'\nimport {getAtPath, setAtPath} from '../lib/locjson/paths'\nimport type {TranslatableField} from '../lib/locjson/types'\nimport {serializeToLocjson} from '../lib/locjson/serialize'\nimport {buildLocjsonFilename} from '../lib/locjson/filename'\nimport {deserializeFromLocjson} from '../lib/locjson/deserialize'\nimport {requireSourceLanguage} from '../lib/constants'\nimport {buildLanguageMappings, findDuplicateSmartcatLanguages} from '../lib/languageMap'\nimport type {LocalizationMode, LocJSON} from '../lib/locjson/types'\nimport {summarizeCompletion, type DocProgress} from '../progress/core'\nimport type {SmartcatLanguage} from '../types'\nimport type {LogFn} from '../lib/log'\n\n/**\n * Browser-side processing for the Smartcat workflow. All content transformation\n * (Portable Text ⇄ HTML, field selection, variant creation) happens here in the\n * Studio, where the real schema and a native DOM are available — so the Sanity\n * Functions stay thin and dependency-free.\n */\n\n/** A loosely-typed Sanity client (the Studio's `useClient` result satisfies this). */\nexport interface ProcessingClient {\n fetch<T = unknown>(query: string, params?: Record<string, unknown>): Promise<T>\n create(doc: Record<string, unknown>): Promise<{_id: string}>\n createIfNotExists(doc: Record<string, unknown>): Promise<{_id: string}>\n patch(id: string): ProcessingPatch\n}\ninterface ProcessingPatch {\n set(attrs: Record<string, unknown>): ProcessingPatch\n setIfMissing(attrs: Record<string, unknown>): ProcessingPatch\n insert(at: 'before' | 'after' | 'replace', selector: string, items: unknown[]): ProcessingPatch\n unset(keys: string[]): ProcessingPatch\n commit(): Promise<unknown>\n}\n\n/** A compiled schema (the Studio's `useSchema` result satisfies this). */\nexport interface ProcessingSchema {\n get(typeName: string): unknown\n}\n\nconst METADATA_TYPE = 'translation.metadata'\nconst REFERENCE_VALUE_TYPE = 'internationalizedArrayReferenceValue'\n\nfunction parseHtml(html: string): Document {\n return new DOMParser().parseFromString(html, 'text/html')\n}\n\nconst VALUE_PREVIEW_CAP = 2000\n\n/** A capped, display-safe string for a field value (source or translated). */\nfunction valuePreview(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined\n const text = typeof value === 'string' ? value : JSON.stringify(value, null, 2)\n if (!text) return undefined\n return text.length > VALUE_PREVIEW_CAP ? `${text.slice(0, VALUE_PREVIEW_CAP)}…` : text\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\n/**\n * For a field-level (internationalized-array) field, the member locales that\n * actually carry content — so a \"no source content\" skip can say *which* locales\n * exist (\"I see only: en-GB\") when the source-language member is simply missing,\n * turning a silent source-language mismatch into a self-explaining log line.\n */\nfunction memberLocalesWithContent(members: unknown, languageKey: string): string[] {\n if (!Array.isArray(members)) return []\n const locales: string[] = []\n for (const member of members) {\n if (!member || typeof member !== 'object') continue\n const locale = (member as Record<string, unknown>)[languageKey]\n const value = (member as {value?: unknown}).value\n const hasContent =\n typeof value === 'string' ? value.trim().length > 0 : Array.isArray(value) ? value.length > 0 : value != null\n if (typeof locale === 'string' && hasContent) locales.push(locale)\n }\n return locales\n}\n\n/** Top-level, non-system schema field names for a type (for \"not translatable\" reporting). */\nfunction schemaFieldNames(schema: ProcessingSchema, type: string): string[] {\n const compiled = schema.get(type) as {fields?: {name?: string}[]} | undefined\n return (compiled?.fields ?? [])\n .map((f) => f?.name)\n .filter((n): n is string => typeof n === 'string' && !n.startsWith('_'))\n}\n\nfunction blockContentTypeFor(schema: ProcessingSchema, type: string, fieldPath: string): unknown {\n const compiled = schema.get(type) as {fields?: {name: string; type: unknown}[]} | undefined\n const fieldType = compiled?.fields?.find((f) => f.name === fieldPath)?.type\n // Field-level Portable Text lives under the array member's `value`; resolve the\n // inner block-content type rather than the internationalized-array wrapper.\n if (isInternationalizedArrayType(fieldType as never)) {\n return innerValueType(fieldType as never)\n }\n return fieldType\n}\n\n// ---------------------------------------------------------------------------\n// Export: serialize project items → outbox (LocJSON), set status = queued\n// ---------------------------------------------------------------------------\n\n/** An item the editor marked for deletion; carried to the export Function. */\nexport interface PendingDeletion {\n itemKey: string\n sourceDocId: string\n smartcatDocumentId?: string\n}\n\nexport interface PrepareExportArgs {\n client: ProcessingClient\n schema: ProcessingSchema\n projectId: string\n targetLanguages: string[]\n sourceLanguage: string\n /** Configured languages, used to resolve each id → its Smartcat code. */\n languages: SmartcatLanguage[]\n /** Configured translatable types (undefined = all), logged in the config header. */\n translatableTypes?: string[]\n exclude?: string[]\n /** How internationalized-array members identify their locale (field name or `'_key'`). */\n fieldLanguageKey: string\n /** Items to delete from Smartcat (and the project) on this export. */\n deletions?: PendingDeletion[]\n /** Streams per-document/per-field progress to the UI; no-op if omitted. */\n onLog?: LogFn\n}\n\nconst ITEMS_QUERY = `*[_id == $id][0]{\n sourceLanguage,\n items[]{\n \"docId\": ${ITEM_ID},\n \"docType\": docType,\n \"doc\": ${itemDocDerefRespectingDraft()}\n }\n}`\n\nexport async function prepareExport({\n client,\n schema,\n projectId,\n targetLanguages,\n sourceLanguage,\n languages,\n translatableTypes,\n exclude,\n fieldLanguageKey,\n deletions = [],\n onLog,\n}: PrepareExportArgs): Promise<{prepared: number; deleting: number}> {\n const log: LogFn = onLog ?? (() => {})\n const project = await client.fetch<{\n sourceLanguage?: string\n items?: {\n docId?: string\n docType?: string\n doc: (Record<string, unknown> & {_id: string; _type: string}) | null\n }[]\n } | null>(ITEMS_QUERY, {id: projectId})\n\n const source = project?.sourceLanguage || sourceLanguage\n\n // Resolve the id → Smartcat-code mapping for this project's languages and\n // stamp it on the project, so the Functions can map to/from Smartcat codes.\n // Two targets resolving to the same code can't be routed back, so reject it.\n const smartcatLanguages = buildLanguageMappings(languages, [source, ...targetLanguages])\n const dups = findDuplicateSmartcatLanguages(\n smartcatLanguages.filter((m) => targetLanguages.includes(m.sanityId)),\n )\n if (dups.length > 0) {\n const detail = dups.map((d) => `${d.sanityIds.join(', ')} → ${d.smartcatLanguage}`).join('; ')\n throw new Error(`Multiple target languages map to the same Smartcat language: ${detail}`)\n }\n // Don't re-upload documents that are being deleted this round.\n const deletedDocIds = new Set(deletions.map((d) => d.sourceDocId))\n // Resolve each project item to its (draft-or-published) document. An item that\n // derefs to nothing — deleted, or expected published but never published — is\n // reported below rather than silently dropped.\n const items = (project?.items ?? []).filter(\n (item) => !(item.docId && deletedDocIds.has(item.docId)),\n )\n const unresolved = items.filter((item) => !item.doc)\n const docs = items\n .map((item) => item.doc)\n .filter((d): d is Record<string, unknown> & {_id: string; _type: string} => Boolean(d))\n\n // The translatable field list is per-type, so compute it once per type even\n // when a project holds many documents of the same type.\n const fieldsByType = new Map<string, ReturnType<typeof getTranslatableFields>>()\n const fieldsFor = (type: string) => {\n let fields = fieldsByType.get(type)\n if (!fields) {\n fields = getTranslatableFields(schema.get(type), {exclude})\n fieldsByType.set(type, fields)\n }\n return fields\n }\n\n // Config header — surfaces the resolved plugin config and this project's\n // languages up front, so a \"nothing serialized\" run can be traced to a\n // source-language or translatable-types mismatch straight from the log.\n const configuredLanguages = languages.map((l) => l.id).join(', ') || '(none)'\n const configuredTypes =\n translatableTypes === undefined ? 'all types' : translatableTypes.join(', ') || '(none)'\n log({level: 'info', message: `Config — source language: ${sourceLanguage}`})\n log({level: 'info', indent: true, message: `languages: ${configuredLanguages}`})\n log({level: 'info', indent: true, message: `translatable types: ${configuredTypes}`})\n log({level: 'info', message: `Project — source: ${source} → targets: ${targetLanguages.join(', ') || '(no targets)'}`})\n log({level: 'info', message: `Export — ${docs.length} document(s)`})\n\n // Items that resolved to no document at all: don't drop them silently — the\n // usual cause is a document that was never published (or was deleted).\n for (const item of unresolved) {\n log({\n level: 'error',\n message: `${item.docId ?? 'unknown document'} (${item.docType ?? 'unknown type'}): no document found — it may be unpublished or deleted; skipped`,\n })\n }\n\n const outbox: {_key: string; sourceDocId: string; title?: string; filename: string; locjson: string}[] = []\n for (const rawDoc of docs) {\n // Serialize under the canonical (bare) id so identity, metadata and progress\n // stay stable, even when the *content* came from the draft. Mark draft-sourced\n // files so they're recognizable in Smartcat.\n const isDraft = rawDoc._id.startsWith('drafts.')\n const doc = isDraft ? {...rawDoc, _id: publishedId(rawDoc._id)} : rawDoc\n const name = resolveDocumentTitle(schema, doc)\n log({level: 'info', message: `${name || doc._id} · ${doc._type}${isDraft ? ' (draft)' : ''}`})\n try {\n const fields = fieldsFor(doc._type)\n // Fields skipped because they hold a block type that can't be serialized\n // (e.g. a custom `table`): left untranslated on purpose, reported as errors\n // below so the editor knows to act rather than lose content silently.\n const skippedBlockTypes = new Map<string, string[]>()\n const locjson = serializeToLocjson(doc as never, fields, {\n sourceLanguage: source,\n fieldLanguageKey,\n onSkippedField: ({fieldPath, types}) => skippedBlockTypes.set(fieldPath, types),\n })\n // A field produced a unit ⇒ serialized; otherwise its source was empty.\n const unitByKey = new Map(locjson.units.map((u) => [u.key, u]))\n for (const field of fields) {\n const unit = unitByKey.get(field.path)\n const skippedTypes = skippedBlockTypes.get(field.path)\n if (unit) {\n log({level: 'success', indent: true, message: `${field.title || field.path}: serialized (${field.kind})`, value: unit.source.join('')})\n } else if (skippedTypes) {\n log({\n level: 'error',\n indent: true,\n message: `${field.title || field.path}: not translated — contains block type(s) that can't be translated: ${skippedTypes.join(', ')}. The whole field was left untranslated to avoid losing this content.`,\n })\n } else {\n // Field-level with members in other locales but not the source is a\n // source-language mismatch, not an empty field — name the locales seen.\n const otherLocales =\n field.localization === 'field'\n ? memberLocalesWithContent(getAtPath(doc, field.path), fieldLanguageKey).filter((l) => l !== source)\n : []\n const reason = otherLocales.length\n ? `no '${source}' content (I see only: ${otherLocales.join(', ')})`\n : 'no source content'\n log({level: 'skip', indent: true, message: `${field.title || field.path}: skipped — ${reason}`})\n }\n }\n // Surface the rest of the type's fields too, so a missing translation is\n // explained (\"not translatable\") rather than silently absent.\n const selected = new Set(fields.map((f) => f.path))\n const excluded = new Set(exclude ?? [])\n for (const fieldName of schemaFieldNames(schema, doc._type)) {\n if (selected.has(fieldName) || excluded.has(fieldName)) continue\n log({level: 'skip', indent: true, message: `${fieldName}: skipped — not translatable`})\n }\n if (locjson.units.length === 0) {\n // Distinguish \"nothing to translate\" from \"everything translatable was\n // held back\": the latter means the whole document goes untranslated, so\n // flag it as an error rather than a benign skip.\n if (skippedBlockTypes.size > 0) {\n log({\n level: 'error',\n indent: true,\n message: 'not sent — its only translatable content is in field(s) with block type(s) that can’t be translated (see above)',\n })\n } else {\n log({level: 'skip', indent: true, message: 'no translatable content — not sent'})\n }\n continue\n }\n outbox.push({\n _key: uuid(),\n sourceDocId: doc._id,\n title: name,\n filename: buildLocjsonFilename(doc._type, doc._id, name, {draft: isDraft}),\n locjson: JSON.stringify(locjson),\n })\n } catch (err) {\n log({level: 'error', indent: true, message: `failed to serialize: ${errorMessage(err)}`})\n }\n }\n log({level: 'success', message: `Queued ${outbox.length} file(s)${deletions.length ? ` · ${deletions.length} for deletion` : ''}`})\n\n await client\n .patch(projectId)\n .set({\n outbox,\n pendingDeletions: deletions,\n targetLanguages,\n sourceLanguage: source,\n smartcatLanguages,\n status: 'queued',\n lastError: null,\n })\n .commit()\n\n return {prepared: outbox.length, deleting: deletions.length}\n}\n\n// ---------------------------------------------------------------------------\n// Import: inbox (translated LocJSON) → locale variants + metadata, status = completed\n// ---------------------------------------------------------------------------\n\nexport interface ApplyImportArgs {\n client: ProcessingClient\n schema: ProcessingSchema\n projectId: string\n /** Document-level locale field name (document-internationalization `languageField`). */\n documentLanguageField: string\n /** Field-level locale key (internationalized-array): field name or `'_key'`. */\n fieldLanguageKey: string\n /** Streams per-document/per-field progress to the UI; no-op if omitted. */\n onLog?: LogFn\n}\n\nconst INBOX_QUERY = `*[_id == $id][0]{\n sourceLanguage,\n inbox[]{ sourceDocId, targetLanguage, smartcatDocumentId, locjson },\n progress[]{_key, sourceDocId, title, targets[]{_key, language, smartcatDocumentId, stages, complete, imported, syncedAt}}\n}`\n\nexport async function applyImportedTranslations({\n client,\n schema,\n projectId,\n documentLanguageField,\n fieldLanguageKey,\n onLog,\n}: ApplyImportArgs): Promise<{imported: number; status: 'completed' | 'translating'}> {\n const log: LogFn = onLog ?? (() => {})\n const project = await client.fetch<{\n sourceLanguage?: string\n inbox?: {sourceDocId?: string; targetLanguage: string; smartcatDocumentId?: string; locjson: string}[]\n progress?: DocProgress[]\n } | null>(INBOX_QUERY, {id: projectId})\n\n const sourceLanguage = requireSourceLanguage(project?.sourceLanguage)\n const inbox = project?.inbox ?? []\n // Resolved titles per source doc, from the stored progress (the same source the\n // import Function log uses) — so the log shows names, not raw document ids.\n const titleByDoc = new Map<string, string>()\n for (const p of project?.progress ?? []) {\n if (p.sourceDocId && p.title) titleByDoc.set(p.sourceDocId, p.title)\n }\n let imported = 0\n // (sourceDocId, targetLanguage) pairs we successfully imported.\n const importedKeys = new Set<string>()\n\n // Localization mode is per-type; derive once per type from the schema.\n const modeByType = new Map<string, LocalizationMode>()\n const modeFor = (type: string): LocalizationMode => {\n let mode = modeByType.get(type)\n if (!mode) {\n mode = localizationMode(schema.get(type))\n modeByType.set(type, mode)\n }\n return mode\n }\n\n // Translatable-field descriptors per type (shapes + nesting), for reconstructing\n // nested/array member values on write-back. Same exclude as export.\n const descriptorsByType = new Map<string, ReturnType<typeof getTranslatableFields>>()\n const descriptorsFor = (type: string) => {\n let d = descriptorsByType.get(type)\n if (!d) {\n d = getTranslatableFields(schema.get(type), {exclude: [documentLanguageField]})\n descriptorsByType.set(type, d)\n }\n return d\n }\n\n log({level: 'info', message: `Import — ${inbox.length} translated file(s)`})\n\n for (const item of inbox) {\n let parsed: LocJSON\n try {\n parsed = JSON.parse(item.locjson) as LocJSON\n } catch {\n log({level: 'error', message: `${item.sourceDocId || 'unknown'} → ${item.targetLanguage}: invalid LocJSON, skipped`})\n continue\n }\n const type = parsed.properties?.['x-sanity']?.documentType\n const result = deserializeFromLocjson(parsed, {\n parseHtml,\n getBlockContentType: (fieldPath) => (type ? blockContentTypeFor(schema, type, fieldPath) : undefined),\n })\n if (!result.documentId || !result.documentType) {\n log({level: 'error', message: `${item.sourceDocId || 'unknown'} → ${item.targetLanguage}: missing document id/type, skipped`})\n continue\n }\n\n const mode = modeFor(result.documentType)\n const title = titleByDoc.get(result.documentId)\n const label = title ? `${title} (Sanity ID: ${result.documentId})` : result.documentId\n log({level: 'info', message: `${label} → ${item.targetLanguage} · ${result.documentType} (${mode} mode)`})\n\n let ok = false\n // Each item is isolated: a failure is logged and skipped, so one bad\n // document never aborts the rest of the batch.\n try {\n ok =\n mode === 'field'\n ? await applyFieldLevelTranslations(client, {\n schema,\n type: result.documentType,\n docId: result.documentId,\n locale: item.targetLanguage,\n sourceLanguage: result.sourceLanguage || sourceLanguage,\n descriptors: descriptorsFor(result.documentType),\n translations: result.fields,\n sources: result.sources,\n languageKey: fieldLanguageKey,\n }, log)\n : await upsertVariant(client, {\n sourceId: result.documentId,\n type: result.documentType,\n sourceLanguage,\n locale: item.targetLanguage,\n fields: result.fields,\n sources: result.sources,\n languageField: documentLanguageField,\n }, log)\n } catch (err) {\n log({level: 'error', indent: true, message: `failed: ${errorMessage(err)}`})\n }\n if (ok) {\n imported++\n importedKeys.add(`${result.documentId}__${item.targetLanguage}`)\n }\n }\n\n // Mark the imported targets, then decide completion: the project is \"completed\"\n // only when every target is complete AND imported. Otherwise it stays\n // \"translating\" so the remaining targets can be imported once they finish.\n const progress = (project?.progress ?? []).map((doc) => ({\n ...doc,\n targets: doc.targets.map((target) =>\n importedKeys.has(`${doc.sourceDocId}__${target.language}`)\n ? {...target, imported: true}\n : target,\n ),\n }))\n const status = summarizeCompletion(progress).allDone ? 'completed' : 'translating'\n\n await client\n .patch(projectId)\n .set({progress, status, lastImportAt: new Date().toISOString()})\n .unset(['inbox'])\n .commit()\n\n return {imported, status}\n}\n\ninterface ApplyFieldLevelArgs {\n schema: ProcessingSchema\n type: string\n docId: string\n locale: string\n /** Source language — its array member is the structural template for reconstruction. */\n sourceLanguage: string\n /** Translatable-field descriptors for `type` (shapes + nesting). */\n descriptors: TranslatableField[]\n /** Translated leaf values keyed by full unit path. */\n translations: Record<string, unknown>\n /** Source (pre-translation) text per unit path, for the JSON well-formedness check. */\n sources: Record<string, string>\n /** How members identify their locale: a field name (`'language'`) or `'_key'`. */\n languageKey: string\n}\n\n/** A value is \"potential JSON\" if it's a string whose first non-blank char is `{`. */\nfunction isPotentialJson(value: unknown): value is string {\n return typeof value === 'string' && value.trimStart().startsWith('{')\n}\n\n/**\n * Guards a field whose **source** is JSON: the translated value must also parse.\n * Returns the parse error message when the translation is malformed (caller logs\n * it and skips the field); `null` when there's nothing to enforce — the source\n * isn't confirmed JSON — or the translation is valid JSON.\n */\nfunction malformedJsonError(source: unknown, translated: unknown): string | null {\n // Only enforce when the source is confirmed JSON (starts with `{` and parses).\n if (!isPotentialJson(source)) return null\n try {\n JSON.parse(source)\n } catch {\n return null // source isn't really JSON, so don't hold the translation to it\n }\n if (typeof translated !== 'string') return 'translated value is not a string'\n try {\n JSON.parse(translated)\n return null\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n}\n\nconst DRAFTS_PREFIX = 'drafts.'\n\n/** The published (bare) form of a document id. */\nfunction publishedId(id: string): string {\n return id.startsWith(DRAFTS_PREFIX) ? id.slice(DRAFTS_PREFIX.length) : id\n}\n\n/** The draft form of a document id. */\nfunction draftId(id: string): string {\n return id.startsWith(DRAFTS_PREFIX) ? id : DRAFTS_PREFIX + id\n}\n\ninterface EditableDraft {\n draftId: string\n /** Content edits are computed against: the draft if one exists, else published. */\n base: Record<string, unknown>\n /** Whether a draft already exists (so we don't clone published over it). */\n exists: boolean\n}\n\n/**\n * Resolves the **draft** to write imported translations into, so they accumulate\n * for editorial review instead of landing on the live document (where they'd be\n * invisible behind an existing draft and overwritten on the next publish).\n *\n * Read-only: returns the existing draft if there is one (so a concurrent draft\n * isn't clobbered), otherwise the published document as the base to seed from.\n * `null` if neither exists. Use {@link commitToDraft} to actually write.\n */\nasync function loadEditableDraft(client: ProcessingClient, id: string): Promise<EditableDraft | null> {\n const dId = draftId(id)\n const draft = await client.fetch<Record<string, unknown> | null>(`*[_id == $id][0]`, {id: dId})\n if (draft) return {draftId: dId, base: draft, exists: true}\n\n const published = await client.fetch<Record<string, unknown> | null>(`*[_id == $id][0]`, {id: publishedId(id)})\n if (!published) return null\n return {draftId: dId, base: published, exists: false}\n}\n\n/**\n * Writes `attrs` onto the draft, first cloning the published document into a new\n * draft if none exists yet. Only call when there is something to write, so an\n * unchanged import never leaves a spurious empty draft behind.\n */\nasync function commitToDraft(client: ProcessingClient, editable: EditableDraft, attrs: Record<string, unknown>): Promise<void> {\n if (!editable.exists) {\n await client.createIfNotExists({...stripSystemFields(editable.base), _id: editable.draftId, _type: editable.base._type})\n }\n await client.patch(editable.draftId).set(attrs).commit()\n}\n\n/**\n * Field-level (internationalized-array) import: writes each translated field's\n * value into the **same** document's **draft**, as the array member for `locale`\n * — updating the existing member (preserving its `_key`) or appending a new one.\n * No locale variant document and no translation.metadata.\n */\nasync function applyFieldLevelTranslations(\n client: ProcessingClient,\n {docId, locale, sourceLanguage, descriptors, translations, sources, languageKey}: ApplyFieldLevelArgs,\n log: LogFn,\n): Promise<boolean> {\n const editable = await loadEditableDraft(client, docId)\n if (!editable) {\n log({level: 'error', indent: true, message: `source document not found: ${docId}`})\n return false\n }\n const doc = editable.base\n const byKey = languageKey === '_key'\n const patchSet: Record<string, unknown> = {}\n\n // One patch entry per (nested) i18n field. The target member value is rebuilt\n // from the SOURCE member as a template — preserving `_key`s and non-text fields\n // — with each translated leaf overlaid by its valuePath.\n for (const field of descriptors) {\n if (field.localization !== 'field') continue\n const existing = (Array.isArray(getAtPath(doc, field.path)) ? getAtPath(doc, field.path) : []) as Record<string, unknown>[]\n const template = (existing.find((m) => m?.[languageKey] === sourceLanguage) ?? existing.find((m) => m?.value !== undefined))?.value\n\n let target: unknown = structuredClone(template)\n let changed = false\n for (const leaf of enumerateLeaves(field, template)) {\n let value = translations[leaf.fullKey]\n if (value === undefined) continue\n if (leaf.kind === 'portableText' && Array.isArray(value)) value = value.map((b) => keyBlock(b as Record<string, unknown>))\n // A JSON source ⇒ its translation must parse too, or we'd write broken JSON.\n const jsonError = malformedJsonError(sources[leaf.fullKey], value)\n if (jsonError) {\n log({level: 'error', indent: true, message: `${leaf.fullKey}: '${locale}' translation is not valid JSON — skipped`, value: valuePreview(value), error: jsonError})\n continue\n }\n target = leaf.valuePath ? setAtPath(target, leaf.valuePath, value) : value\n changed = true\n }\n if (!changed) continue\n\n const idx = existing.findIndex((m) => m?.[languageKey] === locale)\n if (idx >= 0 && sameValue(existing[idx]?.value, target)) {\n log({level: 'skip', indent: true, message: `${field.path}: '${locale}' unchanged — skipped`})\n continue\n }\n if (idx >= 0) {\n patchSet[field.path] = existing.map((m, i) => (i === idx ? {...m, value: target} : m))\n log({level: 'update', indent: true, message: `${field.path}: updating '${locale}' field variant`, before: valuePreview(existing[idx]?.value), value: valuePreview(target)})\n } else {\n // v4.x keys members by `_key`; v5+ uses a uuid `_key` plus a language field.\n const _type = existing.find((m) => m?._type)?._type\n patchSet[field.path] = [\n ...existing,\n byKey ? {_key: locale, _type, value: target} : {_key: uuid(), _type, [languageKey]: locale, value: target},\n ]\n log({level: 'info', indent: true, message: `${field.path}: creating '${locale}' field variant`, value: valuePreview(target)})\n }\n }\n\n if (Object.keys(patchSet).length === 0) {\n log({level: 'success', indent: true, message: `${docId}: no field changes`})\n return true\n }\n await commitToDraft(client, editable, patchSet)\n log({level: 'success', indent: true, message: `saved ${Object.keys(patchSet).length} field(s) on draft of ${docId}`})\n return true\n}\n\ninterface UpsertVariantArgs {\n sourceId: string\n type: string\n sourceLanguage: string\n locale: string\n fields: Record<string, unknown>\n /** Source (pre-translation) text per field, for the JSON well-formedness check. */\n sources: Record<string, string>\n /** Document locale field name (document-internationalization `languageField`). */\n languageField: string\n}\n\ninterface MetaTranslation {\n language?: string\n value?: {_ref?: string}\n}\n\nasync function upsertVariant(\n client: ProcessingClient,\n {sourceId, type, sourceLanguage, locale, fields, sources, languageField}: UpsertVariantArgs,\n log: LogFn,\n): Promise<boolean> {\n const source = await client.fetch<Record<string, unknown> | null>(`*[_id == $id][0]`, {id: sourceId})\n if (!source) {\n log({level: 'error', indent: true, message: `source document not found: ${sourceId}`})\n return false\n }\n\n const translatedFields = keyPortableText(fields)\n\n const metadata = await client.fetch<{_id: string; translations?: MetaTranslation[]} | null>(\n `*[_type == $metaType && references($sourceId)][0]{_id, translations}`,\n {metaType: METADATA_TYPE, sourceId},\n )\n const existingVariantId = metadata?.translations?.find((t) => t.language === locale)?.value?._ref\n\n // Log the intent before each write so a failure mid-op is still traceable.\n // All writes target the variant's draft, so translations accumulate for review.\n let variantId: string\n if (existingVariantId) {\n // Edit the variant's draft (seeded from its published version if needed), so\n // imported fields are reviewable and don't get clobbered by an open draft.\n const editable = await loadEditableDraft(client, existingVariantId)\n if (!editable) {\n log({level: 'error', indent: true, message: `'${locale}' document variant not found: ${existingVariantId}`})\n return false\n }\n const variant = editable.base\n // Only write fields whose translated value actually differs from the variant.\n const changed: Record<string, unknown> = {}\n for (const [path, value] of Object.entries(translatedFields)) {\n if (sameValue(variant[path], value)) {\n log({level: 'skip', indent: true, message: `${path}: unchanged — skipped`})\n continue\n }\n const jsonError = malformedJsonError(sources[path], value)\n if (jsonError) {\n log({\n level: 'error',\n indent: true,\n message: `${path}: translation is not valid JSON — skipped`,\n before: valuePreview(variant[path]),\n value: valuePreview(value),\n error: jsonError,\n })\n continue\n }\n changed[path] = value\n log({\n level: 'update',\n indent: true,\n message: `${path}: updating`,\n before: valuePreview(variant[path]),\n value: valuePreview(value),\n })\n }\n if (Object.keys(changed).length > 0) {\n await commitToDraft(client, editable, changed)\n log({level: 'success', indent: true, message: `updated ${Object.keys(changed).length} field(s) on '${locale}' document variant draft`})\n } else {\n log({level: 'success', indent: true, message: `'${locale}' document variant already up to date`})\n }\n variantId = publishedId(existingVariantId)\n } else {\n // Drop any field whose source is JSON but whose translation doesn't parse,\n // so a malformed value never lands on the new variant.\n const writableFields: Record<string, unknown> = {}\n for (const [path, value] of Object.entries(translatedFields)) {\n const jsonError = malformedJsonError(sources[path], value)\n if (jsonError) {\n log({\n level: 'error',\n indent: true,\n message: `${path}: translation is not valid JSON — skipped`,\n value: valuePreview(value),\n error: jsonError,\n })\n continue\n }\n writableFields[path] = value\n log({level: 'info', indent: true, message: `${path}`, value: valuePreview(value)})\n }\n log({level: 'info', indent: true, message: `creating new '${locale}' document variant draft`})\n // Create the variant as a draft; metadata references its published (bare) id.\n variantId = uuid()\n await client.create({...stripSystemFields(source), _id: draftId(variantId), [languageField]: locale, ...writableFields})\n }\n\n if (!metadata?._id) {\n log({level: 'info', indent: true, message: 'creating translation metadata'})\n await client.create({\n _type: METADATA_TYPE,\n schemaTypes: [type],\n translations: [translationEntry(sourceLanguage, sourceId), translationEntry(locale, variantId)],\n })\n } else if (!existingVariantId) {\n log({level: 'info', indent: true, message: 'linking variant into translation metadata'})\n await client\n .patch(metadata._id)\n .setIfMissing({translations: []})\n .insert('after', 'translations[-1]', [translationEntry(locale, variantId)])\n .commit()\n }\n\n log({level: 'success', indent: true, message: `'${locale}' document variant ready: ${variantId}`})\n return true\n}\n\nfunction translationEntry(language: string, ref: string) {\n return {\n _key: uuid(),\n _type: REFERENCE_VALUE_TYPE,\n language,\n value: {_type: 'reference', _ref: ref, _weak: true},\n }\n}\n\nfunction stripSystemFields(doc: Record<string, unknown>): Record<string, unknown> {\n const {_id, _rev, _createdAt, _updatedAt, ...rest} = doc\n void _id\n void _rev\n void _createdAt\n void _updatedAt\n return rest\n}\n\nfunction keyPortableText(fields: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(fields)) {\n if (Array.isArray(value) && value.some((v) => v && typeof v === 'object' && '_type' in v)) {\n out[key] = value.map((b) => keyBlock(b as Record<string, unknown>))\n } else {\n out[key] = value\n }\n }\n return out\n}\n\nfunction keyBlock(block: Record<string, unknown>): Record<string, unknown> {\n const keyed: Record<string, unknown> = {_key: (block._key as string) || uuid(), ...block}\n if (Array.isArray(keyed.children)) {\n keyed.children = (keyed.children as Record<string, unknown>[]).map((child) => ({\n _key: (child._key as string) || uuid(),\n ...child,\n }))\n }\n return keyed\n}\n\n/**\n * Deep value equality that ignores volatile `_key`s and object-key order, so an\n * unchanged translation — whose Portable Text gets freshly re-keyed on each\n * deserialize — isn't mistaken for a change.\n */\nfunction sameValue(a: unknown, b: unknown): boolean {\n return stableString(a) === stableString(b)\n}\n\nfunction stableString(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableString).join(',')}]`\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([k]) => k !== '_key')\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${stableString(v)}`).join(',')}}`\n }\n return JSON.stringify(value) ?? 'undefined'\n}\n","import {Badge, Box, Button, Flex, Inline, Stack, Text, useTheme_v2, Card} from '@sanity/ui'\nimport {LaunchIcon} from '@sanity/icons'\nimport {useIntentLink} from 'sanity/router'\nimport {targetPercent, type DocProgress, type TargetProgress} from '../progress/core'\nimport type {SmartcatLanguage} from '../types'\n\n/** Readable name for a language id, falling back to the id itself. */\nexport function languageTitle(languages: SmartcatLanguage[], id: string): string {\n return languages.find((l) => l.id === id)?.title || id\n}\n\n/** Locale variants for an item: language id -> Sanity variant document id. */\nexport interface VariantLinks {\n type: string\n byLanguage: Record<string, string>\n}\n\n/** Icon-only link that opens a language variant document in the Studio. */\nfunction OpenVariantInStudio({id, type}: {id: string; type: string}) {\n const {onClick, href} = useIntentLink({intent: 'edit', params: {id, type}})\n return (\n <Button\n as=\"a\"\n href={href}\n onClick={onClick}\n mode=\"bleed\"\n icon={LaunchIcon}\n title=\"Open this language version in Studio\"\n fontSize={0}\n padding={1}\n />\n )\n}\n\n/**\n * Smartcat editor URL for a target document. Host comes from the project's\n * Smartcat URL; the file guid and numeric language id are the two halves of the\n * target document id (`<fileGuid>_<langNum>`).\n */\nfunction editorUrl(projectUrl: string | null | undefined, smartcatDocumentId?: string): string | null {\n if (!projectUrl || !smartcatDocumentId) return null\n let origin: string\n try {\n origin = new URL(projectUrl).origin\n } catch {\n return null\n }\n const sep = smartcatDocumentId.lastIndexOf('_')\n if (sep < 0) return null\n const fileGuid = smartcatDocumentId.slice(0, sep)\n const langNum = smartcatDocumentId.slice(sep + 1)\n return `${origin}/open-editor/${fileGuid}?targetLanguageId=${langNum}`\n}\n\n/**\n * A thin track with a vivid fill whose width reflects the actual percentage.\n * Uses the design system's solid button colors (the same vivid blue/green used on\n * primary/positive buttons) rather than the muted Card surface tones — green once\n * the target is complete, blue while in progress.\n */\nfunction ProgressBar({percent, complete}: {percent: number; complete: boolean}) {\n const {color} = useTheme_v2()\n const pct = Math.max(0, Math.min(100, percent))\n const fill = (complete ? color.button.default.positive : color.button.default.primary).enabled.bg\n return (\n <Card tone=\"transparent\" border radius={3} style={{height: 10, overflow: 'hidden'}}>\n <div\n style={{\n width: `${pct}%`,\n height: '100%',\n background: fill,\n borderRadius: 'inherit',\n transition: 'width 0.3s ease',\n }}\n />\n </Card>\n )\n}\n\nfunction TargetRow({\n target,\n languages,\n smartcatProjectUrl,\n variants,\n}: {\n target: TargetProgress\n languages: SmartcatLanguage[]\n smartcatProjectUrl?: string | null\n variants?: VariantLinks\n}) {\n const percent = targetPercent(target.stages)\n const href = editorUrl(smartcatProjectUrl, target.smartcatDocumentId)\n const label = languageTitle(languages, target.language)\n const variantId = variants?.byLanguage[target.language]\n return (\n <Stack space={2}>\n <Flex align=\"center\" gap={3}>\n <Box style={{width: 150, flex: 'none'}}>\n <Flex align=\"center\" gap={1}>\n <Text size={1} weight=\"medium\">\n {href ? (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Open document in Smartcat editor\"\n >\n {label}\n </a>\n ) : (\n label\n )}\n </Text>\n {variantId && variants && <OpenVariantInStudio id={variantId} type={variants.type} />}\n </Flex>\n </Box>\n <Box flex={1}>\n <ProgressBar percent={percent} complete={target.complete} />\n </Box>\n <Box style={{width: 38, flex: 'none'}}>\n <Text size={1} muted align=\"right\">\n {percent}%\n </Text>\n </Box>\n <Box style={{width: 72, flex: 'none'}}>\n {target.imported ? (\n <Badge tone=\"positive\" fontSize={0} padding={2}>\n imported\n </Badge>\n ) : target.complete ? (\n <Badge tone=\"primary\" fontSize={0} padding={2}>\n ready\n </Badge>\n ) : null}\n </Box>\n </Flex>\n {target.stages.length > 0 && (\n <Inline space={3} style={{paddingLeft: 162}}>\n {target.stages.map((stage) => (\n <Text key={stage.name} size={0} muted>\n {stage.name}: {stage.percent}%\n </Text>\n ))}\n </Inline>\n )}\n </Stack>\n )\n}\n\n/** Per-language, per-stage progress for a single project item. */\nexport function ItemProgress({\n doc,\n languages,\n smartcatProjectUrl,\n variants,\n}: {\n doc: DocProgress\n languages: SmartcatLanguage[]\n smartcatProjectUrl?: string | null\n variants?: VariantLinks\n}) {\n if (!doc.targets || doc.targets.length === 0) return null\n return (\n <Stack space={3} paddingTop={1}>\n {doc.targets.map((target) => (\n <TargetRow\n key={target._key}\n target={target}\n languages={languages}\n smartcatProjectUrl={smartcatProjectUrl}\n variants={variants}\n />\n ))}\n </Stack>\n )\n}\n","import {useEffect, useLayoutEffect, useRef, useState} from 'react'\nimport {Box, Button, Card, Flex, Heading, Stack, Text, useTheme} from '@sanity/ui'\nimport {CheckmarkIcon, CopyIcon} from '@sanity/icons'\nimport type {LogLine, LogLevel} from '../lib/log'\n\n/** Flat, paste-friendly text for the whole log (indented lines + any values). */\nfunction logsToText(logs: LogLine[]): string {\n return logs\n .map((l) => {\n const prefix = l.indent ? ' ' : ''\n const detail = [\n l.before !== undefined ? `before: ${l.before}` : null,\n l.value !== undefined ? `${l.before !== undefined ? 'after' : 'value'}: ${l.value}` : null,\n l.error !== undefined ? `error: ${l.error}` : null,\n ]\n .filter(Boolean)\n .map((d) => ` ${d}`)\n .join('\\n')\n return `${prefix}${l.message}${detail ? `\\n${detail}` : ''}`\n })\n .join('\\n')\n}\n\nconst MONO = 'var(--font-family-mono, monospace)'\nconst VALUE_BG = 'var(--card-code-bg-color, rgba(127,127,127,0.12))'\n\n/** Status glyph per level. Info/update have none — only success/error/skip are marked. */\nconst GLYPH: Record<LogLevel, string> = {info: '', success: '✓', skip: '–', error: '✗', update: ''}\n\n/** Level → a theme-provided foreground colour (muted tone, good contrast in both themes). */\nfunction levelColor(theme: ReturnType<typeof useTheme>, level: LogLevel): string | undefined {\n const muted = theme.sanity.color.muted\n if (level === 'success') return muted.positive.enabled.fg\n if (level === 'error') return muted.critical.enabled.fg\n if (level === 'update') return muted.primary.enabled.fg\n return undefined\n}\n\n/** Background for a value box: light red for errors, the neutral gray otherwise. */\nfunction valueBg(theme: ReturnType<typeof useTheme>, level: LogLevel): string {\n return level === 'error' ? theme.sanity.color.muted.critical.enabled.bg : VALUE_BG\n}\n\n/** A value box; optional label (e.g. \"Before\"/\"After\") shown above the text. */\nfunction ValueBox({label, text, bg}: {label?: string; text: string; bg: string}) {\n return (\n <Box flex={1} padding={2} style={{background: bg, borderRadius: 3, minWidth: 0}}>\n <Stack space={2}>\n {label && (\n <Text size={0} muted weight=\"semibold\">\n {label}\n </Text>\n )}\n <Text size={0} style={{fontFamily: MONO, whiteSpace: 'pre-wrap'}}>\n {text}\n </Text>\n </Stack>\n </Box>\n )\n}\n\nfunction LogRow({line}: {line: LogLine}) {\n const theme = useTheme()\n const [open, setOpen] = useState(false)\n const hasDetail = line.value !== undefined || line.before !== undefined || line.error !== undefined\n const toggle = hasDetail ? () => setOpen((v) => !v) : undefined\n return (\n <Box paddingLeft={line.indent ? 4 : 0}>\n <Text\n size={1}\n muted={line.level === 'skip'}\n onClick={toggle}\n style={{\n fontFamily: MONO,\n whiteSpace: 'pre-wrap',\n cursor: hasDetail ? 'pointer' : 'default',\n color: levelColor(theme, line.level),\n }}\n >\n {/* Triangle is part of the line text, pushing the message right. */}\n {hasDetail && <span style={{opacity: 0.6, userSelect: 'none'}}>{open ? '▾' : '▸'} </span>}\n {GLYPH[line.level] ? <span style={{opacity: 0.7}}>{GLYPH[line.level]} </span> : null}\n {line.message}\n </Text>\n {hasDetail && open && (\n <Box marginTop={1}>\n <Stack space={2}>\n {line.before !== undefined ? (\n // Before/after side by side, two boxes with a gap.\n <Flex gap={3} align=\"stretch\">\n <ValueBox label=\"Before\" text={line.before} bg={valueBg(theme, line.level)} />\n <ValueBox label=\"After\" text={line.value ?? ''} bg={valueBg(theme, line.level)} />\n </Flex>\n ) : line.value !== undefined ? (\n <ValueBox text={line.value} bg={valueBg(theme, line.level)} />\n ) : null}\n {line.error !== undefined && (\n <ValueBox label=\"JSON error\" text={line.error} bg={valueBg(theme, line.level)} />\n )}\n </Stack>\n </Box>\n )}\n </Box>\n )\n}\n\n/**\n * Live, collapsible log of the export/import flow. Collapsed by default. While\n * expanded it auto-scrolls to the newest line only when the user is already at\n * the bottom; once they scroll up to inspect, it stops following so the view\n * doesn't jump out from under them.\n */\nexport function LogPanel({\n logs,\n expanded: expandedProp,\n onExpandedChange,\n}: {\n logs: LogLine[]\n /** Controlled expansion; omit to let the panel manage its own (collapsed default). */\n expanded?: boolean\n onExpandedChange?: (expanded: boolean) => void\n}) {\n const [internalExpanded, setInternalExpanded] = useState(false)\n const expanded = expandedProp ?? internalExpanded\n const setExpanded = (next: boolean) => {\n onExpandedChange?.(next)\n if (expandedProp === undefined) setInternalExpanded(next)\n }\n const [copied, setCopied] = useState(false)\n const scrollRef = useRef<HTMLDivElement>(null)\n const stickToBottom = useRef(true)\n const copyTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n useEffect(() => () => {\n if (copyTimeout.current) clearTimeout(copyTimeout.current)\n }, [])\n\n const handleCopy = () => {\n navigator.clipboard?.writeText(logsToText(logs))\n setCopied(true)\n if (copyTimeout.current) clearTimeout(copyTimeout.current)\n copyTimeout.current = setTimeout(() => setCopied(false), 1500)\n }\n\n const handleScroll = () => {\n const el = scrollRef.current\n if (!el) return\n stickToBottom.current = el.scrollHeight - el.scrollTop - el.clientHeight < 8\n }\n\n useLayoutEffect(() => {\n const el = scrollRef.current\n if (el && stickToBottom.current) el.scrollTop = el.scrollHeight\n }, [logs, expanded])\n\n return (\n <Stack space={3}>\n <Flex\n align=\"center\"\n gap={2}\n onClick={() => setExpanded(!expanded)}\n style={{cursor: 'pointer', userSelect: 'none'}}\n >\n <Heading size={1}>\n {expanded ? '▾' : '▸'} {logs.length > 0 ? `Log (${logs.length})` : 'Log'}\n </Heading>\n </Flex>\n\n {expanded && (\n <Card radius={2} border style={{position: 'relative'}}>\n {logs.length === 0 ? (\n <Box padding={3}>\n <Text size={1} muted>\n The log is empty — it will show the status of any send or import operation.\n </Text>\n </Box>\n ) : (\n <>\n <Box style={{position: 'absolute', top: 6, right: 6, zIndex: 1}}>\n <Button\n mode=\"ghost\"\n padding={2}\n fontSize={1}\n icon={copied ? CheckmarkIcon : CopyIcon}\n tone={copied ? 'positive' : 'default'}\n onClick={handleCopy}\n title={copied ? 'Copied' : 'Copy log'}\n />\n </Box>\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n style={{maxHeight: 320, overflowY: 'auto', padding: 12}}\n >\n <Stack space={2}>\n {logs.map((line, i) => (\n <LogRow key={i} line={line} />\n ))}\n </Stack>\n </div>\n </>\n )}\n </Card>\n )}\n </Stack>\n )\n}\n","/**\n * Live, in-memory log lines for the export/import flows, streamed to the\n * ProjectView Log panel as each document and field is processed. Never persisted\n * — purely a session-scoped trace for troubleshooting (e.g. on client calls).\n */\nexport type LogLevel = 'info' | 'success' | 'skip' | 'error' | 'update'\n\nexport interface LogLine {\n level: LogLevel\n message: string\n /** Field-level lines are indented under their document header. */\n indent?: boolean\n /** Optional value (source or translated text); revealed on click in the panel. */\n value?: string\n /** Prior value; when set, the panel shows `before` and `value` side by side. */\n before?: string\n /** Extra detail (e.g. a JSON parse error); shown in its own box on expand. */\n error?: string\n}\n\n/** Sink for log lines; processing accepts one to stream progress to the UI. */\nexport type LogFn = (line: LogLine) => void\n\n/** Parse a Function's JSON-encoded `functionLog` field into log lines (lenient). */\nexport function parseFunctionLog(raw: string | null | undefined): LogLine[] {\n if (!raw) return []\n try {\n const parsed = JSON.parse(raw)\n return Array.isArray(parsed) ? (parsed as LogLine[]) : []\n } catch {\n return []\n }\n}\n","import {useCallback, useEffect, useRef, useState} from 'react'\nimport {useClient, useRelativeTime, useSchema, useValuePreview} from 'sanity'\nimport {applyImportedTranslations, prepareExport, type PendingDeletion} from './processing'\nimport {getTranslatableFields, localizationMode} from '../lib/locjson/fields'\nimport {serializeToLocjson} from '../lib/locjson/serialize'\nimport {buildLocjsonFilename} from '../lib/locjson/filename'\nimport {resolveDocumentTitle} from '../lib/documentTitle'\nimport type {LocalizationMode} from '../lib/locjson/types'\nimport {useIntentLink} from 'sanity/router'\nimport {\n Badge,\n Box,\n Button,\n Card,\n Checkbox,\n Dialog,\n Flex,\n Heading,\n Inline,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport {\n ArrowLeftIcon,\n LaunchIcon,\n TrashIcon,\n PublishIcon,\n CloseIcon,\n DownloadIcon,\n SyncIcon,\n RemoveCircleIcon,\n JsonIcon,\n} from '@sanity/icons'\nimport styled, {css, keyframes} from 'styled-components'\nimport {API_VERSION} from '../lib/constants'\nimport {UNTITLED} from '../lib/documentTitle'\nimport {PROJECT_DETAIL_QUERY, type ProjectDetail, type ProjectItemRef} from './data'\nimport {StatusBadge, statusLabel} from './StatusBadge'\nimport {ItemProgress, languageTitle} from './ItemProgress'\nimport {LogPanel} from './LogPanel'\nimport {type DocProgress} from '../progress/core'\nimport {parseFunctionLog, type LogLine} from '../lib/log'\nimport type {SmartcatLanguage, TranslationProjectStatus} from '../types'\n\ninterface ProjectViewProps {\n projectId: string\n onBack: () => void\n languages: SmartcatLanguage[]\n sourceLanguage: string\n /** Configured translatable types (undefined = all), shown in the export log. */\n translatableTypes?: string[]\n /** document-internationalization `languageField` (document locale field name). */\n documentI18nLanguageField: string\n /** internationalized-array locale key: field name (`'language'`) or `'_key'`. */\n fieldI18nLanguageField: string\n}\n\n/**\n * Shows how a language maps to Smartcat: `(fr)` when the codes match, or\n * `(PL-PL → pl)` when the Sanity id differs from the Smartcat code.\n */\nfunction languageMappingLabel(language: SmartcatLanguage): string {\n const code = language.smartcatLanguage || language.id\n return code === language.id ? language.id : `${language.id} → ${code}`\n}\n\n/**\n * Resolve an item's title the way the Studio does — by running the schema type's\n * `preview.prepare` — so types without a literal `title` field (e.g. field-level\n * localized docs) show the same label as in the structure tree, not 'Untitled'.\n */\nfunction DocTitle({doc}: {doc: ProjectItemRef['doc']}) {\n const schema = useSchema()\n const schemaType = doc ? schema.get(doc._type) : undefined\n const preview = useValuePreview({\n enabled: Boolean(doc && schemaType),\n schemaType,\n value: doc ? {_id: doc._id, _type: doc._type} : undefined,\n })\n // String-only: never fall back to the raw projected value, which is an\n // internationalized-array object for field-level i18n types (renders as React #31).\n const title = typeof preview.value?.title === 'string' ? preview.value.title : undefined\n // Placeholder while the async preview resolves, so a real title isn't briefly mislabeled.\n return <>{title ?? (preview.isLoading ? '…' : UNTITLED)}</>\n}\n\n/**\n * Statuses during which a Function is actively running, so the project shouldn't\n * be re-sent until it settles. `translating`/`sent`/`completed` are resting\n * states (work is happening in Smartcat, or it's done) — re-syncing and importing\n * are allowed there, so they are deliberately excluded.\n */\nconst IN_FLIGHT: TranslationProjectStatus[] = ['queued', 'importing', 'downloaded']\n\n/**\n * Statuses during which importing is allowed: the Smartcat project exists and\n * we're not mid export/import. Import pulls only the targets that are 100%\n * complete, so it's useful any time translation is underway or finished.\n */\nconst CAN_IMPORT: TranslationProjectStatus[] = ['sent', 'translating', 'completed']\n\nconst rotate = keyframes`\n to { transform: rotate(360deg); }\n`\n/** SyncIcon that spins while a refresh is in flight (keeps the button label visible). */\nconst SpinningSyncIcon = styled(SyncIcon)<{$spinning?: boolean}>`\n ${({$spinning}) =>\n $spinning &&\n css`\n animation: ${rotate} 0.8s linear infinite;\n `}\n`\n\n/** \"Last update: x ago\" — relative time, with the absolute timestamp on hover. */\nfunction LastUpdate({date}: {date: string}) {\n const relative = useRelativeTime(date, {useTemporalPhrase: true})\n return (\n <Text size={1} muted title={new Date(date).toLocaleString()}>\n Last update: {relative}\n </Text>\n )\n}\n\n/** Opens the document in the Studio. */\nfunction OpenInStudioButton({id, type}: {id: string; type: string}) {\n const {onClick, href} = useIntentLink({intent: 'edit', params: {id, type}})\n return (\n <Button\n as=\"a\"\n href={href}\n onClick={onClick}\n mode=\"bleed\"\n icon={LaunchIcon}\n text=\"Open in Studio\"\n fontSize={0}\n padding={2}\n />\n )\n}\n\n/** Read-only, monospace, full-height code view for the LocJSON modal. */\nconst CodeArea = styled.textarea`\n width: 100%;\n height: 70vh;\n resize: none;\n border: none;\n outline: none;\n padding: 0;\n background: transparent;\n color: inherit;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 12px;\n line-height: 1.5;\n white-space: pre;\n tab-size: 2;\n`\n\n/**\n * Builds the LocJSON the export would produce for an item — same field selection\n * and serialize options as {@link prepareExport} — and shows it (pretty-printed)\n * in a read-only modal, for inspecting exactly what gets sent to Smartcat.\n */\nfunction ViewLocjsonButton(props: {\n docId: string\n type: string\n /** Whether the export will translate the published doc (else prefer the draft). */\n sourceIsPublished: boolean | null\n client: {fetch: (query: string, params?: Record<string, unknown>) => Promise<unknown>}\n schema: {get: (typeName: string) => unknown}\n sourceLanguage: string\n documentI18nLanguageField: string\n fieldI18nLanguageField: string\n}) {\n const {docId, type, sourceIsPublished, client, schema, sourceLanguage, documentI18nLanguageField, fieldI18nLanguageField} = props\n const [open, setOpen] = useState(false)\n const [content, setContent] = useState<string | null>(null)\n const [filename, setFilename] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const build = useCallback(async () => {\n setOpen(true)\n setContent(null)\n setFilename(null)\n setError(null)\n try {\n // Resolve the same version the export will send: the draft (fallback to\n // published) unless the item was added from the published perspective.\n const raw = (await client.fetch(\n sourceIsPublished\n ? '*[_id == $id][0]'\n : 'coalesce(*[_id == \"drafts.\" + $id][0], *[_id == $id][0])',\n {id: docId},\n )) as (Record<string, unknown> & {_id: string}) | null\n if (!raw) throw new Error(`Document not found: ${docId}`)\n const isDraft = typeof raw._id === 'string' && raw._id.startsWith('drafts.')\n // Serialize under the canonical (bare) id, matching the export.\n const doc = isDraft ? {...raw, _id: docId} : raw\n const fields = getTranslatableFields(schema.get(type), {exclude: [documentI18nLanguageField]})\n const locjson = serializeToLocjson(doc as never, fields, {\n sourceLanguage,\n fieldLanguageKey: fieldI18nLanguageField,\n })\n // Same name the export sends to Smartcat; the last path segment is the\n // file's basename (the Smartcat \"folder/\" prefix can't be a local filename).\n const smartcatName = buildLocjsonFilename(type, docId, resolveDocumentTitle(schema, doc as never), {draft: isDraft})\n setFilename(smartcatName.split('/').pop() || smartcatName)\n setContent(JSON.stringify(locjson, null, 2))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }, [client, schema, docId, type, sourceIsPublished, sourceLanguage, documentI18nLanguageField, fieldI18nLanguageField])\n\n const download = useCallback(() => {\n if (content == null || !filename) return\n const url = URL.createObjectURL(new Blob([content], {type: 'application/json'}))\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = filename\n anchor.click()\n URL.revokeObjectURL(url)\n }, [content, filename])\n\n return (\n <>\n <Button\n mode=\"bleed\"\n icon={JsonIcon}\n title=\"View LocJSON\"\n fontSize={0}\n padding={2}\n onClick={build}\n />\n {open && (\n <Dialog\n id={`locjson-${docId}`}\n header={\n <Flex align=\"center\" gap={3}>\n <Text weight=\"semibold\">LocJSON · {type}</Text>\n <Button\n icon={DownloadIcon}\n text=\"Download\"\n mode=\"ghost\"\n fontSize={1}\n padding={2}\n disabled={content == null}\n onClick={download}\n />\n </Flex>\n }\n onClose={() => setOpen(false)}\n width={3}\n >\n <Box padding={4}>\n {error ? (\n <Text size={1} muted>\n {error}\n </Text>\n ) : content === null ? (\n <Flex align=\"center\" justify=\"center\" padding={5}>\n <Spinner muted />\n </Flex>\n ) : (\n <CodeArea\n readOnly\n spellCheck={false}\n value={content}\n onFocus={(e) => e.currentTarget.select()}\n />\n )}\n </Box>\n </Dialog>\n )}\n </>\n )\n}\n\nexport function ProjectView({\n projectId,\n onBack,\n languages,\n sourceLanguage,\n translatableTypes,\n documentI18nLanguageField,\n fieldI18nLanguageField,\n}: ProjectViewProps) {\n const client = useClient({apiVersion: API_VERSION})\n const schema = useSchema()\n const toast = useToast()\n const [project, setProject] = useState<ProjectDetail | null | undefined>(undefined)\n const [name, setName] = useState('')\n const [busy, setBusy] = useState(false)\n const [sending, setSending] = useState(false)\n const [importing, setImporting] = useState(false)\n const [cancelling, setCancelling] = useState(false)\n const [refreshing, setRefreshing] = useState(false)\n const [targets, setTargets] = useState<string[]>([])\n const [confirmDelete, setConfirmDelete] = useState(false)\n // Local-only: which items the editor has marked for deletion. Reset on reload;\n // committed to Smartcat + the project only when the user re-syncs.\n const [markedForDeletion, setMarkedForDeletion] = useState<Set<string>>(new Set())\n // Session-only live trace of the current export/import run (never persisted).\n const [logs, setLogs] = useState<LogLine[]>([])\n // Controlled so a partial-failure export can auto-expand the panel.\n const [logExpanded, setLogExpanded] = useState(false)\n const appendLog = useCallback((line: LogLine) => setLogs((prev) => [...prev, line]), [])\n // Merge a Function's server-side log (from the project doc) as an indented\n // group under a header, mirroring how per-document client lines are grouped.\n const appendServerLog = useCallback(\n (raw: string | null | undefined, header: string) => {\n const lines = parseFunctionLog(raw)\n // Our Functions always emit ≥1 line by this point, so an empty log here\n // means an outdated Function is deployed — surface that instead of nothing.\n setLogs((prev) =>\n lines.length === 0\n ? [...prev, {level: 'info', message: `${header}: no server log returned — deploy the latest Functions to see server-side steps`}]\n : [...prev, {level: 'info', message: header}, ...lines.map((l) => ({...l, indent: true}))],\n )\n },\n [],\n )\n const seeded = useRef(false)\n\n const toggleMark = useCallback((key: string) => {\n setMarkedForDeletion((prev) => {\n const next = new Set(prev)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const load = useCallback(() => {\n return client\n .fetch<ProjectDetail | null>(PROJECT_DETAIL_QUERY, {id: projectId})\n .then((res) => {\n setProject(res)\n if (res) setName(res.name)\n // Seed the target-language selection once, so live updates don't clobber edits.\n if (res && !seeded.current) {\n setTargets(res.targetLanguages ?? [])\n seeded.current = true\n }\n })\n .catch((err) => toast.push({status: 'error', title: 'Failed to load project', description: String(err)}))\n }, [client, projectId, toast])\n\n useEffect(() => {\n load()\n const sub = client\n .listen(PROJECT_DETAIL_QUERY, {id: projectId}, {visibility: 'query'})\n .subscribe({next: () => load(), error: () => {}})\n return () => sub.unsubscribe()\n }, [client, projectId, load])\n\n // When the import Function has downloaded translations (status \"downloaded\"),\n // process them here in the browser: build locale variants + metadata links.\n const processingDownload = useRef(false)\n useEffect(() => {\n // Each import cycle starts at \"importing\"; clear the guard there so the next\n // \"downloaded\" is processed (otherwise a second import in the same session is\n // blocked, leaving the project stuck at \"downloaded\").\n if (project?.status === 'importing') processingDownload.current = false\n if (project?.status !== 'downloaded' || processingDownload.current) return\n processingDownload.current = true\n // Targets the download Function deferred (size/time caps); after applying\n // this batch we auto-continue the import so nobody has to click through.\n const remaining = project.importRemaining ?? 0\n appendLog({level: 'info', message: 'Translations downloaded — applying to documents'})\n // The import Function's download log lands on the doc; show it before the\n // browser-side apply log so the import reads top-to-bottom.\n appendServerLog(project.functionLog, 'Import function')\n applyImportedTranslations({\n client,\n schema,\n projectId,\n documentLanguageField: documentI18nLanguageField,\n fieldLanguageKey: fieldI18nLanguageField,\n onLog: appendLog,\n })\n .then(async ({imported, status}) => {\n // Auto-continue only while each cycle makes progress — a cycle that\n // applied nothing would defer the same targets forever, so it stops\n // and leaves the button to the user.\n if (remaining > 0 && imported > 0) {\n appendLog({level: 'success', message: `Imported ${imported} localized version(s)`})\n appendLog({level: 'info', message: `${remaining} target(s) still on Smartcat — continuing import automatically`})\n processingDownload.current = false\n await client.patch(projectId).set({status: 'importing', lastError: null}).commit()\n return\n }\n const description =\n status === 'completed'\n ? 'All targets are fully translated — project completed.'\n : 'Some targets are still translating — import again later to pull the rest.'\n appendLog({level: 'success', message: `Imported ${imported} localized version(s)`})\n appendLog({level: status === 'completed' ? 'success' : 'info', message: description})\n toast.push({status: 'success', title: `Imported ${imported} localized version(s)`, description})\n })\n .catch((err) => {\n // Leave the guard set so we don't auto-retry in a loop (status stays\n // \"downloaded\"); a fresh import (status \"importing\") clears it to retry.\n appendLog({level: 'error', message: `Failed to apply translations: ${String(err)}`})\n toast.push({status: 'error', title: 'Failed to apply translations', description: String(err)})\n })\n }, [project?.status, client, schema, projectId, toast, documentI18nLanguageField, fieldI18nLanguageField, appendLog, appendServerLog])\n\n // After handing the outbox to the export Function, log its response (observed\n // via listen()): status flips to \"sent\" (+ project URL) on success, or \"error\"\n // (+ lastError) on failure. Guarded by a ref so it only fires for a send we\n // started this session, not on initial load of an already-sent project.\n const exportInFlight = useRef(false)\n useEffect(() => {\n if (!exportInFlight.current) return\n if (project?.status === 'sent') {\n appendServerLog(project.functionLog, 'Export function')\n appendLog({level: 'success', message: 'Sent to Smartcat'})\n if (project.smartcatProjectUrl) appendLog({level: 'info', message: `Smartcat project: ${project.smartcatProjectUrl}`})\n // Partial failure: the sync completed (status \"sent\") but some documents\n // failed to upload/update. Flag it and open the log so the errors are seen.\n if (parseFunctionLog(project.functionLog).some((l) => l.level === 'error')) {\n toast.push({status: 'warning', title: 'There were errors sending content into Smartcat — check the log'})\n setLogExpanded(true)\n }\n exportInFlight.current = false\n } else if (project?.status === 'error') {\n appendServerLog(project.functionLog, 'Export function')\n appendLog({level: 'error', message: `Export failed: ${project.lastError ?? 'unknown error'}`})\n exportInFlight.current = false\n }\n }, [project?.status, project?.smartcatProjectUrl, project?.lastError, project?.functionLog, appendLog, appendServerLog, toast])\n\n // Refresh per-document progress from Smartcat. The browser only bumps the\n // `progressRequestedAt` trigger; the smartcat-progress Function reacts (it\n // holds the API key), fetches the Smartcat project, and writes the stage\n // percentages back — which `listen()` above re-renders.\n const requestProgress = useCallback(() => {\n return client.patch(projectId).set({progressRequestedAt: new Date().toISOString()}).commit()\n }, [client, projectId])\n\n // Track the latest synced timestamp in a ref so a refresh can detect when\n // fresh progress has actually arrived. We can't tie the spinner to the patch\n // commit: on a warm client it resolves in a few ms (before paint), so the\n // spinner was only visible after a cold hard-reload.\n const syncedAtRef = useRef<string | null | undefined>(undefined)\n useEffect(() => {\n syncedAtRef.current = project?.progressSyncedAt\n }, [project?.progressSyncedAt])\n\n const refreshBaseline = useRef<string | null | undefined>(undefined)\n const refreshTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(\n () => () => {\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n },\n [],\n )\n\n const handleRefreshProgress = useCallback(async () => {\n // Spin until the progress Function writes a new progressSyncedAt (cleared by\n // the effect below), with a safety timeout in case nothing comes back.\n refreshBaseline.current = syncedAtRef.current\n setRefreshing(true)\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n refreshTimeout.current = setTimeout(() => setRefreshing(false), 30000)\n try {\n await requestProgress()\n } catch (err) {\n setRefreshing(false)\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n toast.push({status: 'error', title: 'Failed to refresh progress', description: String(err)})\n }\n }, [requestProgress, toast])\n\n // Stop spinning once fresh progress has landed (progressSyncedAt changed).\n useEffect(() => {\n if (!refreshing) return\n if (project?.progressSyncedAt !== refreshBaseline.current) {\n setRefreshing(false)\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n // The progress Function stamps progressSyncedAt on failure too (and sets\n // lastError). When it did, surface its log so a timeout/error is visible\n // instead of the refresh just quietly not updating.\n if (project?.lastError) {\n appendServerLog(project.functionLog, 'Progress function')\n appendLog({level: 'error', message: `Progress refresh failed: ${project.lastError}`})\n toast.push({status: 'error', title: 'Failed to refresh progress', description: project.lastError})\n setLogExpanded(true)\n }\n }\n }, [project?.progressSyncedAt, project?.lastError, project?.functionLog, refreshing, appendServerLog, appendLog, toast])\n\n // Auto-refresh once on page load, as soon as a Smartcat project exists. Runs\n // the same handler as the button, so the loading state matches.\n const progressRequested = useRef(false)\n useEffect(() => {\n if (progressRequested.current || !project?.smartcatProjectId) return\n progressRequested.current = true\n handleRefreshProgress()\n }, [project?.smartcatProjectId, handleRefreshProgress])\n\n const handleRename = useCallback(async () => {\n const trimmed = name.trim()\n if (!trimmed || trimmed === project?.name) return\n setBusy(true)\n try {\n await client.patch(projectId).set({name: trimmed}).commit()\n toast.push({status: 'success', title: 'Renamed project'})\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to rename', description: String(err)})\n } finally {\n setBusy(false)\n }\n }, [name, project, client, projectId, toast])\n\n const handleDelete = useCallback(async () => {\n setBusy(true)\n try {\n await client.delete(projectId)\n toast.push({status: 'success', title: 'Deleted project'})\n onBack()\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to delete', description: String(err)})\n setBusy(false)\n }\n }, [client, projectId, toast, onBack])\n\n const toggleTarget = useCallback((id: string) => {\n setTargets((prev) => (prev.includes(id) ? prev.filter((t) => t !== id) : [...prev, id]))\n }, [])\n\n const handleImport = useCallback(async () => {\n setImporting(true)\n try {\n // Clear the download-processing guard up front (race-free), so this import's\n // \"downloaded\" state is processed even if we never observe the \"importing\"\n // transition via listen().\n processingDownload.current = false\n await client.patch(projectId).set({status: 'importing', lastError: null}).commit()\n // Clear here (not when the download lands) so these lines lead the import log.\n setLogs([])\n appendLog({level: 'info', message: 'Importing from Smartcat'})\n appendLog({level: 'info', message: 'The import function will download translations and create localized versions.'})\n toast.push({\n status: 'success',\n title: 'Importing from Smartcat',\n description: 'The import function will download translations and create localized versions.',\n })\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to start import', description: String(err)})\n } finally {\n setImporting(false)\n }\n }, [client, projectId, toast, appendLog])\n\n const handleCancel = useCallback(async () => {\n setCancelling(true)\n try {\n // Reset to draft so the project can be edited and re-sent. This is a local\n // undo — it does not delete an already-created Smartcat project.\n await client.patch(projectId).set({status: 'draft'}).commit()\n toast.push({status: 'success', title: 'Cancelled — project reset to draft'})\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to cancel', description: String(err)})\n } finally {\n setCancelling(false)\n }\n }, [client, projectId, toast])\n\n const handleSend = useCallback(async () => {\n if (targets.length === 0) {\n toast.push({status: 'warning', title: 'Select at least one target language'})\n return\n }\n setSending(true)\n setLogs([])\n try {\n // Translate marked items into deletion instructions for the export Function:\n // pair each with one of its Smartcat document ids (one id deletes the whole doc).\n const deletions: PendingDeletion[] = []\n for (const item of project?.items ?? []) {\n if (!markedForDeletion.has(item._key) || !item.doc?._id) continue\n const dp = (project?.progress ?? []).find((p) => p.sourceDocId === item.doc!._id)\n // Any one target id deletes the whole document, so pick the first target\n // that actually has one (matches the `isLinked` check in the item list —\n // targets[0] may not be the one carrying the id).\n const smartcatDocumentId = dp?.targets?.find((t) => t.smartcatDocumentId)?.smartcatDocumentId\n deletions.push({\n itemKey: item._key,\n sourceDocId: item.doc._id,\n smartcatDocumentId,\n })\n }\n\n // Serialize content to LocJSON here in the Studio (real schema + DOM),\n // then queue it; the thin export Function uploads, updates and deletes.\n const {prepared, deleting} = await prepareExport({\n client,\n schema,\n projectId,\n targetLanguages: targets,\n sourceLanguage,\n languages,\n translatableTypes,\n exclude: [documentI18nLanguageField],\n fieldLanguageKey: fieldI18nLanguageField,\n deletions,\n onLog: appendLog,\n })\n setMarkedForDeletion(new Set())\n // Hand-off: the outbox is queued; the export Function now uploads it. Arm\n // the response watcher so its result (\"sent\"/\"error\") lands in the log.\n exportInFlight.current = true\n appendLog({level: 'info', message: 'Uploading to Smartcat via the export function…'})\n toast.push({\n status: 'success',\n title: 'Queued for Smartcat',\n description:\n `Prepared ${prepared} file(s)` +\n (deleting ? ` and ${deleting} for deletion` : '') +\n '; the export function will sync them.',\n })\n } catch (err) {\n appendLog({level: 'error', message: `Failed to queue: ${String(err)}`})\n toast.push({status: 'error', title: 'Failed to queue', description: String(err)})\n } finally {\n setSending(false)\n }\n }, [targets, client, projectId, toast, schema, sourceLanguage, languages, documentI18nLanguageField, fieldI18nLanguageField, project, markedForDeletion, appendLog])\n\n const handleRemoveItem = useCallback(\n async (item: ProjectItemRef) => {\n try {\n await client.patch(projectId).unset([`items[_key==\"${item._key}\"]`]).commit()\n toast.push({status: 'success', title: 'Removed item'})\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to remove item', description: String(err)})\n }\n },\n [client, projectId, toast],\n )\n\n if (project === undefined) {\n return (\n <Flex align=\"center\" justify=\"center\" padding={5}>\n <Spinner muted />\n </Flex>\n )\n }\n\n if (project === null) {\n return (\n <Stack space={4}>\n <Button icon={ArrowLeftIcon} text=\"Back\" mode=\"bleed\" onClick={onBack} />\n <Card padding={5} radius={2} tone=\"critical\" border>\n <Text>This project no longer exists.</Text>\n </Card>\n </Stack>\n )\n }\n\n const items = project.items ?? []\n const nameChanged = name.trim() !== project.name && name.trim().length > 0\n // Smartcat doesn't allow non-destructive target-language changes after a project\n // exists, so lock the picker once the project has been sent.\n const languagesLocked = Boolean(project.smartcatProjectId)\n\n const progress = project.progress ?? []\n const progressByDoc = new Map<string, DocProgress>()\n for (const p of progress) {\n if (p.sourceDocId) progressByDoc.set(p.sourceDocId, p)\n }\n const markedCount = items.filter((i) => markedForDeletion.has(i._key)).length\n\n // Localization mode is per-type; compute once per distinct type for the labels.\n const modeByType = new Map<string, LocalizationMode>()\n for (const item of items) {\n const t = item.doc?._type\n if (t && !modeByType.has(t)) modeByType.set(t, localizationMode(schema.get(t)))\n }\n\n return (\n <Stack space={5}>\n <Flex align=\"center\" gap={2}>\n <Button icon={ArrowLeftIcon} text=\"Projects\" mode=\"bleed\" onClick={onBack} />\n <Box flex={1} />\n <StatusBadge status={project.status} />\n <Button\n icon={TrashIcon}\n title=\"Delete project…\"\n tone=\"critical\"\n mode=\"bleed\"\n fontSize={1}\n padding={2}\n onClick={() => setConfirmDelete(true)}\n disabled={busy}\n />\n </Flex>\n\n <Card padding={4} radius={2} shadow={1}>\n <Stack space={4}>\n <Flex gap={2} align=\"flex-end\">\n <Box flex={1}>\n <Stack space={2}>\n <Text size={1} weight=\"semibold\" muted>\n Project name\n </Text>\n <TextInput\n value={name}\n onChange={(e) => setName(e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleRename()\n }}\n disabled={busy}\n />\n </Stack>\n </Box>\n <Button text=\"Save\" onClick={handleRename} disabled={!nameChanged || busy} loading={busy} />\n </Flex>\n\n <Text size={1} muted>\n Source: <strong>{languageTitle(languages, project.sourceLanguage || sourceLanguage)}</strong>\n </Text>\n\n <Stack space={2}>\n <Text size={1} muted>\n Target languages\n </Text>\n <Flex gap={6} align=\"center\">\n <Stack space={3} padding={3}>\n {languages\n .filter((l) => l.id !== (project.sourceLanguage || sourceLanguage))\n .map((l) => {\n const selected = targets.includes(l.id)\n const disabled = sending || languagesLocked\n return (\n <Flex key={l.id} align=\"center\" gap={2} as=\"label\" style={{cursor: disabled ? 'default' : 'pointer'}}>\n <Checkbox\n checked={selected}\n disabled={disabled}\n onChange={() => toggleTarget(l.id)}\n />\n <Text size={1}>\n {l.title}\n <span\n title={`Sanity language code: '${l.id}'\\nSmartcat language code: '${l.smartcatLanguage || l.id}'`}\n style={{color: 'var(--card-muted-fg-color)', opacity: 0.6, marginLeft: '1em'}}\n >\n {languageMappingLabel(l)}\n </span>\n </Text>\n </Flex>\n )\n })}\n </Stack>\n {project.smartcatProjectUrl ? (\n <Box flex={1} style={{maxWidth: 500}}>\n <Stack space={4}>\n <Text size={1} muted>\n Smartcat project:{' '}\n <a\n href={project.smartcatProjectUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Open project in Smartcat\"\n >\n {project.name}\n </a>\n </Text>\n {languagesLocked && (\n <Text size={1} muted>\n Target languages are locked once the project has been sent to Smartcat.\n </Text>\n )}\n </Stack>\n </Box>\n ) : (\n targets.length === 0 && (\n <Box flex={1} style={{maxWidth: 500}}>\n <Text size={1} muted>\n Select one or more languages to translate your content into before you can\n send it to Smartcat for translation.\n </Text>\n </Box>\n )\n )}\n </Flex>\n </Stack>\n </Stack>\n </Card>\n\n {project.lastError && (\n <Card padding={3} radius={2} tone=\"critical\" border>\n <Text size={1}>{project.lastError}</Text>\n </Card>\n )}\n\n <Flex align=\"center\" gap={3} wrap=\"wrap\">\n <Button\n icon={PublishIcon}\n text=\"Send to Smartcat\"\n // Primary only when it's actually actionable (unsent, with items to\n // send); otherwise it's a secondary action (ghost, like Import) and\n // \"Import translations\" becomes primary.\n mode={!languagesLocked && items.length > 0 ? undefined : 'ghost'}\n tone={!languagesLocked && items.length > 0 ? 'primary' : undefined}\n onClick={handleSend}\n loading={sending}\n disabled={sending || items.length === 0 || targets.length === 0 || IN_FLIGHT.includes(project.status)}\n />\n <Button\n icon={DownloadIcon}\n text=\"Import translations\"\n mode={languagesLocked ? undefined : 'ghost'}\n tone={languagesLocked ? 'primary' : undefined}\n onClick={handleImport}\n loading={importing}\n disabled={importing || !project.smartcatProjectId || !CAN_IMPORT.includes(project.status)}\n />\n {project.smartcatProjectId && (\n <Button\n icon={<SpinningSyncIcon $spinning={refreshing} />}\n text=\"Refresh progress\"\n mode=\"bleed\"\n onClick={handleRefreshProgress}\n disabled={refreshing}\n />\n )}\n {project.progressSyncedAt && <LastUpdate date={project.progressSyncedAt} />}\n {markedCount > 0 && (\n <Text size={1} muted>\n {markedCount} marked for deletion — applied on re-sync\n </Text>\n )}\n {IN_FLIGHT.includes(project.status) && (\n <Inline space={2}>\n <Text size={1} muted>\n Project is <strong>{statusLabel(project.status)}</strong> — wait for it to finish before re-sending.\n </Text>\n <Button\n icon={CloseIcon}\n text=\"Cancel\"\n mode=\"bleed\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n onClick={handleCancel}\n loading={cancelling}\n disabled={cancelling}\n />\n </Inline>\n )}\n </Flex>\n\n <LogPanel logs={logs} expanded={logExpanded} onExpandedChange={setLogExpanded} />\n\n <Stack space={3}>\n <Flex align=\"center\" gap={2}>\n <Heading size={1}>\n {items.length} {items.length === 1 ? 'Item' : 'Items'}\n </Heading>\n </Flex>\n\n {items.length > 0 && (\n <Stack space={2}>\n {items.map((item) => {\n const docProgress = item.doc ? progressByDoc.get(item.doc._id) : undefined\n // Linked = the item already has document(s) in Smartcat.\n const isLinked = Boolean(docProgress?.targets?.some((t) => t.smartcatDocumentId))\n const isMarked = markedForDeletion.has(item._key)\n return (\n <Card\n key={item._key}\n padding={3}\n radius={2}\n shadow={1}\n tone={isMarked ? 'critical' : undefined}\n >\n <Stack space={3}>\n <Flex align=\"center\" gap={3}>\n <Flex align=\"center\" gap={2}>\n <Badge\n tone={item.sourceIsPublished ? 'positive' : 'caution'}\n paddingX={2}\n title={\n item.sourceIsPublished\n ? 'The published version is the translation source'\n : 'The draft version is the translation source'\n }\n >\n {item.sourceIsPublished ? 'Published' : 'Draft'}\n </Badge>\n <Text weight=\"medium\">\n <span style={isMarked ? {textDecoration: 'line-through'} : undefined}>\n <DocTitle doc={item.doc} />\n </span>\n </Text>\n {item.doc?._type && <Badge tone=\"primary\" paddingX={2}>{item.doc._type}</Badge>}\n {item.doc?._type && modeByType.has(item.doc._type) && (\n <Badge\n tone=\"default\"\n fontSize={0}\n paddingX={2}\n title={\n modeByType.get(item.doc._type) === 'field'\n ? 'This item is translated in field mode; translations will be stored as language variants of each field'\n : 'This item is translated in document mode; translations will be stored as linked documents'\n }\n >\n {modeByType.get(item.doc._type) === 'field' ? 'fields' : 'document'}\n </Badge>\n )}\n {item.doc && <OpenInStudioButton id={item.doc._id} type={item.doc._type} />}\n {item.doc && (\n <ViewLocjsonButton\n docId={item.doc._id}\n type={item.doc._type}\n sourceIsPublished={item.sourceIsPublished}\n client={client}\n schema={schema}\n sourceLanguage={sourceLanguage}\n documentI18nLanguageField={documentI18nLanguageField}\n fieldI18nLanguageField={fieldI18nLanguageField}\n />\n )}\n </Flex>\n <Box flex={1} />\n {isLinked ? (\n <Button\n mode={isMarked ? 'default' : 'bleed'}\n tone=\"critical\"\n icon={RemoveCircleIcon}\n title={isMarked ? 'Unmark for deletion' : 'Mark for deletion'}\n padding={2}\n onClick={() => toggleMark(item._key)}\n />\n ) : (\n <Button\n mode=\"bleed\"\n tone=\"critical\"\n icon={TrashIcon}\n title=\"Remove from project\"\n onClick={() => handleRemoveItem(item)}\n />\n )}\n </Flex>\n {docProgress && (\n <ItemProgress\n doc={docProgress}\n languages={languages}\n smartcatProjectUrl={project.smartcatProjectUrl}\n variants={\n item.doc\n ? {\n type: item.doc._type,\n byLanguage: Object.fromEntries(\n (item.translations ?? []).map((t) => [t.language, t.id]),\n ),\n }\n : undefined\n }\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n )}\n\n <Card padding={4} radius={2} tone=\"transparent\" border>\n <Text muted align=\"center\" size={1}>\n Add content from a document’s “⋯ → Add to translation project” menu.\n </Text>\n </Card>\n </Stack>\n\n {confirmDelete && (\n <Dialog\n id=\"confirm-delete\"\n header=\"Delete translation project?\"\n onClose={() => setConfirmDelete(false)}\n width={1}\n >\n <Box padding={4}>\n <Stack space={4}>\n <Text>\n Delete <strong>{project.name}</strong>? This removes the project only — the referenced\n content documents are not deleted.\n {project.smartcatProjectId && ' The Smartcat project is not deleted either and will remain in your Smartcat workspace.'}\n </Text>\n <Flex justify=\"flex-end\" gap={2}>\n <Button mode=\"bleed\" text=\"Cancel\" onClick={() => setConfirmDelete(false)} disabled={busy} />\n <Button tone=\"critical\" text=\"Delete\" icon={TrashIcon} onClick={handleDelete} loading={busy} />\n </Flex>\n </Stack>\n </Box>\n </Dialog>\n )}\n </Stack>\n )\n}\n","import {useCallback} from 'react'\nimport {useRouter, useRouterState} from 'sanity/router'\nimport {Box, Container} from '@sanity/ui'\nimport {ProjectsView} from './ProjectsView'\nimport {ProjectView} from './ProjectView'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\n/**\n * Builds the dashboard component for the Translations tool.\n * Uses the tool router to switch between the projects list and a project detail\n * view, so the selected project is reflected in the URL (deep-linkable).\n */\nexport function createDashboardComponent(config: ResolvedSmartcatConfig) {\n const {sourceLanguage, languages, translatableTypes, documentI18nLanguageField, fieldI18nLanguageField} =\n config\n\n return function Dashboard() {\n const router = useRouter()\n const projectId = useRouterState(\n useCallback((state) => (state.projectId as string | undefined) ?? null, []),\n )\n\n const openProject = useCallback((id: string) => router.navigate({projectId: id}), [router])\n const goBack = useCallback(() => router.navigate({}), [router])\n\n return (\n <Box padding={4} height=\"fill\" overflow=\"auto\">\n <Container width={2}>\n {projectId ? (\n <ProjectView\n projectId={projectId}\n onBack={goBack}\n languages={languages}\n sourceLanguage={sourceLanguage}\n translatableTypes={translatableTypes}\n documentI18nLanguageField={documentI18nLanguageField}\n fieldI18nLanguageField={fieldI18nLanguageField}\n />\n ) : (\n <ProjectsView sourceLanguage={sourceLanguage} onOpenProject={openProject} />\n )}\n </Container>\n </Box>\n )\n }\n}\n","import {route} from 'sanity/router'\nimport {TranslateIcon} from '@sanity/icons'\nimport type {Tool} from 'sanity'\nimport {createDashboardComponent} from './Dashboard'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\n/** Tool name; also the URL segment used to deep-link into the tool. */\nexport const TRANSLATION_TOOL_NAME = 'translation-projects'\n\n/** Builds the \"Translations\" Studio tool (top-nav dashboard). */\nexport function createTranslationsTool(config: ResolvedSmartcatConfig): Tool {\n return {\n name: TRANSLATION_TOOL_NAME,\n title: 'Translation Projects',\n icon: TranslateIcon,\n component: createDashboardComponent(config),\n router: route.create('/', [route.create('/project/:projectId')]),\n }\n}\n","import {Fragment, useCallback, useEffect, useState, type MouseEvent} from 'react'\nimport {useClient, useFormValue, useWorkspace, type InputProps} from 'sanity'\nimport {Card, Stack, Text, type CardTone} from '@sanity/ui'\nimport {useRouter} from 'sanity/router'\nimport {API_VERSION, TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {ITEM_ID} from '../lib/projectItems'\nimport {localizationMode} from '../lib/locjson/fields'\nimport {TRANSLATION_TOOL_NAME} from '../tool'\nimport type {LocalizationMode} from '../lib/locjson/types'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\ninterface ProjectRef {\n _id: string\n name?: string\n /** True when this document is itself in the project's items (the source it was\n * added as); false when it matched via a sibling variant (a translation target). */\n isSource: boolean\n /** True when the project actually targets this document's language — i.e. this\n * variant is a real translation target of it, not just a sibling of its source. */\n targetsThisLanguage: boolean\n}\n\n// Match projects whose items reference this document OR one of its sibling\n// language variants — so the banner shows on both the source and its translated\n// (document-level i18n) variants. The sibling ids come from the\n// translation.metadata group that references this document. Per project we also\n// record which role this document plays: `isSource` (the doc is itself an item)\n// and `targetsThisLanguage` (the project targets this doc's language, so this\n// variant is a genuine target — a project that references the source but doesn't\n// target this language is not). The same document can be a source in one project\n// and a target in another (e.g. pivot-language translation).\nconst QUERY = `*[_type == \"${TRANSLATION_PROJECT_TYPE}\" && count(items[\n ${ITEM_ID} in [$id] + *[_type == \"translation.metadata\" && references($id)].translations[].value._ref\n]) > 0] | order(_updatedAt desc){\n _id,\n name,\n \"isSource\": count(items[${ITEM_ID} == $id]) > 0,\n \"targetsThisLanguage\": $language in targetLanguages\n}`\n\n/** A link to a project's page in the Translations tool, with SPA navigation. */\nfunction ProjectLink({basePath, project}: {basePath: string; project: ProjectRef}) {\n const router = useRouter()\n // basePath is \"/\" by default or a configured prefix; join without doubling slashes.\n const href = `${basePath.replace(/\\/$/, '')}/${TRANSLATION_TOOL_NAME}/project/${project._id}`\n const onClick = useCallback(\n (e: MouseEvent) => {\n // Let modifier-clicks (new tab/window) use the href; otherwise navigate in-app.\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return\n e.preventDefault()\n router.navigateUrl({path: href})\n },\n [router, href],\n )\n return (\n <a href={href} onClick={onClick}>\n {project.name || 'Untitled project'}\n </a>\n )\n}\n\n/** A self-contained card listing same-role projects. `lead` is the full text before the links. */\nfunction RoleCard({\n lead,\n tone = 'primary',\n warning,\n basePath,\n projects,\n}: {\n lead: string\n tone?: CardTone\n warning?: string\n basePath: string\n projects: ProjectRef[]\n}) {\n return (\n <Card tone={tone} padding={3} radius={2} border>\n <Stack space={3}>\n <Text size={1}>\n {lead}\n {projects.map((p, i) => (\n <Fragment key={p._id}>\n {i > 0 && ', '}\n <ProjectLink basePath={basePath} project={p} />\n </Fragment>\n ))}\n </Text>\n {warning && (\n <Text size={1} weight=\"semibold\">\n {warning}\n </Text>\n )}\n </Stack>\n </Card>\n )\n}\n\n/**\n * Status banner naming the project(s) this document belongs to, each linking to\n * its page in the tool.\n *\n * For document-level localization a document can play both roles across projects\n * (source in one, target in another), so source and variant memberships get\n * their own lines. For field-level localization the single document holds every\n * language, so there is no source/variant distinction — it's just \"this document\".\n */\nfunction TranslationStatusLine({mode}: {mode: LocalizationMode}) {\n const client = useClient({apiVersion: API_VERSION})\n const {basePath} = useWorkspace()\n const docId = (useFormValue(['_id']) as string | undefined)?.replace(/^drafts\\./, '')\n const language = (useFormValue(['language']) as string | undefined) ?? null\n const [projects, setProjects] = useState<ProjectRef[]>([])\n\n useEffect(() => {\n if (!docId) return undefined\n let cancelled = false\n const params = {id: docId, language}\n const load = () =>\n client\n .fetch<ProjectRef[]>(QUERY, params)\n .then((res) => !cancelled && setProjects(res))\n .catch(() => !cancelled && setProjects([]))\n load()\n const sub = client.listen(QUERY, params, {visibility: 'query'}).subscribe({next: load, error: () => {}})\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [client, docId, language])\n\n if (projects.length === 0) return null\n\n // Field-level docs hold all languages in one document — neutral, single card.\n if (mode === 'field') {\n return (\n <Stack space={3}>\n <RoleCard\n lead={\n projects.length === 1\n ? 'This document is part of a translation project: '\n : 'This document is part of multiple translation projects: '\n }\n basePath={basePath}\n projects={projects}\n />\n </Stack>\n )\n }\n\n const asSource = projects.filter((p) => p.isSource)\n // A genuine target only if the project actually targets this variant's\n // language — a project that merely includes the source (but targets other\n // languages) doesn't translate into this variant, so it's not a collision.\n const asTarget = projects.filter((p) => !p.isSource && p.targetsThisLanguage)\n\n return (\n <Stack space={3}>\n {asSource.length > 0 && (\n <RoleCard\n lead={\n asSource.length === 1\n ? 'This source document is part of a translation project: '\n : 'This source document is part of multiple translation projects: '\n }\n basePath={basePath}\n projects={asSource}\n />\n )}\n {asTarget.length > 0 && (\n <RoleCard\n // A document being a translation target in more than one project means\n // multiple projects can write back to the same variant — flag it red.\n tone={asTarget.length > 1 ? 'critical' : 'primary'}\n lead={\n asTarget.length === 1\n ? 'This document variant is part of a translation project: '\n : 'This document variant is part of multiple translation projects: '\n }\n warning={\n asTarget.length > 1\n ? 'Importing translations from more than one project can overwrite each other on this document.'\n : undefined\n }\n basePath={basePath}\n projects={asTarget}\n />\n )}\n </Stack>\n )\n}\n\n/**\n * Wraps the document form for translatable types, rendering a status line above\n * the fields when the document belongs to one or more Smartcat translation\n * projects. Resolves live, so it updates as projects change.\n */\nexport function createTranslationStatusInput(config: ResolvedSmartcatConfig) {\n return function TranslationStatusInput(props: InputProps) {\n // Only the document root of a translatable type — not nested fields. This\n // input is registered globally, so the type check also keeps it off the\n // plugin's own `smartcat.*` documents.\n const isDocumentRoot = props.path.length === 0 && config.isTranslatableType(props.schemaType.name)\n if (!isDocumentRoot) return props.renderDefault(props)\n\n return (\n <Stack space={5}>\n <TranslationStatusLine mode={localizationMode(props.schemaType)} />\n {props.renderDefault(props)}\n </Stack>\n )\n }\n}\n","import {useEffect, useRef} from 'react'\nimport {useClient, type LayoutProps} from 'sanity'\nimport {API_VERSION, SETTINGS_DOC_ID, SETTINGS_TYPE} from '../lib/constants'\nimport {isRefreshInFlight} from './useTemplates'\n\ninterface SettingsDoc {\n templatesRequestedAt?: string\n templatesSyncedAt?: string\n}\n\nconst INIT_QUERY = `*[_id == $id][0]{templatesRequestedAt, templatesSyncedAt}`\n\n/**\n * Studio layout wrapper. On first load it bootstraps the template cache *only if\n * it has never been initialized* — i.e. no `templatesSyncedAt` and no request\n * already in flight. Routine freshness is handled by the create dialogs; this\n * just seeds an empty cache the very first time the Studio runs.\n */\nexport function StudioInit(props: LayoutProps) {\n const client = useClient({apiVersion: API_VERSION})\n const didRun = useRef(false)\n\n useEffect(() => {\n if (didRun.current) return\n didRun.current = true\n client\n .fetch<SettingsDoc | null>(INIT_QUERY, {id: SETTINGS_DOC_ID})\n .then((s) => {\n // Skip if already initialized, or a fresh request is still in flight.\n // A stale request (older than the window) falls through and re-bumps.\n if (s?.templatesSyncedAt || isRefreshInFlight(s)) return\n return client\n .transaction()\n .createIfNotExists({_id: SETTINGS_DOC_ID, _type: SETTINGS_TYPE})\n .patch(SETTINGS_DOC_ID, (p) => p.set({templatesRequestedAt: new Date().toISOString()}))\n .commit({visibility: 'async'})\n })\n .catch(() => {})\n }, [client])\n\n return props.renderDefault(props)\n}\n","import {requireSourceLanguage, SETTINGS_TYPE, TRANSLATION_PROJECT_TYPE} from './constants'\nimport type {SmartcatLanguage, SmartcatPluginConfig} from '../types'\n\n/** The plugin's own document types, never translatable regardless of config. */\nconst PLUGIN_TYPES = new Set([TRANSLATION_PROJECT_TYPE, SETTINGS_TYPE])\n\n/**\n * Plugin config with every optional field resolved to its default. This is the\n * single place plugin defaults are applied — notably the internationalized-array\n * locale key, whose default (`'language'`, plugin v5+) is the one version\n * assumption; downstream code receives a concrete value and never re-guesses.\n */\nexport interface ResolvedSmartcatConfig {\n /**\n * Whether a document type shows the \"Add to translation project\" UI. When\n * `translatableTypes` is omitted this is true for every type except the\n * plugin's own `smartcat.*` types; otherwise it's list membership.\n */\n isTranslatableType: (type: string) => boolean\n /**\n * The explicitly-configured translatable types, verbatim, for display/logging.\n * `undefined` means none was configured — every non-plugin type is translatable\n * (see {@link isTranslatableType}). Logic should use the predicate, not this.\n */\n translatableTypes?: string[]\n /** Root/standalone types where the linked-documents crawl stops. */\n rootTypes: string[]\n sourceLanguage: string\n languages: SmartcatLanguage[]\n /** document-internationalization locale field (its `languageField`). */\n documentI18nLanguageField: string\n /** internationalized-array member locale key (`'language'` v5+, `'_key'` v4.x). */\n fieldI18nLanguageField: string\n}\n\nexport function resolveConfig(config: SmartcatPluginConfig): ResolvedSmartcatConfig {\n const translatableTypes = config.translatableTypes\n const isTranslatableType = translatableTypes\n ? (type: string) => translatableTypes.includes(type)\n : (type: string) => !PLUGIN_TYPES.has(type)\n\n return {\n isTranslatableType,\n translatableTypes,\n // `rootTypes` inherits the *explicitly-configured* translatableTypes (not the\n // resolved \"everything\") so an unconfigured Studio gets no crawl boundary\n // rather than every type being a root (which would stop the crawl at once).\n rootTypes: config.rootTypes ?? translatableTypes ?? [],\n sourceLanguage: requireSourceLanguage(config.sourceLanguage),\n languages: config.languages ?? [],\n documentI18nLanguageField: config.documentI18nPluginLanguageField ?? 'language',\n fieldI18nLanguageField: config.fieldI18nPluginLanguageField ?? 'language',\n }\n}\n","import {definePlugin} from 'sanity'\nimport {createTranslationProjectType} from './schema/translationProject'\nimport {createSettingsType} from './schema/settings'\nimport {createAddToProjectAction} from './actions/AddToProjectAction'\nimport {createTranslationStatusInput} from './form/TranslationStatusInput'\nimport {createTranslationsTool} from './tool'\nimport {StudioInit} from './tool/StudioInit'\nimport {resolveConfig} from './lib/resolveConfig'\nimport type {SmartcatPluginConfig} from './types'\n\nexport type {SmartcatPluginConfig, SmartcatLanguage, TranslationProjectStatus} from './types'\n// Re-exported so the `declare module 'sanity'` augmentation (adding\n// `options.smartcatTranslation`) is loaded for consumers of the plugin types.\nexport type {SmartcatTranslationSchemaOptions} from './schema/translatableOptions'\nexport {TRANSLATION_PROJECT_TYPE} from './lib/constants'\n\n/**\n * Smartcat translation plugin for Sanity Studio.\n *\n * - Adds a `smartcat.translationProject` document type (a named set of items).\n * - Adds an \"Add to translation project\" document action on the configured\n * `translatableTypes`.\n * - Shows a status line on those types when the document belongs to one or more\n * translation projects.\n *\n * @public\n */\nexport const smartcatTranslation = definePlugin<SmartcatPluginConfig>((config) => {\n // Resolve all config defaults once, here at the boundary; everything below\n // receives concrete values.\n const resolved = resolveConfig(config)\n const projectType = createTranslationProjectType()\n const settingsType = createSettingsType()\n const addToProjectAction = createAddToProjectAction(resolved)\n const translationStatusInput = createTranslationStatusInput(resolved)\n const translationsTool = createTranslationsTool(resolved)\n\n // The plugin's customizations apply to translatable types (all types by\n // default), but never to the plugin's own `smartcat.*` documents.\n const isTranslatable = resolved.isTranslatableType\n\n return {\n name: 'sanity-plugin-smartcat-translation',\n schema: {\n types: [projectType, settingsType],\n },\n studio: {\n components: {\n // Bootstraps the template cache on first Studio load.\n layout: StudioInit,\n },\n },\n tools: [translationsTool],\n document: {\n actions: (prev, context) => (isTranslatable(context.schemaType) ? [...prev, addToProjectAction] : prev),\n },\n form: {\n components: {\n input: translationStatusInput,\n },\n },\n }\n})\n"],"names":["defineType","TRANSLATION_PROJECT_TYPE","TranslateIcon","defineField","defineArrayMember","SETTINGS_TYPE","CogIcon","jsxs","Select","jsx","TEMPLATE_PREFIX","STANDARD_WORKFLOW_OPTIONS","useClient","API_VERSION","useState","useRef","useEffect","SETTINGS_DOC_ID","useCallback","workflow","useMemo","isWorkflowValid","prepareForPreview","PROJECTS_QUERY","useSchema","useToast","usePerspective","publishedId","uuid","getTranslatableFields","ITEM_ID","Flex","Spinner","Stack","Label","Fragment","TextInput","Card","Text","Badge","Switch","Button","AddIcon","itemDocDeref","ITEM_ID_FROM_SUBQUERY","useRelativeTime","Box","Heading","Dialog","isInternationalizedArrayType","innerValueType","itemDocDerefRespectingDraft","buildLanguageMappings","findDuplicateSmartcatLanguages","locjson","serializeToLocjson","getAtPath","buildLocjsonFilename","requireSourceLanguage","localizationMode","deserializeFromLocjson","progress","summarizeCompletion","enumerateLeaves","setAtPath","useIntentLink","LaunchIcon","useTheme_v2","targetPercent","Inline","useTheme","useLayoutEffect","CheckmarkIcon","CopyIcon","useValuePreview","keyframes","styled","SyncIcon","css","JsonIcon","DownloadIcon","ArrowLeftIcon","TrashIcon","Checkbox","PublishIcon","CloseIcon","RemoveCircleIcon","router","useRouter","useRouterState","Container","route","useWorkspace","useFormValue","definePlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/schema/translationProject.ts","../src/schema/settings.ts","../src/tool/WorkflowSelect.tsx","../src/tool/useTemplates.ts","../src/tool/useWorkflowSelection.ts","../src/lib/documentTitle.ts","../src/lib/linkedDocuments.ts","../src/actions/AddToProjectAction.tsx","../src/tool/data.ts","../src/tool/StatusBadge.tsx","../src/tool/ProjectsView.tsx","../src/tool/processing.ts","../src/tool/DocTitle.tsx","../src/tool/ItemProgress.tsx","../src/tool/itemActions.tsx","../src/tool/AddItemsSearch.tsx","../src/tool/LogPanel.tsx","../src/lib/log.ts","../src/tool/ProjectView.tsx","../src/tool/Dashboard.tsx","../src/tool/index.ts","../src/form/TranslationStatusInput.tsx","../src/tool/StudioInit.tsx","../src/lib/resolveConfig.ts","../src/index.ts"],"sourcesContent":["import {defineType, defineField, defineArrayMember, type SchemaTypeDefinition} from 'sanity'\nimport {TranslateIcon} from '@sanity/icons'\nimport {TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport type {TranslationProjectStatus} from '../types'\n\n/**\n * Single source of truth for status display titles, used by both the schema's\n * status dropdown (document editor) and the dashboard's StatusBadge. Titles are\n * kept terse so they read well in both places.\n */\nexport const STATUS_OPTIONS: {title: string; value: TranslationProjectStatus}[] = [\n {title: 'Draft', value: 'draft'},\n {title: 'Queued', value: 'queued'},\n {title: 'Sent', value: 'sent'},\n {title: 'In progress', value: 'translating'},\n {title: 'Importing', value: 'importing'},\n {title: 'Downloaded', value: 'downloaded'},\n {title: 'Completed', value: 'completed'},\n {title: 'Error', value: 'error'},\n]\n\n/**\n * Builds the translation-project document type.\n *\n * `items` holds `smartcat.projectItem` objects (a `docId`/`docType` pair), not\n * Sanity references, so any document type can be added — including ones linked\n * transitively — without the consumer having to enumerate every referenceable\n * type in a reference `to` list. Reads dereference `docId` manually via GROQ.\n */\nexport function createTranslationProjectType(): SchemaTypeDefinition {\n return defineType({\n name: TRANSLATION_PROJECT_TYPE,\n title: 'Translation project',\n type: 'document',\n icon: TranslateIcon,\n fields: [\n defineField({\n name: 'name',\n title: 'Project name',\n type: 'string',\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: 'status',\n type: 'string',\n // Driven by the dashboard and Functions, not edited by hand.\n readOnly: true,\n initialValue: 'draft',\n options: {list: STATUS_OPTIONS, layout: 'radio'},\n }),\n defineField({\n name: 'sourceLanguage',\n title: 'Source language',\n type: 'string',\n }),\n // Workflow chosen at creation: `template:<id>` or a standard preset.\n // Read by the export Function to build Smartcat's createProject params.\n defineField({name: 'workflow', type: 'string', readOnly: true, hidden: true}),\n defineField({\n name: 'targetLanguages',\n title: 'Target languages',\n type: 'array',\n of: [defineArrayMember({type: 'string'})],\n options: {layout: 'tags'},\n }),\n // Sanity-id → Smartcat-code mapping for this project's source + target\n // languages, stamped by the browser at export time so the thin Functions\n // (which can't see plugin config) can map to/from Smartcat codes.\n defineField({\n name: 'smartcatLanguages',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatLanguageMapping',\n fields: [\n defineField({name: 'sanityId', type: 'string'}),\n defineField({name: 'smartcatLanguage', type: 'string'}),\n ],\n }),\n ],\n }),\n defineField({\n name: 'items',\n title: 'Items',\n description: 'Content added to this project for translation.',\n // Populated by the \"Add to translation project\" action, not by hand.\n readOnly: true,\n type: 'array',\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcat.projectItem',\n title: 'Project item',\n fields: [\n defineField({name: 'docId', title: 'Document ID', type: 'string'}),\n defineField({name: 'docType', title: 'Document type', type: 'string'}),\n // Set when the item was added from the published perspective, so the\n // export translates the published document. Absent/false (incl. all\n // legacy items) prefers the draft — see itemDocDerefRespectingDraft.\n defineField({name: 'sourceIsPublished', title: 'Source is published', type: 'boolean'}),\n // When true, the export sends the item's *existing* translations to\n // Smartcat: one bilingual LocJSON per target language (populated from\n // field/linked-doc translations), grouped via `{name}_{lang}.locjson`.\n // Absent/false (incl. all legacy items) ⇒ today's behaviour: a single\n // source-only file targeting all languages. Note: imported bilingual\n // targets land confirmed at every workflow stage (Smartcat ignores\n // per-segment status on LocJSON import), i.e. they skip human review.\n defineField({\n name: 'sendExistingTranslations',\n title: 'Send existing translations',\n type: 'boolean',\n }),\n ],\n preview: {select: {title: 'docId', subtitle: 'docType'}},\n }),\n ],\n }),\n defineField({\n name: 'smartcatProjectId',\n title: 'Smartcat project ID',\n type: 'string',\n readOnly: true,\n description: 'GUID of the corresponding project in Smartcat.',\n }),\n defineField({\n name: 'smartcatProjectUrl',\n title: 'Smartcat project URL',\n type: 'url',\n readOnly: true,\n description: 'Link to the project in Smartcat (set by the export Function).',\n }),\n defineField({name: 'lastExportAt', type: 'datetime', readOnly: true}),\n defineField({name: 'lastImportAt', type: 'datetime', readOnly: true}),\n // Per-document, per-language, per-stage translation progress, mirrored from\n // Smartcat. The export captures the target document ids; the progress/import\n // Functions refresh the stage percentages; the browser sets `imported`.\n defineField({\n name: 'progress',\n title: 'Translation progress',\n type: 'array',\n readOnly: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatDocProgress',\n fields: [\n defineField({name: 'sourceDocId', type: 'string'}),\n defineField({name: 'title', type: 'string'}),\n defineField({\n name: 'targets',\n type: 'array',\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatTargetProgress',\n fields: [\n defineField({name: 'language', type: 'string'}),\n defineField({name: 'smartcatDocumentId', type: 'string'}),\n defineField({\n name: 'stages',\n type: 'array',\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatStageProgress',\n fields: [\n defineField({name: 'name', type: 'string'}),\n defineField({name: 'percent', type: 'number'}),\n ],\n }),\n ],\n }),\n // All stages at 100% (set by the progress/import Functions).\n defineField({name: 'complete', type: 'boolean'}),\n // A locale variant has been built from this target (set by the browser).\n defineField({name: 'imported', type: 'boolean'}),\n defineField({name: 'syncedAt', type: 'datetime'}),\n ],\n }),\n ],\n }),\n ],\n }),\n ],\n }),\n // Handshake fields for the on-demand progress refresh: the browser bumps\n // `progressRequestedAt`; the smartcat-progress Function reacts and writes\n // `progressSyncedAt`. Keeping them distinct stops the Function re-triggering\n // on its own write (filter is delta::changedAny(progressRequestedAt)).\n defineField({name: 'progressRequestedAt', type: 'datetime', readOnly: true, hidden: true}),\n defineField({name: 'progressSyncedAt', type: 'datetime', readOnly: true, hidden: true}),\n defineField({\n name: 'lastError',\n title: 'Last error',\n type: 'string',\n readOnly: true,\n description: 'Most recent export/import error, if any.',\n }),\n // JSON-encoded LogLine[] from the most recent Function run (export upload or\n // import download). Transient diagnostic data the browser merges into its\n // live Log panel; overwritten each run.\n defineField({\n name: 'functionLog',\n type: 'text',\n readOnly: true,\n hidden: true,\n }),\n // Transient transport buffers. The browser (plugin) serializes content into\n // `outbox`; the thin export Function uploads it. The thin import Function\n // downloads translated files into `inbox`; the browser turns them into\n // locale variants. Both are cleared after processing.\n defineField({\n name: 'outbox',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatOutboxItem',\n fields: [\n defineField({name: 'sourceDocId', type: 'string'}),\n defineField({name: 'title', type: 'string'}),\n defineField({name: 'filename', type: 'string'}),\n defineField({name: 'locjson', type: 'text'}),\n // Present only for per-language bilingual files (send-existing flow):\n // the single target language this file carries, so the export Function\n // uploads it with `documentModel targetLanguages:[lang]`. Absent ⇒\n // upload targeting all project languages (the source-only default).\n defineField({name: 'targetLanguage', type: 'string'}),\n ],\n }),\n ],\n }),\n defineField({\n name: 'inbox',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatInboxItem',\n fields: [\n defineField({name: 'sourceDocId', type: 'string'}),\n defineField({name: 'targetLanguage', type: 'string'}),\n defineField({name: 'smartcatDocumentId', type: 'string'}),\n defineField({name: 'locjson', type: 'text'}),\n ],\n }),\n ],\n }),\n // Transient: items the browser marked for deletion. On the next export the\n // Function deletes the Smartcat document and removes the item + its progress.\n defineField({\n name: 'pendingDeletions',\n type: 'array',\n readOnly: true,\n hidden: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatPendingDeletion',\n fields: [\n defineField({name: 'itemKey', type: 'string'}),\n defineField({name: 'sourceDocId', type: 'string'}),\n defineField({name: 'smartcatDocumentId', type: 'string'}),\n ],\n }),\n ],\n }),\n ],\n preview: {\n select: {name: 'name', status: 'status', items: 'items'},\n prepare({name, status, items}) {\n const count = Array.isArray(items) ? items.length : 0\n return {\n title: name || 'Untitled project',\n subtitle: `${status || 'draft'} · ${count} item${count === 1 ? '' : 's'}`,\n }\n },\n },\n })\n}\n","import {defineType, defineField, defineArrayMember, type SchemaTypeDefinition} from 'sanity'\nimport {CogIcon} from '@sanity/icons'\nimport {SETTINGS_TYPE} from '../lib/constants'\n\n/**\n * Workspace-wide Smartcat settings, stored as a single fixed-id document.\n *\n * Holds the cached project-template list. The browser bumps `templatesRequestedAt`\n * (Studio init / create-dialog open); the `smartcat-templates` Function fetches\n * the list from Smartcat and writes `templates` + `templatesSyncedAt` back.\n * All fields are managed automatically — never hand-edited.\n */\nexport function createSettingsType(): SchemaTypeDefinition {\n return defineType({\n name: SETTINGS_TYPE,\n title: 'Smartcat settings',\n type: 'document',\n icon: CogIcon,\n fields: [\n defineField({\n name: 'templates',\n title: 'Project templates',\n type: 'array',\n readOnly: true,\n of: [\n defineArrayMember({\n type: 'object',\n name: 'smartcatTemplate',\n fields: [\n defineField({name: 'id', type: 'string'}),\n defineField({name: 'name', type: 'string'}),\n ],\n preview: {select: {title: 'name', subtitle: 'id'}},\n }),\n ],\n }),\n // Handshake fields for the on-demand template refresh: the browser bumps\n // `templatesRequestedAt`; the smartcat-templates Function writes\n // `templatesSyncedAt`. Distinct fields stop the Function re-triggering on\n // its own write (filter is delta::changedAny(templatesRequestedAt)).\n defineField({name: 'templatesRequestedAt', type: 'datetime', readOnly: true, hidden: true}),\n defineField({name: 'templatesSyncedAt', type: 'datetime', readOnly: true, hidden: true}),\n ],\n preview: {\n select: {templates: 'templates', syncedAt: 'templatesSyncedAt'},\n prepare({templates, syncedAt}) {\n const count = Array.isArray(templates) ? templates.length : 0\n return {\n title: 'Smartcat settings',\n subtitle: syncedAt ? `${count} template${count === 1 ? '' : 's'} cached` : 'Not synced yet',\n }\n },\n },\n })\n}\n","import {Select} from '@sanity/ui'\nimport type {SmartcatTemplate} from '../smartcat/types'\nimport {STANDARD_WORKFLOW_OPTIONS, TEMPLATE_PREFIX} from '../lib/workflow'\n\ninterface WorkflowSelectProps {\n value: string\n onChange: (value: string) => void\n templates: SmartcatTemplate[]\n disabled?: boolean\n}\n\n/**\n * Workflow picker for new projects: cached Smartcat templates grouped under\n * \"Templates\", followed by the standard presets under \"Standard workflows\".\n * Templates are expected pre-sorted by name (see `useTemplates`).\n */\nexport function WorkflowSelect({value, onChange, templates, disabled}: WorkflowSelectProps) {\n return (\n <Select value={value} onChange={(e) => onChange(e.currentTarget.value)} disabled={disabled}>\n <option value=\"\" disabled>\n Select a workflow…\n </option>\n {templates.length > 0 && (\n <optgroup label=\"Templates\">\n {templates.map((t) => (\n <option key={t.id} value={`${TEMPLATE_PREFIX}${t.id}`}>\n {t.name}\n </option>\n ))}\n </optgroup>\n )}\n <optgroup label=\"Standard workflows\">\n {STANDARD_WORKFLOW_OPTIONS.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </optgroup>\n </Select>\n )\n}\n","import {useCallback, useEffect, useRef, useState} from 'react'\nimport {useClient} from 'sanity'\nimport {API_VERSION, SETTINGS_DOC_ID, SETTINGS_TYPE} from '../lib/constants'\nimport type {SmartcatTemplate} from '../smartcat/types'\n\ninterface SettingsDoc {\n templates?: SmartcatTemplate[]\n templatesRequestedAt?: string\n templatesSyncedAt?: string\n}\n\nconst SETTINGS_QUERY = `*[_id == $id][0]{templates, templatesRequestedAt, templatesSyncedAt}`\n\n/**\n * A request older than this is treated as failed/abandoned, so a fresh refresh\n * is allowed — self-heals a sync that never completed (e.g. a function error)\n * instead of wedging the cache in a perpetual \"in flight\" state.\n */\nexport const REQUEST_STALE_MS = 30_000\n\n/**\n * A refresh is in flight when a request is newer than the last sync *and* recent\n * enough that the function could still be working on it.\n */\nexport function isRefreshInFlight(\n s: {templatesRequestedAt?: string; templatesSyncedAt?: string} | null,\n): boolean {\n const requested = s?.templatesRequestedAt\n if (!requested) return false\n const pending = !s?.templatesSyncedAt || requested > s.templatesSyncedAt\n if (!pending) return false\n return Date.now() - Date.parse(requested) < REQUEST_STALE_MS\n}\n\n/**\n * Reads the cached Smartcat templates from the settings singleton and keeps them\n * live via `listen()`. `requestRefresh()` bumps the refresh trigger so the\n * `smartcat-templates` Function re-fetches — skipped while a request is already\n * in flight (debounce). Returns templates sorted by name.\n */\nexport function useTemplates(): {\n templates: SmartcatTemplate[]\n loaded: boolean\n requestRefresh: () => void\n} {\n const client = useClient({apiVersion: API_VERSION})\n const [settings, setSettings] = useState<SettingsDoc | null>(null)\n const [loaded, setLoaded] = useState(false)\n const settingsRef = useRef<SettingsDoc | null>(null)\n settingsRef.current = settings\n\n useEffect(() => {\n let cancelled = false\n const load = () =>\n client\n .fetch<SettingsDoc | null>(SETTINGS_QUERY, {id: SETTINGS_DOC_ID})\n .then((s) => {\n if (cancelled) return\n setSettings(s)\n setLoaded(true)\n })\n .catch(() => {})\n load()\n const sub = client\n .listen(SETTINGS_QUERY, {id: SETTINGS_DOC_ID}, {visibility: 'query'})\n .subscribe({next: load, error: () => {}})\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [client])\n\n const requestRefresh = useCallback(() => {\n if (isRefreshInFlight(settingsRef.current)) return\n client\n .transaction()\n .createIfNotExists({_id: SETTINGS_DOC_ID, _type: SETTINGS_TYPE})\n .patch(SETTINGS_DOC_ID, (p) => p.set({templatesRequestedAt: new Date().toISOString()}))\n .commit({visibility: 'async'})\n .catch(() => {})\n }, [client])\n\n return {templates: settings?.templates ?? [], loaded, requestRefresh}\n}\n","import {useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {isWorkflowValid} from '../lib/workflow'\nimport type {SmartcatTemplate} from '../smartcat/types'\n\nconst STORAGE_KEY = 'smartcat:lastWorkflow'\n\nfunction readLastWorkflow(): string {\n try {\n return localStorage.getItem(STORAGE_KEY) ?? ''\n } catch {\n return ''\n }\n}\n\nfunction writeLastWorkflow(value: string): void {\n try {\n localStorage.setItem(STORAGE_KEY, value)\n } catch {\n // Ignore unavailable / full storage; selection just won't persist.\n }\n}\n\n/**\n * Workflow selection for a create dialog. Starts with **no selection** so the\n * user must choose, then remembers the last pick per browser (localStorage).\n *\n * When `active` (the dialog is open) and the template cache is `loaded`, it\n * prefills the saved value — but only if it's still valid: a `template:<id>`\n * whose template no longer exists resets to no selection. It also clears the\n * selection live if the chosen template later disappears from the cache.\n */\nexport function useWorkflowSelection(\n active: boolean,\n templates: SmartcatTemplate[],\n loaded: boolean,\n): readonly [string, (value: string) => void] {\n const [workflow, setWorkflowState] = useState('')\n const initialized = useRef(false)\n const templateIds = useMemo(() => templates.map((t) => t.id), [templates])\n\n // Prefill the saved selection once per open, after the cache has loaded.\n useEffect(() => {\n if (!active) {\n initialized.current = false\n return\n }\n if (initialized.current || !loaded) return\n initialized.current = true\n const saved = readLastWorkflow()\n setWorkflowState(isWorkflowValid(saved, templateIds) ? saved : '')\n }, [active, loaded, templateIds])\n\n // If the selected template disappears from the cache, drop back to no selection.\n useEffect(() => {\n if (!active || !loaded || !workflow) return\n if (!isWorkflowValid(workflow, templateIds)) setWorkflowState('')\n }, [active, loaded, workflow, templateIds])\n\n const setWorkflow = useCallback((value: string) => {\n setWorkflowState(value)\n if (value) writeLastWorkflow(value)\n }, [])\n\n return [workflow, setWorkflow] as const\n}\n","import {prepareForPreview} from 'sanity'\n\n/** Fallback label for a document whose schema preview yields no title. */\nexport const UNTITLED = 'Untitled'\n\n/** Minimal schema shape: just enough to look a type up by name. */\nexport interface TitleSchema {\n get(typeName: string): unknown\n}\n\n/**\n * Document display title, resolved the Sanity-native way — by running the schema\n * type's `preview.prepare` (same as the Studio list/structure tree) — so types\n * without a literal `title` field (e.g. field-level i18n) get a real label. Always\n * returns a string or `undefined`, never a raw field value (an internationalized\n * array is an object that crashes React #31 if rendered as a child).\n */\nexport function resolveDocumentTitle(\n schema: TitleSchema,\n doc: Record<string, unknown> & {_type: string},\n): string | undefined {\n const type = schema.get(doc._type)\n if (!type) return undefined\n try {\n const preview = prepareForPreview(doc as never, type as never)\n return typeof preview?.title === 'string' ? preview.title : undefined\n } catch {\n return undefined\n }\n}\n","/** Minimal client surface the gather needs. */\nexport interface GatherClient {\n fetch<T>(query: string, params: Record<string, unknown>): Promise<T>\n}\n\nexport interface LinkedDocument {\n docId: string\n docType: string\n}\n\nexport interface GatherOptions {\n client: GatherClient\n /** Published id of the document to start from. */\n rootId: string\n /** Root/standalone types — traversal stops here (peer content, not pulled in). */\n isRoot: (type: string) => boolean\n /** Types with localizable content — added to the project and recursed into. */\n isTranslatable: (type: string) => boolean\n /** Documents fetched per round. */\n batchSize?: number\n}\n\nconst bareId = (id: string) => id.replace(/^drafts\\./, '')\n\n/** Every `_ref` string anywhere in a document's JSON, as bare (published) ids. */\nexport function collectRefs(node: unknown, out: Set<string> = new Set()): Set<string> {\n if (!node || typeof node !== 'object') return out\n if (Array.isArray(node)) {\n for (const item of node) collectRefs(item, out)\n return out\n }\n const obj = node as Record<string, unknown>\n if (typeof obj._ref === 'string') out.add(bareId(obj._ref))\n for (const [key, value] of Object.entries(obj)) {\n if (key === '_ref') continue\n collectRefs(value, out)\n }\n return out\n}\n\n// Prefer the draft copy (freshest refs) when both draft and published exist.\nfunction pickPreferDraft<T extends {_id: string}>(docs: T[] | null): Map<string, T> {\n const chosen = new Map<string, T>()\n for (const doc of docs ?? []) {\n const bare = bareId(doc._id)\n if (!chosen.has(bare) || doc._id.startsWith('drafts.')) chosen.set(bare, doc)\n }\n return chosen\n}\n\n/**\n * Breadth-first gather of documents linked (transitively) from `rootId`.\n *\n * Follows references only through translatable, non-root documents; stops at\n * root types (peer pages, translated on their own) and at non-localizable leaves\n * (assets, config). Cycle-safe. Returns the linked documents to add — excluding\n * the root itself.\n */\nexport async function gatherLinkedDocuments({\n client,\n rootId,\n isRoot,\n isTranslatable,\n batchSize = 50,\n}: GatherOptions): Promise<LinkedDocument[]> {\n const start = bareId(rootId)\n const seen = new Set<string>([start])\n const result: LinkedDocument[] = []\n let frontier: string[] = [start]\n\n while (frontier.length) {\n const batch = frontier.splice(0, batchSize)\n // Full bodies of the docs we're expanding — needed to read their outgoing refs.\n const bodies = await client.fetch<Array<Record<string, unknown> & {_id: string}>>(\n `*[_id in $ids]`,\n {ids: batch.flatMap((id) => [id, `drafts.${id}`])},\n )\n const candidates = new Set<string>()\n for (const doc of pickPreferDraft(bodies).values()) {\n for (const ref of collectRefs(doc)) candidates.add(ref)\n }\n const fresh = [...candidates].filter((id) => !seen.has(id))\n if (!fresh.length) continue\n fresh.forEach((id) => seen.add(id))\n\n // Classify fresh candidates by type (light query — avoids pulling full\n // bodies of peer pages and assets we won't recurse into).\n const typed = await client.fetch<Array<{_id: string; _type: string}>>(\n `*[_id in $ids]{_id, _type}`,\n {ids: fresh.flatMap((id) => [id, `drafts.${id}`])},\n )\n for (const [id, doc] of pickPreferDraft(typed)) {\n const type = doc._type\n if (!type || isRoot(type) || !isTranslatable(type)) continue\n result.push({docId: id, docType: type})\n frontier.push(id)\n }\n }\n return result\n}\n","import {useCallback, useEffect, useMemo, useState} from 'react'\nimport {useClient, usePerspective, useSchema, type DocumentActionComponent, type DocumentActionProps} from 'sanity'\nimport {Badge, Box, Button, Card, Flex, Inline, Label, Select, Spinner, Stack, Switch, Text, TextInput, useToast} from '@sanity/ui'\nimport {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {uuid} from '@sanity/uuid'\nimport {API_VERSION, TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {WorkflowSelect} from '../tool/WorkflowSelect'\nimport {useTemplates} from '../tool/useTemplates'\nimport {useWorkflowSelection} from '../tool/useWorkflowSelection'\nimport {resolveDocumentTitle, UNTITLED} from '../lib/documentTitle'\nimport {gatherLinkedDocuments} from '../lib/linkedDocuments'\nimport {ITEM_ID} from '../lib/projectItems'\nimport {getTranslatableFields} from '../lib/locjson/fields'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\ninterface ProjectOption {\n _id: string\n name: string\n count: number\n status: string\n}\n\nconst PROJECTS_QUERY = `*[_type == $type] | order(name asc){\n _id,\n name,\n status,\n \"count\": count(items)\n}`\n\nconst CREATE_NEW = '__create_new__'\n\n/**\n * Builds the \"Add to translation project\" document action, shown on the\n * configured translatable types. Lets the editor add the current document to an\n * existing project or create a new one — appending a weak reference to the\n * project's `items`.\n */\nexport function createAddToProjectAction(config: ResolvedSmartcatConfig): DocumentActionComponent {\n const sourceLanguage = config.sourceLanguage\n\n const AddToProjectAction: DocumentActionComponent = (props: DocumentActionProps) => {\n const {id, draft, published, onComplete} = props\n const client = useClient({apiVersion: API_VERSION})\n const schema = useSchema()\n const toast = useToast()\n // Which version is the translation source, decided here and stored on the\n // item (the pill and the export both read it — no re-resolving later): the\n // published document when the published perspective is selected or there is\n // no draft; otherwise the draft, which is what the editor sees and edits.\n const {selectedPerspectiveName} = usePerspective()\n const sourceIsPublished = selectedPerspectiveName === 'published' || !draft\n\n const [open, setOpen] = useState(false)\n const [projects, setProjects] = useState<ProjectOption[] | null>(null)\n const [selection, setSelection] = useState<string>(CREATE_NEW)\n const [newName, setNewName] = useState('')\n const [busy, setBusy] = useState(false)\n const [includeLinked, setIncludeLinked] = useState(true)\n // Whether to also send the item's existing translations (one bilingual file\n // per target language) rather than only its source text. Off by default:\n // imported translations land confirmed at every stage, skipping human review.\n const [sendExisting, setSendExisting] = useState(false)\n const {templates, loaded, requestRefresh} = useTemplates()\n const [workflow, setWorkflow] = useWorkflowSelection(open, templates, loaded)\n\n const publishedId = id.replace(/^drafts\\./, '')\n const doc = draft ?? published\n // Resolve the title natively (preview.prepare) so field-level i18n types yield\n // a string, never the raw internationalized-array object (renders as React #31).\n const docTitle = (doc && resolveDocumentTitle(schema, doc)) || UNTITLED\n\n // Load existing projects when the dialog opens.\n useEffect(() => {\n if (!open) return\n // Refresh the template list each time the dialog opens.\n requestRefresh()\n let cancelled = false\n setProjects(null)\n client\n .fetch<ProjectOption[]>(PROJECTS_QUERY, {type: TRANSLATION_PROJECT_TYPE})\n .then((res) => {\n if (cancelled) return\n setProjects(res)\n // Default to the first existing project if there is one.\n setSelection(res.length > 0 ? res[0]._id : CREATE_NEW)\n })\n .catch((err) => {\n if (!cancelled) toast.push({status: 'error', title: 'Failed to load projects', description: String(err)})\n })\n return () => {\n cancelled = true\n }\n }, [open, client, toast, requestRefresh])\n\n const close = useCallback(() => {\n setOpen(false)\n setNewName('')\n onComplete()\n }, [onComplete])\n\n const handleConfirm = useCallback(async () => {\n setBusy(true)\n try {\n const makeItem = (docId: string, docType?: string) => ({\n _type: 'smartcat.projectItem',\n _key: uuid(),\n docId,\n docType,\n sourceIsPublished,\n sendExistingTranslations: sendExisting,\n })\n\n // The root document plus, optionally, everything it links to — de-duped by id.\n const collected = new Map<string, string | undefined>([[publishedId, doc?._type]])\n if (includeLinked) {\n const isRoot = (type: string) => config.rootTypes.includes(type)\n const isTranslatable = (type: string) =>\n getTranslatableFields(schema.get(type), {exclude: [config.documentI18nLanguageField]}).length > 0\n const linked = await gatherLinkedDocuments({client, rootId: publishedId, isRoot, isTranslatable})\n for (const {docId, docType} of linked) if (!collected.has(docId)) collected.set(docId, docType)\n }\n\n if (selection === CREATE_NEW) {\n const name = newName.trim() || `Translation project ${new Date().toISOString().slice(0, 10)}`\n const items = [...collected].map(([docId, docType]) => makeItem(docId, docType))\n await client.create({\n _type: TRANSLATION_PROJECT_TYPE,\n name,\n status: 'draft',\n sourceLanguage,\n workflow,\n items,\n })\n toast.push({\n status: 'success',\n title: `Created “${name}” with ${items.length} document${items.length === 1 ? '' : 's'}`,\n })\n } else {\n // Skip ids already in the project (normalized across old/new item shapes).\n const existing = await client.fetch<{id: string}[]>(\n `*[_id == $pid][0].items[]{\"id\": ${ITEM_ID}}`,\n {pid: selection},\n )\n const existingIds = new Set((existing ?? []).map((e) => e.id))\n const newItems = [...collected]\n .filter(([docId]) => !existingIds.has(docId))\n .map(([docId, docType]) => makeItem(docId, docType))\n const projName = projects?.find((p) => p._id === selection)?.name ?? 'project'\n if (newItems.length === 0) {\n toast.push({status: 'info', title: `Already in “${projName}”`})\n } else {\n await client.patch(selection).setIfMissing({items: []}).insert('after', 'items[-1]', newItems).commit()\n const skipped = collected.size - newItems.length\n toast.push({\n status: 'success',\n title: `Added ${newItems.length} document${newItems.length === 1 ? '' : 's'} to “${projName}”`,\n description: skipped > 0 ? `${skipped} already in the project` : undefined,\n })\n }\n }\n close()\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to add to project', description: String(err)})\n } finally {\n setBusy(false)\n }\n }, [selection, newName, workflow, publishedId, doc, includeLinked, sendExisting, sourceIsPublished, schema, client, projects, close])\n\n const content = useMemo(() => {\n if (projects === null) {\n return (\n <Flex align=\"center\" justify=\"center\" padding={4}>\n <Spinner muted />\n </Flex>\n )\n }\n return (\n <Stack space={4}>\n <Stack space={3}>\n <Label size={1}>Project</Label>\n <Select\n value={selection}\n onChange={(e) => setSelection(e.currentTarget.value)}\n disabled={busy}\n >\n {projects.map((p) => (\n <option key={p._id} value={p._id}>\n {p.name} ({p.count} item{p.count === 1 ? '' : 's'})\n </option>\n ))}\n <option value={CREATE_NEW}>➕ Create new project…</option>\n </Select>\n </Stack>\n\n {selection === CREATE_NEW && (\n <>\n <Stack space={3}>\n <Label size={1}>New project name</Label>\n <TextInput\n value={newName}\n placeholder=\"e.g. Spring campaign\"\n onChange={(e) => setNewName(e.currentTarget.value)}\n disabled={busy}\n />\n </Stack>\n <Stack space={3}>\n <Label size={1}>Workflow</Label>\n <WorkflowSelect\n value={workflow}\n onChange={setWorkflow}\n templates={templates}\n disabled={busy}\n />\n </Stack>\n </>\n )}\n\n <Card padding={3} radius={2} tone=\"transparent\" border>\n <Stack space={4}>\n <Text size={1} muted>\n Adding{' '}\n <Badge\n tone={sourceIsPublished ? 'positive' : 'caution'}\n fontSize={1}\n paddingX={2}\n style={{verticalAlign: 'middle'}}\n >\n {sourceIsPublished ? 'Published' : 'Draft'}\n </Badge>{' '}\n version of <strong>{docTitle}</strong> to the selected project.\n </Text>\n <Flex align=\"flex-start\" gap={3}>\n <Switch\n checked={includeLinked}\n onChange={(e) => setIncludeLinked(e.currentTarget.checked)}\n disabled={busy}\n />\n <Stack space={2}>\n <Text size={1} weight=\"medium\">\n Include linked content\n </Text>\n <Text size={1} muted>\n Also add documents this one references, recursively — skipping any already in the project.\n </Text>\n </Stack>\n </Flex>\n <Flex align=\"flex-start\" gap={3}>\n <Switch\n checked={sendExisting}\n onChange={(e) => setSendExisting(e.currentTarget.checked)}\n disabled={busy}\n />\n <Stack space={2}>\n <Text size={1} weight=\"medium\">\n Send existing translations\n </Text>\n <Text size={1} muted>\n Upload current translations alongside the source, so Smartcat starts pre-filled.\n Imported translations are marked confirmed at every stage — they skip human review.\n </Text>\n </Stack>\n </Flex>\n </Stack>\n </Card>\n\n <Flex justify=\"flex-end\" gap={2}>\n <Button mode=\"bleed\" text=\"Cancel\" onClick={close} disabled={busy} />\n <Button\n tone=\"primary\"\n text=\"Add to project\"\n icon={AddIcon}\n onClick={handleConfirm}\n loading={busy}\n disabled={selection === CREATE_NEW && !workflow}\n />\n </Flex>\n </Stack>\n )\n }, [projects, selection, newName, workflow, templates, busy, includeLinked, sendExisting, docTitle, sourceIsPublished, close, handleConfirm])\n\n return {\n label: 'Add to translation project',\n icon: TranslateIcon,\n onHandle: () => setOpen(true),\n dialog: open && {\n type: 'dialog',\n header: 'Add to translation project',\n onClose: close,\n content,\n },\n }\n }\n\n return AddToProjectAction\n}\n","import {TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {ITEM_ID, ITEM_ID_FROM_SUBQUERY, itemDocDeref} from '../lib/projectItems'\nimport type {TranslationProjectStatus} from '../types'\nimport type {DocProgress} from '../progress/core'\n\n/** A row in the projects list. */\nexport interface ProjectListItem {\n _id: string\n name: string\n status: TranslationProjectStatus\n count: number\n _createdAt: string\n _updatedAt: string\n}\n\n/** A resolved item inside a project. */\nexport interface ProjectItemRef {\n _key: string\n /** Published id of the added document, normalized across old (`_ref`) and new (`docId`) items. */\n docId: string\n /**\n * Whether the published version is the translation source (vs the draft),\n * decided and stored when the item was added. Drives the Draft/Published pill\n * and which version the export serializes. Null on legacy items (pre-flag).\n */\n sourceIsPublished: boolean | null\n /**\n * Whether the export sends this item's existing translations (one bilingual\n * file per target language) or only its source text. Null/false on legacy\n * items (pre-flag) ⇒ source-only, today's behaviour.\n */\n sendExistingTranslations: boolean | null\n doc: {_id: string; _type: string} | null\n /** Locale variants linked via translation.metadata: language -> variant doc id. */\n translations: {language: string; id: string}[] | null\n}\n\n/** A single project with its resolved items. */\nexport interface ProjectDetail {\n _id: string\n name: string\n status: TranslationProjectStatus\n sourceLanguage: string | null\n targetLanguages: string[] | null\n smartcatProjectId: string | null\n smartcatProjectUrl: string | null\n lastError: string | null\n /** JSON-encoded LogLine[] from the most recent Function run. */\n functionLog: string | null\n /** Targets the last download run deferred (size/time caps) — drives auto-continue. */\n importRemaining: number | null\n items: ProjectItemRef[] | null\n progress: DocProgress[] | null\n progressSyncedAt: string | null\n}\n\nexport const PROJECTS_QUERY = `*[_type == \"${TRANSLATION_PROJECT_TYPE}\"] | order(_createdAt desc){\n _id,\n name,\n status,\n _createdAt,\n _updatedAt,\n \"count\": count(items)\n}`\n\nexport const PROJECT_DETAIL_QUERY = `*[_id == $id][0]{\n _id,\n name,\n status,\n sourceLanguage,\n targetLanguages,\n smartcatProjectId,\n smartcatProjectUrl,\n lastError,\n functionLog,\n importRemaining,\n progressSyncedAt,\n items[]{\n _key,\n \"docId\": ${ITEM_ID},\n sourceIsPublished,\n sendExistingTranslations,\n \"doc\": ${itemDocDeref('{_id, _type}')},\n \"translations\": *[_type == \"translation.metadata\" && references(${ITEM_ID_FROM_SUBQUERY})][0]\n .translations[]{language, \"id\": value._ref}\n },\n progress[]{\n _key,\n sourceDocId,\n title,\n targets[]{_key, language, smartcatDocumentId, stages, complete, imported, syncedAt}\n }\n}`\n","import {Badge, type BadgeTone} from '@sanity/ui'\nimport type {TranslationProjectStatus} from '../types'\nimport {STATUS_OPTIONS} from '../schema/translationProject'\n\n// Badge color is a UI-only concern (no schema equivalent), so it lives here.\nconst TONES: Record<TranslationProjectStatus, BadgeTone> = {\n draft: 'default',\n queued: 'caution',\n sent: 'primary',\n translating: 'primary',\n importing: 'caution',\n downloaded: 'primary',\n completed: 'positive',\n error: 'critical',\n}\n\n// Display titles come from the schema's STATUS_OPTIONS — the single source.\nconst LABELS: Record<string, string> = Object.fromEntries(\n STATUS_OPTIONS.map((o) => [o.value, o.title]),\n)\n\n/** Display label for a project status (from the schema's status titles). */\nexport function statusLabel(status: TranslationProjectStatus): string {\n return LABELS[status] ?? status\n}\n\nexport function StatusBadge({status}: {status: TranslationProjectStatus}) {\n return (\n <Badge tone={TONES[status] ?? 'default'} fontSize={0} padding={2} radius={2}>\n {statusLabel(status)}\n </Badge>\n )\n}\n","import {useCallback, useEffect, useState} from 'react'\nimport {useClient, useRelativeTime} from 'sanity'\nimport {\n Box,\n Button,\n Card,\n Dialog,\n Flex,\n Heading,\n Label,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport {AddIcon, TranslateIcon} from '@sanity/icons'\nimport {API_VERSION, TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {PROJECTS_QUERY, type ProjectListItem} from './data'\nimport {StatusBadge} from './StatusBadge'\nimport {WorkflowSelect} from './WorkflowSelect'\nimport {useTemplates} from './useTemplates'\nimport {useWorkflowSelection} from './useWorkflowSelection'\n\ninterface ProjectsViewProps {\n sourceLanguage: string\n onOpenProject: (id: string) => void\n}\n\n/** A single project row. Extracted so `useRelativeTime` can run per row. */\nfunction ProjectRow({project: p, onOpen}: {project: ProjectListItem; onOpen: (id: string) => void}) {\n const createdAgo = useRelativeTime(p._createdAt, {useTemporalPhrase: true})\n return (\n <Card\n padding={3}\n radius={2}\n shadow={1}\n as=\"button\"\n onClick={() => onOpen(p._id)}\n style={{cursor: 'pointer', textAlign: 'left', width: '100%'}}\n >\n <Flex align=\"center\" gap={3}>\n <Box style={{width: 110}}>\n <Text size={1} muted title={new Date(p._createdAt).toLocaleString()}>\n {createdAgo}\n </Text>\n </Box>\n <Box style={{width: 100}}>\n <StatusBadge status={p.status} />\n </Box>\n <Box>\n <TranslateIcon />\n </Box>\n <Box flex={1}>\n <Text weight=\"semibold\">{p.name}</Text>\n </Box>\n <Text size={1} muted>\n {p.count} item{p.count === 1 ? '' : 's'}\n </Text>\n </Flex>\n </Card>\n )\n}\n\nexport function ProjectsView({sourceLanguage, onOpenProject}: ProjectsViewProps) {\n const client = useClient({apiVersion: API_VERSION})\n const toast = useToast()\n const [projects, setProjects] = useState<ProjectListItem[] | null>(null)\n const [creating, setCreating] = useState(false)\n const [newName, setNewName] = useState('')\n const [busy, setBusy] = useState(false)\n const {templates, loaded, requestRefresh} = useTemplates()\n const [workflow, setWorkflow] = useWorkflowSelection(creating, templates, loaded)\n\n // Refresh the template list each time the create dialog opens.\n useEffect(() => {\n if (creating) requestRefresh()\n }, [creating, requestRefresh])\n\n const load = useCallback(() => {\n return client\n .fetch<ProjectListItem[]>(PROJECTS_QUERY)\n .then(setProjects)\n .catch((err) => toast.push({status: 'error', title: 'Failed to load projects', description: String(err)}))\n }, [client, toast])\n\n // Initial load + live updates.\n useEffect(() => {\n load()\n const sub = client\n .listen(PROJECTS_QUERY, {}, {visibility: 'query'})\n .subscribe({next: () => load(), error: () => {}})\n return () => sub.unsubscribe()\n }, [client, load])\n\n const handleCreate = useCallback(async () => {\n const name = newName.trim()\n if (!name) return\n setBusy(true)\n try {\n const created = await client.create({\n _type: TRANSLATION_PROJECT_TYPE,\n name,\n status: 'draft',\n sourceLanguage,\n workflow,\n items: [],\n })\n toast.push({status: 'success', title: `Created “${name}”`})\n setCreating(false)\n setNewName('')\n onOpenProject(created._id)\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to create project', description: String(err)})\n } finally {\n setBusy(false)\n }\n }, [newName, workflow, client, sourceLanguage, toast, onOpenProject])\n\n return (\n <Stack space={4}>\n <Flex align=\"center\" justify=\"space-between\">\n <Heading size={2}>Translation projects</Heading>\n <Button icon={AddIcon} text=\"New project\" tone=\"primary\" onClick={() => setCreating(true)} />\n </Flex>\n\n {projects === null ? (\n <Flex align=\"center\" justify=\"center\" padding={5}>\n <Spinner muted />\n </Flex>\n ) : projects.length === 0 ? (\n <Card padding={5} radius={2} tone=\"transparent\" border>\n <Stack space={3}>\n <Text muted align=\"center\">\n No translation projects yet.\n </Text>\n <Flex justify=\"center\">\n <Button icon={AddIcon} text=\"Create your first project\" onClick={() => setCreating(true)} />\n </Flex>\n </Stack>\n </Card>\n ) : (\n <Stack space={2}>\n {projects.map((p) => (\n <ProjectRow key={p._id} project={p} onOpen={onOpenProject} />\n ))}\n </Stack>\n )}\n\n {creating && (\n <Dialog\n id=\"create-project\"\n header=\"New translation project\"\n onClose={() => {\n setCreating(false)\n setNewName('')\n }}\n width={1}\n >\n <Box padding={4}>\n <Stack space={4}>\n <Stack space={3}>\n <Label size={1}>Project name</Label>\n <TextInput\n value={newName}\n placeholder=\"e.g. Spring campaign\"\n autoFocus\n onChange={(e) => setNewName(e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleCreate()\n }}\n disabled={busy}\n />\n </Stack>\n <Stack space={3}>\n <Label size={1}>Workflow</Label>\n <WorkflowSelect\n value={workflow}\n onChange={setWorkflow}\n templates={templates}\n disabled={busy}\n />\n </Stack>\n <Flex justify=\"flex-end\" gap={2}>\n <Button\n mode=\"bleed\"\n text=\"Cancel\"\n onClick={() => {\n setCreating(false)\n setNewName('')\n }}\n disabled={busy}\n />\n <Button\n tone=\"primary\"\n text=\"Create\"\n onClick={handleCreate}\n loading={busy}\n disabled={!newName.trim() || !workflow}\n />\n </Flex>\n </Stack>\n </Box>\n </Dialog>\n )}\n </Stack>\n )\n}\n","import {uuid} from '@sanity/uuid'\nimport {resolveDocumentTitle} from '../lib/documentTitle'\nimport {ITEM_ID, itemDocDerefRespectingDraft} from '../lib/projectItems'\nimport {\n enumerateLeaves,\n getTranslatableFields,\n innerValueType,\n isInternationalizedArrayType,\n localizationMode,\n} from '../lib/locjson/fields'\nimport {getAtPath, setAtPath} from '../lib/locjson/paths'\nimport type {TranslatableField} from '../lib/locjson/types'\nimport {serializeToLocjson} from '../lib/locjson/serialize'\nimport {buildLocjsonFilename} from '../lib/locjson/filename'\nimport {deserializeFromLocjson} from '../lib/locjson/deserialize'\nimport {requireSourceLanguage} from '../lib/constants'\nimport {buildLanguageMappings, findDuplicateSmartcatLanguages, toSmartcatLanguage} from '../lib/languageMap'\nimport type {LocalizationMode, LocJSON} from '../lib/locjson/types'\nimport {summarizeCompletion, type DocProgress} from '../progress/core'\nimport type {SmartcatLanguage} from '../types'\nimport type {LogFn} from '../lib/log'\n\n/**\n * Browser-side processing for the Smartcat workflow. All content transformation\n * (Portable Text ⇄ HTML, field selection, variant creation) happens here in the\n * Studio, where the real schema and a native DOM are available — so the Sanity\n * Functions stay thin and dependency-free.\n */\n\n/** A loosely-typed Sanity client (the Studio's `useClient` result satisfies this). */\nexport interface ProcessingClient {\n fetch<T = unknown>(query: string, params?: Record<string, unknown>): Promise<T>\n create(doc: Record<string, unknown>): Promise<{_id: string}>\n createIfNotExists(doc: Record<string, unknown>): Promise<{_id: string}>\n patch(id: string): ProcessingPatch\n}\ninterface ProcessingPatch {\n set(attrs: Record<string, unknown>): ProcessingPatch\n setIfMissing(attrs: Record<string, unknown>): ProcessingPatch\n insert(at: 'before' | 'after' | 'replace', selector: string, items: unknown[]): ProcessingPatch\n unset(keys: string[]): ProcessingPatch\n commit(): Promise<unknown>\n}\n\n/** A compiled schema (the Studio's `useSchema` result satisfies this). */\nexport interface ProcessingSchema {\n get(typeName: string): unknown\n}\n\nconst METADATA_TYPE = 'translation.metadata'\nconst REFERENCE_VALUE_TYPE = 'internationalizedArrayReferenceValue'\n\nfunction parseHtml(html: string): Document {\n return new DOMParser().parseFromString(html, 'text/html')\n}\n\nconst VALUE_PREVIEW_CAP = 2000\n\n/** A capped, display-safe string for a field value (source or translated). */\nfunction valuePreview(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined\n const text = typeof value === 'string' ? value : JSON.stringify(value, null, 2)\n if (!text) return undefined\n return text.length > VALUE_PREVIEW_CAP ? `${text.slice(0, VALUE_PREVIEW_CAP)}…` : text\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\n/**\n * For a field-level (internationalized-array) field, the member locales that\n * actually carry content — so a \"no source content\" skip can say *which* locales\n * exist (\"I see only: en-GB\") when the source-language member is simply missing,\n * turning a silent source-language mismatch into a self-explaining log line.\n */\nfunction memberLocalesWithContent(members: unknown, languageKey: string): string[] {\n if (!Array.isArray(members)) return []\n const locales: string[] = []\n for (const member of members) {\n if (!member || typeof member !== 'object') continue\n const locale = (member as Record<string, unknown>)[languageKey]\n const value = (member as {value?: unknown}).value\n const hasContent =\n typeof value === 'string' ? value.trim().length > 0 : Array.isArray(value) ? value.length > 0 : value != null\n if (typeof locale === 'string' && hasContent) locales.push(locale)\n }\n return locales\n}\n\n/** Top-level, non-system schema field names for a type (for \"not translatable\" reporting). */\nfunction schemaFieldNames(schema: ProcessingSchema, type: string): string[] {\n const compiled = schema.get(type) as {fields?: {name?: string}[]} | undefined\n return (compiled?.fields ?? [])\n .map((f) => f?.name)\n .filter((n): n is string => typeof n === 'string' && !n.startsWith('_'))\n}\n\nfunction blockContentTypeFor(schema: ProcessingSchema, type: string, fieldPath: string): unknown {\n const compiled = schema.get(type) as {fields?: {name: string; type: unknown}[]} | undefined\n const fieldType = compiled?.fields?.find((f) => f.name === fieldPath)?.type\n // Field-level Portable Text lives under the array member's `value`; resolve the\n // inner block-content type rather than the internationalized-array wrapper.\n if (isInternationalizedArrayType(fieldType as never)) {\n return innerValueType(fieldType as never)\n }\n return fieldType\n}\n\n// ---------------------------------------------------------------------------\n// Export: serialize project items → outbox (LocJSON), set status = queued\n// ---------------------------------------------------------------------------\n\n/** An item the editor marked for deletion; carried to the export Function. */\nexport interface PendingDeletion {\n itemKey: string\n sourceDocId: string\n smartcatDocumentId?: string\n}\n\nexport interface PrepareExportArgs {\n client: ProcessingClient\n schema: ProcessingSchema\n projectId: string\n targetLanguages: string[]\n sourceLanguage: string\n /** Configured languages, used to resolve each id → its Smartcat code. */\n languages: SmartcatLanguage[]\n /** Configured translatable types (undefined = all), logged in the config header. */\n translatableTypes?: string[]\n exclude?: string[]\n /** How internationalized-array members identify their locale (field name or `'_key'`). */\n fieldLanguageKey: string\n /** Items to delete from Smartcat (and the project) on this export. */\n deletions?: PendingDeletion[]\n /** Streams per-document/per-field progress to the UI; no-op if omitted. */\n onLog?: LogFn\n}\n\nconst ITEMS_QUERY = `*[_id == $id][0]{\n sourceLanguage,\n items[]{\n \"docId\": ${ITEM_ID},\n \"docType\": docType,\n sendExistingTranslations,\n \"doc\": ${itemDocDerefRespectingDraft()}\n }\n}`\n\n/**\n * Target-locale sibling documents for a set of source ids, via\n * document-internationalization's `translation.metadata`. Returns, per metadata\n * group, every locale variant's `{language, doc}` — the send-existing flow reads\n * each target language's sibling as the translation to upload. Document-level\n * only; field-level types keep all languages inline on the same document.\n *\n * The variant's locale lives in its language field (v5+, with a uuid `_key`) or\n * in `_key` itself (v4.x); `coalesce` reads whichever applies per the configured\n * {@link fieldLanguageKey}. Reading only `_key` misses v5+ siblings entirely.\n */\nexport function siblingsQuery(fieldLanguageKey: string): string {\n return `*[_type == \"translation.metadata\" && references($ids)]{\n \"variants\": translations[]{ \"language\": coalesce(${fieldLanguageKey}, _key), \"doc\": value-> }\n}`\n}\n\nexport async function prepareExport({\n client,\n schema,\n projectId,\n targetLanguages,\n sourceLanguage,\n languages,\n translatableTypes,\n exclude,\n fieldLanguageKey,\n deletions = [],\n onLog,\n}: PrepareExportArgs): Promise<{prepared: number; deleting: number}> {\n const log: LogFn = onLog ?? (() => {})\n const project = await client.fetch<{\n sourceLanguage?: string\n items?: {\n docId?: string\n docType?: string\n sendExistingTranslations?: boolean\n doc: (Record<string, unknown> & {_id: string; _type: string}) | null\n }[]\n } | null>(ITEMS_QUERY, {id: projectId})\n\n const source = project?.sourceLanguage || sourceLanguage\n\n // Resolve the id → Smartcat-code mapping for this project's languages and\n // stamp it on the project, so the Functions can map to/from Smartcat codes.\n // Two targets resolving to the same code can't be routed back, so reject it.\n const smartcatLanguages = buildLanguageMappings(languages, [source, ...targetLanguages])\n const dups = findDuplicateSmartcatLanguages(\n smartcatLanguages.filter((m) => targetLanguages.includes(m.sanityId)),\n )\n if (dups.length > 0) {\n const detail = dups.map((d) => `${d.sanityIds.join(', ')} → ${d.smartcatLanguage}`).join('; ')\n throw new Error(`Multiple target languages map to the same Smartcat language: ${detail}`)\n }\n // Don't re-upload documents that are being deleted this round.\n const deletedDocIds = new Set(deletions.map((d) => d.sourceDocId))\n // Resolve each project item to its (draft-or-published) document. An item that\n // derefs to nothing — deleted, or expected published but never published — is\n // reported below rather than silently dropped.\n const items = (project?.items ?? []).filter(\n (item) => !(item.docId && deletedDocIds.has(item.docId)),\n )\n const unresolved = items.filter((item) => !item.doc)\n const docs = items\n .map((item) => item.doc)\n .filter((d): d is Record<string, unknown> & {_id: string; _type: string} => Boolean(d))\n\n // For \"send existing translations\" document-level items, fetch each source's\n // target-locale sibling documents up front (one query), keyed by\n // bare-source-id → (Sanity locale → sibling doc). Field-level types need none —\n // their translations live inline on the same document.\n type TargetDoc = Record<string, unknown> & {_id: string; _type: string}\n const siblingsByDocId = new Map<string, Map<string, TargetDoc>>()\n const flaggedDocLevelIds = items\n .filter(\n (item) =>\n item.doc && item.sendExistingTranslations === true && localizationMode(schema.get(item.doc._type)) === 'document',\n )\n .map((item) => publishedId((item.doc as {_id: string})._id))\n if (flaggedDocLevelIds.length > 0) {\n const groups = await client.fetch<{variants: {language: string; doc: TargetDoc | null}[]}[]>(\n siblingsQuery(fieldLanguageKey),\n {ids: flaggedDocLevelIds},\n )\n for (const group of groups ?? []) {\n const byLang = new Map<string, TargetDoc>()\n const groupSourceIds: string[] = []\n for (const variant of group.variants ?? []) {\n if (!variant.doc) continue\n byLang.set(variant.language, variant.doc)\n groupSourceIds.push(publishedId(variant.doc._id))\n }\n // Every member of a translation group can reach the same sibling set, so key\n // the map by each variant's id — the source doc looks up its own group.\n for (const sid of groupSourceIds) siblingsByDocId.set(sid, byLang)\n }\n }\n\n // The translatable field list is per-type, so compute it once per type even\n // when a project holds many documents of the same type.\n const fieldsByType = new Map<string, ReturnType<typeof getTranslatableFields>>()\n const fieldsFor = (type: string) => {\n let fields = fieldsByType.get(type)\n if (!fields) {\n fields = getTranslatableFields(schema.get(type), {exclude})\n fieldsByType.set(type, fields)\n }\n return fields\n }\n\n // Config header — surfaces the resolved plugin config and this project's\n // languages up front, so a \"nothing serialized\" run can be traced to a\n // source-language or translatable-types mismatch straight from the log.\n const configuredLanguages = languages.map((l) => l.id).join(', ') || '(none)'\n const configuredTypes =\n translatableTypes === undefined ? 'all types' : translatableTypes.join(', ') || '(none)'\n log({level: 'info', message: `Config — source language: ${sourceLanguage}`})\n log({level: 'info', indent: true, message: `languages: ${configuredLanguages}`})\n log({level: 'info', indent: true, message: `translatable types: ${configuredTypes}`})\n log({level: 'info', message: `Project — source: ${source} → targets: ${targetLanguages.join(', ') || '(no targets)'}`})\n log({level: 'info', message: `Export — ${docs.length} document(s)`})\n\n // Items that resolved to no document at all: don't drop them silently — the\n // usual cause is a document that was never published (or was deleted).\n for (const item of unresolved) {\n log({\n level: 'error',\n message: `${item.docId ?? 'unknown document'} (${item.docType ?? 'unknown type'}): no document found — it may be unpublished or deleted; skipped`,\n })\n }\n\n const outbox: {\n _key: string\n sourceDocId: string\n title?: string\n filename: string\n locjson: string\n /** Present for per-language bilingual files (send-existing flow). */\n targetLanguage?: string\n }[] = []\n\n /**\n * Queue one bilingual LocJSON per target language for a \"send existing\n * translations\" item. Each file carries the source plus that language's\n * existing translation (field-level: the inline member; document-level: the\n * locale-sibling document), is named `…_{smartcatCode}.locjson` so Smartcat\n * groups the languages as one document, and records its single target language.\n */\n const queueBilingual = (\n doc: Record<string, unknown> & {_id: string; _type: string},\n name: string | undefined,\n fields: TranslatableField[],\n isDraft: boolean,\n ): void => {\n const mode = localizationMode(schema.get(doc._type))\n const byLang = mode === 'document' ? siblingsByDocId.get(doc._id) : undefined\n let queued = 0\n for (const targetSanityId of targetLanguages) {\n const smartcatCode = toSmartcatLanguage(smartcatLanguages, targetSanityId)\n const target =\n mode === 'field' ? {language: targetSanityId} : {language: targetSanityId, doc: byLang?.get(targetSanityId)}\n const locjson = serializeToLocjson(doc as never, fields, {sourceLanguage: source, fieldLanguageKey, target})\n if (locjson.units.length === 0) {\n log({level: 'skip', indent: true, message: `${targetSanityId}: no translatable content — not sent`})\n continue\n }\n const prefilled = locjson.units.filter((u) => u.target.length > 0).length\n outbox.push({\n _key: uuid(),\n sourceDocId: doc._id,\n title: name,\n filename: buildLocjsonFilename(doc._type, doc._id, name, {draft: isDraft, language: smartcatCode}),\n locjson: JSON.stringify(locjson),\n targetLanguage: smartcatCode,\n })\n queued++\n log({\n level: 'success',\n indent: true,\n message: `${targetSanityId} → ${smartcatCode}: queued ${locjson.units.length} unit(s), ${prefilled} with existing translation`,\n })\n }\n if (queued === 0) log({level: 'skip', indent: true, message: 'no translatable content — not sent'})\n }\n for (const item of items) {\n const rawDoc = item.doc\n if (!rawDoc) continue\n // Serialize under the canonical (bare) id so identity, metadata and progress\n // stay stable, even when the *content* came from the draft. Mark draft-sourced\n // files so they're recognizable in Smartcat.\n const isDraft = rawDoc._id.startsWith('drafts.')\n const doc = isDraft ? {...rawDoc, _id: publishedId(rawDoc._id)} : rawDoc\n const name = resolveDocumentTitle(schema, doc)\n const sendExisting = item.sendExistingTranslations === true\n log({\n level: 'info',\n message: `${name || doc._id} · ${doc._type}${isDraft ? ' (draft)' : ''}${sendExisting ? ' · sending existing translations' : ''}`,\n })\n try {\n const fields = fieldsFor(doc._type)\n if (sendExisting) {\n queueBilingual(doc, name, fields, isDraft)\n continue\n }\n // Fields skipped because they hold a block type that can't be serialized\n // (e.g. a custom `table`): left untranslated on purpose, reported as errors\n // below so the editor knows to act rather than lose content silently.\n const skippedBlockTypes = new Map<string, string[]>()\n const locjson = serializeToLocjson(doc as never, fields, {\n sourceLanguage: source,\n fieldLanguageKey,\n onSkippedField: ({fieldPath, types}) => skippedBlockTypes.set(fieldPath, types),\n })\n // A field produced a unit ⇒ serialized; otherwise its source was empty.\n const unitByKey = new Map(locjson.units.map((u) => [u.key, u]))\n for (const field of fields) {\n const unit = unitByKey.get(field.path)\n const skippedTypes = skippedBlockTypes.get(field.path)\n if (unit) {\n log({level: 'success', indent: true, message: `${field.title || field.path}: serialized (${field.kind})`, value: unit.source.join('')})\n } else if (skippedTypes) {\n log({\n level: 'error',\n indent: true,\n message: `${field.title || field.path}: not translated — contains block type(s) that can't be translated: ${skippedTypes.join(', ')}. The whole field was left untranslated to avoid losing this content.`,\n })\n } else {\n // Field-level with members in other locales but not the source is a\n // source-language mismatch, not an empty field — name the locales seen.\n const otherLocales =\n field.localization === 'field'\n ? memberLocalesWithContent(getAtPath(doc, field.path), fieldLanguageKey).filter((l) => l !== source)\n : []\n const reason = otherLocales.length\n ? `no '${source}' content (I see only: ${otherLocales.join(', ')})`\n : 'no source content'\n log({level: 'skip', indent: true, message: `${field.title || field.path}: skipped — ${reason}`})\n }\n }\n // Surface the rest of the type's fields too, so a missing translation is\n // explained (\"not translatable\") rather than silently absent.\n const selected = new Set(fields.map((f) => f.path))\n const excluded = new Set(exclude ?? [])\n for (const fieldName of schemaFieldNames(schema, doc._type)) {\n if (selected.has(fieldName) || excluded.has(fieldName)) continue\n log({level: 'skip', indent: true, message: `${fieldName}: skipped — not translatable`})\n }\n if (locjson.units.length === 0) {\n // Distinguish \"nothing to translate\" from \"everything translatable was\n // held back\": the latter means the whole document goes untranslated, so\n // flag it as an error rather than a benign skip.\n if (skippedBlockTypes.size > 0) {\n log({\n level: 'error',\n indent: true,\n message: 'not sent — its only translatable content is in field(s) with block type(s) that can’t be translated (see above)',\n })\n } else {\n log({level: 'skip', indent: true, message: 'no translatable content — not sent'})\n }\n continue\n }\n outbox.push({\n _key: uuid(),\n sourceDocId: doc._id,\n title: name,\n filename: buildLocjsonFilename(doc._type, doc._id, name, {draft: isDraft}),\n locjson: JSON.stringify(locjson),\n })\n } catch (err) {\n log({level: 'error', indent: true, message: `failed to serialize: ${errorMessage(err)}`})\n }\n }\n log({level: 'success', message: `Queued ${outbox.length} file(s)${deletions.length ? ` · ${deletions.length} for deletion` : ''}`})\n\n await client\n .patch(projectId)\n .set({\n outbox,\n pendingDeletions: deletions,\n targetLanguages,\n sourceLanguage: source,\n smartcatLanguages,\n status: 'queued',\n lastError: null,\n })\n .commit()\n\n return {prepared: outbox.length, deleting: deletions.length}\n}\n\n// ---------------------------------------------------------------------------\n// Import: inbox (translated LocJSON) → locale variants + metadata, status = completed\n// ---------------------------------------------------------------------------\n\nexport interface ApplyImportArgs {\n client: ProcessingClient\n schema: ProcessingSchema\n projectId: string\n /** Document-level locale field name (document-internationalization `languageField`). */\n documentLanguageField: string\n /** Field-level locale key (internationalized-array): field name or `'_key'`. */\n fieldLanguageKey: string\n /** Streams per-document/per-field progress to the UI; no-op if omitted. */\n onLog?: LogFn\n}\n\nconst INBOX_QUERY = `*[_id == $id][0]{\n sourceLanguage,\n inbox[]{ sourceDocId, targetLanguage, smartcatDocumentId, locjson },\n progress[]{_key, sourceDocId, title, targets[]{_key, language, smartcatDocumentId, stages, complete, imported, syncedAt}}\n}`\n\nexport async function applyImportedTranslations({\n client,\n schema,\n projectId,\n documentLanguageField,\n fieldLanguageKey,\n onLog,\n}: ApplyImportArgs): Promise<{imported: number; status: 'completed' | 'translating'}> {\n const log: LogFn = onLog ?? (() => {})\n const project = await client.fetch<{\n sourceLanguage?: string\n inbox?: {sourceDocId?: string; targetLanguage: string; smartcatDocumentId?: string; locjson: string}[]\n progress?: DocProgress[]\n } | null>(INBOX_QUERY, {id: projectId})\n\n const sourceLanguage = requireSourceLanguage(project?.sourceLanguage)\n const inbox = project?.inbox ?? []\n // Resolved titles per source doc, from the stored progress (the same source the\n // import Function log uses) — so the log shows names, not raw document ids.\n const titleByDoc = new Map<string, string>()\n for (const p of project?.progress ?? []) {\n if (p.sourceDocId && p.title) titleByDoc.set(p.sourceDocId, p.title)\n }\n let imported = 0\n // (sourceDocId, targetLanguage) pairs we successfully imported.\n const importedKeys = new Set<string>()\n\n // Localization mode is per-type; derive once per type from the schema.\n const modeByType = new Map<string, LocalizationMode>()\n const modeFor = (type: string): LocalizationMode => {\n let mode = modeByType.get(type)\n if (!mode) {\n mode = localizationMode(schema.get(type))\n modeByType.set(type, mode)\n }\n return mode\n }\n\n // Translatable-field descriptors per type (shapes + nesting), for reconstructing\n // nested/array member values on write-back. Same exclude as export.\n const descriptorsByType = new Map<string, ReturnType<typeof getTranslatableFields>>()\n const descriptorsFor = (type: string) => {\n let d = descriptorsByType.get(type)\n if (!d) {\n d = getTranslatableFields(schema.get(type), {exclude: [documentLanguageField]})\n descriptorsByType.set(type, d)\n }\n return d\n }\n\n log({level: 'info', message: `Import — ${inbox.length} translated file(s)`})\n\n for (const item of inbox) {\n let parsed: LocJSON\n try {\n parsed = JSON.parse(item.locjson) as LocJSON\n } catch {\n log({level: 'error', message: `${item.sourceDocId || 'unknown'} → ${item.targetLanguage}: invalid LocJSON, skipped`})\n continue\n }\n const type = parsed.properties?.['x-sanity']?.documentType\n const result = deserializeFromLocjson(parsed, {\n parseHtml,\n getBlockContentType: (fieldPath) => (type ? blockContentTypeFor(schema, type, fieldPath) : undefined),\n })\n if (!result.documentId || !result.documentType) {\n log({level: 'error', message: `${item.sourceDocId || 'unknown'} → ${item.targetLanguage}: missing document id/type, skipped`})\n continue\n }\n\n const mode = modeFor(result.documentType)\n const title = titleByDoc.get(result.documentId)\n const label = title ? `${title} (Sanity ID: ${result.documentId})` : result.documentId\n log({level: 'info', message: `${label} → ${item.targetLanguage} · ${result.documentType} (${mode} mode)`})\n\n let ok = false\n // Each item is isolated: a failure is logged and skipped, so one bad\n // document never aborts the rest of the batch.\n try {\n ok =\n mode === 'field'\n ? await applyFieldLevelTranslations(client, {\n schema,\n type: result.documentType,\n docId: result.documentId,\n locale: item.targetLanguage,\n sourceLanguage: result.sourceLanguage || sourceLanguage,\n descriptors: descriptorsFor(result.documentType),\n translations: result.fields,\n sources: result.sources,\n languageKey: fieldLanguageKey,\n }, log)\n : await upsertVariant(client, {\n sourceId: result.documentId,\n type: result.documentType,\n sourceLanguage,\n locale: item.targetLanguage,\n fields: result.fields,\n sources: result.sources,\n languageField: documentLanguageField,\n }, log)\n } catch (err) {\n log({level: 'error', indent: true, message: `failed: ${errorMessage(err)}`})\n }\n if (ok) {\n imported++\n importedKeys.add(`${result.documentId}__${item.targetLanguage}`)\n }\n }\n\n // Mark the imported targets, then decide completion: the project is \"completed\"\n // only when every target is complete AND imported. Otherwise it stays\n // \"translating\" so the remaining targets can be imported once they finish.\n const progress = (project?.progress ?? []).map((doc) => ({\n ...doc,\n targets: doc.targets.map((target) =>\n importedKeys.has(`${doc.sourceDocId}__${target.language}`)\n ? {...target, imported: true}\n : target,\n ),\n }))\n const status = summarizeCompletion(progress).allDone ? 'completed' : 'translating'\n\n await client\n .patch(projectId)\n .set({progress, status, lastImportAt: new Date().toISOString()})\n .unset(['inbox'])\n .commit()\n\n return {imported, status}\n}\n\ninterface ApplyFieldLevelArgs {\n schema: ProcessingSchema\n type: string\n docId: string\n locale: string\n /** Source language — its array member is the structural template for reconstruction. */\n sourceLanguage: string\n /** Translatable-field descriptors for `type` (shapes + nesting). */\n descriptors: TranslatableField[]\n /** Translated leaf values keyed by full unit path. */\n translations: Record<string, unknown>\n /** Source (pre-translation) text per unit path, for the JSON well-formedness check. */\n sources: Record<string, string>\n /** How members identify their locale: a field name (`'language'`) or `'_key'`. */\n languageKey: string\n}\n\n/** A value is \"potential JSON\" if it's a string whose first non-blank char is `{`. */\nfunction isPotentialJson(value: unknown): value is string {\n return typeof value === 'string' && value.trimStart().startsWith('{')\n}\n\n/**\n * Guards a field whose **source** is JSON: the translated value must also parse.\n * Returns the parse error message when the translation is malformed (caller logs\n * it and skips the field); `null` when there's nothing to enforce — the source\n * isn't confirmed JSON — or the translation is valid JSON.\n */\nfunction malformedJsonError(source: unknown, translated: unknown): string | null {\n // Only enforce when the source is confirmed JSON (starts with `{` and parses).\n if (!isPotentialJson(source)) return null\n try {\n JSON.parse(source)\n } catch {\n return null // source isn't really JSON, so don't hold the translation to it\n }\n if (typeof translated !== 'string') return 'translated value is not a string'\n try {\n JSON.parse(translated)\n return null\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n}\n\nconst DRAFTS_PREFIX = 'drafts.'\n\n/** The published (bare) form of a document id. */\nfunction publishedId(id: string): string {\n return id.startsWith(DRAFTS_PREFIX) ? id.slice(DRAFTS_PREFIX.length) : id\n}\n\n/** The draft form of a document id. */\nfunction draftId(id: string): string {\n return id.startsWith(DRAFTS_PREFIX) ? id : DRAFTS_PREFIX + id\n}\n\ninterface EditableDraft {\n draftId: string\n /** Content edits are computed against: the draft if one exists, else published. */\n base: Record<string, unknown>\n /** Whether a draft already exists (so we don't clone published over it). */\n exists: boolean\n}\n\n/**\n * Resolves the **draft** to write imported translations into, so they accumulate\n * for editorial review instead of landing on the live document (where they'd be\n * invisible behind an existing draft and overwritten on the next publish).\n *\n * Read-only: returns the existing draft if there is one (so a concurrent draft\n * isn't clobbered), otherwise the published document as the base to seed from.\n * `null` if neither exists. Use {@link commitToDraft} to actually write.\n */\nasync function loadEditableDraft(client: ProcessingClient, id: string): Promise<EditableDraft | null> {\n const dId = draftId(id)\n const draft = await client.fetch<Record<string, unknown> | null>(`*[_id == $id][0]`, {id: dId})\n if (draft) return {draftId: dId, base: draft, exists: true}\n\n const published = await client.fetch<Record<string, unknown> | null>(`*[_id == $id][0]`, {id: publishedId(id)})\n if (!published) return null\n return {draftId: dId, base: published, exists: false}\n}\n\n/**\n * Writes `attrs` onto the draft, first cloning the published document into a new\n * draft if none exists yet. Only call when there is something to write, so an\n * unchanged import never leaves a spurious empty draft behind.\n */\nasync function commitToDraft(client: ProcessingClient, editable: EditableDraft, attrs: Record<string, unknown>): Promise<void> {\n if (!editable.exists) {\n await client.createIfNotExists({...stripSystemFields(editable.base), _id: editable.draftId, _type: editable.base._type})\n }\n await client.patch(editable.draftId).set(attrs).commit()\n}\n\n/**\n * Field-level (internationalized-array) import: writes each translated field's\n * value into the **same** document's **draft**, as the array member for `locale`\n * — updating the existing member (preserving its `_key`) or appending a new one.\n * No locale variant document and no translation.metadata.\n */\nasync function applyFieldLevelTranslations(\n client: ProcessingClient,\n {docId, locale, sourceLanguage, descriptors, translations, sources, languageKey}: ApplyFieldLevelArgs,\n log: LogFn,\n): Promise<boolean> {\n const editable = await loadEditableDraft(client, docId)\n if (!editable) {\n log({level: 'error', indent: true, message: `source document not found: ${docId}`})\n return false\n }\n const doc = editable.base\n const byKey = languageKey === '_key'\n const patchSet: Record<string, unknown> = {}\n\n // One patch entry per (nested) i18n field. The target member value is rebuilt\n // from the SOURCE member as a template — preserving `_key`s and non-text fields\n // — with each translated leaf overlaid by its valuePath.\n for (const field of descriptors) {\n if (field.localization !== 'field') continue\n const existing = (Array.isArray(getAtPath(doc, field.path)) ? getAtPath(doc, field.path) : []) as Record<string, unknown>[]\n const template = (existing.find((m) => m?.[languageKey] === sourceLanguage) ?? existing.find((m) => m?.value !== undefined))?.value\n\n let target: unknown = structuredClone(template)\n let changed = false\n for (const leaf of enumerateLeaves(field, template)) {\n let value = translations[leaf.fullKey]\n if (value === undefined) continue\n if (leaf.kind === 'portableText' && Array.isArray(value)) value = value.map((b) => keyBlock(b as Record<string, unknown>))\n // A JSON source ⇒ its translation must parse too, or we'd write broken JSON.\n const jsonError = malformedJsonError(sources[leaf.fullKey], value)\n if (jsonError) {\n log({level: 'error', indent: true, message: `${leaf.fullKey}: '${locale}' translation is not valid JSON — skipped`, value: valuePreview(value), error: jsonError})\n continue\n }\n target = leaf.valuePath ? setAtPath(target, leaf.valuePath, value) : value\n changed = true\n }\n if (!changed) continue\n\n const idx = existing.findIndex((m) => m?.[languageKey] === locale)\n if (idx >= 0 && sameValue(existing[idx]?.value, target)) {\n log({level: 'skip', indent: true, message: `${field.path}: '${locale}' unchanged — skipped`})\n continue\n }\n if (idx >= 0) {\n patchSet[field.path] = existing.map((m, i) => (i === idx ? {...m, value: target} : m))\n log({level: 'update', indent: true, message: `${field.path}: updating '${locale}' field variant`, before: valuePreview(existing[idx]?.value), value: valuePreview(target)})\n } else {\n // v4.x keys members by `_key`; v5+ uses a uuid `_key` plus a language field.\n const _type = existing.find((m) => m?._type)?._type\n patchSet[field.path] = [\n ...existing,\n byKey ? {_key: locale, _type, value: target} : {_key: uuid(), _type, [languageKey]: locale, value: target},\n ]\n log({level: 'info', indent: true, message: `${field.path}: creating '${locale}' field variant`, value: valuePreview(target)})\n }\n }\n\n if (Object.keys(patchSet).length === 0) {\n log({level: 'success', indent: true, message: `${docId}: no field changes`})\n return true\n }\n await commitToDraft(client, editable, patchSet)\n log({level: 'success', indent: true, message: `saved ${Object.keys(patchSet).length} field(s) on draft of ${docId}`})\n return true\n}\n\ninterface UpsertVariantArgs {\n sourceId: string\n type: string\n sourceLanguage: string\n locale: string\n fields: Record<string, unknown>\n /** Source (pre-translation) text per field, for the JSON well-formedness check. */\n sources: Record<string, string>\n /** Document locale field name (document-internationalization `languageField`). */\n languageField: string\n}\n\ninterface MetaTranslation {\n language?: string\n value?: {_ref?: string}\n}\n\nasync function upsertVariant(\n client: ProcessingClient,\n {sourceId, type, sourceLanguage, locale, fields, sources, languageField}: UpsertVariantArgs,\n log: LogFn,\n): Promise<boolean> {\n const source = await client.fetch<Record<string, unknown> | null>(`*[_id == $id][0]`, {id: sourceId})\n if (!source) {\n log({level: 'error', indent: true, message: `source document not found: ${sourceId}`})\n return false\n }\n\n const translatedFields = keyPortableText(fields)\n\n const metadata = await client.fetch<{_id: string; translations?: MetaTranslation[]} | null>(\n `*[_type == $metaType && references($sourceId)][0]{_id, translations}`,\n {metaType: METADATA_TYPE, sourceId},\n )\n const existingVariantId = metadata?.translations?.find((t) => t.language === locale)?.value?._ref\n\n // Log the intent before each write so a failure mid-op is still traceable.\n // All writes target the variant's draft, so translations accumulate for review.\n let variantId: string\n if (existingVariantId) {\n // Edit the variant's draft (seeded from its published version if needed), so\n // imported fields are reviewable and don't get clobbered by an open draft.\n const editable = await loadEditableDraft(client, existingVariantId)\n if (!editable) {\n log({level: 'error', indent: true, message: `'${locale}' document variant not found: ${existingVariantId}`})\n return false\n }\n const variant = editable.base\n // Only write fields whose translated value actually differs from the variant.\n const changed: Record<string, unknown> = {}\n for (const [path, value] of Object.entries(translatedFields)) {\n if (sameValue(variant[path], value)) {\n log({level: 'skip', indent: true, message: `${path}: unchanged — skipped`})\n continue\n }\n const jsonError = malformedJsonError(sources[path], value)\n if (jsonError) {\n log({\n level: 'error',\n indent: true,\n message: `${path}: translation is not valid JSON — skipped`,\n before: valuePreview(variant[path]),\n value: valuePreview(value),\n error: jsonError,\n })\n continue\n }\n changed[path] = value\n log({\n level: 'update',\n indent: true,\n message: `${path}: updating`,\n before: valuePreview(variant[path]),\n value: valuePreview(value),\n })\n }\n if (Object.keys(changed).length > 0) {\n await commitToDraft(client, editable, changed)\n log({level: 'success', indent: true, message: `updated ${Object.keys(changed).length} field(s) on '${locale}' document variant draft`})\n } else {\n log({level: 'success', indent: true, message: `'${locale}' document variant already up to date`})\n }\n variantId = publishedId(existingVariantId)\n } else {\n // Drop any field whose source is JSON but whose translation doesn't parse,\n // so a malformed value never lands on the new variant.\n const writableFields: Record<string, unknown> = {}\n for (const [path, value] of Object.entries(translatedFields)) {\n const jsonError = malformedJsonError(sources[path], value)\n if (jsonError) {\n log({\n level: 'error',\n indent: true,\n message: `${path}: translation is not valid JSON — skipped`,\n value: valuePreview(value),\n error: jsonError,\n })\n continue\n }\n writableFields[path] = value\n log({level: 'info', indent: true, message: `${path}`, value: valuePreview(value)})\n }\n log({level: 'info', indent: true, message: `creating new '${locale}' document variant draft`})\n // Create the variant as a draft; metadata references its published (bare) id.\n variantId = uuid()\n await client.create({...stripSystemFields(source), _id: draftId(variantId), [languageField]: locale, ...writableFields})\n }\n\n if (!metadata?._id) {\n log({level: 'info', indent: true, message: 'creating translation metadata'})\n await client.create({\n _type: METADATA_TYPE,\n schemaTypes: [type],\n translations: [translationEntry(sourceLanguage, sourceId), translationEntry(locale, variantId)],\n })\n } else if (!existingVariantId) {\n log({level: 'info', indent: true, message: 'linking variant into translation metadata'})\n await client\n .patch(metadata._id)\n .setIfMissing({translations: []})\n .insert('after', 'translations[-1]', [translationEntry(locale, variantId)])\n .commit()\n }\n\n log({level: 'success', indent: true, message: `'${locale}' document variant ready: ${variantId}`})\n return true\n}\n\nfunction translationEntry(language: string, ref: string) {\n return {\n _key: uuid(),\n _type: REFERENCE_VALUE_TYPE,\n language,\n value: {_type: 'reference', _ref: ref, _weak: true},\n }\n}\n\nfunction stripSystemFields(doc: Record<string, unknown>): Record<string, unknown> {\n const {_id, _rev, _createdAt, _updatedAt, ...rest} = doc\n void _id\n void _rev\n void _createdAt\n void _updatedAt\n return rest\n}\n\nfunction keyPortableText(fields: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(fields)) {\n if (Array.isArray(value) && value.some((v) => v && typeof v === 'object' && '_type' in v)) {\n out[key] = value.map((b) => keyBlock(b as Record<string, unknown>))\n } else {\n out[key] = value\n }\n }\n return out\n}\n\nfunction keyBlock(block: Record<string, unknown>): Record<string, unknown> {\n const keyed: Record<string, unknown> = {_key: (block._key as string) || uuid(), ...block}\n if (Array.isArray(keyed.children)) {\n keyed.children = (keyed.children as Record<string, unknown>[]).map((child) => ({\n _key: (child._key as string) || uuid(),\n ...child,\n }))\n }\n return keyed\n}\n\n/**\n * Deep value equality that ignores volatile `_key`s and object-key order, so an\n * unchanged translation — whose Portable Text gets freshly re-keyed on each\n * deserialize — isn't mistaken for a change.\n */\nfunction sameValue(a: unknown, b: unknown): boolean {\n return stableString(a) === stableString(b)\n}\n\nfunction stableString(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableString).join(',')}]`\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([k]) => k !== '_key')\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${stableString(v)}`).join(',')}}`\n }\n return JSON.stringify(value) ?? 'undefined'\n}\n","import {useSchema, useValuePreview} from 'sanity'\nimport {UNTITLED} from '../lib/documentTitle'\n\n/**\n * Resolve a document's title the way the Studio does — by running the schema\n * type's `preview.prepare` — so types without a literal `title` field (e.g.\n * field-level localized docs) show the same label as in the structure tree,\n * not 'Untitled'.\n */\nexport function DocTitle({doc}: {doc: {_id: string; _type: string} | null}) {\n const schema = useSchema()\n const schemaType = doc ? schema.get(doc._type) : undefined\n const preview = useValuePreview({\n enabled: Boolean(doc && schemaType),\n schemaType,\n value: doc ? {_id: doc._id, _type: doc._type} : undefined,\n })\n // String-only: never fall back to the raw projected value, which is an\n // internationalized-array object for field-level i18n types (renders as React #31).\n const title = typeof preview.value?.title === 'string' ? preview.value.title : undefined\n // Placeholder while the async preview resolves, so a real title isn't briefly mislabeled.\n return <>{title ?? (preview.isLoading ? '…' : UNTITLED)}</>\n}\n","import {Badge, Box, Button, Flex, Inline, Stack, Text, useTheme_v2, Card} from '@sanity/ui'\nimport {LaunchIcon} from '@sanity/icons'\nimport {useIntentLink} from 'sanity/router'\nimport {targetPercent, type DocProgress, type TargetProgress} from '../progress/core'\nimport type {SmartcatLanguage} from '../types'\n\n/** Readable name for a language id, falling back to the id itself. */\nexport function languageTitle(languages: SmartcatLanguage[], id: string): string {\n return languages.find((l) => l.id === id)?.title || id\n}\n\n/** Locale variants for an item: language id -> Sanity variant document id. */\nexport interface VariantLinks {\n type: string\n byLanguage: Record<string, string>\n}\n\n/** Icon-only link that opens a language variant document in the Studio. */\nfunction OpenVariantInStudio({id, type}: {id: string; type: string}) {\n const {onClick, href} = useIntentLink({intent: 'edit', params: {id, type}})\n return (\n <Button\n as=\"a\"\n href={href}\n onClick={onClick}\n mode=\"bleed\"\n icon={LaunchIcon}\n title=\"Open this language version in Studio\"\n fontSize={0}\n padding={1}\n />\n )\n}\n\n/**\n * Smartcat editor URL for a target document. Host comes from the project's\n * Smartcat URL; the file guid and numeric language id are the two halves of the\n * target document id (`<fileGuid>_<langNum>`).\n */\nfunction editorUrl(projectUrl: string | null | undefined, smartcatDocumentId?: string): string | null {\n if (!projectUrl || !smartcatDocumentId) return null\n let origin: string\n try {\n origin = new URL(projectUrl).origin\n } catch {\n return null\n }\n const sep = smartcatDocumentId.lastIndexOf('_')\n if (sep < 0) return null\n const fileGuid = smartcatDocumentId.slice(0, sep)\n const langNum = smartcatDocumentId.slice(sep + 1)\n return `${origin}/open-editor/${fileGuid}?targetLanguageId=${langNum}`\n}\n\n/**\n * A thin track with a vivid fill whose width reflects the actual percentage.\n * Uses the design system's solid button colors (the same vivid blue/green used on\n * primary/positive buttons) rather than the muted Card surface tones — green once\n * the target is complete, blue while in progress.\n */\nfunction ProgressBar({percent, complete}: {percent: number; complete: boolean}) {\n const {color} = useTheme_v2()\n const pct = Math.max(0, Math.min(100, percent))\n const fill = (complete ? color.button.default.positive : color.button.default.primary).enabled.bg\n return (\n <Card tone=\"transparent\" border radius={3} style={{height: 10, overflow: 'hidden'}}>\n <div\n style={{\n width: `${pct}%`,\n height: '100%',\n background: fill,\n borderRadius: 'inherit',\n transition: 'width 0.3s ease',\n }}\n />\n </Card>\n )\n}\n\nfunction TargetRow({\n target,\n languages,\n smartcatProjectUrl,\n variants,\n}: {\n target: TargetProgress\n languages: SmartcatLanguage[]\n smartcatProjectUrl?: string | null\n variants?: VariantLinks\n}) {\n const percent = targetPercent(target.stages)\n const href = editorUrl(smartcatProjectUrl, target.smartcatDocumentId)\n const label = languageTitle(languages, target.language)\n const variantId = variants?.byLanguage[target.language]\n return (\n <Stack space={2}>\n <Flex align=\"center\" gap={3}>\n <Box style={{width: 150, flex: 'none'}}>\n <Flex align=\"center\" gap={1}>\n <Text size={1} weight=\"medium\">\n {href ? (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Open document in Smartcat editor\"\n >\n {label}\n </a>\n ) : (\n label\n )}\n </Text>\n {variantId && variants && <OpenVariantInStudio id={variantId} type={variants.type} />}\n </Flex>\n </Box>\n <Box flex={1}>\n <ProgressBar percent={percent} complete={target.complete} />\n </Box>\n <Box style={{width: 38, flex: 'none'}}>\n <Text size={1} muted align=\"right\">\n {percent}%\n </Text>\n </Box>\n <Box style={{width: 72, flex: 'none'}}>\n {target.imported ? (\n <Badge tone=\"positive\" fontSize={0} padding={2}>\n imported\n </Badge>\n ) : target.complete ? (\n <Badge tone=\"primary\" fontSize={0} padding={2}>\n ready\n </Badge>\n ) : null}\n </Box>\n </Flex>\n {target.stages.length > 0 && (\n <Inline space={3} style={{paddingLeft: 162}}>\n {target.stages.map((stage) => (\n <Text key={stage.name} size={0} muted>\n {stage.name}: {stage.percent}%\n </Text>\n ))}\n </Inline>\n )}\n </Stack>\n )\n}\n\n/** Per-language, per-stage progress for a single project item. */\nexport function ItemProgress({\n doc,\n languages,\n smartcatProjectUrl,\n variants,\n}: {\n doc: DocProgress\n languages: SmartcatLanguage[]\n smartcatProjectUrl?: string | null\n variants?: VariantLinks\n}) {\n if (!doc.targets || doc.targets.length === 0) return null\n return (\n <Stack space={3} paddingTop={1}>\n {doc.targets.map((target) => (\n <TargetRow\n key={target._key}\n target={target}\n languages={languages}\n smartcatProjectUrl={smartcatProjectUrl}\n variants={variants}\n />\n ))}\n </Stack>\n )\n}\n","import {useCallback, useState} from 'react'\nimport {useIntentLink} from 'sanity/router'\nimport {Box, Button, Dialog, Flex, Menu, MenuButton, MenuItem, Spinner, Text} from '@sanity/ui'\nimport {LaunchIcon, JsonIcon, ChevronDownIcon, DownloadIcon} from '@sanity/icons'\nimport styled from 'styled-components'\nimport {getTranslatableFields, localizationMode} from '../lib/locjson/fields'\nimport {serializeToLocjson} from '../lib/locjson/serialize'\nimport {buildLocjsonFilename} from '../lib/locjson/filename'\nimport {resolveDocumentTitle} from '../lib/documentTitle'\nimport {languageTitle} from './ItemProgress'\nimport type {SmartcatLanguage} from '../types'\n\n/** Opens the document in the Studio. */\nexport function OpenInStudioButton({id, type}: {id: string; type: string}) {\n const {onClick, href} = useIntentLink({intent: 'edit', params: {id, type}})\n return (\n <Button\n as=\"a\"\n href={href}\n onClick={onClick}\n mode=\"bleed\"\n icon={LaunchIcon}\n text=\"Open in Studio\"\n fontSize={0}\n padding={2}\n />\n )\n}\n\n/** Read-only, monospace, full-height code view for the LocJSON modal. */\nconst CodeArea = styled.textarea`\n width: 100%;\n height: 70vh;\n resize: none;\n border: none;\n outline: none;\n padding: 0;\n background: transparent;\n color: inherit;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 12px;\n line-height: 1.5;\n white-space: pre;\n tab-size: 2;\n`\n\n/**\n * Target-locale siblings of a document-level item, via translation.metadata. The\n * member's locale lives in its language field (v5+, uuid `_key`) or in `_key`\n * itself (v4.x) — `coalesce` reads whichever applies, per {@link fieldLanguageKey}.\n */\nfunction siblingsQuery(fieldLanguageKey: string): string {\n return `*[_type == \"translation.metadata\" && references($id)][0].translations[]{\"language\": coalesce(${fieldLanguageKey}, _key), \"doc\": value->}`\n}\n\n/**\n * Dropdown that builds the LocJSON the export would produce for an item — same\n * field selection and serialize options as {@link prepareExport} — and shows it\n * (pretty-printed) in a read-only modal. Offers \"Source only\" (what a plain\n * export sends) plus \"Source + <language>\" for each target language: the\n * bilingual file the send-existing flow would upload for that language, so you\n * can inspect exactly what goes to Smartcat per language.\n */\nexport function ViewLocjsonButton(props: {\n docId: string\n type: string\n /** Whether the export will translate the published doc (else prefer the draft). */\n sourceIsPublished: boolean | null\n client: {fetch: (query: string, params?: Record<string, unknown>) => Promise<unknown>}\n schema: {get: (typeName: string) => unknown}\n sourceLanguage: string\n documentI18nLanguageField: string\n fieldI18nLanguageField: string\n /** Project target languages (Sanity locale ids). */\n targetLanguages: string[]\n /** Configured languages (for titles + Smartcat codes). */\n languages: SmartcatLanguage[]\n}) {\n const {docId, type, sourceIsPublished, client, schema, sourceLanguage, documentI18nLanguageField, fieldI18nLanguageField, targetLanguages, languages} = props\n const [open, setOpen] = useState(false)\n const [content, setContent] = useState<string | null>(null)\n const [filename, setFilename] = useState<string | null>(null)\n const [title, setTitle] = useState<string>('Source only')\n const [error, setError] = useState<string | null>(null)\n\n // Build the LocJSON for one variant: `targetLanguage` undefined ⇒ source-only\n // (a plain export), otherwise the bilingual file for that Sanity locale.\n const build = useCallback(\n async (targetLanguage?: string) => {\n setOpen(true)\n setContent(null)\n setFilename(null)\n setError(null)\n setTitle(targetLanguage ? `Source + ${languageTitle(languages, targetLanguage)}` : 'Source only')\n try {\n // Resolve the same version the export will send: the draft (fallback to\n // published) unless the item was added from the published perspective.\n const raw = (await client.fetch(\n sourceIsPublished\n ? '*[_id == $id][0]'\n : 'coalesce(*[_id == \"drafts.\" + $id][0], *[_id == $id][0])',\n {id: docId},\n )) as (Record<string, unknown> & {_id: string}) | null\n if (!raw) throw new Error(`Document not found: ${docId}`)\n const isDraft = typeof raw._id === 'string' && raw._id.startsWith('drafts.')\n // Serialize under the canonical (bare) id, matching the export.\n const doc = isDraft ? {...raw, _id: docId} : raw\n const fields = getTranslatableFields(schema.get(type), {exclude: [documentI18nLanguageField]})\n\n // For a bilingual variant, resolve the existing translation the same way\n // the export does: field-level from the inline member, document-level from\n // the target-locale sibling document.\n let target: {language: string; doc?: Record<string, unknown> & {_id: string; _type: string}} | undefined\n if (targetLanguage) {\n if (localizationMode(schema.get(type)) === 'document') {\n const variants = (await client.fetch(siblingsQuery(fieldI18nLanguageField), {id: docId})) as\n | {language: string; doc: (Record<string, unknown> & {_id: string; _type: string}) | null}[]\n | null\n const sibling = (variants ?? []).find((v) => v.language === targetLanguage)?.doc ?? undefined\n target = {language: targetLanguage, doc: sibling}\n } else {\n target = {language: targetLanguage}\n }\n }\n\n const locjson = serializeToLocjson(doc as never, fields, {\n sourceLanguage,\n fieldLanguageKey: fieldI18nLanguageField,\n target,\n })\n // Same name the export sends to Smartcat; the last path segment is the\n // file's basename (the Smartcat \"folder/\" prefix can't be a local filename).\n const smartcatCode = targetLanguage\n ? languages.find((l) => l.id === targetLanguage)?.smartcatLanguage || targetLanguage\n : undefined\n const smartcatName = buildLocjsonFilename(type, docId, resolveDocumentTitle(schema, doc as never), {\n draft: isDraft,\n language: smartcatCode,\n })\n setFilename(smartcatName.split('/').pop() || smartcatName)\n setContent(JSON.stringify(locjson, null, 2))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n },\n [client, schema, docId, type, sourceIsPublished, sourceLanguage, documentI18nLanguageField, fieldI18nLanguageField, languages],\n )\n\n const download = useCallback(() => {\n if (content == null || !filename) return\n const url = URL.createObjectURL(new Blob([content], {type: 'application/json'}))\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = filename\n anchor.click()\n URL.revokeObjectURL(url)\n }, [content, filename])\n\n return (\n <>\n <MenuButton\n id={`locjson-menu-${docId}`}\n button={<Button mode=\"bleed\" icon={JsonIcon} iconRight={ChevronDownIcon} title=\"View LocJSON\" fontSize={0} padding={2} />}\n menu={\n <Menu>\n <MenuItem text=\"Source only\" onClick={() => build()} />\n {targetLanguages.map((lang) => (\n <MenuItem key={lang} text={`Source + ${languageTitle(languages, lang)}`} onClick={() => build(lang)} />\n ))}\n </Menu>\n }\n popover={{portal: true}}\n />\n {open && (\n <Dialog\n id={`locjson-${docId}`}\n header={\n <Flex align=\"center\" gap={3}>\n <Text weight=\"semibold\">LocJSON · {type} · {title}</Text>\n <Button\n icon={DownloadIcon}\n text=\"Download\"\n mode=\"ghost\"\n fontSize={1}\n padding={2}\n disabled={content == null}\n onClick={download}\n />\n </Flex>\n }\n onClose={() => setOpen(false)}\n width={3}\n >\n <Box padding={4}>\n {error ? (\n <Text size={1} muted>\n {error}\n </Text>\n ) : content === null ? (\n <Flex align=\"center\" justify=\"center\" padding={5}>\n <Spinner muted />\n </Flex>\n ) : (\n <CodeArea\n readOnly\n spellCheck={false}\n value={content}\n onFocus={(e) => e.currentTarget.select()}\n />\n )}\n </Box>\n </Dialog>\n )}\n </>\n )\n}\n","import {Fragment, useCallback, useEffect, useState, type MouseEvent} from 'react'\nimport {useClient, useSchema} from 'sanity'\nimport {useRouter} from 'sanity/router'\nimport {Badge, Box, Button, Card, Checkbox, Flex, Menu, MenuButton, MenuItem, Spinner, Stack, Text, TextInput, useToast} from '@sanity/ui'\nimport {AddIcon, CheckmarkIcon, ChevronDownIcon, SearchIcon} from '@sanity/icons'\nimport {uuid} from '@sanity/uuid'\nimport {API_VERSION, TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {ITEM_ID} from '../lib/projectItems'\nimport {DocTitle} from './DocTitle'\nimport {OpenInStudioButton, ViewLocjsonButton} from './itemActions'\nimport type {SmartcatLanguage} from '../types'\n\n/** A raw matched row — a draft or published document variant. */\ninterface SearchRow {\n _id: string\n _type: string\n /** True when this row is a draft, or a published doc that has a draft. */\n hasDraft: boolean\n}\n\n/** A deduped search hit — one logical document, addable to the project. */\ninterface SearchHit {\n /** Published (bare) id, the value stored as an item's `docId`. */\n docId: string\n _type: string\n /** Whether a draft exists — drives the source badge and the added item's `sourceIsPublished`. */\n hasDraft: boolean\n}\n\n/**\n * Documents fetched per search before de-duplication. Higher than what we show,\n * since a document can appear twice (draft + published). Inlined into the query\n * (GROQ slices must be constant).\n */\nconst QUERY_LIMIT = 50\n\n/** Distinct documents shown after de-duplication. */\nconst DISPLAY_LIMIT = 25\n\n/** Max query tokens honored, to keep the generated query bounded. */\nconst MAX_TOKENS = 6\n\n/** Don't search until the box has some substance, or single letters flood results. */\nconst MIN_QUERY_LENGTH = 2\n\n/**\n * Fields a term matches against in the default (\"title\") mode, plus `_type`/`_id`\n * so a term can match the schema type name or id. Kept in one place: this is the\n * curated notion of \"a document's title\" across arbitrary schema types.\n */\nconst TITLE_FIELDS = '[title, name, heading, label, question, slug.current, _type, _id]'\n\n/** Title-ish fields used for scoring, so title matches rank above `_type`/content hits. */\nconst SCORE_FIELDS = '[title, name, heading, label, question, slug.current]'\n\n/** Types the plugin never treats as translatable, excluded when no allowlist is configured. */\nconst EXCLUDED_TYPES = ['smartcat.translationProject', 'smartcat.settings', 'translation.metadata']\n\n/**\n * Turn the raw search box text into a GROQ query + params, or `null` when there's\n * nothing worth searching for yet.\n *\n * Each whitespace-separated term must match (AND across terms); within a term the\n * match spans the title fields plus `_type`/`_id`. So `\"faq cancel\"` finds an FAQ\n * titled \"Can I cancel my subscription\" (`faq`→`_type`, `cancel`→title) but not a\n * `page` whose body mentions \"cancel\" — unless \"Also search in content\" is on,\n * which widens each term to the whole document (`@`).\n */\nfunction buildSearch(\n rawQuery: string,\n searchContent: boolean,\n translatableTypes: string[] | undefined,\n): {query: string; params: Record<string, unknown>} | null {\n if (rawQuery.trim().length < MIN_QUERY_LENGTH) return null\n const tokens = rawQuery\n .trim()\n .split(/\\s+/)\n // Neutralize text::query operators so plain text can't be read as phrase\n // quoting (`\"`), exclusion (leading `-`), or an explicit wildcard (`*`).\n .map((t) => t.replace(/[\"*]/g, '').replace(/^-+/, '').trim())\n .filter(Boolean)\n .slice(0, MAX_TOKENS)\n if (tokens.length === 0) return null\n\n // Whole-document search when the editor opts in; otherwise the curated fields.\n const target = searchContent ? '@' : TITLE_FIELDS\n const params: Record<string, unknown> = {}\n const tokenClauses: string[] = []\n const scoreClauses: string[] = []\n tokens.forEach((tok, i) => {\n // Trailing wildcard → prefix matching, so results narrow as the editor types.\n params[`t${i}`] = `${tok}*`\n tokenClauses.push(`${target} match text::query($t${i})`)\n scoreClauses.push(`boost(${SCORE_FIELDS} match text::query($t${i}), 2)`)\n })\n\n // Mirror resolveConfig: an explicit allowlist is a positive filter; otherwise\n // exclude the plugin's own + document-i18n metadata + system types — never\n // enumerating \"all types\", which could be thousands.\n let typeFilter: string\n if (translatableTypes) {\n params.types = translatableTypes\n typeFilter = '_type in $types'\n } else {\n params.excluded = EXCLUDED_TYPES\n typeFilter = '!(_type in $excluded) && !(_type match \"sanity.*\")'\n }\n\n // Drafts are included (the plugin can translate the draft version). Both a\n // draft and its published counterpart may match; de-duplication happens after\n // the fetch. `hasDraft` lets a published-only match still detect its draft, so\n // a document whose draft didn't match the term is still flagged correctly.\n const filter = [typeFilter, ...tokenClauses].join(' && ')\n const projection = '{_id, _type, \"hasDraft\": _id in path(\"drafts.**\") || count(*[_id == \"drafts.\" + ^._id]) > 0}'\n const query = `*[${filter}] | score(${scoreClauses.join(', ')}) | order(_score desc)[0...${QUERY_LIMIT}]${projection}`\n return {query, params}\n}\n\n/**\n * Collapse draft/published variants into one hit per logical document, keyed by\n * the bare (published) id. Input is ordered by relevance; the Map preserves that\n * order (first occurrence wins the position), and `hasDraft` is OR-ed across\n * variants so a draft is detected whichever variant matched.\n */\nfunction dedupeHits(rows: SearchRow[]): SearchHit[] {\n const byDoc = new Map<string, SearchHit>()\n for (const row of rows) {\n const docId = row._id.replace(/^drafts\\./, '')\n const existing = byDoc.get(docId)\n if (existing) existing.hasDraft = existing.hasDraft || row.hasDraft\n else byDoc.set(docId, {docId, _type: row._type, hasDraft: row.hasDraft})\n }\n return [...byDoc.values()].slice(0, DISPLAY_LIMIT)\n}\n\n/** A translation project a searched document is an item of. */\ninterface ProjectRef {\n _id: string\n name?: string\n}\n\n/**\n * For the given document ids, the projects that include each as a (source) item.\n * One batched query builds a `docId → projects` map; `references()`/sibling\n * membership is deliberately out of scope — what matters here is whether adding\n * the document to a project would be redundant.\n */\nconst MEMBERSHIP_QUERY = `*[_type == \"${TRANSLATION_PROJECT_TYPE}\" && count(items[${ITEM_ID} in $ids]) > 0] | order(name asc){\n _id,\n name,\n \"docIds\": items[${ITEM_ID} in $ids]{\"id\": ${ITEM_ID}}\n}`\n\n/** Shape of one row from {@link MEMBERSHIP_QUERY}. */\ninterface MembershipRow {\n _id: string\n name?: string\n docIds: {id: string}[]\n}\n\n/** A project name that navigates to its page in the Translations tool (SPA nav). */\nfunction ProjectChip({project, current}: {project: ProjectRef; current: boolean}) {\n const router = useRouter()\n const onClick = useCallback(\n (e: MouseEvent) => {\n e.preventDefault()\n router.navigate({projectId: project._id})\n },\n [router, project._id],\n )\n return (\n <a href=\"#\" onClick={onClick}>\n {project.name || 'Untitled project'}\n {current ? ' (this project)' : ''}\n </a>\n )\n}\n\ninterface AddItemsSearchProps {\n projectId: string\n /** Configured translatable types (undefined = every non-plugin type). */\n translatableTypes?: string[]\n /** Published ids already in the project, so their results show as added, not addable. */\n existingDocIds: Set<string>\n /** Source language (Sanity locale id) — for the LocJSON preview. */\n sourceLanguage: string\n /** Configured languages (titles + Smartcat codes) — for the LocJSON preview. */\n languages: SmartcatLanguage[]\n /** Project target languages — the per-language bilingual LocJSON variants to offer. */\n targetLanguages: string[]\n /** document-internationalization locale field name. */\n documentI18nLanguageField: string\n /** internationalized-array locale key. */\n fieldI18nLanguageField: string\n}\n\n/**\n * Search box + results, shown under a project's item list, for finding documents\n * anywhere in the dataset and adding them to the project without opening each one.\n * Searches drafts and published documents; a document with a draft is added\n * draft-as-source (the plugin translates the draft), matching a fresh \"Add to\n * translation project\", with existing-translations upload left off. Linked-content\n * gathering is not applied here — each result adds just that one document.\n */\nexport function AddItemsSearch({\n projectId,\n translatableTypes,\n existingDocIds,\n sourceLanguage,\n languages,\n targetLanguages,\n documentI18nLanguageField,\n fieldI18nLanguageField,\n}: AddItemsSearchProps) {\n const client = useClient({apiVersion: API_VERSION})\n const schema = useSchema()\n const toast = useToast()\n const [query, setQuery] = useState('')\n const [searchContent, setSearchContent] = useState(false)\n const [results, setResults] = useState<SearchHit[] | null>(null)\n const [loading, setLoading] = useState(false)\n const [addingId, setAddingId] = useState<string | null>(null)\n // Optimistic: added rows show as \"Added\" immediately, before the project's\n // live subscription refreshes `existingDocIds`.\n const [addedIds, setAddedIds] = useState<Set<string>>(new Set())\n // docId → the projects that already include it (live), so each result lists\n // its memberships the way the document editor's status banner does.\n const [projectsByDoc, setProjectsByDoc] = useState<Map<string, ProjectRef[]>>(new Map())\n\n useEffect(() => {\n const built = buildSearch(query, searchContent, translatableTypes)\n if (!built) {\n setResults(null)\n setLoading(false)\n return undefined\n }\n setLoading(true)\n let cancelled = false\n const handle = setTimeout(() => {\n client\n .fetch<SearchRow[]>(built.query, built.params)\n .then((res) => {\n if (!cancelled) setResults(dedupeHits(res))\n })\n .catch((err) => {\n if (cancelled) return\n setResults([])\n toast.push({status: 'error', title: 'Search failed', description: String(err)})\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n }, 250)\n return () => {\n cancelled = true\n clearTimeout(handle)\n }\n }, [query, searchContent, translatableTypes, client, toast])\n\n // Resolve (and keep live) the projects each visible result belongs to. Keyed\n // on the result ids so it re-runs when the result set changes; the listener\n // then reflects adds/removes anywhere without a manual refetch.\n const docIdsKey = (results ?? []).map((r) => r.docId).join(',')\n useEffect(() => {\n const ids = docIdsKey ? docIdsKey.split(',') : []\n if (ids.length === 0) {\n setProjectsByDoc(new Map())\n return undefined\n }\n let cancelled = false\n const load = () =>\n client\n .fetch<MembershipRow[]>(MEMBERSHIP_QUERY, {ids})\n .then((rows) => {\n if (cancelled) return\n const map = new Map<string, ProjectRef[]>()\n for (const row of rows) {\n for (const {id} of row.docIds ?? []) {\n const list = map.get(id) ?? []\n list.push({_id: row._id, name: row.name})\n map.set(id, list)\n }\n }\n setProjectsByDoc(map)\n })\n .catch(() => !cancelled && setProjectsByDoc(new Map()))\n load()\n const sub = client.listen(MEMBERSHIP_QUERY, {ids}, {visibility: 'query'}).subscribe({next: load, error: () => {}})\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [docIdsKey, client])\n\n // Once the project's live items reflect an optimistic add, drop it from the\n // local set. Otherwise `addedIds` (which only ever grows) would keep a row\n // marked \"Added\" even after it's removed from the project — `existingDocIds`\n // then becomes the single source of truth, so removal flips it back to addable.\n const existingKey = [...existingDocIds].sort().join(',')\n useEffect(() => {\n setAddedIds((prev) => {\n if (prev.size === 0) return prev\n const next = new Set([...prev].filter((id) => !existingDocIds.has(id)))\n return next.size === prev.size ? prev : next\n })\n // existingDocIds is a fresh Set each render; `existingKey` tracks its contents.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [existingKey])\n\n const addItem = async (hit: SearchHit, sendExistingTranslations: boolean) => {\n setAddingId(hit.docId)\n try {\n const item = {\n _type: 'smartcat.projectItem',\n _key: uuid(),\n docId: hit.docId,\n docType: hit._type,\n // Prefer the draft as source when one exists (the plugin translates the\n // draft version); the caller chose whether to also upload existing\n // translations — matching a fresh \"Add to translation project\".\n sourceIsPublished: !hit.hasDraft,\n sendExistingTranslations,\n }\n await client.patch(projectId).setIfMissing({items: []}).insert('after', 'items[-1]', [item]).commit()\n setAddedIds((prev) => new Set(prev).add(hit.docId))\n toast.push({status: 'success', title: 'Added to project'})\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to add item', description: String(err)})\n } finally {\n setAddingId(null)\n }\n }\n\n return (\n <Stack space={3}>\n <Card padding={4} radius={2} border>\n <Stack space={4}>\n <Stack space={3}>\n <TextInput\n icon={SearchIcon}\n placeholder=\"Search documents to add — by title, or schema type…\"\n value={query}\n onChange={(e) => setQuery(e.currentTarget.value)}\n clearButton={query.length > 0}\n onClear={() => setQuery('')}\n />\n <Flex as=\"label\" align=\"center\" gap={2} style={{cursor: 'pointer'}}>\n <Checkbox checked={searchContent} onChange={(e) => setSearchContent(e.currentTarget.checked)} />\n <Text size={1} muted>\n Also search in content (slower; matches body text, not just titles)\n </Text>\n </Flex>\n </Stack>\n\n {loading ? (\n <Flex align=\"center\" justify=\"center\" padding={4}>\n <Spinner muted />\n </Flex>\n ) : results === null ? null : results.length === 0 ? (\n <Text muted align=\"center\" size={1}>\n No documents match “{query.trim()}”.\n </Text>\n ) : (\n <Stack space={2}>\n {results.map((hit) => {\n // \"Added\" means added to *this* project — the only case where\n // adding again is redundant. Membership in other projects is fine\n // and just listed below.\n const inThisProject = addedIds.has(hit.docId) || existingDocIds.has(hit.docId)\n const memberships = projectsByDoc.get(hit.docId) ?? []\n // Preview (and translate) the draft when there is one; else the published doc.\n const previewId = hit.hasDraft ? `drafts.${hit.docId}` : hit.docId\n return (\n <Card key={hit.docId} padding={2} radius={2} shadow={1}>\n <Flex align=\"center\" gap={3}>\n <Box flex={1}>\n <Stack space={2}>\n <Flex align=\"center\" gap={2}>\n <Badge\n tone={hit.hasDraft ? 'caution' : 'positive'}\n paddingX={2}\n title={\n hit.hasDraft\n ? 'The draft version will be the translation source'\n : 'The published version will be the translation source'\n }\n >\n {hit.hasDraft ? 'Draft' : 'Published'}\n </Badge>\n <Text weight=\"medium\" textOverflow=\"ellipsis\">\n <DocTitle doc={{_id: previewId, _type: hit._type}} />\n </Text>\n <Badge tone=\"primary\" paddingX={2}>\n {hit._type}\n </Badge>\n </Flex>\n {memberships.length > 0 && (\n <Text size={0} muted>\n In:{' '}\n {memberships.map((p, i) => (\n <Fragment key={p._id}>\n {i > 0 && ', '}\n <ProjectChip project={p} current={p._id === projectId} />\n </Fragment>\n ))}\n </Text>\n )}\n </Stack>\n </Box>\n <OpenInStudioButton id={hit.docId} type={hit._type} />\n <ViewLocjsonButton\n docId={hit.docId}\n type={hit._type}\n sourceIsPublished={!hit.hasDraft}\n client={client}\n schema={schema}\n sourceLanguage={sourceLanguage}\n documentI18nLanguageField={documentI18nLanguageField}\n fieldI18nLanguageField={fieldI18nLanguageField}\n targetLanguages={targetLanguages}\n languages={languages}\n />\n {inThisProject ? (\n <Button mode=\"bleed\" icon={CheckmarkIcon} text=\"Added\" fontSize={1} padding={2} disabled />\n ) : (\n <MenuButton\n id={`add-${hit.docId}`}\n button={\n <Button\n mode=\"ghost\"\n icon={AddIcon}\n iconRight={ChevronDownIcon}\n text=\"Add\"\n fontSize={1}\n padding={2}\n loading={addingId === hit.docId}\n disabled={addingId !== null}\n />\n }\n menu={\n <Menu>\n <MenuItem text=\"Add source\" onClick={() => addItem(hit, false)} />\n <MenuItem text=\"Add source + translations\" onClick={() => addItem(hit, true)} />\n </Menu>\n }\n popover={{portal: true}}\n />\n )}\n </Flex>\n </Card>\n )\n })}\n </Stack>\n )}\n </Stack>\n </Card>\n <Text size={1} muted>\n You can also add content from a document’s “⋯ → Add to translation project” menu.\n </Text>\n </Stack>\n )\n}\n","import {useEffect, useLayoutEffect, useRef, useState} from 'react'\nimport {Box, Button, Card, Flex, Heading, Stack, Text, useTheme} from '@sanity/ui'\nimport {CheckmarkIcon, CopyIcon} from '@sanity/icons'\nimport type {LogLine, LogLevel} from '../lib/log'\n\n/** Flat, paste-friendly text for the whole log (indented lines + any values). */\nfunction logsToText(logs: LogLine[]): string {\n return logs\n .map((l) => {\n const prefix = l.indent ? ' ' : ''\n const detail = [\n l.before !== undefined ? `before: ${l.before}` : null,\n l.value !== undefined ? `${l.before !== undefined ? 'after' : 'value'}: ${l.value}` : null,\n l.error !== undefined ? `error: ${l.error}` : null,\n ]\n .filter(Boolean)\n .map((d) => ` ${d}`)\n .join('\\n')\n return `${prefix}${l.message}${detail ? `\\n${detail}` : ''}`\n })\n .join('\\n')\n}\n\nconst MONO = 'var(--font-family-mono, monospace)'\nconst VALUE_BG = 'var(--card-code-bg-color, rgba(127,127,127,0.12))'\n\n/** Status glyph per level. Info/update have none — only success/error/skip are marked. */\nconst GLYPH: Record<LogLevel, string> = {info: '', success: '✓', skip: '–', error: '✗', update: ''}\n\n/** Level → a theme-provided foreground colour (muted tone, good contrast in both themes). */\nfunction levelColor(theme: ReturnType<typeof useTheme>, level: LogLevel): string | undefined {\n const muted = theme.sanity.color.muted\n if (level === 'success') return muted.positive.enabled.fg\n if (level === 'error') return muted.critical.enabled.fg\n if (level === 'update') return muted.primary.enabled.fg\n return undefined\n}\n\n/** Background for a value box: light red for errors, the neutral gray otherwise. */\nfunction valueBg(theme: ReturnType<typeof useTheme>, level: LogLevel): string {\n return level === 'error' ? theme.sanity.color.muted.critical.enabled.bg : VALUE_BG\n}\n\n/** A value box; optional label (e.g. \"Before\"/\"After\") shown above the text. */\nfunction ValueBox({label, text, bg}: {label?: string; text: string; bg: string}) {\n return (\n <Box flex={1} padding={2} style={{background: bg, borderRadius: 3, minWidth: 0}}>\n <Stack space={2}>\n {label && (\n <Text size={0} muted weight=\"semibold\">\n {label}\n </Text>\n )}\n <Text size={0} style={{fontFamily: MONO, whiteSpace: 'pre-wrap'}}>\n {text}\n </Text>\n </Stack>\n </Box>\n )\n}\n\nfunction LogRow({line}: {line: LogLine}) {\n const theme = useTheme()\n const [open, setOpen] = useState(false)\n const hasDetail = line.value !== undefined || line.before !== undefined || line.error !== undefined\n const toggle = hasDetail ? () => setOpen((v) => !v) : undefined\n return (\n <Box paddingLeft={line.indent ? 4 : 0}>\n <Text\n size={1}\n muted={line.level === 'skip'}\n onClick={toggle}\n style={{\n fontFamily: MONO,\n whiteSpace: 'pre-wrap',\n cursor: hasDetail ? 'pointer' : 'default',\n color: levelColor(theme, line.level),\n }}\n >\n {/* Triangle is part of the line text, pushing the message right. */}\n {hasDetail && <span style={{opacity: 0.6, userSelect: 'none'}}>{open ? '▾' : '▸'} </span>}\n {GLYPH[line.level] ? <span style={{opacity: 0.7}}>{GLYPH[line.level]} </span> : null}\n {line.message}\n </Text>\n {hasDetail && open && (\n <Box marginTop={1}>\n <Stack space={2}>\n {line.before !== undefined ? (\n // Before/after side by side, two boxes with a gap.\n <Flex gap={3} align=\"stretch\">\n <ValueBox label=\"Before\" text={line.before} bg={valueBg(theme, line.level)} />\n <ValueBox label=\"After\" text={line.value ?? ''} bg={valueBg(theme, line.level)} />\n </Flex>\n ) : line.value !== undefined ? (\n <ValueBox text={line.value} bg={valueBg(theme, line.level)} />\n ) : null}\n {line.error !== undefined && (\n <ValueBox label=\"JSON error\" text={line.error} bg={valueBg(theme, line.level)} />\n )}\n </Stack>\n </Box>\n )}\n </Box>\n )\n}\n\n/**\n * Live, collapsible log of the export/import flow. Collapsed by default. While\n * expanded it auto-scrolls to the newest line only when the user is already at\n * the bottom; once they scroll up to inspect, it stops following so the view\n * doesn't jump out from under them.\n */\nexport function LogPanel({\n logs,\n expanded: expandedProp,\n onExpandedChange,\n}: {\n logs: LogLine[]\n /** Controlled expansion; omit to let the panel manage its own (collapsed default). */\n expanded?: boolean\n onExpandedChange?: (expanded: boolean) => void\n}) {\n const [internalExpanded, setInternalExpanded] = useState(false)\n const expanded = expandedProp ?? internalExpanded\n const setExpanded = (next: boolean) => {\n onExpandedChange?.(next)\n if (expandedProp === undefined) setInternalExpanded(next)\n }\n const [copied, setCopied] = useState(false)\n const scrollRef = useRef<HTMLDivElement>(null)\n const stickToBottom = useRef(true)\n const copyTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n useEffect(() => () => {\n if (copyTimeout.current) clearTimeout(copyTimeout.current)\n }, [])\n\n const handleCopy = () => {\n navigator.clipboard?.writeText(logsToText(logs))\n setCopied(true)\n if (copyTimeout.current) clearTimeout(copyTimeout.current)\n copyTimeout.current = setTimeout(() => setCopied(false), 1500)\n }\n\n const handleScroll = () => {\n const el = scrollRef.current\n if (!el) return\n stickToBottom.current = el.scrollHeight - el.scrollTop - el.clientHeight < 8\n }\n\n useLayoutEffect(() => {\n const el = scrollRef.current\n if (el && stickToBottom.current) el.scrollTop = el.scrollHeight\n }, [logs, expanded])\n\n return (\n <Stack space={3}>\n <Flex\n align=\"center\"\n gap={2}\n onClick={() => setExpanded(!expanded)}\n style={{cursor: 'pointer', userSelect: 'none'}}\n >\n <Heading size={1}>\n {expanded ? '▾' : '▸'} {logs.length > 0 ? `Log (${logs.length})` : 'Log'}\n </Heading>\n </Flex>\n\n {expanded && (\n <Card radius={2} border style={{position: 'relative'}}>\n {logs.length === 0 ? (\n <Box padding={3}>\n <Text size={1} muted>\n The log is empty — it will show the status of any send or import operation.\n </Text>\n </Box>\n ) : (\n <>\n <Box style={{position: 'absolute', top: 6, right: 6, zIndex: 1}}>\n <Button\n mode=\"ghost\"\n padding={2}\n fontSize={1}\n icon={copied ? CheckmarkIcon : CopyIcon}\n tone={copied ? 'positive' : 'default'}\n onClick={handleCopy}\n title={copied ? 'Copied' : 'Copy log'}\n />\n </Box>\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n style={{maxHeight: 320, overflowY: 'auto', padding: 12}}\n >\n <Stack space={2}>\n {logs.map((line, i) => (\n <LogRow key={i} line={line} />\n ))}\n </Stack>\n </div>\n </>\n )}\n </Card>\n )}\n </Stack>\n )\n}\n","/**\n * Live, in-memory log lines for the export/import flows, streamed to the\n * ProjectView Log panel as each document and field is processed. Never persisted\n * — purely a session-scoped trace for troubleshooting (e.g. on client calls).\n */\nexport type LogLevel = 'info' | 'success' | 'skip' | 'error' | 'update'\n\nexport interface LogLine {\n level: LogLevel\n message: string\n /** Field-level lines are indented under their document header. */\n indent?: boolean\n /** Optional value (source or translated text); revealed on click in the panel. */\n value?: string\n /** Prior value; when set, the panel shows `before` and `value` side by side. */\n before?: string\n /** Extra detail (e.g. a JSON parse error); shown in its own box on expand. */\n error?: string\n}\n\n/** Sink for log lines; processing accepts one to stream progress to the UI. */\nexport type LogFn = (line: LogLine) => void\n\n/** Parse a Function's JSON-encoded `functionLog` field into log lines (lenient). */\nexport function parseFunctionLog(raw: string | null | undefined): LogLine[] {\n if (!raw) return []\n try {\n const parsed = JSON.parse(raw)\n return Array.isArray(parsed) ? (parsed as LogLine[]) : []\n } catch {\n return []\n }\n}\n","import {useCallback, useEffect, useRef, useState} from 'react'\nimport {useClient, useRelativeTime, useSchema} from 'sanity'\nimport {applyImportedTranslations, prepareExport, type PendingDeletion} from './processing'\nimport {localizationMode} from '../lib/locjson/fields'\nimport type {LocalizationMode} from '../lib/locjson/types'\nimport {\n Badge,\n Box,\n Button,\n Card,\n Checkbox,\n Dialog,\n Flex,\n Heading,\n Inline,\n Spinner,\n Stack,\n Text,\n TextInput,\n useToast,\n} from '@sanity/ui'\nimport {\n ArrowLeftIcon,\n TrashIcon,\n PublishIcon,\n CloseIcon,\n DownloadIcon,\n SyncIcon,\n RemoveCircleIcon,\n} from '@sanity/icons'\nimport styled, {css, keyframes} from 'styled-components'\nimport {API_VERSION} from '../lib/constants'\nimport {DocTitle} from './DocTitle'\nimport {AddItemsSearch} from './AddItemsSearch'\nimport {OpenInStudioButton, ViewLocjsonButton} from './itemActions'\nimport {PROJECT_DETAIL_QUERY, type ProjectDetail, type ProjectItemRef} from './data'\nimport {StatusBadge, statusLabel} from './StatusBadge'\nimport {ItemProgress, languageTitle} from './ItemProgress'\nimport {LogPanel} from './LogPanel'\nimport {type DocProgress} from '../progress/core'\nimport {parseFunctionLog, type LogLine} from '../lib/log'\nimport type {SmartcatLanguage, TranslationProjectStatus} from '../types'\n\ninterface ProjectViewProps {\n projectId: string\n onBack: () => void\n languages: SmartcatLanguage[]\n sourceLanguage: string\n /** Configured translatable types (undefined = all), shown in the export log. */\n translatableTypes?: string[]\n /** document-internationalization `languageField` (document locale field name). */\n documentI18nLanguageField: string\n /** internationalized-array locale key: field name (`'language'`) or `'_key'`. */\n fieldI18nLanguageField: string\n}\n\n/**\n * Shows how a language maps to Smartcat: `(fr)` when the codes match, or\n * `(PL-PL → pl)` when the Sanity id differs from the Smartcat code.\n */\nfunction languageMappingLabel(language: SmartcatLanguage): string {\n const code = language.smartcatLanguage || language.id\n return code === language.id ? language.id : `${language.id} → ${code}`\n}\n\n/**\n * Statuses during which a Function is actively running, so the project shouldn't\n * be re-sent until it settles. `translating`/`sent`/`completed` are resting\n * states (work is happening in Smartcat, or it's done) — re-syncing and importing\n * are allowed there, so they are deliberately excluded.\n */\nconst IN_FLIGHT: TranslationProjectStatus[] = ['queued', 'importing', 'downloaded']\n\n/**\n * Statuses during which importing is allowed: the Smartcat project exists and\n * we're not mid export/import. Import pulls only the targets that are 100%\n * complete, so it's useful any time translation is underway or finished.\n */\nconst CAN_IMPORT: TranslationProjectStatus[] = ['sent', 'translating', 'completed']\n\nconst rotate = keyframes`\n to { transform: rotate(360deg); }\n`\n/** SyncIcon that spins while a refresh is in flight (keeps the button label visible). */\nconst SpinningSyncIcon = styled(SyncIcon)<{$spinning?: boolean}>`\n ${({$spinning}) =>\n $spinning &&\n css`\n animation: ${rotate} 0.8s linear infinite;\n `}\n`\n\n/** \"Last update: x ago\" — relative time, with the absolute timestamp on hover. */\nfunction LastUpdate({date}: {date: string}) {\n const relative = useRelativeTime(date, {useTemporalPhrase: true})\n return (\n <Text size={1} muted title={new Date(date).toLocaleString()}>\n Last update: {relative}\n </Text>\n )\n}\n\nexport function ProjectView({\n projectId,\n onBack,\n languages,\n sourceLanguage,\n translatableTypes,\n documentI18nLanguageField,\n fieldI18nLanguageField,\n}: ProjectViewProps) {\n const client = useClient({apiVersion: API_VERSION})\n const schema = useSchema()\n const toast = useToast()\n const [project, setProject] = useState<ProjectDetail | null | undefined>(undefined)\n const [name, setName] = useState('')\n const [busy, setBusy] = useState(false)\n const [sending, setSending] = useState(false)\n const [importing, setImporting] = useState(false)\n const [cancelling, setCancelling] = useState(false)\n const [refreshing, setRefreshing] = useState(false)\n const [targets, setTargets] = useState<string[]>([])\n const [confirmDelete, setConfirmDelete] = useState(false)\n // Local-only: which items the editor has marked for deletion. Reset on reload;\n // committed to Smartcat + the project only when the user re-syncs.\n const [markedForDeletion, setMarkedForDeletion] = useState<Set<string>>(new Set())\n // Session-only live trace of the current export/import run (never persisted).\n const [logs, setLogs] = useState<LogLine[]>([])\n // Controlled so a partial-failure export can auto-expand the panel.\n const [logExpanded, setLogExpanded] = useState(false)\n const appendLog = useCallback((line: LogLine) => setLogs((prev) => [...prev, line]), [])\n // Merge a Function's server-side log (from the project doc) as an indented\n // group under a header, mirroring how per-document client lines are grouped.\n const appendServerLog = useCallback(\n (raw: string | null | undefined, header: string) => {\n const lines = parseFunctionLog(raw)\n // Our Functions always emit ≥1 line by this point, so an empty log here\n // means an outdated Function is deployed — surface that instead of nothing.\n setLogs((prev) =>\n lines.length === 0\n ? [...prev, {level: 'info', message: `${header}: no server log returned — deploy the latest Functions to see server-side steps`}]\n : [...prev, {level: 'info', message: header}, ...lines.map((l) => ({...l, indent: true}))],\n )\n },\n [],\n )\n const seeded = useRef(false)\n\n const toggleMark = useCallback((key: string) => {\n setMarkedForDeletion((prev) => {\n const next = new Set(prev)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const load = useCallback(() => {\n return client\n .fetch<ProjectDetail | null>(PROJECT_DETAIL_QUERY, {id: projectId})\n .then((res) => {\n setProject(res)\n if (res) setName(res.name)\n // Seed the target-language selection once, so live updates don't clobber edits.\n if (res && !seeded.current) {\n setTargets(res.targetLanguages ?? [])\n seeded.current = true\n }\n })\n .catch((err) => toast.push({status: 'error', title: 'Failed to load project', description: String(err)}))\n }, [client, projectId, toast])\n\n useEffect(() => {\n load()\n const sub = client\n .listen(PROJECT_DETAIL_QUERY, {id: projectId}, {visibility: 'query'})\n .subscribe({next: () => load(), error: () => {}})\n return () => sub.unsubscribe()\n }, [client, projectId, load])\n\n // When the import Function has downloaded translations (status \"downloaded\"),\n // process them here in the browser: build locale variants + metadata links.\n const processingDownload = useRef(false)\n useEffect(() => {\n // Each import cycle starts at \"importing\"; clear the guard there so the next\n // \"downloaded\" is processed (otherwise a second import in the same session is\n // blocked, leaving the project stuck at \"downloaded\").\n if (project?.status === 'importing') processingDownload.current = false\n if (project?.status !== 'downloaded' || processingDownload.current) return\n processingDownload.current = true\n // Targets the download Function deferred (size/time caps); after applying\n // this batch we auto-continue the import so nobody has to click through.\n const remaining = project.importRemaining ?? 0\n appendLog({level: 'info', message: 'Translations downloaded — applying to documents'})\n // The import Function's download log lands on the doc; show it before the\n // browser-side apply log so the import reads top-to-bottom.\n appendServerLog(project.functionLog, 'Import function')\n applyImportedTranslations({\n client,\n schema,\n projectId,\n documentLanguageField: documentI18nLanguageField,\n fieldLanguageKey: fieldI18nLanguageField,\n onLog: appendLog,\n })\n .then(async ({imported, status}) => {\n // Auto-continue only while each cycle makes progress — a cycle that\n // applied nothing would defer the same targets forever, so it stops\n // and leaves the button to the user.\n if (remaining > 0 && imported > 0) {\n appendLog({level: 'success', message: `Imported ${imported} localized version(s)`})\n appendLog({level: 'info', message: `${remaining} target(s) still on Smartcat — continuing import automatically`})\n processingDownload.current = false\n await client.patch(projectId).set({status: 'importing', lastError: null}).commit()\n return\n }\n const description =\n status === 'completed'\n ? 'All targets are fully translated — project completed.'\n : 'Some targets are still translating — import again later to pull the rest.'\n appendLog({level: 'success', message: `Imported ${imported} localized version(s)`})\n appendLog({level: status === 'completed' ? 'success' : 'info', message: description})\n toast.push({status: 'success', title: `Imported ${imported} localized version(s)`, description})\n })\n .catch((err) => {\n // Leave the guard set so we don't auto-retry in a loop (status stays\n // \"downloaded\"); a fresh import (status \"importing\") clears it to retry.\n appendLog({level: 'error', message: `Failed to apply translations: ${String(err)}`})\n toast.push({status: 'error', title: 'Failed to apply translations', description: String(err)})\n })\n }, [project?.status, client, schema, projectId, toast, documentI18nLanguageField, fieldI18nLanguageField, appendLog, appendServerLog])\n\n // After handing the outbox to the export Function, log its response (observed\n // via listen()): status flips to \"sent\" (+ project URL) on success, or \"error\"\n // (+ lastError) on failure. Guarded by a ref so it only fires for a send we\n // started this session, not on initial load of an already-sent project.\n const exportInFlight = useRef(false)\n useEffect(() => {\n if (!exportInFlight.current) return\n if (project?.status === 'sent') {\n appendServerLog(project.functionLog, 'Export function')\n appendLog({level: 'success', message: 'Sent to Smartcat'})\n if (project.smartcatProjectUrl) appendLog({level: 'info', message: `Smartcat project: ${project.smartcatProjectUrl}`})\n // Partial failure: the sync completed (status \"sent\") but some documents\n // failed to upload/update. Flag it and open the log so the errors are seen.\n if (parseFunctionLog(project.functionLog).some((l) => l.level === 'error')) {\n toast.push({status: 'warning', title: 'There were errors sending content into Smartcat — check the log'})\n setLogExpanded(true)\n }\n exportInFlight.current = false\n } else if (project?.status === 'error') {\n appendServerLog(project.functionLog, 'Export function')\n appendLog({level: 'error', message: `Export failed: ${project.lastError ?? 'unknown error'}`})\n exportInFlight.current = false\n }\n }, [project?.status, project?.smartcatProjectUrl, project?.lastError, project?.functionLog, appendLog, appendServerLog, toast])\n\n // Refresh per-document progress from Smartcat. The browser only bumps the\n // `progressRequestedAt` trigger; the smartcat-progress Function reacts (it\n // holds the API key), fetches the Smartcat project, and writes the stage\n // percentages back — which `listen()` above re-renders.\n const requestProgress = useCallback(() => {\n return client.patch(projectId).set({progressRequestedAt: new Date().toISOString()}).commit()\n }, [client, projectId])\n\n // Track the latest synced timestamp in a ref so a refresh can detect when\n // fresh progress has actually arrived. We can't tie the spinner to the patch\n // commit: on a warm client it resolves in a few ms (before paint), so the\n // spinner was only visible after a cold hard-reload.\n const syncedAtRef = useRef<string | null | undefined>(undefined)\n useEffect(() => {\n syncedAtRef.current = project?.progressSyncedAt\n }, [project?.progressSyncedAt])\n\n const refreshBaseline = useRef<string | null | undefined>(undefined)\n const refreshTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(\n () => () => {\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n },\n [],\n )\n\n const handleRefreshProgress = useCallback(async () => {\n // Spin until the progress Function writes a new progressSyncedAt (cleared by\n // the effect below), with a safety timeout in case nothing comes back.\n refreshBaseline.current = syncedAtRef.current\n setRefreshing(true)\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n refreshTimeout.current = setTimeout(() => setRefreshing(false), 30000)\n try {\n await requestProgress()\n } catch (err) {\n setRefreshing(false)\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n toast.push({status: 'error', title: 'Failed to refresh progress', description: String(err)})\n }\n }, [requestProgress, toast])\n\n // Stop spinning once fresh progress has landed (progressSyncedAt changed).\n useEffect(() => {\n if (!refreshing) return\n if (project?.progressSyncedAt !== refreshBaseline.current) {\n setRefreshing(false)\n if (refreshTimeout.current) clearTimeout(refreshTimeout.current)\n // The progress Function stamps progressSyncedAt on failure too (and sets\n // lastError). When it did, surface its log so a timeout/error is visible\n // instead of the refresh just quietly not updating.\n if (project?.lastError) {\n appendServerLog(project.functionLog, 'Progress function')\n appendLog({level: 'error', message: `Progress refresh failed: ${project.lastError}`})\n toast.push({status: 'error', title: 'Failed to refresh progress', description: project.lastError})\n setLogExpanded(true)\n }\n }\n }, [project?.progressSyncedAt, project?.lastError, project?.functionLog, refreshing, appendServerLog, appendLog, toast])\n\n // Auto-refresh once on page load, as soon as a Smartcat project exists. Runs\n // the same handler as the button, so the loading state matches.\n const progressRequested = useRef(false)\n useEffect(() => {\n if (progressRequested.current || !project?.smartcatProjectId) return\n progressRequested.current = true\n handleRefreshProgress()\n }, [project?.smartcatProjectId, handleRefreshProgress])\n\n const handleRename = useCallback(async () => {\n const trimmed = name.trim()\n if (!trimmed || trimmed === project?.name) return\n setBusy(true)\n try {\n await client.patch(projectId).set({name: trimmed}).commit()\n toast.push({status: 'success', title: 'Renamed project'})\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to rename', description: String(err)})\n } finally {\n setBusy(false)\n }\n }, [name, project, client, projectId, toast])\n\n const handleDelete = useCallback(async () => {\n setBusy(true)\n try {\n await client.delete(projectId)\n toast.push({status: 'success', title: 'Deleted project'})\n onBack()\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to delete', description: String(err)})\n setBusy(false)\n }\n }, [client, projectId, toast, onBack])\n\n const toggleTarget = useCallback((id: string) => {\n setTargets((prev) => (prev.includes(id) ? prev.filter((t) => t !== id) : [...prev, id]))\n }, [])\n\n const handleImport = useCallback(async () => {\n setImporting(true)\n try {\n // Clear the download-processing guard up front (race-free), so this import's\n // \"downloaded\" state is processed even if we never observe the \"importing\"\n // transition via listen().\n processingDownload.current = false\n await client.patch(projectId).set({status: 'importing', lastError: null}).commit()\n // Clear here (not when the download lands) so these lines lead the import log.\n setLogs([])\n appendLog({level: 'info', message: 'Importing from Smartcat'})\n appendLog({level: 'info', message: 'The import function will download translations and create localized versions.'})\n toast.push({\n status: 'success',\n title: 'Importing from Smartcat',\n description: 'The import function will download translations and create localized versions.',\n })\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to start import', description: String(err)})\n } finally {\n setImporting(false)\n }\n }, [client, projectId, toast, appendLog])\n\n const handleCancel = useCallback(async () => {\n setCancelling(true)\n try {\n // Reset to draft so the project can be edited and re-sent. This is a local\n // undo — it does not delete an already-created Smartcat project.\n await client.patch(projectId).set({status: 'draft'}).commit()\n toast.push({status: 'success', title: 'Cancelled — project reset to draft'})\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to cancel', description: String(err)})\n } finally {\n setCancelling(false)\n }\n }, [client, projectId, toast])\n\n const handleSend = useCallback(async () => {\n if (targets.length === 0) {\n toast.push({status: 'warning', title: 'Select at least one target language'})\n return\n }\n setSending(true)\n setLogs([])\n try {\n // Translate marked items into deletion instructions for the export Function:\n // pair each with one of its Smartcat document ids (one id deletes the whole doc).\n const deletions: PendingDeletion[] = []\n for (const item of project?.items ?? []) {\n if (!markedForDeletion.has(item._key) || !item.doc?._id) continue\n const dp = (project?.progress ?? []).find((p) => p.sourceDocId === item.doc!._id)\n // Any one target id deletes the whole document, so pick the first target\n // that actually has one (matches the `isLinked` check in the item list —\n // targets[0] may not be the one carrying the id).\n const smartcatDocumentId = dp?.targets?.find((t) => t.smartcatDocumentId)?.smartcatDocumentId\n deletions.push({\n itemKey: item._key,\n sourceDocId: item.doc._id,\n smartcatDocumentId,\n })\n }\n\n // Serialize content to LocJSON here in the Studio (real schema + DOM),\n // then queue it; the thin export Function uploads, updates and deletes.\n const {prepared, deleting} = await prepareExport({\n client,\n schema,\n projectId,\n targetLanguages: targets,\n sourceLanguage,\n languages,\n translatableTypes,\n exclude: [documentI18nLanguageField],\n fieldLanguageKey: fieldI18nLanguageField,\n deletions,\n onLog: appendLog,\n })\n setMarkedForDeletion(new Set())\n // Hand-off: the outbox is queued; the export Function now uploads it. Arm\n // the response watcher so its result (\"sent\"/\"error\") lands in the log.\n exportInFlight.current = true\n appendLog({level: 'info', message: 'Uploading to Smartcat via the export function…'})\n toast.push({\n status: 'success',\n title: 'Queued for Smartcat',\n description:\n `Prepared ${prepared} file(s)` +\n (deleting ? ` and ${deleting} for deletion` : '') +\n '; the export function will sync them.',\n })\n } catch (err) {\n appendLog({level: 'error', message: `Failed to queue: ${String(err)}`})\n toast.push({status: 'error', title: 'Failed to queue', description: String(err)})\n } finally {\n setSending(false)\n }\n }, [targets, client, projectId, toast, schema, sourceLanguage, languages, documentI18nLanguageField, fieldI18nLanguageField, project, markedForDeletion, appendLog])\n\n const handleRemoveItem = useCallback(\n async (item: ProjectItemRef) => {\n try {\n await client.patch(projectId).unset([`items[_key==\"${item._key}\"]`]).commit()\n toast.push({status: 'success', title: 'Removed item'})\n } catch (err) {\n toast.push({status: 'error', title: 'Failed to remove item', description: String(err)})\n }\n },\n [client, projectId, toast],\n )\n\n if (project === undefined) {\n return (\n <Flex align=\"center\" justify=\"center\" padding={5}>\n <Spinner muted />\n </Flex>\n )\n }\n\n if (project === null) {\n return (\n <Stack space={4}>\n <Button icon={ArrowLeftIcon} text=\"Back\" mode=\"bleed\" onClick={onBack} />\n <Card padding={5} radius={2} tone=\"critical\" border>\n <Text>This project no longer exists.</Text>\n </Card>\n </Stack>\n )\n }\n\n const items = project.items ?? []\n const nameChanged = name.trim() !== project.name && name.trim().length > 0\n // Smartcat doesn't allow non-destructive target-language changes after a project\n // exists, so lock the picker once the project has been sent.\n const languagesLocked = Boolean(project.smartcatProjectId)\n\n const progress = project.progress ?? []\n const progressByDoc = new Map<string, DocProgress>()\n for (const p of progress) {\n if (p.sourceDocId) progressByDoc.set(p.sourceDocId, p)\n }\n const markedCount = items.filter((i) => markedForDeletion.has(i._key)).length\n\n // Localization mode is per-type; compute once per distinct type for the labels.\n const modeByType = new Map<string, LocalizationMode>()\n for (const item of items) {\n const t = item.doc?._type\n if (t && !modeByType.has(t)) modeByType.set(t, localizationMode(schema.get(t)))\n }\n\n return (\n <Stack space={5}>\n <Flex align=\"center\" gap={2}>\n <Button icon={ArrowLeftIcon} text=\"Projects\" mode=\"bleed\" onClick={onBack} />\n <Box flex={1} />\n <StatusBadge status={project.status} />\n <Button\n icon={TrashIcon}\n title=\"Delete project…\"\n tone=\"critical\"\n mode=\"bleed\"\n fontSize={1}\n padding={2}\n onClick={() => setConfirmDelete(true)}\n disabled={busy}\n />\n </Flex>\n\n <Card padding={4} radius={2} shadow={1}>\n <Stack space={4}>\n <Flex gap={2} align=\"flex-end\">\n <Box flex={1}>\n <Stack space={2}>\n <Text size={1} weight=\"semibold\" muted>\n Project name\n </Text>\n <TextInput\n value={name}\n onChange={(e) => setName(e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleRename()\n }}\n disabled={busy}\n />\n </Stack>\n </Box>\n <Button text=\"Save\" onClick={handleRename} disabled={!nameChanged || busy} loading={busy} />\n </Flex>\n\n <Text size={1} muted>\n Source: <strong>{languageTitle(languages, project.sourceLanguage || sourceLanguage)}</strong>\n </Text>\n\n <Stack space={2}>\n <Text size={1} muted>\n Target languages\n </Text>\n <Flex gap={6} align=\"center\">\n <Stack space={3} padding={3}>\n {languages\n .filter((l) => l.id !== (project.sourceLanguage || sourceLanguage))\n .map((l) => {\n const selected = targets.includes(l.id)\n const disabled = sending || languagesLocked\n return (\n <Flex key={l.id} align=\"center\" gap={2} as=\"label\" style={{cursor: disabled ? 'default' : 'pointer'}}>\n <Checkbox\n checked={selected}\n disabled={disabled}\n onChange={() => toggleTarget(l.id)}\n />\n <Text size={1}>\n {l.title}\n <span\n title={`Sanity language code: '${l.id}'\\nSmartcat language code: '${l.smartcatLanguage || l.id}'`}\n style={{color: 'var(--card-muted-fg-color)', opacity: 0.6, marginLeft: '1em'}}\n >\n {languageMappingLabel(l)}\n </span>\n </Text>\n </Flex>\n )\n })}\n </Stack>\n {project.smartcatProjectUrl ? (\n <Box flex={1} style={{maxWidth: 500}}>\n <Stack space={4}>\n <Text size={1} muted>\n Smartcat project:{' '}\n <a\n href={project.smartcatProjectUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Open project in Smartcat\"\n >\n {project.name}\n </a>\n </Text>\n {languagesLocked && (\n <Text size={1} muted>\n Target languages are locked once the project has been sent to Smartcat.\n </Text>\n )}\n </Stack>\n </Box>\n ) : (\n targets.length === 0 && (\n <Box flex={1} style={{maxWidth: 500}}>\n <Text size={1} muted>\n Select one or more languages to translate your content into before you can\n send it to Smartcat for translation.\n </Text>\n </Box>\n )\n )}\n </Flex>\n </Stack>\n </Stack>\n </Card>\n\n {project.lastError && (\n <Card padding={3} radius={2} tone=\"critical\" border>\n <Text size={1}>{project.lastError}</Text>\n </Card>\n )}\n\n <Flex align=\"center\" gap={3} wrap=\"wrap\">\n <Button\n icon={PublishIcon}\n text=\"Send to Smartcat\"\n // Primary only when it's actually actionable (unsent, with items to\n // send); otherwise it's a secondary action (ghost, like Import) and\n // \"Import translations\" becomes primary.\n mode={!languagesLocked && items.length > 0 ? undefined : 'ghost'}\n tone={!languagesLocked && items.length > 0 ? 'primary' : undefined}\n onClick={handleSend}\n loading={sending}\n disabled={sending || items.length === 0 || targets.length === 0 || IN_FLIGHT.includes(project.status)}\n />\n <Button\n icon={DownloadIcon}\n text=\"Import translations\"\n mode={languagesLocked ? undefined : 'ghost'}\n tone={languagesLocked ? 'primary' : undefined}\n onClick={handleImport}\n loading={importing}\n disabled={importing || !project.smartcatProjectId || !CAN_IMPORT.includes(project.status)}\n />\n {project.smartcatProjectId && (\n <Button\n icon={<SpinningSyncIcon $spinning={refreshing} />}\n text=\"Refresh progress\"\n mode=\"bleed\"\n onClick={handleRefreshProgress}\n disabled={refreshing}\n />\n )}\n {project.progressSyncedAt && <LastUpdate date={project.progressSyncedAt} />}\n {markedCount > 0 && (\n <Text size={1} muted>\n {markedCount} marked for deletion — applied on re-sync\n </Text>\n )}\n {IN_FLIGHT.includes(project.status) && (\n <Inline space={2}>\n <Text size={1} muted>\n Project is <strong>{statusLabel(project.status)}</strong> — wait for it to finish before re-sending.\n </Text>\n <Button\n icon={CloseIcon}\n text=\"Cancel\"\n mode=\"bleed\"\n tone=\"critical\"\n fontSize={1}\n padding={2}\n onClick={handleCancel}\n loading={cancelling}\n disabled={cancelling}\n />\n </Inline>\n )}\n </Flex>\n\n <LogPanel logs={logs} expanded={logExpanded} onExpandedChange={setLogExpanded} />\n\n <Stack space={3}>\n <Flex align=\"center\" gap={2}>\n <Heading size={1}>\n {items.length} {items.length === 1 ? 'Item' : 'Items'}\n </Heading>\n </Flex>\n\n {items.length > 0 && (\n <Stack space={2}>\n {items.map((item) => {\n const docProgress = item.doc ? progressByDoc.get(item.doc._id) : undefined\n // Linked = the item already has document(s) in Smartcat.\n const isLinked = Boolean(docProgress?.targets?.some((t) => t.smartcatDocumentId))\n const isMarked = markedForDeletion.has(item._key)\n return (\n <Card\n key={item._key}\n padding={3}\n radius={2}\n shadow={1}\n tone={isMarked ? 'critical' : undefined}\n >\n <Stack space={3}>\n <Flex align=\"center\" gap={3}>\n <Flex align=\"center\" gap={2}>\n <Badge\n tone={item.sourceIsPublished ? 'positive' : 'caution'}\n paddingX={2}\n title={\n item.sourceIsPublished\n ? 'The published version is the translation source'\n : 'The draft version is the translation source'\n }\n >\n {item.sourceIsPublished ? 'Published' : 'Draft'}\n </Badge>\n <Text weight=\"medium\">\n <span style={isMarked ? {textDecoration: 'line-through'} : undefined}>\n <DocTitle doc={item.doc} />\n </span>\n </Text>\n {item.doc?._type && <Badge tone=\"primary\" paddingX={2}>{item.doc._type}</Badge>}\n {item.doc?._type && modeByType.has(item.doc._type) && (\n <Badge\n tone=\"default\"\n fontSize={0}\n paddingX={2}\n title={\n modeByType.get(item.doc._type) === 'field'\n ? 'This item is translated in field mode; translations will be stored as language variants of each field'\n : 'This item is translated in document mode; translations will be stored as linked documents'\n }\n >\n {modeByType.get(item.doc._type) === 'field' ? 'fields' : 'document'}\n </Badge>\n )}\n <Badge\n tone={item.sendExistingTranslations ? 'primary' : 'default'}\n fontSize={0}\n paddingX={2}\n title={\n item.sendExistingTranslations\n ? 'Existing translations are uploaded to Smartcat (one bilingual file per language) and marked confirmed'\n : 'Only source text is sent; Smartcat translates from scratch'\n }\n >\n {item.sendExistingTranslations ? 'source + translations' : 'source only'}\n </Badge>\n {item.doc && <OpenInStudioButton id={item.doc._id} type={item.doc._type} />}\n {item.doc && (\n <ViewLocjsonButton\n docId={item.doc._id}\n type={item.doc._type}\n sourceIsPublished={item.sourceIsPublished}\n client={client}\n schema={schema}\n sourceLanguage={sourceLanguage}\n documentI18nLanguageField={documentI18nLanguageField}\n fieldI18nLanguageField={fieldI18nLanguageField}\n targetLanguages={targets}\n languages={languages}\n />\n )}\n </Flex>\n <Box flex={1} />\n {isLinked ? (\n <Button\n mode={isMarked ? 'default' : 'bleed'}\n tone=\"critical\"\n icon={RemoveCircleIcon}\n title={isMarked ? 'Unmark for deletion' : 'Mark for deletion'}\n padding={2}\n onClick={() => toggleMark(item._key)}\n />\n ) : (\n <Button\n mode=\"bleed\"\n tone=\"critical\"\n icon={TrashIcon}\n title=\"Remove from project\"\n onClick={() => handleRemoveItem(item)}\n />\n )}\n </Flex>\n {docProgress && (\n <ItemProgress\n doc={docProgress}\n languages={languages}\n smartcatProjectUrl={project.smartcatProjectUrl}\n variants={\n item.doc\n ? {\n type: item.doc._type,\n byLanguage: Object.fromEntries(\n (item.translations ?? []).map((t) => [t.language, t.id]),\n ),\n }\n : undefined\n }\n />\n )}\n </Stack>\n </Card>\n )\n })}\n </Stack>\n )}\n\n <AddItemsSearch\n projectId={projectId}\n translatableTypes={translatableTypes}\n existingDocIds={new Set(items.map((i) => i.docId))}\n sourceLanguage={sourceLanguage}\n languages={languages}\n targetLanguages={targets}\n documentI18nLanguageField={documentI18nLanguageField}\n fieldI18nLanguageField={fieldI18nLanguageField}\n />\n </Stack>\n\n {confirmDelete && (\n <Dialog\n id=\"confirm-delete\"\n header=\"Delete translation project?\"\n onClose={() => setConfirmDelete(false)}\n width={1}\n >\n <Box padding={4}>\n <Stack space={4}>\n <Text>\n Delete <strong>{project.name}</strong>? This removes the project only — the referenced\n content documents are not deleted.\n {project.smartcatProjectId && ' The Smartcat project is not deleted either and will remain in your Smartcat workspace.'}\n </Text>\n <Flex justify=\"flex-end\" gap={2}>\n <Button mode=\"bleed\" text=\"Cancel\" onClick={() => setConfirmDelete(false)} disabled={busy} />\n <Button tone=\"critical\" text=\"Delete\" icon={TrashIcon} onClick={handleDelete} loading={busy} />\n </Flex>\n </Stack>\n </Box>\n </Dialog>\n )}\n </Stack>\n )\n}\n","import {useCallback} from 'react'\nimport {useRouter, useRouterState} from 'sanity/router'\nimport {Box, Container} from '@sanity/ui'\nimport {ProjectsView} from './ProjectsView'\nimport {ProjectView} from './ProjectView'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\n/**\n * Builds the dashboard component for the Translations tool.\n * Uses the tool router to switch between the projects list and a project detail\n * view, so the selected project is reflected in the URL (deep-linkable).\n */\nexport function createDashboardComponent(config: ResolvedSmartcatConfig) {\n const {sourceLanguage, languages, translatableTypes, documentI18nLanguageField, fieldI18nLanguageField} =\n config\n\n return function Dashboard() {\n const router = useRouter()\n const projectId = useRouterState(\n useCallback((state) => (state.projectId as string | undefined) ?? null, []),\n )\n\n const openProject = useCallback((id: string) => router.navigate({projectId: id}), [router])\n const goBack = useCallback(() => router.navigate({}), [router])\n\n return (\n <Box padding={4} height=\"fill\" overflow=\"auto\">\n <Container width={2}>\n {projectId ? (\n <ProjectView\n projectId={projectId}\n onBack={goBack}\n languages={languages}\n sourceLanguage={sourceLanguage}\n translatableTypes={translatableTypes}\n documentI18nLanguageField={documentI18nLanguageField}\n fieldI18nLanguageField={fieldI18nLanguageField}\n />\n ) : (\n <ProjectsView sourceLanguage={sourceLanguage} onOpenProject={openProject} />\n )}\n </Container>\n </Box>\n )\n }\n}\n","import {route} from 'sanity/router'\nimport {TranslateIcon} from '@sanity/icons'\nimport type {Tool} from 'sanity'\nimport {createDashboardComponent} from './Dashboard'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\n/** Tool name; also the URL segment used to deep-link into the tool. */\nexport const TRANSLATION_TOOL_NAME = 'translation-projects'\n\n/** Builds the \"Translations\" Studio tool (top-nav dashboard). */\nexport function createTranslationsTool(config: ResolvedSmartcatConfig): Tool {\n return {\n name: TRANSLATION_TOOL_NAME,\n title: 'Translation Projects',\n icon: TranslateIcon,\n component: createDashboardComponent(config),\n router: route.create('/', [route.create('/project/:projectId')]),\n }\n}\n","import {Fragment, useCallback, useEffect, useState, type MouseEvent} from 'react'\nimport {useClient, useFormValue, useWorkspace, type InputProps} from 'sanity'\nimport {Card, Stack, Text, type CardTone} from '@sanity/ui'\nimport {useRouter} from 'sanity/router'\nimport {API_VERSION, TRANSLATION_PROJECT_TYPE} from '../lib/constants'\nimport {ITEM_ID} from '../lib/projectItems'\nimport {localizationMode} from '../lib/locjson/fields'\nimport {TRANSLATION_TOOL_NAME} from '../tool'\nimport type {LocalizationMode} from '../lib/locjson/types'\nimport type {ResolvedSmartcatConfig} from '../lib/resolveConfig'\n\ninterface ProjectRef {\n _id: string\n name?: string\n /** True when this document is itself in the project's items (the source it was\n * added as); false when it matched via a sibling variant (a translation target). */\n isSource: boolean\n /** True when the project actually targets this document's language — i.e. this\n * variant is a real translation target of it, not just a sibling of its source. */\n targetsThisLanguage: boolean\n}\n\n// Match projects whose items reference this document OR one of its sibling\n// language variants — so the banner shows on both the source and its translated\n// (document-level i18n) variants. The sibling ids come from the\n// translation.metadata group that references this document. Per project we also\n// record which role this document plays: `isSource` (the doc is itself an item)\n// and `targetsThisLanguage` (the project targets this doc's language, so this\n// variant is a genuine target — a project that references the source but doesn't\n// target this language is not). The same document can be a source in one project\n// and a target in another (e.g. pivot-language translation).\nconst QUERY = `*[_type == \"${TRANSLATION_PROJECT_TYPE}\" && count(items[\n ${ITEM_ID} in [$id] + *[_type == \"translation.metadata\" && references($id)].translations[].value._ref\n]) > 0] | order(_updatedAt desc){\n _id,\n name,\n \"isSource\": count(items[${ITEM_ID} == $id]) > 0,\n \"targetsThisLanguage\": $language in targetLanguages\n}`\n\n/** A link to a project's page in the Translations tool, with SPA navigation. */\nfunction ProjectLink({basePath, project}: {basePath: string; project: ProjectRef}) {\n const router = useRouter()\n // basePath is \"/\" by default or a configured prefix; join without doubling slashes.\n const href = `${basePath.replace(/\\/$/, '')}/${TRANSLATION_TOOL_NAME}/project/${project._id}`\n const onClick = useCallback(\n (e: MouseEvent) => {\n // Let modifier-clicks (new tab/window) use the href; otherwise navigate in-app.\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return\n e.preventDefault()\n router.navigateUrl({path: href})\n },\n [router, href],\n )\n return (\n <a href={href} onClick={onClick}>\n {project.name || 'Untitled project'}\n </a>\n )\n}\n\n/** A self-contained card listing same-role projects. `lead` is the full text before the links. */\nfunction RoleCard({\n lead,\n tone = 'primary',\n warning,\n basePath,\n projects,\n}: {\n lead: string\n tone?: CardTone\n warning?: string\n basePath: string\n projects: ProjectRef[]\n}) {\n return (\n <Card tone={tone} padding={3} radius={2} border>\n <Stack space={3}>\n <Text size={1}>\n {lead}\n {projects.map((p, i) => (\n <Fragment key={p._id}>\n {i > 0 && ', '}\n <ProjectLink basePath={basePath} project={p} />\n </Fragment>\n ))}\n </Text>\n {warning && (\n <Text size={1} weight=\"semibold\">\n {warning}\n </Text>\n )}\n </Stack>\n </Card>\n )\n}\n\n/**\n * Status banner naming the project(s) this document belongs to, each linking to\n * its page in the tool.\n *\n * For document-level localization a document can play both roles across projects\n * (source in one, target in another), so source and variant memberships get\n * their own lines. For field-level localization the single document holds every\n * language, so there is no source/variant distinction — it's just \"this document\".\n */\nfunction TranslationStatusLine({mode}: {mode: LocalizationMode}) {\n const client = useClient({apiVersion: API_VERSION})\n const {basePath} = useWorkspace()\n const docId = (useFormValue(['_id']) as string | undefined)?.replace(/^drafts\\./, '')\n const language = (useFormValue(['language']) as string | undefined) ?? null\n const [projects, setProjects] = useState<ProjectRef[]>([])\n\n useEffect(() => {\n if (!docId) return undefined\n let cancelled = false\n const params = {id: docId, language}\n const load = () =>\n client\n .fetch<ProjectRef[]>(QUERY, params)\n .then((res) => !cancelled && setProjects(res))\n .catch(() => !cancelled && setProjects([]))\n load()\n const sub = client.listen(QUERY, params, {visibility: 'query'}).subscribe({next: load, error: () => {}})\n return () => {\n cancelled = true\n sub.unsubscribe()\n }\n }, [client, docId, language])\n\n if (projects.length === 0) return null\n\n // Field-level docs hold all languages in one document — neutral, single card.\n if (mode === 'field') {\n return (\n <Stack space={3}>\n <RoleCard\n lead={\n projects.length === 1\n ? 'This document is part of a translation project: '\n : 'This document is part of multiple translation projects: '\n }\n basePath={basePath}\n projects={projects}\n />\n </Stack>\n )\n }\n\n const asSource = projects.filter((p) => p.isSource)\n // A genuine target only if the project actually targets this variant's\n // language — a project that merely includes the source (but targets other\n // languages) doesn't translate into this variant, so it's not a collision.\n const asTarget = projects.filter((p) => !p.isSource && p.targetsThisLanguage)\n\n return (\n <Stack space={3}>\n {asSource.length > 0 && (\n <RoleCard\n lead={\n asSource.length === 1\n ? 'This source document is part of a translation project: '\n : 'This source document is part of multiple translation projects: '\n }\n basePath={basePath}\n projects={asSource}\n />\n )}\n {asTarget.length > 0 && (\n <RoleCard\n // A document being a translation target in more than one project means\n // multiple projects can write back to the same variant — flag it red.\n tone={asTarget.length > 1 ? 'critical' : 'primary'}\n lead={\n asTarget.length === 1\n ? 'This document variant is part of a translation project: '\n : 'This document variant is part of multiple translation projects: '\n }\n warning={\n asTarget.length > 1\n ? 'Importing translations from more than one project can overwrite each other on this document.'\n : undefined\n }\n basePath={basePath}\n projects={asTarget}\n />\n )}\n </Stack>\n )\n}\n\n/**\n * Wraps the document form for translatable types, rendering a status line above\n * the fields when the document belongs to one or more Smartcat translation\n * projects. Resolves live, so it updates as projects change.\n */\nexport function createTranslationStatusInput(config: ResolvedSmartcatConfig) {\n return function TranslationStatusInput(props: InputProps) {\n // Only the document root of a translatable type — not nested fields. This\n // input is registered globally, so the type check also keeps it off the\n // plugin's own `smartcat.*` documents.\n const isDocumentRoot = props.path.length === 0 && config.isTranslatableType(props.schemaType.name)\n if (!isDocumentRoot) return props.renderDefault(props)\n\n return (\n <Stack space={5}>\n <TranslationStatusLine mode={localizationMode(props.schemaType)} />\n {props.renderDefault(props)}\n </Stack>\n )\n }\n}\n","import {useEffect, useRef} from 'react'\nimport {useClient, type LayoutProps} from 'sanity'\nimport {API_VERSION, SETTINGS_DOC_ID, SETTINGS_TYPE} from '../lib/constants'\nimport {isRefreshInFlight} from './useTemplates'\n\ninterface SettingsDoc {\n templatesRequestedAt?: string\n templatesSyncedAt?: string\n}\n\nconst INIT_QUERY = `*[_id == $id][0]{templatesRequestedAt, templatesSyncedAt}`\n\n/**\n * Studio layout wrapper. On first load it bootstraps the template cache *only if\n * it has never been initialized* — i.e. no `templatesSyncedAt` and no request\n * already in flight. Routine freshness is handled by the create dialogs; this\n * just seeds an empty cache the very first time the Studio runs.\n */\nexport function StudioInit(props: LayoutProps) {\n const client = useClient({apiVersion: API_VERSION})\n const didRun = useRef(false)\n\n useEffect(() => {\n if (didRun.current) return\n didRun.current = true\n client\n .fetch<SettingsDoc | null>(INIT_QUERY, {id: SETTINGS_DOC_ID})\n .then((s) => {\n // Skip if already initialized, or a fresh request is still in flight.\n // A stale request (older than the window) falls through and re-bumps.\n if (s?.templatesSyncedAt || isRefreshInFlight(s)) return\n return client\n .transaction()\n .createIfNotExists({_id: SETTINGS_DOC_ID, _type: SETTINGS_TYPE})\n .patch(SETTINGS_DOC_ID, (p) => p.set({templatesRequestedAt: new Date().toISOString()}))\n .commit({visibility: 'async'})\n })\n .catch(() => {})\n }, [client])\n\n return props.renderDefault(props)\n}\n","import {requireSourceLanguage, SETTINGS_TYPE, TRANSLATION_PROJECT_TYPE} from './constants'\nimport type {SmartcatLanguage, SmartcatPluginConfig} from '../types'\n\n/** The plugin's own document types, never translatable regardless of config. */\nconst PLUGIN_TYPES = new Set([TRANSLATION_PROJECT_TYPE, SETTINGS_TYPE])\n\n/**\n * Plugin config with every optional field resolved to its default. This is the\n * single place plugin defaults are applied — notably the internationalized-array\n * locale key, whose default (`'language'`, plugin v5+) is the one version\n * assumption; downstream code receives a concrete value and never re-guesses.\n */\nexport interface ResolvedSmartcatConfig {\n /**\n * Whether a document type shows the \"Add to translation project\" UI. When\n * `translatableTypes` is omitted this is true for every type except the\n * plugin's own `smartcat.*` types; otherwise it's list membership.\n */\n isTranslatableType: (type: string) => boolean\n /**\n * The explicitly-configured translatable types, verbatim, for display/logging.\n * `undefined` means none was configured — every non-plugin type is translatable\n * (see {@link isTranslatableType}). Logic should use the predicate, not this.\n */\n translatableTypes?: string[]\n /** Root/standalone types where the linked-documents crawl stops. */\n rootTypes: string[]\n sourceLanguage: string\n languages: SmartcatLanguage[]\n /** document-internationalization locale field (its `languageField`). */\n documentI18nLanguageField: string\n /** internationalized-array member locale key (`'language'` v5+, `'_key'` v4.x). */\n fieldI18nLanguageField: string\n}\n\nexport function resolveConfig(config: SmartcatPluginConfig): ResolvedSmartcatConfig {\n const translatableTypes = config.translatableTypes\n const isTranslatableType = translatableTypes\n ? (type: string) => translatableTypes.includes(type)\n : (type: string) => !PLUGIN_TYPES.has(type)\n\n return {\n isTranslatableType,\n translatableTypes,\n // `rootTypes` inherits the *explicitly-configured* translatableTypes (not the\n // resolved \"everything\") so an unconfigured Studio gets no crawl boundary\n // rather than every type being a root (which would stop the crawl at once).\n rootTypes: config.rootTypes ?? translatableTypes ?? [],\n sourceLanguage: requireSourceLanguage(config.sourceLanguage),\n languages: config.languages ?? [],\n documentI18nLanguageField: config.documentI18nPluginLanguageField ?? 'language',\n fieldI18nLanguageField: config.fieldI18nPluginLanguageField ?? 'language',\n }\n}\n","import {definePlugin} from 'sanity'\nimport {createTranslationProjectType} from './schema/translationProject'\nimport {createSettingsType} from './schema/settings'\nimport {createAddToProjectAction} from './actions/AddToProjectAction'\nimport {createTranslationStatusInput} from './form/TranslationStatusInput'\nimport {createTranslationsTool} from './tool'\nimport {StudioInit} from './tool/StudioInit'\nimport {resolveConfig} from './lib/resolveConfig'\nimport type {SmartcatPluginConfig} from './types'\n\nexport type {SmartcatPluginConfig, SmartcatLanguage, TranslationProjectStatus} from './types'\n// Re-exported so the `declare module 'sanity'` augmentation (adding\n// `options.smartcatTranslation`) is loaded for consumers of the plugin types.\nexport type {SmartcatTranslationSchemaOptions} from './schema/translatableOptions'\nexport {TRANSLATION_PROJECT_TYPE} from './lib/constants'\n\n/**\n * Smartcat translation plugin for Sanity Studio.\n *\n * - Adds a `smartcat.translationProject` document type (a named set of items).\n * - Adds an \"Add to translation project\" document action on the configured\n * `translatableTypes`.\n * - Shows a status line on those types when the document belongs to one or more\n * translation projects.\n *\n * @public\n */\nexport const smartcatTranslation = definePlugin<SmartcatPluginConfig>((config) => {\n // Resolve all config defaults once, here at the boundary; everything below\n // receives concrete values.\n const resolved = resolveConfig(config)\n const projectType = createTranslationProjectType()\n const settingsType = createSettingsType()\n const addToProjectAction = createAddToProjectAction(resolved)\n const translationStatusInput = createTranslationStatusInput(resolved)\n const translationsTool = createTranslationsTool(resolved)\n\n // The plugin's customizations apply to translatable types (all types by\n // default), but never to the plugin's own `smartcat.*` documents.\n const isTranslatable = resolved.isTranslatableType\n\n return {\n name: 'sanity-plugin-smartcat-translation',\n schema: {\n types: [projectType, settingsType],\n },\n studio: {\n components: {\n // Bootstraps the template cache on first Studio load.\n layout: StudioInit,\n },\n },\n tools: [translationsTool],\n document: {\n actions: (prev, context) => (isTranslatable(context.schemaType) ? [...prev, addToProjectAction] : prev),\n },\n form: {\n components: {\n input: translationStatusInput,\n },\n },\n }\n})\n"],"names":["defineType","TRANSLATION_PROJECT_TYPE","TranslateIcon","defineField","defineArrayMember","SETTINGS_TYPE","CogIcon","jsxs","Select","jsx","TEMPLATE_PREFIX","STANDARD_WORKFLOW_OPTIONS","useClient","API_VERSION","useState","useRef","useEffect","SETTINGS_DOC_ID","useCallback","workflow","useMemo","isWorkflowValid","prepareForPreview","PROJECTS_QUERY","useSchema","useToast","usePerspective","publishedId","uuid","getTranslatableFields","ITEM_ID","Flex","Spinner","Stack","Label","Fragment","TextInput","Card","Text","Badge","Switch","Button","AddIcon","itemDocDeref","ITEM_ID_FROM_SUBQUERY","useRelativeTime","Box","Heading","Dialog","isInternationalizedArrayType","innerValueType","itemDocDerefRespectingDraft","siblingsQuery","buildLanguageMappings","findDuplicateSmartcatLanguages","localizationMode","toSmartcatLanguage","locjson","serializeToLocjson","buildLocjsonFilename","getAtPath","requireSourceLanguage","deserializeFromLocjson","progress","summarizeCompletion","enumerateLeaves","setAtPath","useValuePreview","useIntentLink","LaunchIcon","useTheme_v2","targetPercent","Inline","styled","MenuButton","JsonIcon","ChevronDownIcon","Menu","MenuItem","DownloadIcon","router","useRouter","SearchIcon","Checkbox","CheckmarkIcon","useTheme","useLayoutEffect","CopyIcon","keyframes","SyncIcon","css","ArrowLeftIcon","TrashIcon","PublishIcon","CloseIcon","RemoveCircleIcon","useRouterState","Container","route","useWorkspace","useFormValue","definePlugin"],"mappings":"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"}
|