@braze/sanity-plugin-ai-translation 0.3.0 → 0.3.1
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/README.md +15 -1
- package/dist/index.d.ts +56 -10
- package/dist/index.js +70 -65
- package/dist/index.js.map +1 -1
- package/package.json +21 -19
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ Your Studio must already support internationalized documents.
|
|
|
64
64
|
|
|
65
65
|
Required:
|
|
66
66
|
|
|
67
|
-
- **Sanity Studio
|
|
67
|
+
- **Sanity Studio v6.12 or newer** with `@sanity/ui` v4, React 19.2+, and Node.js 22.12+ (the plugin invokes Sanity Functions through Studio's client, which needs `@sanity/client` 8.3+; Studio 6.12 is the first release that bundles it)
|
|
68
68
|
- `@sanity/document-internationalization` configured
|
|
69
69
|
- `sanity-plugin-internationalized-array` installed and configured (used for glossary term translations)
|
|
70
70
|
- `@sanity/client` **7.1.0+** (required for Agent Actions)
|
|
@@ -159,6 +159,7 @@ export default defineConfig({
|
|
|
159
159
|
|
|
160
160
|
- `schemaId` is usually `'_.schemas.default'` for most projects.
|
|
161
161
|
- `languageFieldName` must match the field your documents use (often `language`).
|
|
162
|
+
- `glossaryDataset` (optional) reads glossary terms from another dataset in the same project. See [`translationGlossaryTerm`](#translationglossaryterm).
|
|
162
163
|
|
|
163
164
|
### 3) Add translation history metadata
|
|
164
165
|
|
|
@@ -382,6 +383,19 @@ Conceptual example:
|
|
|
382
383
|
|
|
383
384
|
Glossary terms are used to build locale-specific translation instructions.
|
|
384
385
|
|
|
386
|
+
By default, glossary terms are read from the dataset of the document being translated. To share one glossary across datasets, set `glossaryDataset` to another dataset in the same project:
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
aiTranslationPlugin({
|
|
390
|
+
// ...
|
|
391
|
+
glossaryDataset: "production",
|
|
392
|
+
});
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
- Terms are read with the editor's existing Studio session, so editors need read access to that dataset.
|
|
396
|
+
- Only glossary terms come from `glossaryDataset`. `translationSettings` (global prompt, locale prompts, protected phrases) is still read from the document's dataset.
|
|
397
|
+
- Nothing is written to either dataset's glossary.
|
|
398
|
+
|
|
385
399
|
---
|
|
386
400
|
|
|
387
401
|
## Advanced configuration
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import { ArrayDefinition } from "sanity";
|
|
2
|
-
import { FieldDefinitionBase } from "sanity";
|
|
3
1
|
import { Plugin as Plugin_2 } from "sanity";
|
|
4
2
|
import type { SanityDocument } from "sanity";
|
|
5
|
-
import { WidenInitialValue } from "sanity";
|
|
6
|
-
import { WidenValidation } from "sanity";
|
|
7
3
|
|
|
8
4
|
/**
|
|
9
5
|
* AI translation plugin for Sanity Studio
|
|
@@ -310,7 +306,7 @@ export declare interface PluginConfig {
|
|
|
310
306
|
* Requires `@sanity/client` 8.1 or newer as Studio's client.
|
|
311
307
|
*/
|
|
312
308
|
openai?: {
|
|
313
|
-
/** Blueprint stack that contains the translation function, e.g. `ST-
|
|
309
|
+
/** Blueprint stack that contains the translation function, e.g. `ST-xxxxxxxxxx`. Required for OpenAI mode. */
|
|
314
310
|
stackId: string;
|
|
315
311
|
/**
|
|
316
312
|
* Name of the translation function, as declared in the blueprint.
|
|
@@ -362,6 +358,17 @@ export declare interface PluginConfig {
|
|
|
362
358
|
* ```
|
|
363
359
|
*/
|
|
364
360
|
unsetFields?: UnsetFieldEntry[];
|
|
361
|
+
/**
|
|
362
|
+
* Dataset (in the same project) to read `translationGlossaryTerm` documents from.
|
|
363
|
+
* Defaults to the dataset of the document being translated.
|
|
364
|
+
* Translation settings and locale prompts are always read from the document's dataset.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```typescript
|
|
368
|
+
* glossaryDataset: 'production'
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
glossaryDataset?: string;
|
|
365
372
|
/**
|
|
366
373
|
* Optional telemetry configuration for monitoring translation operations.
|
|
367
374
|
* Provides callbacks for lightweight events and detailed error bundles.
|
|
@@ -684,12 +691,51 @@ declare type TranslationErrorType =
|
|
|
684
691
|
* @public
|
|
685
692
|
*/
|
|
686
693
|
export declare const translationHistorySchema: {
|
|
687
|
-
type: "array";
|
|
688
694
|
name: "translationHistory";
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
695
|
+
type: "array";
|
|
696
|
+
of: {
|
|
697
|
+
name: string;
|
|
698
|
+
type: "object";
|
|
699
|
+
fields: (
|
|
700
|
+
| {
|
|
701
|
+
name: "language";
|
|
702
|
+
title: string;
|
|
703
|
+
description: string;
|
|
704
|
+
type: "string";
|
|
705
|
+
}
|
|
706
|
+
| {
|
|
707
|
+
name: "sourceId";
|
|
708
|
+
title: string;
|
|
709
|
+
description: string;
|
|
710
|
+
type: "string";
|
|
711
|
+
}
|
|
712
|
+
| {
|
|
713
|
+
name: "sourceRev";
|
|
714
|
+
title: string;
|
|
715
|
+
description: string;
|
|
716
|
+
type: "string";
|
|
717
|
+
}
|
|
718
|
+
| {
|
|
719
|
+
name: "sourceLanguage";
|
|
720
|
+
title: string;
|
|
721
|
+
description: string;
|
|
722
|
+
type: "string";
|
|
723
|
+
}
|
|
724
|
+
| {
|
|
725
|
+
name: "sourceSnapshot";
|
|
726
|
+
title: string;
|
|
727
|
+
description: string;
|
|
728
|
+
type: "text";
|
|
729
|
+
}
|
|
730
|
+
| {
|
|
731
|
+
name: "targetId";
|
|
732
|
+
title: string;
|
|
733
|
+
description: string;
|
|
734
|
+
type: "string";
|
|
735
|
+
}
|
|
736
|
+
)[];
|
|
737
|
+
}[];
|
|
738
|
+
};
|
|
693
739
|
|
|
694
740
|
/**
|
|
695
741
|
* Event emitted when an individual translation job completes successfully
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { WarningOutlineIcon, ErrorOutlineIcon, CheckmarkIcon, SyncIcon, PanelRig
|
|
|
4
4
|
import { createContext, useEffect, useReducer, useRef, useContext, useMemo, useState, useCallback } from "react";
|
|
5
5
|
import { devLog, retryWithBackoff, isNetworkError, isSanityMutationError } from "./_chunks-es/retry.js";
|
|
6
6
|
import defaults from "lodash.defaults";
|
|
7
|
-
import { Card, Stack, Flex, Text, Box, Heading, Button, Spinner, Badge, Inline, Radio, Checkbox, Grid, TextInput, Select, Label
|
|
7
|
+
import { Card, Stack, Flex, Text, Box, Heading, Button, Spinner, Badge, Inline, Radio, Checkbox, Grid, TextInput, Select, Label } from "@sanity/ui";
|
|
8
8
|
import { IntentLink } from "sanity/router";
|
|
9
9
|
import { useOpenInNewPane, useListeningQuery } from "sanity-plugin-utils";
|
|
10
10
|
import { toPlainText } from "@portabletext/react";
|
|
@@ -12,6 +12,8 @@ import { uuid } from "@sanity/uuid";
|
|
|
12
12
|
import cloneDeep from "lodash.clonedeep";
|
|
13
13
|
import get from "lodash.get";
|
|
14
14
|
import set from "lodash.set";
|
|
15
|
+
import { Code } from "@sanity/ui/code";
|
|
16
|
+
import { Tooltip } from "@sanity/ui/tooltip";
|
|
15
17
|
const DEFAULT_TRANSLATION_FUNCTION_NAME = "ai-translation", DEFAULT_MODEL = "gpt-5", TRANSLATION_FUNCTION_TIMEOUT_MS = 9e5, isOpenAIConfigured = (openaiConfig) => !!(openaiConfig?.enabled && typeof openaiConfig.stackId == "string" && openaiConfig.stackId.trim() !== ""), supportsFunctionInvoke = (client) => typeof client.functions?.invoke == "function", toNumber = (value) => typeof value == "number" && Number.isFinite(value) ? value : 0, parseResult = (result, functionName) => {
|
|
16
18
|
const value = result ?? {};
|
|
17
19
|
if (typeof value.content != "string")
|
|
@@ -645,7 +647,10 @@ function documentToPlainText(document) {
|
|
|
645
647
|
) ? result[key] = toPlainText(value) : result[key] = value;
|
|
646
648
|
return JSON.stringify(result);
|
|
647
649
|
}
|
|
648
|
-
|
|
650
|
+
let glossaryDataset;
|
|
651
|
+
const setGlossaryDataset = (dataset) => {
|
|
652
|
+
glossaryDataset = typeof dataset == "string" && dataset.trim() ? dataset.trim() : void 0;
|
|
653
|
+
}, getGlossaryDataset = () => glossaryDataset, DEFAULTS = {
|
|
649
654
|
windowSlack: 2,
|
|
650
655
|
minTokenMatchRatio: 1,
|
|
651
656
|
stopwords: [
|
|
@@ -761,7 +766,11 @@ const fetchTranslationPrompts = async ({
|
|
|
761
766
|
protectedPhrasesCount: translationSettings2?.protectedPhrases?.length,
|
|
762
767
|
targetLanguages
|
|
763
768
|
});
|
|
764
|
-
const
|
|
769
|
+
const glossaryDataset2 = getGlossaryDataset(), glossaryClient = glossaryDataset2 ? client.withConfig({ dataset: glossaryDataset2 }) : client;
|
|
770
|
+
devLog.debug("Fetching glossary terms", {
|
|
771
|
+
glossaryDataset: glossaryDataset2 || "document dataset"
|
|
772
|
+
});
|
|
773
|
+
const translationGlossaryTerms = await glossaryClient.fetch(
|
|
765
774
|
`*[
|
|
766
775
|
_type == "translationGlossaryTerm"
|
|
767
776
|
&& count(translations[_key in $targetLanguages]) > 0
|
|
@@ -3096,7 +3105,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3096
3105
|
onSkipConflicts
|
|
3097
3106
|
}) => {
|
|
3098
3107
|
const uniqueDocuments = useMemo(() => new Set(conflicts.map((c) => c.sourceDocumentId)).size, [conflicts]), nonConflictingCount = totalTranslations - conflicts.length, hasNonConflicting = nonConflictingCount > 0, summaryText = useMemo(() => conflicts.length === 1 ? "1 translation" : uniqueDocuments === 1 ? `${conflicts.length} translations` : `${conflicts.length} translations across ${uniqueDocuments} documents`, [conflicts.length, uniqueDocuments]);
|
|
3099
|
-
return /* @__PURE__ */ jsx(Card, { tone: "caution", padding: 4, border: !0, radius: 2, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3108
|
+
return /* @__PURE__ */ jsx(Card, { tone: "caution", padding: 4, border: !0, radius: 2, children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3100
3109
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
3101
3110
|
/* @__PURE__ */ jsx(Text, { size: 2, children: /* @__PURE__ */ jsx(WarningOutlineIcon, {}) }),
|
|
3102
3111
|
/* @__PURE__ */ jsx(Text, { weight: "semibold", children: "This release already contains translations for this content and target language(s)." })
|
|
@@ -3106,13 +3115,13 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3106
3115
|
summaryText,
|
|
3107
3116
|
" that will be overwritten if you continue:"
|
|
3108
3117
|
] }),
|
|
3109
|
-
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "500px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, {
|
|
3118
|
+
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "500px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, { gap: 2, children: conflicts.map((conflict) => /* @__PURE__ */ jsxs(Text, { size: 1, muted: !0, children: [
|
|
3110
3119
|
conflict.sourceDocumentTitle || conflict.sourceDocumentId,
|
|
3111
3120
|
conflict.sourceDocumentType && ` (${conflict.sourceDocumentType})`,
|
|
3112
3121
|
" \u2192 ",
|
|
3113
3122
|
conflict.targetLanguage
|
|
3114
3123
|
] }, conflict.existingVersionId)) }) }) }),
|
|
3115
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3124
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3116
3125
|
/* @__PURE__ */ jsx(Heading, { size: 0, children: "Choose an action:" }),
|
|
3117
3126
|
/* @__PURE__ */ jsxs(Text, { size: 1, children: [
|
|
3118
3127
|
/* @__PURE__ */ jsx("strong", { children: "Cancel" }),
|
|
@@ -3358,7 +3367,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3358
3367
|
}, [startTranslation, conflictContext]), handleSkipConflicts = useCallback(() => {
|
|
3359
3368
|
conflictContext && startTranslation(!1, conflictContext.releaseId, conflictContext.conflicts);
|
|
3360
3369
|
}, [startTranslation, conflictContext]), totalTranslations = useMemo(() => (1 + filteredReferences.length) * selectedTargetLanguages.length, [filteredReferences.length, selectedTargetLanguages.length]);
|
|
3361
|
-
return conflictContext ? /* @__PURE__ */ jsx(Stack, {
|
|
3370
|
+
return conflictContext ? /* @__PURE__ */ jsx(Stack, { gap: 4, children: /* @__PURE__ */ jsx(
|
|
3362
3371
|
ReleaseConflictWarning,
|
|
3363
3372
|
{
|
|
3364
3373
|
conflicts: conflictContext.conflicts,
|
|
@@ -3367,7 +3376,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3367
3376
|
onReplace: handleReplaceConflict,
|
|
3368
3377
|
onSkipConflicts: handleSkipConflicts
|
|
3369
3378
|
}
|
|
3370
|
-
) }) : /* @__PURE__ */ jsxs(Stack, {
|
|
3379
|
+
) }) : /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3371
3380
|
activeValidators.map((doc) => /* @__PURE__ */ jsx(
|
|
3372
3381
|
DocumentValidator,
|
|
3373
3382
|
{
|
|
@@ -3391,14 +3400,14 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3391
3400
|
" document",
|
|
3392
3401
|
filteredReferences.length !== 0 ? "s" : ""
|
|
3393
3402
|
] }),
|
|
3394
|
-
/* @__PURE__ */ jsx(Card, { padding: 4, border: !0, radius: 2, tone: hasValidationErrors ? "critical" : void 0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3403
|
+
/* @__PURE__ */ jsx(Card, { padding: 4, border: !0, radius: 2, tone: hasValidationErrors ? "critical" : void 0, children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3395
3404
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
3396
3405
|
someStillValidating ? /* @__PURE__ */ jsx(Spinner, { muted: !0 }) : hasValidationErrors ? /* @__PURE__ */ jsx(Text, { size: 2, children: /* @__PURE__ */ jsx(ErrorOutlineIcon, {}) }) : /* @__PURE__ */ jsx(Text, { size: 2, children: /* @__PURE__ */ jsx(CheckmarkIcon, {}) }),
|
|
3397
3406
|
/* @__PURE__ */ jsx(Text, { weight: "semibold", children: someStillValidating ? `Validating documents (${validationResults.size}/${documentsToValidate.length})\u2026` : hasValidationErrors ? `Validation errors in ${documentsWithErrors.length} document${documentsWithErrors.length !== 1 ? "s" : ""}` : "All documents pass validation" })
|
|
3398
3407
|
] }),
|
|
3399
3408
|
documentsWithErrors.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3400
3409
|
/* @__PURE__ */ jsx(Text, { size: 1, children: "Documents must pass validation before they can be translated. Click a document to open it and fix the errors." }),
|
|
3401
|
-
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "300px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, {
|
|
3410
|
+
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "300px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, { gap: 3, children: documentsWithErrors.map((doc) => {
|
|
3402
3411
|
const publishedId = getPublishedId(doc._id), displayName = doc._id === document._id ? "This document" : doc.title || doc._id, hasUnpublishedChanges = sourceRefDraftIds.has(publishedId);
|
|
3403
3412
|
return /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "space-between", gap: 2, children: [
|
|
3404
3413
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, flex: 1, style: { minWidth: 0 }, children: [
|
|
@@ -3426,14 +3435,14 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3426
3435
|
}) }) }) })
|
|
3427
3436
|
] })
|
|
3428
3437
|
] }) }),
|
|
3429
|
-
filteredReferences.length > 0 && /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, radius: 2, tone: sourceRefsWithDrafts.length > 0 ? "caution" : void 0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3438
|
+
filteredReferences.length > 0 && /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, radius: 2, tone: sourceRefsWithDrafts.length > 0 ? "caution" : void 0, children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3430
3439
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
3431
3440
|
isSourceDraftCheckLoading ? /* @__PURE__ */ jsx(Spinner, { muted: !0 }) : sourceRefsWithDrafts.length > 0 ? /* @__PURE__ */ jsx(Text, { size: 2, children: /* @__PURE__ */ jsx(WarningOutlineIcon, {}) }) : /* @__PURE__ */ jsx(Text, { size: 2, children: /* @__PURE__ */ jsx(CheckmarkIcon, {}) }),
|
|
3432
3441
|
/* @__PURE__ */ jsx(Text, { weight: "semibold", children: isSourceDraftCheckLoading ? "Checking referenced documents\u2026" : sourceRefsWithDrafts.length > 0 ? `${sourceRefsWithDrafts.length} referenced document${sourceRefsWithDrafts.length !== 1 ? "s have" : " has"} unpublished changes` : "All referenced documents are in sync" })
|
|
3433
3442
|
] }),
|
|
3434
3443
|
sourceRefsWithDrafts.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3435
3444
|
/* @__PURE__ */ jsx(Text, { size: 1, children: documentSource === "draft" ? 'You are translating from drafts. These unpublished changes will be included in the translation. If this is not intended, go back and switch to "Translate from published".' : 'You are translating from published. Unpublished changes on these documents will be ignored. If you want to include them, go back and switch to "Translate from drafts".' }),
|
|
3436
|
-
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "300px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, {
|
|
3445
|
+
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "300px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, { gap: 3, children: sourceRefsWithDrafts.map((ref) => /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "space-between", gap: 2, children: [
|
|
3437
3446
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, flex: 1, style: { minWidth: 0 }, children: [
|
|
3438
3447
|
/* @__PURE__ */ jsx(Text, { size: 1, children: ref.title || ref.publishedId }),
|
|
3439
3448
|
/* @__PURE__ */ jsx(Badge, { tone: "primary", fontSize: 0, children: ref._type })
|
|
@@ -3442,14 +3451,14 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3442
3451
|
] }, ref.publishedId)) }) }) })
|
|
3443
3452
|
] })
|
|
3444
3453
|
] }) }),
|
|
3445
|
-
(isDraftCheckLoading || hasStaleDrafts) && /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, radius: 2, tone: hasStaleDrafts && !draftsDismissed ? "caution" : void 0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3454
|
+
(isDraftCheckLoading || hasStaleDrafts) && /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, radius: 2, tone: hasStaleDrafts && !draftsDismissed ? "caution" : void 0, children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3446
3455
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
3447
3456
|
isDraftCheckLoading ? /* @__PURE__ */ jsx(Spinner, { muted: !0 }) : draftsDismissed ? /* @__PURE__ */ jsx(Text, { size: 2, children: /* @__PURE__ */ jsx(CheckmarkIcon, {}) }) : /* @__PURE__ */ jsx(Text, { size: 2, children: /* @__PURE__ */ jsx(WarningOutlineIcon, {}) }),
|
|
3448
3457
|
/* @__PURE__ */ jsx(Text, { weight: "semibold", children: isDraftCheckLoading ? "Checking for stale drafts on target documents\u2026" : draftsDismissed ? "Stale drafts acknowledged" : `${staleDrafts.length} draft${staleDrafts.length !== 1 ? "s" : ""} found on existing translated document${staleDrafts.length !== 1 ? "s" : ""}` })
|
|
3449
3458
|
] }),
|
|
3450
3459
|
hasStaleDrafts && !draftsDismissed && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3451
3460
|
/* @__PURE__ */ jsx(Text, { size: 1, children: "These existing translations have unpublished changes that will be out-of-date after this translation is completed. Use the links below to either publish each draft or discard the changes." }),
|
|
3452
|
-
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "300px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, {
|
|
3461
|
+
/* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsx(Box, { style: { maxHeight: "300px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, { gap: 3, children: staleDrafts.map((draft) => /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "space-between", gap: 2, children: [
|
|
3453
3462
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, flex: 1, style: { minWidth: 0 }, children: [
|
|
3454
3463
|
/* @__PURE__ */ jsx(Text, { size: 1, children: draft.title || draft.targetId }),
|
|
3455
3464
|
/* @__PURE__ */ jsx(Badge, { tone: "primary", fontSize: 0, children: draft.targetLanguage }),
|
|
@@ -3493,17 +3502,16 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3493
3502
|
}, [dispatch]);
|
|
3494
3503
|
return /* @__PURE__ */ jsxs(Flex, { justify: "space-between", gap: 2, children: [
|
|
3495
3504
|
/* @__PURE__ */ jsxs(Flex, { justify: "flex-start", gap: 2, children: [
|
|
3496
|
-
/* @__PURE__ */ jsx(Button, { mode: "ghost",
|
|
3497
|
-
/* @__PURE__ */ jsx(Button, { mode: "ghost",
|
|
3505
|
+
/* @__PURE__ */ jsx(Button, { mode: "ghost", onClick: handleSelectAll, children: "Select All" }),
|
|
3506
|
+
/* @__PURE__ */ jsx(Button, { mode: "ghost", onClick: handleSelectNone, children: "Select None" })
|
|
3498
3507
|
] }),
|
|
3499
3508
|
/* @__PURE__ */ jsxs(Flex, { justify: "flex-end", gap: 2, children: [
|
|
3500
|
-
/* @__PURE__ */ jsx(Button, { onClick: () => setIsDialogOpen(!1), mode: "ghost",
|
|
3509
|
+
/* @__PURE__ */ jsx(Button, { onClick: () => setIsDialogOpen(!1), mode: "ghost", children: "Cancel" }),
|
|
3501
3510
|
/* @__PURE__ */ jsx(
|
|
3502
3511
|
Button,
|
|
3503
3512
|
{
|
|
3504
3513
|
mode: "ghost",
|
|
3505
3514
|
tone: "positive",
|
|
3506
|
-
size: 2,
|
|
3507
3515
|
onClick: handleTranslate,
|
|
3508
3516
|
disabled: selectedTargetLanguages.length === 0 || !["idle", "completed"].includes(overallStatus) || releaseConfig.mode === "existing" && !releaseConfig.existingReleaseId,
|
|
3509
3517
|
children: "Translate"
|
|
@@ -3523,9 +3531,9 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3523
3531
|
payload: source
|
|
3524
3532
|
});
|
|
3525
3533
|
};
|
|
3526
|
-
return /* @__PURE__ */ jsx(Card, { tone: "caution", padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3534
|
+
return /* @__PURE__ */ jsx(Card, { tone: "caution", padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3527
3535
|
/* @__PURE__ */ jsx(Text, { weight: "semibold", children: "This document has unpublished changes" }),
|
|
3528
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3536
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3529
3537
|
/* @__PURE__ */ jsx(
|
|
3530
3538
|
Button,
|
|
3531
3539
|
{
|
|
@@ -3533,9 +3541,9 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3533
3541
|
mode: documentSource === "draft" ? "ghost" : "bleed",
|
|
3534
3542
|
tone: documentSource === "draft" ? "primary" : "default",
|
|
3535
3543
|
onClick: () => handleSourceChange("draft"),
|
|
3536
|
-
children: /* @__PURE__ */ jsxs(Inline, {
|
|
3544
|
+
children: /* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
3537
3545
|
/* @__PURE__ */ jsx(Radio, { checked: documentSource === "draft", readOnly: !0 }),
|
|
3538
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3546
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3539
3547
|
/* @__PURE__ */ jsx(Text, { children: "Translate from drafts" }),
|
|
3540
3548
|
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "Uses the latest draft of this document and all referenced documents" })
|
|
3541
3549
|
] })
|
|
@@ -3549,9 +3557,9 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3549
3557
|
mode: documentSource === "published" ? "ghost" : "bleed",
|
|
3550
3558
|
tone: documentSource === "published" ? "primary" : "default",
|
|
3551
3559
|
onClick: () => handleSourceChange("published"),
|
|
3552
|
-
children: /* @__PURE__ */ jsxs(Inline, {
|
|
3560
|
+
children: /* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
3553
3561
|
/* @__PURE__ */ jsx(Radio, { checked: documentSource === "published", readOnly: !0 }),
|
|
3554
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3562
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3555
3563
|
/* @__PURE__ */ jsx(Text, { children: "Translate from published" }),
|
|
3556
3564
|
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "Uses only published content for this document and all referenced documents" })
|
|
3557
3565
|
] })
|
|
@@ -3596,17 +3604,16 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3596
3604
|
payload: updatedLanguages
|
|
3597
3605
|
});
|
|
3598
3606
|
};
|
|
3599
|
-
return isLoading ? /* @__PURE__ */ jsx(Button, { type: "button", mode: "bleed",
|
|
3607
|
+
return isLoading ? /* @__PURE__ */ jsx(Button, { type: "button", mode: "bleed", onClick: handleChange, disabled: !0, muted: !0, children: /* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", paddingY: 3, children: /* @__PURE__ */ jsx(Spinner, { size: 1 }) }) }) : /* @__PURE__ */ jsx(
|
|
3600
3608
|
Button,
|
|
3601
3609
|
{
|
|
3602
3610
|
type: "button",
|
|
3603
3611
|
mode: isChecked ? "ghost" : "bleed",
|
|
3604
|
-
size: 2,
|
|
3605
3612
|
onClick: handleChange,
|
|
3606
3613
|
disabled: isDisabled,
|
|
3607
3614
|
tone: isChecked ? "primary" : "default",
|
|
3608
3615
|
muted: !0,
|
|
3609
|
-
children: /* @__PURE__ */ jsx(Flex, { align: "center", gap: 2, style: { cursor: "pointer" }, children: /* @__PURE__ */ jsxs(Inline, {
|
|
3616
|
+
children: /* @__PURE__ */ jsx(Flex, { align: "center", gap: 2, style: { cursor: "pointer" }, children: /* @__PURE__ */ jsxs(Inline, { gap: 3, children: [
|
|
3610
3617
|
/* @__PURE__ */ jsx(Checkbox, { checked: isChecked, onChange: handleChange, label: lang.title, disabled: isDisabled }),
|
|
3611
3618
|
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
|
3612
3619
|
/* @__PURE__ */ jsx(Text, { children: lang.title }),
|
|
@@ -3619,7 +3626,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3619
3626
|
const { document, config } = useTranslationContext(), { loading } = useTranslationMetadata({
|
|
3620
3627
|
documentId: document._id
|
|
3621
3628
|
});
|
|
3622
|
-
return /* @__PURE__ */ jsx(Card, { padding: 4, muted: !0, border: !0, children: /* @__PURE__ */ jsx(Grid, {
|
|
3629
|
+
return /* @__PURE__ */ jsx(Card, { padding: 4, muted: !0, border: !0, children: /* @__PURE__ */ jsx(Grid, { gridTemplateColumns: [1, 2], gap: 3, children: config?.supportedLanguages.map((lang) => /* @__PURE__ */ jsx(LanguageCheckbox, { lang, isLoading: loading }, lang.id)) }) });
|
|
3623
3630
|
}, reconcileReleaseReferences = async ({
|
|
3624
3631
|
client,
|
|
3625
3632
|
releaseId,
|
|
@@ -3762,9 +3769,9 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3762
3769
|
if (releaseConfig.mode !== "existing" || !releaseId)
|
|
3763
3770
|
return null;
|
|
3764
3771
|
const isTranslating = overallStatus === "translating" || overallStatus === "linking_references", isReconciling = reconcilingStatus === "reconciling";
|
|
3765
|
-
return /* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, tone: reconcilingStatus === "error" ? "critical" : "default", children: /* @__PURE__ */ jsxs(Stack, {
|
|
3772
|
+
return /* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, tone: reconcilingStatus === "error" ? "critical" : "default", children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3766
3773
|
/* @__PURE__ */ jsxs(Flex, { align: "center", justify: "space-between", gap: 3, children: [
|
|
3767
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3774
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3768
3775
|
/* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: "Reconcile References" }),
|
|
3769
3776
|
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: isLoadingCount ? "Loading..." : documentCount === null ? "Unable to load document count" : documentCount === 0 ? "No documents in release" : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3770
3777
|
documentCount,
|
|
@@ -3854,8 +3861,8 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3854
3861
|
day: "numeric",
|
|
3855
3862
|
year: "numeric"
|
|
3856
3863
|
});
|
|
3857
|
-
return /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3858
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3864
|
+
return /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3865
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3859
3866
|
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: 3, as: "label", style: { cursor: "pointer" }, onClick: () => handleModeChange("new"), children: [
|
|
3860
3867
|
/* @__PURE__ */ jsx(Radio, { checked: releaseConfig.mode === "new", readOnly: !0 }),
|
|
3861
3868
|
/* @__PURE__ */ jsx(Text, { weight: "medium", children: "Create new release" })
|
|
@@ -3883,7 +3890,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3883
3890
|
placeholder: "Release title..."
|
|
3884
3891
|
}
|
|
3885
3892
|
),
|
|
3886
|
-
releaseConfig.mode === "existing" && /* @__PURE__ */ jsxs(Stack, {
|
|
3893
|
+
releaseConfig.mode === "existing" && /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3887
3894
|
isLoading && /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
3888
3895
|
/* @__PURE__ */ jsx(Spinner, { muted: !0 }),
|
|
3889
3896
|
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "Loading..." })
|
|
@@ -3900,7 +3907,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3900
3907
|
placeholder: "Search releases..."
|
|
3901
3908
|
}
|
|
3902
3909
|
),
|
|
3903
|
-
/* @__PURE__ */ jsx(Box, { style: { maxHeight: "200px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, {
|
|
3910
|
+
/* @__PURE__ */ jsx(Box, { style: { maxHeight: "200px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, { gap: 1, children: filteredReleases.length === 0 ? /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "No releases match your search." }) : filteredReleases.map((release) => {
|
|
3904
3911
|
const releaseName = release._id.replace("_.releases.", ""), isSelected = releaseConfig.existingReleaseId === releaseName;
|
|
3905
3912
|
return /* @__PURE__ */ jsx(
|
|
3906
3913
|
Card,
|
|
@@ -3949,7 +3956,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3949
3956
|
if (!isOpenAIConfigured(config?.openai))
|
|
3950
3957
|
return null;
|
|
3951
3958
|
if (!openaiValidated)
|
|
3952
|
-
return /* @__PURE__ */ jsx(Card, { tone: "caution", padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3959
|
+
return /* @__PURE__ */ jsx(Card, { tone: "caution", padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3953
3960
|
/* @__PURE__ */ jsx(Text, { weight: "semibold", children: "OpenAI Unavailable" }),
|
|
3954
3961
|
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "This Studio's Sanity client cannot invoke the translation function. OpenAI mode requires @sanity/client 8.1 or newer." })
|
|
3955
3962
|
] }) });
|
|
@@ -3959,12 +3966,12 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3959
3966
|
payload: mode
|
|
3960
3967
|
});
|
|
3961
3968
|
};
|
|
3962
|
-
return /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
3963
|
-
/* @__PURE__ */ jsxs(Inline, {
|
|
3969
|
+
return /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
3970
|
+
/* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
3964
3971
|
/* @__PURE__ */ jsx(Text, { weight: "semibold", children: "Translation Mode" }),
|
|
3965
3972
|
/* @__PURE__ */ jsx(Badge, { tone: "positive", children: "OpenAI Available" })
|
|
3966
3973
|
] }),
|
|
3967
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3974
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3968
3975
|
/* @__PURE__ */ jsx(
|
|
3969
3976
|
Button,
|
|
3970
3977
|
{
|
|
@@ -3972,9 +3979,9 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3972
3979
|
mode: translationMode === "sanity-only" ? "ghost" : "bleed",
|
|
3973
3980
|
tone: translationMode === "sanity-only" ? "primary" : "default",
|
|
3974
3981
|
onClick: () => handleModeChange("sanity-only"),
|
|
3975
|
-
children: /* @__PURE__ */ jsxs(Inline, {
|
|
3982
|
+
children: /* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
3976
3983
|
/* @__PURE__ */ jsx(Radio, { checked: translationMode === "sanity-only", readOnly: !0 }),
|
|
3977
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3984
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3978
3985
|
/* @__PURE__ */ jsx(Text, { children: "Sanity Agent Only" }),
|
|
3979
3986
|
/* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "Fast, reliable, and included with Sanity." })
|
|
3980
3987
|
] })
|
|
@@ -3988,10 +3995,10 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
3988
3995
|
mode: translationMode === "openai-only" ? "ghost" : "bleed",
|
|
3989
3996
|
tone: translationMode === "openai-only" ? "primary" : "default",
|
|
3990
3997
|
onClick: () => handleModeChange("openai-only"),
|
|
3991
|
-
children: /* @__PURE__ */ jsxs(Inline, {
|
|
3998
|
+
children: /* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
3992
3999
|
/* @__PURE__ */ jsx(Radio, { checked: translationMode === "openai-only", readOnly: !0 }),
|
|
3993
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
3994
|
-
/* @__PURE__ */ jsxs(Inline, {
|
|
4000
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4001
|
+
/* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
3995
4002
|
/* @__PURE__ */ jsx(Text, { children: "OpenAI Only" }),
|
|
3996
4003
|
/* @__PURE__ */ jsx(Badge, { tone: "caution", children: "Beta" })
|
|
3997
4004
|
] }),
|
|
@@ -4110,7 +4117,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4110
4117
|
payload: newSelection
|
|
4111
4118
|
});
|
|
4112
4119
|
};
|
|
4113
|
-
return references.length === 0 ? null : /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, muted: !0, children: /* @__PURE__ */ jsxs(Stack, {
|
|
4120
|
+
return references.length === 0 ? null : /* @__PURE__ */ jsx(Card, { padding: 4, border: !0, muted: !0, children: /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
4114
4121
|
/* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", gap: 2, children: [
|
|
4115
4122
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, align: "center", children: [
|
|
4116
4123
|
/* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: "Select References" }),
|
|
@@ -4123,8 +4130,8 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4123
4130
|
] })
|
|
4124
4131
|
] }),
|
|
4125
4132
|
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
4126
|
-
/* @__PURE__ */ jsx(Button, { mode: "ghost",
|
|
4127
|
-
/* @__PURE__ */ jsx(Button, { mode: "ghost",
|
|
4133
|
+
/* @__PURE__ */ jsx(Button, { mode: "ghost", onClick: handleSelectAll, text: "Select All" }),
|
|
4134
|
+
/* @__PURE__ */ jsx(Button, { mode: "ghost", onClick: handleSelectNone, text: "Select None" })
|
|
4128
4135
|
] })
|
|
4129
4136
|
] }),
|
|
4130
4137
|
documentTypes.length > 1 && /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
@@ -4154,7 +4161,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4154
4161
|
}
|
|
4155
4162
|
)
|
|
4156
4163
|
] }),
|
|
4157
|
-
/* @__PURE__ */ jsx(Box, { style: { maxHeight: "400px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, {
|
|
4164
|
+
/* @__PURE__ */ jsx(Box, { style: { maxHeight: "400px", overflowY: "auto" }, children: /* @__PURE__ */ jsx(Stack, { gap: 2, children: filteredReferences.length === 0 ? /* @__PURE__ */ jsx(Text, { size: 1, muted: !0, children: "No references match the selected filter." }) : filteredReferences.map((reference) => {
|
|
4158
4165
|
const isSelected = selectedReferenceIds.has(reference._id), displayTitle = reference.title || reference._id;
|
|
4159
4166
|
return /* @__PURE__ */ jsx(Card, { padding: 3, border: !0, radius: 2, children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 3, children: [
|
|
4160
4167
|
/* @__PURE__ */ jsx(Checkbox, { checked: isSelected, onChange: () => handleToggleReference(reference._id) }),
|
|
@@ -4199,17 +4206,16 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4199
4206
|
payload: !shouldTranslateReferences
|
|
4200
4207
|
});
|
|
4201
4208
|
};
|
|
4202
|
-
return /* @__PURE__ */ jsxs(Stack, {
|
|
4209
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4203
4210
|
/* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", children: [
|
|
4204
4211
|
/* @__PURE__ */ jsx(
|
|
4205
4212
|
Button,
|
|
4206
4213
|
{
|
|
4207
4214
|
type: "button",
|
|
4208
4215
|
mode: shouldTranslateReferences ? "ghost" : "bleed",
|
|
4209
|
-
size: 2,
|
|
4210
4216
|
onClick: handleShouldTranslateChange,
|
|
4211
4217
|
tone: shouldTranslateReferences ? "primary" : "neutral",
|
|
4212
|
-
children: /* @__PURE__ */ jsxs(Inline, {
|
|
4218
|
+
children: /* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
4213
4219
|
/* @__PURE__ */ jsx(
|
|
4214
4220
|
Checkbox,
|
|
4215
4221
|
{
|
|
@@ -4222,7 +4228,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4222
4228
|
] })
|
|
4223
4229
|
}
|
|
4224
4230
|
),
|
|
4225
|
-
shouldTranslateReferences ? /* @__PURE__ */ jsxs(Inline, {
|
|
4231
|
+
shouldTranslateReferences ? /* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
4226
4232
|
/* @__PURE__ */ jsx(Text, { children: "Max Depth:" }),
|
|
4227
4233
|
/* @__PURE__ */ jsx(
|
|
4228
4234
|
Select,
|
|
@@ -4246,7 +4252,6 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4246
4252
|
Button,
|
|
4247
4253
|
{
|
|
4248
4254
|
mode: "ghost",
|
|
4249
|
-
size: 1,
|
|
4250
4255
|
text: showSelectionPanel ? "Hide selection" : "Select specific references...",
|
|
4251
4256
|
onClick: () => setShowSelectionPanel(!showSelectionPanel)
|
|
4252
4257
|
}
|
|
@@ -4255,21 +4260,21 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4255
4260
|
!isLoadingReferences && references.length > 0 && showSelectionPanel && /* @__PURE__ */ jsx(ReferenceSelectionPanel, {})
|
|
4256
4261
|
] }) : null
|
|
4257
4262
|
] });
|
|
4258
|
-
}, WriteSettingsPanel = () => /* @__PURE__ */ jsx(ReferenceConfigPanel, {}), TranslationConfigView = ({ setIsDialogOpen }) => /* @__PURE__ */ jsxs(Stack, {
|
|
4263
|
+
}, WriteSettingsPanel = () => /* @__PURE__ */ jsx(ReferenceConfigPanel, {}), TranslationConfigView = ({ setIsDialogOpen }) => /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
4259
4264
|
/* @__PURE__ */ jsx(DocumentSourcePanel, {}),
|
|
4260
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
4265
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4261
4266
|
/* @__PURE__ */ jsx(Label, { children: "Languages" }),
|
|
4262
4267
|
/* @__PURE__ */ jsx(LanguageSelectionPanel, {})
|
|
4263
4268
|
] }),
|
|
4264
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
4269
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4265
4270
|
/* @__PURE__ */ jsx(Label, { children: "Translation Method" }),
|
|
4266
4271
|
/* @__PURE__ */ jsx(TranslationModePanel, {})
|
|
4267
4272
|
] }),
|
|
4268
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
4273
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4269
4274
|
/* @__PURE__ */ jsx(Label, { children: "Content Release" }),
|
|
4270
4275
|
/* @__PURE__ */ jsx(ReleaseSelectionPanel, {})
|
|
4271
4276
|
] }),
|
|
4272
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
4277
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4273
4278
|
/* @__PURE__ */ jsx(Label, { children: "Settings" }),
|
|
4274
4279
|
/* @__PURE__ */ jsx(Card, { padding: 4, border: !0, muted: !0, children: /* @__PURE__ */ jsx(WriteSettingsPanel, {}) })
|
|
4275
4280
|
] }),
|
|
@@ -4278,16 +4283,16 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4278
4283
|
const { overallStatus, translationJobs, dispatch, document } = useTranslationContext(), headline = useMemo(() => overallStatus === "completed" ? "Translation completed" : overallStatus === "error" ? "Translation failed" : "Translation in progress", [overallStatus]), jobs = useMemo(() => Array.from(translationJobs.values()), [translationJobs]), isTerminalState = overallStatus === "completed" || overallStatus === "error", handleReset = useCallback(() => {
|
|
4279
4284
|
forceCleanupActiveTranslation(document._id), dispatch({ type: "RESET_TRANSLATION_STATE" });
|
|
4280
4285
|
}, [dispatch, document._id]);
|
|
4281
|
-
return /* @__PURE__ */ jsxs(Stack, {
|
|
4286
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
4282
4287
|
/* @__PURE__ */ jsx(Heading, { size: 2, children: headline }),
|
|
4283
4288
|
/* @__PURE__ */ jsx(ProgressBar, { progress: jobs.filter((job) => TERMINAL_STATUSES.includes(job.status)).length, max: jobs.length }),
|
|
4284
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
4289
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
4285
4290
|
/* @__PURE__ */ jsx(Label, { children: "Translations" }),
|
|
4286
|
-
/* @__PURE__ */ jsx(Card, { padding: 2, tone: "transparent", children: /* @__PURE__ */ jsx(Stack, {
|
|
4287
|
-
/* @__PURE__ */ jsxs(Inline, {
|
|
4291
|
+
/* @__PURE__ */ jsx(Card, { padding: 2, tone: "transparent", children: /* @__PURE__ */ jsx(Stack, { gap: 2, children: /* @__PURE__ */ jsx("ul", { style: { listStyleType: "none", paddingInlineStart: "0" }, children: jobs.map((job) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Box, { padding: 3, children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", children: [
|
|
4292
|
+
/* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
4288
4293
|
/* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", style: { width: "24px", height: "24px" }, children: ["completed", "skipped"].includes(job.status) ? /* @__PURE__ */ jsx(CheckmarkIcon, { fontSize: 24 }) : job.status === "error" ? /* @__PURE__ */ jsx(Box, { style: { color: "var(--card-critical-fg-color)" }, children: /* @__PURE__ */ jsx(ErrorOutlineIcon, { fontSize: 24 }) }) : job.status === "queued" ? /* @__PURE__ */ jsx(CircleIcon, { fontSize: 24 }) : /* @__PURE__ */ jsx(Spinner, {}) }),
|
|
4289
|
-
/* @__PURE__ */ jsxs(Stack, {
|
|
4290
|
-
/* @__PURE__ */ jsxs(Inline, {
|
|
4294
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
|
|
4295
|
+
/* @__PURE__ */ jsxs(Inline, { gap: 2, children: [
|
|
4291
4296
|
/* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: job.title || "Untitled Document" }),
|
|
4292
4297
|
/* @__PURE__ */ jsx(ArrowRightIcon, { fontSize: 18 }),
|
|
4293
4298
|
/* @__PURE__ */ jsx(Code, { size: 1, children: job.language })
|
|
@@ -4323,7 +4328,7 @@ ${protectedPhrases.join(", ")}`, buildStyleGuideSection = (globalPrompt, localeP
|
|
|
4323
4328
|
] });
|
|
4324
4329
|
}, ProgressBar = ({ progress, max = 100 }) => {
|
|
4325
4330
|
const percentage = Math.min(progress / max * 100, 100);
|
|
4326
|
-
return /* @__PURE__ */ jsxs(Stack, {
|
|
4331
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4327
4332
|
/* @__PURE__ */ jsx(
|
|
4328
4333
|
"div",
|
|
4329
4334
|
{
|
|
@@ -5176,7 +5181,7 @@ function getDocumentLanguage(document) {
|
|
|
5176
5181
|
}
|
|
5177
5182
|
const aiTranslationPlugin = definePlugin((config) => (config.fieldTransforms?.length && (devLog.info(`Registering ${config.fieldTransforms.length} custom field transforms`), config.fieldTransforms.forEach((transform) => {
|
|
5178
5183
|
globalTransformRegistry.register(transform);
|
|
5179
|
-
})), {
|
|
5184
|
+
})), setGlossaryDataset(config.glossaryDataset), {
|
|
5180
5185
|
name: "sanity-plugin-ai-translation",
|
|
5181
5186
|
document: {
|
|
5182
5187
|
actions: [getTranslateAction(config)]
|