@parhelia/localization 0.1.12903 → 0.1.12904
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/LocalizeItemCommand.d.ts +1 -7
- package/dist/LocalizeItemCommand.d.ts.map +1 -1
- package/dist/LocalizeItemCommand.js +18 -31
- package/dist/LocalizeItemDialog.d.ts.map +1 -1
- package/dist/LocalizeItemDialog.js +35 -97
- package/dist/LocalizeItemUtils.d.ts +2 -1
- package/dist/LocalizeItemUtils.d.ts.map +1 -1
- package/dist/LocalizeItemUtils.js +36 -78
- package/dist/api/discovery.d.ts +0 -25
- package/dist/api/discovery.d.ts.map +1 -1
- package/dist/api/discovery.js +2 -106
- package/dist/constants.d.ts +15 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +21 -0
- package/dist/hooks/useTranslationWizard.d.ts.map +1 -1
- package/dist/hooks/useTranslationWizard.js +3 -3
- package/dist/index.d.ts +11 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -36
- package/dist/services/translationService.d.ts +10 -41
- package/dist/services/translationService.d.ts.map +1 -1
- package/dist/services/translationService.js +6 -48
- package/dist/settings/TranslationServicesPanel.d.ts.map +1 -1
- package/dist/settings/TranslationServicesPanel.js +36 -21
- package/dist/setup/LocalizationSetupStep.d.ts.map +1 -1
- package/dist/setup/LocalizationSetupStep.js +18 -29
- package/dist/sidebar/TranslationSidebar.d.ts.map +1 -1
- package/dist/sidebar/TranslationSidebar.js +10 -20
- package/dist/steps/MetadataInputStep.d.ts +4 -0
- package/dist/steps/MetadataInputStep.d.ts.map +1 -0
- package/dist/steps/MetadataInputStep.js +41 -0
- package/dist/steps/PromptCustomizationStep.d.ts +1 -1
- package/dist/steps/PromptCustomizationStep.d.ts.map +1 -1
- package/dist/steps/PromptCustomizationStep.js +56 -159
- package/dist/steps/ServiceLanguageSelectionStep.d.ts +1 -6
- package/dist/steps/ServiceLanguageSelectionStep.d.ts.map +1 -1
- package/dist/steps/ServiceLanguageSelectionStep.js +165 -92
- package/dist/steps/SubitemDiscoveryStep.d.ts +3 -0
- package/dist/steps/SubitemDiscoveryStep.d.ts.map +1 -0
- package/dist/steps/SubitemDiscoveryStep.js +313 -0
- package/dist/steps/index.d.ts +5 -0
- package/dist/steps/index.d.ts.map +1 -0
- package/dist/steps/index.js +4 -0
- package/dist/steps/types.d.ts +1 -17
- package/dist/steps/types.d.ts.map +1 -1
- package/dist/translation-center/BatchTranslationView.d.ts +8 -0
- package/dist/translation-center/BatchTranslationView.d.ts.map +1 -0
- package/dist/translation-center/BatchTranslationView.js +870 -0
- package/dist/translation-center/RecentTranslations.d.ts +2 -0
- package/dist/translation-center/RecentTranslations.d.ts.map +1 -0
- package/dist/translation-center/RecentTranslations.js +309 -0
- package/dist/translation-center/TranslationManagement.d.ts.map +1 -1
- package/dist/translation-center/TranslationManagement.js +15 -25
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/createVersions.d.ts +14 -0
- package/dist/utils/createVersions.d.ts.map +1 -0
- package/dist/utils/createVersions.js +26 -0
- package/package.json +1 -1
- package/dist/steps/ItemSelectionStep.d.ts +0 -3
- package/dist/steps/ItemSelectionStep.d.ts.map +0 -1
- package/dist/steps/ItemSelectionStep.js +0 -24
- package/dist/steps/ItemSelectionTree.d.ts +0 -13
- package/dist/steps/ItemSelectionTree.d.ts.map +0 -1
- package/dist/steps/ItemSelectionTree.js +0 -327
- package/dist/steps/WizardStepShell.d.ts +0 -17
- package/dist/steps/WizardStepShell.d.ts.map +0 -1
- package/dist/steps/WizardStepShell.js +0 -11
- package/dist/translation-center/TranslationBatches.d.ts +0 -2
- package/dist/translation-center/TranslationBatches.d.ts.map +0 -1
- package/dist/translation-center/TranslationBatches.js +0 -1180
- package/dist/translation-center/TranslationsTitlebar.d.ts +0 -6
- package/dist/translation-center/TranslationsTitlebar.d.ts.map +0 -1
- package/dist/translation-center/TranslationsTitlebar.js +0 -25
- package/dist/translationEvents.d.ts +0 -6
- package/dist/translationEvents.d.ts.map +0 -1
- package/dist/translationEvents.js +0 -4
|
@@ -1,67 +1,63 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
// Version creation now offered via VersionOnlyTranslationProvider. No custom button here.
|
|
4
|
+
function getTranslationStatusBadgeClass(status) {
|
|
5
|
+
switch (status) {
|
|
6
|
+
case "Completed":
|
|
7
|
+
return "text-green-700 bg-green-100";
|
|
8
|
+
case "Error":
|
|
9
|
+
return "text-red-700 bg-red-100";
|
|
10
|
+
case "In Progress":
|
|
11
|
+
return "text-purple-800 bg-purple-100";
|
|
12
|
+
case "Not started":
|
|
13
|
+
return "text-[var(--color-gray-2)] bg-[var(--color-gray-4)]";
|
|
14
|
+
default:
|
|
15
|
+
return "text-[var(--color-gray-2)] bg-[var(--color-gray-4)]";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function ServiceLanguageSelectionStep({ stepIndex, isActive = true, data, setData, onStepCompleted, editContext, setFooterActions, requestClose }) {
|
|
11
19
|
const [languageSelection, setLanguageSelection] = useState({});
|
|
12
20
|
const dataRef = useRef(data);
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
useEffect(() => { dataRef.current = data; }, [data]);
|
|
22
|
+
// Check if multi-item translation is enabled
|
|
23
|
+
const multiItemEnabled = editContext?.configuration?.localization?.multiItem !== false;
|
|
24
|
+
// Use ref to track onStepCompleted to avoid dependency issues
|
|
16
25
|
const onStepCompletedRef = useRef(onStepCompleted);
|
|
17
26
|
useEffect(() => {
|
|
18
27
|
onStepCompletedRef.current = onStepCompleted;
|
|
19
28
|
}, [onStepCompleted]);
|
|
29
|
+
// Track last completion state to prevent unnecessary calls
|
|
20
30
|
const lastCompletionStateRef = useRef(null);
|
|
31
|
+
// Call completion check when component mounts or when returning to this step
|
|
32
|
+
// Also check when data changes (but only if we're actually the active step)
|
|
21
33
|
useEffect(() => {
|
|
34
|
+
// Only update completion when this step is active
|
|
22
35
|
if (!isActive)
|
|
23
36
|
return;
|
|
24
|
-
const
|
|
37
|
+
const hasProvider = !!data.translationProvider;
|
|
38
|
+
const hasLanguages = data.targetLanguages.length > 0;
|
|
39
|
+
const isCompleted = hasProvider && hasLanguages;
|
|
40
|
+
// Only call if completion state actually changed
|
|
25
41
|
if (lastCompletionStateRef.current !== isCompleted) {
|
|
26
42
|
lastCompletionStateRef.current = isCompleted;
|
|
27
43
|
onStepCompletedRef.current(isCompleted);
|
|
28
44
|
}
|
|
29
|
-
}, [isActive, data.targetLanguages.length]);
|
|
45
|
+
}, [isActive, data.translationProvider, data.targetLanguages.length]);
|
|
46
|
+
// 1) Derive provider + available languages (lightweight, in-memory)
|
|
47
|
+
const provider = useMemo(() => data.translationProviders.find(p => p.name === data.translationProvider), [data.translationProviders, data.translationProvider]);
|
|
48
|
+
// Use editContext.itemLanguages (like TranslationSidebar) to get all languages including source language
|
|
49
|
+
// This is not item-specific - it shows all available languages for the site
|
|
30
50
|
const editContextLanguages = useMemo(() => editContext?.itemLanguages || [], [editContext?.itemLanguages]);
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
if (editContextLanguages.length > 0 || data.languageData.size > 0)
|
|
34
|
-
return;
|
|
35
|
-
let cancelled = false;
|
|
36
|
-
const loadSiteLanguages = async () => {
|
|
37
|
-
try {
|
|
38
|
-
const res = await getLanguages();
|
|
39
|
-
const languages = (res?.data ?? res ?? []);
|
|
40
|
-
if (!cancelled && Array.isArray(languages)) {
|
|
41
|
-
setSiteLanguages(languages);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
console.error("Failed to load languages:", error);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
loadSiteLanguages();
|
|
49
|
-
return () => {
|
|
50
|
-
cancelled = true;
|
|
51
|
-
};
|
|
52
|
-
}, [editContextLanguages.length, data.languageData.size]);
|
|
51
|
+
// Get language codes from editContext languages, or fallback to languageData keys
|
|
53
52
|
const siteLanguageCodes = useMemo(() => {
|
|
54
53
|
if (editContextLanguages.length > 0) {
|
|
55
|
-
return editContextLanguages.map(
|
|
56
|
-
}
|
|
57
|
-
if (data.languageData.size > 0) {
|
|
58
|
-
return Array.from(data.languageData.keys());
|
|
59
|
-
}
|
|
60
|
-
if (siteLanguages.length > 0) {
|
|
61
|
-
return siteLanguages.map((lang) => lang.languageCode);
|
|
54
|
+
return editContextLanguages.map(lang => lang.languageCode);
|
|
62
55
|
}
|
|
63
56
|
return Array.from(data.languageData.keys());
|
|
64
|
-
}, [editContextLanguages, data.languageData
|
|
57
|
+
}, [editContextLanguages, data.languageData]);
|
|
58
|
+
const availableLanguageCodes = useMemo(() => (provider?.supportedLanguages?.length ? provider.supportedLanguages : siteLanguageCodes), [provider?.supportedLanguages, siteLanguageCodes]);
|
|
59
|
+
// Determine the source language from the items being translated
|
|
60
|
+
// Use the first item's language as the source language (all items should have the same source language)
|
|
65
61
|
const itemSourceLanguage = useMemo(() => {
|
|
66
62
|
return (data.items[0]?.descriptor.language ||
|
|
67
63
|
editContext?.item?.descriptor.language ||
|
|
@@ -69,100 +65,177 @@ export function ServiceLanguageSelectionStep({ isActive = true, data, setData, o
|
|
|
69
65
|
"en");
|
|
70
66
|
}, [data.items, editContext?.item, editContext?.currentItemDescriptor]);
|
|
71
67
|
const allLanguages = useMemo(() => {
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
const arr =
|
|
75
|
-
.map(
|
|
68
|
+
// Create a map of language codes to Language objects from editContext for quick lookup
|
|
69
|
+
const editContextLanguageMap = new Map(editContextLanguages.map(lang => [lang.languageCode, lang]));
|
|
70
|
+
const arr = availableLanguageCodes
|
|
71
|
+
.map(code => {
|
|
72
|
+
// Prefer language info from editContext (like TranslationSidebar), fallback to languageData
|
|
76
73
|
const editContextLang = editContextLanguageMap.get(code);
|
|
77
|
-
const siteLanguage = siteLanguageMap.get(code);
|
|
78
74
|
const languageDataLang = data.languageData.get(code);
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
// Determine source language: prefer from translationStatus, fallback to item's source language
|
|
76
|
+
const sourceLanguage = languageDataLang?.translationStatus?.sourceLanguage || itemSourceLanguage;
|
|
81
77
|
return {
|
|
82
78
|
code,
|
|
83
|
-
name: editContextLang?.name ||
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
icon: editContextLang?.icon || siteLanguage?.icon,
|
|
88
|
-
sourceLanguage,
|
|
79
|
+
name: editContextLang?.name || languageDataLang?.name || code,
|
|
80
|
+
hasVersions: (editContextLang?.versions || 0) > 0 || (languageDataLang?.items.length || 0) > 0,
|
|
81
|
+
translationStatus: languageDataLang?.translationStatus,
|
|
82
|
+
sourceLanguage, // Add source language to the language object
|
|
89
83
|
};
|
|
90
84
|
})
|
|
91
|
-
|
|
85
|
+
// Filter out languages where sourceLanguage equals targetLanguage
|
|
86
|
+
.filter(lang => lang.sourceLanguage !== lang.code);
|
|
92
87
|
arr.sort((a, b) => a.name.localeCompare(b.name));
|
|
93
88
|
return arr;
|
|
94
|
-
}, [
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
data.languageData,
|
|
99
|
-
itemSourceLanguage,
|
|
100
|
-
]);
|
|
101
|
-
const lastProcessedTargetLanguagesRef = useRef("");
|
|
89
|
+
}, [availableLanguageCodes, editContextLanguages, data.languageData, itemSourceLanguage]);
|
|
90
|
+
// Track last processed targetLanguages to prevent unnecessary updates
|
|
91
|
+
const lastProcessedTargetLanguagesRef = useRef('');
|
|
92
|
+
// Rehydrate UI selection from saved wizard data when returning to this step
|
|
102
93
|
useEffect(() => {
|
|
103
94
|
if (!allLanguages || allLanguages.length === 0)
|
|
104
95
|
return;
|
|
96
|
+
// Create a stable key from targetLanguages to detect actual changes
|
|
105
97
|
const targetLanguagesKey = JSON.stringify([...data.targetLanguages].sort());
|
|
106
|
-
if
|
|
98
|
+
// Skip if we've already processed this exact set of target languages
|
|
99
|
+
if (lastProcessedTargetLanguagesRef.current === targetLanguagesKey) {
|
|
107
100
|
return;
|
|
101
|
+
}
|
|
108
102
|
lastProcessedTargetLanguagesRef.current = targetLanguagesKey;
|
|
109
103
|
const initialSelection = {};
|
|
104
|
+
// Mark as selected any language that's in our saved targetLanguages array
|
|
110
105
|
for (const langCode of data.targetLanguages) {
|
|
111
|
-
const lang = allLanguages.find(
|
|
112
|
-
if (lang)
|
|
106
|
+
const lang = allLanguages.find(l => l.code === langCode);
|
|
107
|
+
if (lang) {
|
|
113
108
|
initialSelection[langCode] = true;
|
|
109
|
+
}
|
|
114
110
|
}
|
|
115
111
|
setLanguageSelection(initialSelection);
|
|
116
112
|
}, [allLanguages, data.targetLanguages]);
|
|
117
|
-
|
|
113
|
+
// Track last set targetLanguages to prevent unnecessary setData calls
|
|
114
|
+
const lastSetTargetLanguagesRef = useRef('');
|
|
115
|
+
// Update wizard data when language selection changes
|
|
118
116
|
useEffect(() => {
|
|
119
117
|
const selectedLanguages = Object.entries(languageSelection)
|
|
120
118
|
.filter(([, isSelected]) => isSelected)
|
|
121
119
|
.map(([code]) => code);
|
|
122
120
|
const selectedLanguagesKey = JSON.stringify([...selectedLanguages].sort());
|
|
123
121
|
const currentTargetLanguagesKey = JSON.stringify([...data.targetLanguages].sort());
|
|
124
|
-
if
|
|
122
|
+
// Only update if the selection has actually changed AND we haven't already set this value
|
|
123
|
+
if (selectedLanguagesKey === currentTargetLanguagesKey) {
|
|
124
|
+
// Selection matches current data, no update needed
|
|
125
125
|
return;
|
|
126
|
-
|
|
126
|
+
}
|
|
127
|
+
if (lastSetTargetLanguagesRef.current === selectedLanguagesKey) {
|
|
128
|
+
// We've already set this value, skip to prevent loops
|
|
127
129
|
return;
|
|
130
|
+
}
|
|
128
131
|
lastSetTargetLanguagesRef.current = selectedLanguagesKey;
|
|
129
132
|
const newData = {
|
|
130
133
|
...dataRef.current,
|
|
131
|
-
targetLanguages: selectedLanguages
|
|
134
|
+
targetLanguages: selectedLanguages
|
|
132
135
|
};
|
|
133
136
|
setData(newData);
|
|
137
|
+
// Completion will be updated by the useEffect that watches data.targetLanguages.length
|
|
134
138
|
}, [languageSelection, setData, data.targetLanguages]);
|
|
139
|
+
const handleProviderChange = (e) => {
|
|
140
|
+
const newProvider = e.target.value;
|
|
141
|
+
// Always create a new Map instance to ensure React detects the change
|
|
142
|
+
const newServiceCustomData = new Map();
|
|
143
|
+
if (data.serviceCustomData) {
|
|
144
|
+
data.serviceCustomData.forEach((value, key) => {
|
|
145
|
+
// Only preserve custom data if not switching away from OpenAI
|
|
146
|
+
if (key !== "OpenAI" || newProvider === "OpenAI") {
|
|
147
|
+
newServiceCustomData.set(key, value);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
const newData = {
|
|
152
|
+
...data,
|
|
153
|
+
translationProvider: newProvider,
|
|
154
|
+
serviceCustomData: newServiceCustomData,
|
|
155
|
+
// Clear target languages when provider changes since language availability might change
|
|
156
|
+
targetLanguages: []
|
|
157
|
+
};
|
|
158
|
+
setData(newData);
|
|
159
|
+
// Clear UI selection too
|
|
160
|
+
setLanguageSelection({});
|
|
161
|
+
// Completion will be updated by the useEffect that watches data.translationProvider
|
|
162
|
+
};
|
|
135
163
|
const handleLanguageToggle = (langCode) => {
|
|
136
|
-
setLanguageSelection(
|
|
164
|
+
setLanguageSelection(prev => ({ ...prev, [langCode]: !prev[langCode] }));
|
|
165
|
+
};
|
|
166
|
+
const handleSubitemsToggle = () => {
|
|
167
|
+
const newData = {
|
|
168
|
+
...data,
|
|
169
|
+
includeSubitems: !data.includeSubitems
|
|
170
|
+
};
|
|
171
|
+
setData(newData);
|
|
137
172
|
};
|
|
138
173
|
const handleSelectAllLanguages = () => {
|
|
139
|
-
const allSelected = allLanguages.every(
|
|
174
|
+
const allSelected = allLanguages.every(lang => languageSelection[lang.code]);
|
|
140
175
|
const newSelection = {};
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
176
|
+
if (allSelected) {
|
|
177
|
+
// Deselect all
|
|
178
|
+
allLanguages.forEach(lang => {
|
|
179
|
+
newSelection[lang.code] = false;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
// Select all
|
|
184
|
+
allLanguages.forEach(lang => {
|
|
185
|
+
newSelection[lang.code] = true;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
144
188
|
setLanguageSelection(newSelection);
|
|
145
189
|
};
|
|
146
190
|
const areAllLanguagesSelected = useMemo(() => {
|
|
147
191
|
if (allLanguages.length === 0)
|
|
148
192
|
return false;
|
|
149
|
-
return allLanguages.every(
|
|
193
|
+
return allLanguages.every(lang => languageSelection[lang.code]);
|
|
150
194
|
}, [allLanguages, languageSelection]);
|
|
151
195
|
const areSomeLanguagesSelected = useMemo(() => {
|
|
152
|
-
return allLanguages.some(
|
|
196
|
+
return allLanguages.some(lang => languageSelection[lang.code]);
|
|
153
197
|
}, [allLanguages, languageSelection]);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
198
|
+
// Compute checkbox state for prompt customization
|
|
199
|
+
const isPromptCustomizationEnabled = useMemo(() => {
|
|
200
|
+
if (data.translationProvider !== "OpenAI") {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
const serviceData = data.serviceCustomData?.get("OpenAI");
|
|
204
|
+
return serviceData?.enableCustomPrompt === true;
|
|
205
|
+
}, [data.translationProvider, data.serviceCustomData]);
|
|
206
|
+
return (_jsx("div", { className: "p-6 space-y-6 h-full flex flex-col", "data-testid": "service-language-selection-step", children: _jsxs("div", { className: "space-y-6 flex-1", children: [_jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsx("h3", { className: "text-sm font-medium text-[var(--color-dark)] mb-2", children: "Translation Provider" }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mb-3", children: "Choose how to translate your content. \"Create Versions\" will create new language versions without automatic translation." }), _jsxs("select", { value: data.translationProvider || "", onChange: handleProviderChange, className: "block w-full px-3 py-2 border border-[var(--color-gray-3)] rounded-md bg-[var(--color-gray-5)] text-[var(--color-dark)] text-sm focus:outline-none focus:ring-2 focus:ring-[#9650fb] focus:border-[#9650fb] transition-colors", "data-testid": "translation-provider-select", children: [_jsx("option", { value: "", disabled: true, children: "Select a provider..." }), data.translationProviders.map((provider) => (_jsx("option", { value: provider.name, children: provider.displayName || provider.name }, provider.name)))] })] }), multiItemEnabled && (_jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsxs("label", { className: "flex items-center cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: data.includeSubitems, onChange: handleSubitemsToggle, className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": "include-subitems-checkbox" }), _jsx("span", { className: "ml-2 text-sm text-[var(--color-dark)] font-medium", children: "Include subitems" })] }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mt-1.5 ml-6", children: "Also translate any child components and nested content within this item." })] })), data.translationProvider === "OpenAI" && (_jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsxs("label", { className: "flex items-center cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: isPromptCustomizationEnabled, onChange: (e) => {
|
|
207
|
+
const isChecked = e.target.checked;
|
|
208
|
+
// Always create a new Map instance to ensure React detects the change
|
|
209
|
+
const newServiceCustomData = new Map();
|
|
210
|
+
if (data.serviceCustomData) {
|
|
211
|
+
data.serviceCustomData.forEach((value, key) => {
|
|
212
|
+
newServiceCustomData.set(key, value);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (isChecked) {
|
|
216
|
+
newServiceCustomData.set("OpenAI", {
|
|
217
|
+
enableCustomPrompt: true,
|
|
218
|
+
customPrompt: "",
|
|
219
|
+
promptCustomizationType: "extend",
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// Remove the service data when unchecked
|
|
224
|
+
newServiceCustomData.delete("OpenAI");
|
|
159
225
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
226
|
+
const newData = {
|
|
227
|
+
...data,
|
|
228
|
+
serviceCustomData: newServiceCustomData
|
|
229
|
+
};
|
|
230
|
+
setData(newData);
|
|
231
|
+
}, className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": "enable-custom-prompt-checkbox" }), _jsx("span", { className: "ml-2 text-sm text-[var(--color-dark)] font-medium", children: "Customize translation prompt" })] }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mt-1.5 ml-6", children: "Enable advanced prompt customization for the translation service." })] })), _jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("h3", { className: "text-sm font-medium text-[var(--color-dark)]", children: "Target Languages" }), allLanguages.length > 1 && (_jsxs("label", { className: "flex items-center cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: areAllLanguagesSelected, ref: (input) => {
|
|
232
|
+
if (input) {
|
|
233
|
+
input.indeterminate = areSomeLanguagesSelected && !areAllLanguagesSelected;
|
|
234
|
+
}
|
|
235
|
+
}, onChange: handleSelectAllLanguages, className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": "select-all-languages-checkbox" }), _jsx("span", { className: "ml-2 text-xs text-[var(--color-gray-2)]", children: "Select All" })] }))] }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mb-3", children: "Select the languages you want to translate this content into." }), _jsx("div", { className: "border border-[var(--color-gray-3)] rounded-lg min-h-[200px] max-h-64 overflow-y-auto bg-[var(--color-gray-5)]", children: data.translationProviders.length === 0 || allLanguages.length === 0 ? (
|
|
236
|
+
// Loading skeleton
|
|
237
|
+
_jsx("div", { className: "p-3 space-y-2", children: [...Array(4)].map((_, i) => (_jsxs("div", { className: "flex items-center animate-pulse", children: [_jsx("div", { className: "h-4 w-4 bg-[var(--color-gray-3)] rounded" }), _jsx("div", { className: "ml-2 h-4 bg-[var(--color-gray-3)] rounded w-32" }), _jsx("div", { className: "ml-auto h-4 bg-[var(--color-gray-3)] rounded w-16" })] }, i))) })) : (_jsx("div", { className: "p-3 grid grid-cols-1 gap-2", children: allLanguages.map((lang) => {
|
|
238
|
+
const statusLabel = lang.translationStatus?.status || "Not started";
|
|
239
|
+
return (_jsxs("label", { className: "flex items-start gap-2 py-1.5 px-2 rounded-md hover:bg-[var(--color-gray-4)] transition-colors cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: languageSelection[lang.code] || false, onChange: () => handleLanguageToggle(lang.code), className: "mt-0.5 h-4 w-4 shrink-0 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": `language-checkbox-${lang.code}` }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "text-sm text-[var(--color-dark)]", children: [lang.name, " (", lang.code, ")"] }), _jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-[var(--color-gray-2)]", children: [lang.sourceLanguage && _jsxs("span", { children: ["from: ", lang.sourceLanguage] }), !lang.hasVersions && (_jsx("span", { className: "text-2xs text-orange-600 bg-orange-100 px-2 py-1 rounded-full font-medium", children: "No versions" })), lang.hasVersions && (_jsx("span", { title: lang.translationStatus?.message, className: `text-2xs px-2 py-1 rounded-full font-medium ${getTranslationStatusBadgeClass(statusLabel)}`, "data-testid": `translation-status-badge-${lang.code}`, children: statusLabel }))] })] })] }, lang.code));
|
|
240
|
+
}) })) })] })] }) }));
|
|
168
241
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TranslationStepProps } from "./types";
|
|
2
|
+
export declare function SubitemDiscoveryStep({ stepIndex, isActive, data, setData, editContext, onStepCompleted, setBeforeNextCallback, setFooterActions, requestClose }: TranslationStepProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=SubitemDiscoveryStep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubitemDiscoveryStep.d.ts","sourceRoot":"","sources":["../../src/steps/SubitemDiscoveryStep.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW/C,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,QAAe,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,oBAAoB,2CAga5L"}
|