@parhelia/localization 0.1.12902 → 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.map +1 -1
- package/dist/LocalizeItemCommand.js +2 -4
- 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 +163 -56
- 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 -1160
- 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 -16
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useState, useEffect, } from "react";
|
|
3
|
-
import { Button,
|
|
4
|
-
import { CheckCircle as LucideCheckCircle, AlertCircle as LucideAlertCircle, RefreshCw as LucideRefreshCw, Plus as LucidePlus, Settings as LucideSettings,
|
|
3
|
+
import { Button, useEditContext, Splitter, ItemConfigPanel, } from "@parhelia/core";
|
|
4
|
+
import { CheckCircle as LucideCheckCircle, AlertCircle as LucideAlertCircle, RefreshCw as LucideRefreshCw, Plus as LucidePlus, Settings as LucideSettings, Trash2 as LucideTrash2, } from "lucide-react";
|
|
5
5
|
import { getAvailableTranslationServices, createProviderSettings, getTranslationStructure, ensureTranslationStructure, } from "../services/translationService";
|
|
6
6
|
const CheckCircleIcon = LucideCheckCircle;
|
|
7
7
|
const AlertCircleIcon = LucideAlertCircle;
|
|
8
8
|
const RefreshCwIcon = LucideRefreshCw;
|
|
9
9
|
const PlusIcon = LucidePlus;
|
|
10
10
|
const SettingsIcon = LucideSettings;
|
|
11
|
-
const
|
|
12
|
-
const ListChecksIcon = LucideListChecks;
|
|
11
|
+
const Trash2Icon = LucideTrash2;
|
|
13
12
|
const DEFAULT_STRUCTURE_SETTINGS = {
|
|
14
13
|
translationFolderPath: "/sitecore/system/Parhelia/Settings/Translation",
|
|
15
14
|
translationFolderTemplateId: "b1e40cfe-6e36-4a0e-a49e-19c10b2127b7",
|
|
@@ -237,30 +236,46 @@ export function TranslationServicesPanel() {
|
|
|
237
236
|
useEffect(() => {
|
|
238
237
|
loadData();
|
|
239
238
|
}, [loadData]);
|
|
239
|
+
const statusIcon = (currentState) => {
|
|
240
|
+
if (currentState === "success")
|
|
241
|
+
return (_jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-600", strokeWidth: 1 }));
|
|
242
|
+
if (currentState === "error")
|
|
243
|
+
return (_jsx(AlertCircleIcon, { className: "h-4 w-4 text-red-600", strokeWidth: 1 }));
|
|
244
|
+
return (_jsx(RefreshCwIcon, { className: "h-4 w-4 animate-spin text-amber-600", strokeWidth: 1 }));
|
|
245
|
+
};
|
|
240
246
|
const configuredCount = services.filter((s) => s.isConfigured).length;
|
|
241
247
|
const totalCount = services.length;
|
|
242
248
|
const translationFolderExists = !!structureState?.translationFolder?.exists;
|
|
243
249
|
const providersFolderExists = !!structureState?.translationProvidersFolder?.exists;
|
|
244
250
|
// Build the services list content
|
|
245
|
-
const servicesListContent = (
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
251
|
+
const servicesListContent = (_jsx("div", { className: "h-full overflow-auto p-4", "data-testid": "translation-services-panel", children: _jsx("div", { className: "mx-auto", children: _jsx("div", { className: "rounded-lg bg-white p-4 md:p-6", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-4", "data-testid": "translation-services-prerequisites", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-semibold text-gray-900", children: "Prerequisites" }), _jsxs("div", { className: "mt-1 flex items-center gap-2", children: [translationFolderExists && providersFolderExists ? (_jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-600", strokeWidth: 1 })) : (_jsx(AlertCircleIcon, { className: "h-4 w-4 text-amber-500", strokeWidth: 1 })), _jsx("span", { className: "text-sm text-gray-700", children: translationFolderExists && providersFolderExists
|
|
252
|
+
? "All parent items found"
|
|
253
|
+
: "Parent items missing" })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { size: "sm", variant: "outline", onClick: loadStructure, disabled: structureLoading || ensuringStructure, children: [_jsx(RefreshCwIcon, { strokeWidth: 1, className: `h-4 w-4 ${structureLoading ? "animate-spin" : ""}` }), "Refresh"] }), !providersFolderExists && (_jsxs(Button, { size: "sm", onClick: ensureStructure, disabled: ensuringStructure || structureLoading, children: [ensuringStructure ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-4 w-4 animate-spin" })) : (_jsx(PlusIcon, { strokeWidth: 1.5, className: "h-4 w-4" })), "Ensure Items"] }))] })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { "data-testid": "translation-structure-folder", className: `flex items-center justify-between rounded border p-3 text-sm transition-shadow hover:shadow-sm ${selectedConfigTarget?.key ===
|
|
254
|
+
`structure:${structureState?.translationFolder?.itemId}`
|
|
255
|
+
? "border-blue-400 bg-blue-50"
|
|
256
|
+
: "border-gray-200 bg-white"}`, children: [_jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [translationFolderExists ? (_jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-600 shrink-0", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-4 w-4 text-amber-500 shrink-0", strokeWidth: 1.5 })), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "font-medium text-gray-900", children: "Translation folder" }), _jsx("div", { className: "text-xs text-gray-500 truncate", children: structureSettings.translationFolderPath })] })] }), _jsx("div", { className: "flex items-center gap-2 ml-4 shrink-0", children: translationFolderExists &&
|
|
257
|
+
structureState?.translationFolder?.itemId && (_jsxs(Button, { size: "sm", variant: selectedConfigTarget?.key ===
|
|
258
|
+
`structure:${structureState.translationFolder.itemId}`
|
|
259
|
+
? "default"
|
|
260
|
+
: "ghost", onClick: () => handleOpenStructureConfig(structureState.translationFolder.itemId, "Configure: Translation folder"), className: "shrink-0", children: [_jsx(SettingsIcon, { className: "h-4 w-4", strokeWidth: 1.5 }), editContext?.isMobile ? "" : "Configure"] })) })] }), _jsxs("div", { "data-testid": "translation-structure-providers-folder", className: `flex items-center justify-between rounded border p-3 text-sm transition-shadow hover:shadow-sm ${selectedConfigTarget?.key ===
|
|
261
|
+
`structure:${structureState?.translationProvidersFolder?.itemId}`
|
|
262
|
+
? "border-blue-400 bg-blue-50"
|
|
263
|
+
: "border-gray-200 bg-white"}`, children: [_jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [providersFolderExists ? (_jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-600 shrink-0", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-4 w-4 text-amber-500 shrink-0", strokeWidth: 1.5 })), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "font-medium text-gray-900", children: "Translation providers folder" }), _jsx("div", { className: "text-xs text-gray-500 truncate", children: structureSettings.translationProvidersPath })] })] }), _jsx("div", { className: "flex items-center gap-2 ml-4 shrink-0", children: providersFolderExists &&
|
|
264
|
+
structureState?.translationProvidersFolder?.itemId && (_jsxs(Button, { size: "sm", variant: selectedConfigTarget?.key ===
|
|
265
|
+
`structure:${structureState.translationProvidersFolder.itemId}`
|
|
266
|
+
? "default"
|
|
267
|
+
: "ghost", onClick: () => handleOpenStructureConfig(structureState.translationProvidersFolder.itemId, "Configure: Translation Providers folder"), className: "shrink-0", children: [_jsx(SettingsIcon, { className: "h-4 w-4", strokeWidth: 1.5 }), editContext?.isMobile ? "" : "Configure"] })) })] })] })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-semibold text-gray-900", children: "Providers" }), _jsxs("div", { className: "mt-1 flex items-center gap-2", children: [statusIcon(state), _jsx("span", { className: "text-sm text-gray-700", children: totalCount > 0
|
|
268
|
+
? `${configuredCount} of ${totalCount} service${totalCount !== 1 ? "s" : ""} configured`
|
|
269
|
+
: "No services found" })] })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: loadData, children: [_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-4 w-4" }), "Refresh"] })] }), totalCount === 0 && state === "success" && (_jsx("div", { className: "rounded border border-yellow-200 bg-yellow-50 p-3 text-sm text-yellow-800", children: "No translation services are registered in dependency injection. Please check the server configuration." })), services.length > 0 && (_jsx("div", { className: "space-y-1", "data-testid": "translation-services-providers", children: services.map((service) => {
|
|
254
270
|
const isSelected = selectedConfigTarget?.key ===
|
|
255
271
|
`service:${service.serviceName}`;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
service.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}) })) })] })] }));
|
|
272
|
+
return (_jsxs("div", { className: `flex items-center justify-between rounded border p-3 text-sm transition-shadow hover:shadow-sm ${isSelected
|
|
273
|
+
? "border-blue-400 bg-blue-50"
|
|
274
|
+
: "border-gray-200 bg-white"}`, children: [_jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [service.isConfigured ? (_jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-600 shrink-0", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-4 w-4 text-amber-500 shrink-0", strokeWidth: 1.5 })), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "font-medium text-gray-900 truncate", children: service.displayName || service.serviceName }), service.displayName &&
|
|
275
|
+
service.displayName !== service.serviceName && (_jsxs("div", { className: "text-xs text-gray-500 truncate", children: ["Service: ", service.serviceName] })), service.isConfigured &&
|
|
276
|
+
service.supportedLanguages &&
|
|
277
|
+
service.supportedLanguages.length > 0 && (_jsxs("div", { className: "text-xs text-gray-500 mt-1 truncate", children: ["Languages:", " ", service.supportedLanguages.join(", ")] })), !service.isConfigured && (_jsx("div", { className: "text-xs text-amber-600 mt-1", children: "Not configured" }))] })] }), _jsx("div", { className: "flex items-center gap-2 ml-4 shrink-0", children: service.isConfigured && service.settingsItemId ? (_jsxs(_Fragment, { children: [_jsxs(Button, { size: "sm", variant: isSelected ? "default" : "ghost", onClick: () => handleOpenConfig(service), className: "shrink-0", disabled: service.deleting, children: [_jsx(SettingsIcon, { className: "h-4 w-4", strokeWidth: 1.5 }), editContext?.isMobile ? "" : "Configure"] }), _jsxs(Button, { size: "sm", variant: "ghost", onClick: () => deleteSettings(service), className: "shrink-0 text-red-600 hover:text-red-700", disabled: service.deleting, title: `Delete settings for ${service.displayName || service.serviceName}`, children: [service.deleting ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-4 w-4 animate-spin" })) : (_jsx(Trash2Icon, { className: "h-4 w-4", strokeWidth: 1.5 })), editContext?.isMobile ? "" : "Delete"] })] })) : (_jsxs(Button, { size: "sm", variant: "outline", onClick: () => createSettings(service.serviceName, service.templateId), disabled: service.creating, title: `Create settings using template: ${service.templateName}`, className: "shrink-0", children: [service.creating ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-4 w-4 animate-spin" })) : (_jsx(PlusIcon, { strokeWidth: 1.5, className: "h-4 w-4" })), "Create Settings"] })) })] }, service.serviceName));
|
|
278
|
+
}) })), error && (_jsx("div", { className: "rounded border border-red-200 bg-red-50 p-3 text-sm text-red-700 whitespace-pre-wrap", children: error }))] }) }) }) }));
|
|
264
279
|
// Build splitter panels - only show config panel when a service is selected
|
|
265
280
|
const panels = selectedConfigTarget?.itemId
|
|
266
281
|
? [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalizationSetupStep.d.ts","sourceRoot":"","sources":["../../src/setup/LocalizationSetupStep.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"LocalizationSetupStep.d.ts","sourceRoot":"","sources":["../../src/setup/LocalizationSetupStep.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,qBAAqB,4CA6NpC;AAED,eAAe,qBAAqB,CAAC"}
|
|
@@ -15,12 +15,12 @@ export function LocalizationSetupStep() {
|
|
|
15
15
|
const [services, setServices] = useState([]);
|
|
16
16
|
const statusIcon = useCallback((state) => {
|
|
17
17
|
if (state === "success")
|
|
18
|
-
return
|
|
18
|
+
return _jsx(CheckCircleIcon, { className: "h-4 w-4 text-[#8ae048]", strokeWidth: 1 });
|
|
19
19
|
if (state === "error")
|
|
20
|
-
return
|
|
20
|
+
return _jsx(AlertCircleIcon, { className: "h-4 w-4 text-destructive", strokeWidth: 1 });
|
|
21
21
|
if (state === "partial")
|
|
22
|
-
return
|
|
23
|
-
return (_jsx(RefreshCwIcon, { className: "h-4 w-4 animate-spin text-[
|
|
22
|
+
return _jsx(AlertCircleIcon, { className: "h-4 w-4 text-[#ffc310]", strokeWidth: 1 });
|
|
23
|
+
return (_jsx(RefreshCwIcon, { className: "h-4 w-4 animate-spin text-[#9650fb]", strokeWidth: 1 }));
|
|
24
24
|
}, []);
|
|
25
25
|
const checkLocalization = useCallback(async () => {
|
|
26
26
|
try {
|
|
@@ -42,14 +42,14 @@ export function LocalizationSetupStep() {
|
|
|
42
42
|
else {
|
|
43
43
|
const serviceStates = availableServices.map((svc) => ({
|
|
44
44
|
...svc,
|
|
45
|
-
creating: false
|
|
45
|
+
creating: false
|
|
46
46
|
}));
|
|
47
47
|
setServices(serviceStates);
|
|
48
|
-
const configuredCount = serviceStates.filter(
|
|
48
|
+
const configuredCount = serviceStates.filter(s => s.isConfigured).length;
|
|
49
49
|
const totalCount = serviceStates.length;
|
|
50
50
|
if (configuredCount === 0) {
|
|
51
51
|
setState("error");
|
|
52
|
-
setError(`Found ${totalCount} translation service${totalCount !== 1 ?
|
|
52
|
+
setError(`Found ${totalCount} translation service${totalCount !== 1 ? 's' : ''} in DI, but none have Sitecore Settings items configured.`);
|
|
53
53
|
}
|
|
54
54
|
else if (configuredCount < totalCount) {
|
|
55
55
|
setState("partial");
|
|
@@ -62,8 +62,7 @@ export function LocalizationSetupStep() {
|
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
64
|
setState("error");
|
|
65
|
-
setError(result.details ||
|
|
66
|
-
"Failed to check translation services. The translation API may not be available.");
|
|
65
|
+
setError(result.details || "Failed to check translation services. The translation API may not be available.");
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
catch (e) {
|
|
@@ -73,7 +72,7 @@ export function LocalizationSetupStep() {
|
|
|
73
72
|
}, []);
|
|
74
73
|
const createSettings = useCallback(async (serviceName, templateId) => {
|
|
75
74
|
try {
|
|
76
|
-
setServices(
|
|
75
|
+
setServices(prev => prev.map(s => s.serviceName === serviceName ? { ...s, creating: true } : s));
|
|
77
76
|
setError(null);
|
|
78
77
|
const language = editContext?.item?.language ??
|
|
79
78
|
editContext?.currentItemDescriptor?.language ??
|
|
@@ -81,20 +80,13 @@ export function LocalizationSetupStep() {
|
|
|
81
80
|
const result = await createProviderSettings(serviceName, templateId, language);
|
|
82
81
|
if (result.type === "success" && result.data) {
|
|
83
82
|
if (result.data.success && result.data.data) {
|
|
84
|
-
setServices(
|
|
85
|
-
? {
|
|
86
|
-
...s,
|
|
87
|
-
isConfigured: true,
|
|
88
|
-
creating: false,
|
|
89
|
-
settingsItemId: result.data?.data?.itemId,
|
|
90
|
-
}
|
|
83
|
+
setServices(prev => prev.map(s => s.serviceName === serviceName
|
|
84
|
+
? { ...s, isConfigured: true, creating: false, settingsItemId: result.data?.data?.itemId }
|
|
91
85
|
: s));
|
|
92
86
|
setTimeout(() => checkLocalization(), 500);
|
|
93
87
|
}
|
|
94
88
|
else {
|
|
95
|
-
throw new Error(result.data.error ||
|
|
96
|
-
result.details ||
|
|
97
|
-
"Failed to create settings");
|
|
89
|
+
throw new Error(result.data.error || result.details || "Failed to create settings");
|
|
98
90
|
}
|
|
99
91
|
}
|
|
100
92
|
else {
|
|
@@ -103,25 +95,22 @@ export function LocalizationSetupStep() {
|
|
|
103
95
|
}
|
|
104
96
|
catch (e) {
|
|
105
97
|
setError(`Failed to create settings for ${serviceName}: ${e?.message || "Unknown error"}`);
|
|
106
|
-
setServices(
|
|
98
|
+
setServices(prev => prev.map(s => s.serviceName === serviceName ? { ...s, creating: false } : s));
|
|
107
99
|
}
|
|
108
100
|
}, [editContext, checkLocalization]);
|
|
109
101
|
React.useEffect(() => {
|
|
110
102
|
checkLocalization();
|
|
111
103
|
}, [checkLocalization]);
|
|
112
|
-
const configuredCount = services.filter(
|
|
104
|
+
const configuredCount = services.filter(s => s.isConfigured).length;
|
|
113
105
|
const totalCount = services.length;
|
|
114
|
-
return (_jsx(Card, { icon: _jsx(LanguagesIcon, { strokeWidth: 1, className: "h-5 w-5" }), title: "Localization setup", description: "Verifies that translation services registered in DI have corresponding Sitecore Settings items.", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [statusIcon(state), _jsx("span", { className: "text-sm text-
|
|
115
|
-
? `All ${totalCount} translation service${totalCount !== 1 ?
|
|
106
|
+
return (_jsx(Card, { icon: _jsx(LanguagesIcon, { strokeWidth: 1, className: "h-5 w-5" }), title: "Localization setup", description: "Verifies that translation services registered in DI have corresponding Sitecore Settings items.", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [statusIcon(state), _jsx("span", { className: "text-sm text-[var(--color-gray-1)]", children: state === "success"
|
|
107
|
+
? `All ${totalCount} translation service${totalCount !== 1 ? 's' : ''} configured`
|
|
116
108
|
: state === "partial"
|
|
117
109
|
? `${configuredCount} of ${totalCount} services configured`
|
|
118
110
|
: state === "error" && totalCount > 0
|
|
119
|
-
? `${totalCount} service${totalCount !== 1 ?
|
|
111
|
+
? `${totalCount} service${totalCount !== 1 ? 's' : ''} found, none configured`
|
|
120
112
|
: state === "error"
|
|
121
113
|
? "No services found"
|
|
122
|
-
: "Checking..." })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: checkLocalization, children: [_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-4 w-4" }), "Recheck"] })] }), services.length > 0 && (_jsxs("div", { className: "space-y-2 rounded-lg border border-
|
|
123
|
-
service.displayName !== service.serviceName && (_jsxs("div", { className: "text-xs text-neutral-grey-50", children: ["Service: ", service.serviceName] })), service.isConfigured &&
|
|
124
|
-
service.supportedLanguages &&
|
|
125
|
-
service.supportedLanguages.length > 0 && (_jsxs("div", { className: "text-xs text-neutral-grey-50", children: ["Languages: ", service.supportedLanguages.join(", ")] }))] })] }), !service.isConfigured && (_jsxs(Button, { size: "xs", onClick: () => createSettings(service.serviceName, service.templateId), disabled: service.creating, title: `Create using template: ${service.templateName}`, children: [service.creating ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-3 w-3 animate-spin" })) : (_jsx(PlusIcon, { strokeWidth: 1.5, className: "h-3 w-3" })), "Create Settings"] }))] }, service.serviceName)))] })), error && (_jsx("div", { className: "rounded-md border border-feedback-orange/30 bg-feedback-orange/10 p-3 text-xs whitespace-pre-wrap text-neutral-grey-100", children: error }))] }) }));
|
|
114
|
+
: "Checking..." })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: checkLocalization, children: [_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-4 w-4" }), "Recheck"] })] }), services.length > 0 && (_jsxs("div", { className: "space-y-2 rounded-lg border border-[var(--color-gray-3)] bg-[var(--color-gray-5)] p-3", children: [_jsx("div", { className: "text-xs font-semibold text-[var(--color-gray-2)] uppercase tracking-wide", children: "Translation Services" }), services.map((service) => (_jsxs("div", { className: "flex items-center justify-between rounded-md bg-background p-3 shadow-sm border border-[var(--color-gray-3)]", children: [_jsxs("div", { className: "flex items-center gap-2", children: [service.isConfigured ? (_jsx(CheckCircleIcon, { className: "h-3.5 w-3.5 text-[#8ae048]", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-3.5 w-3.5 text-[#ffc310]", strokeWidth: 1.5 })), _jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-[var(--color-dark)]", children: service.displayName || service.serviceName }), service.displayName && service.displayName !== service.serviceName && (_jsxs("div", { className: "text-xs text-[var(--color-gray-2)]", children: ["Service: ", service.serviceName] })), service.isConfigured && service.supportedLanguages && service.supportedLanguages.length > 0 && (_jsxs("div", { className: "text-xs text-[var(--color-gray-2)]", children: ["Languages: ", service.supportedLanguages.join(", ")] }))] })] }), !service.isConfigured && (_jsxs(Button, { size: "xs", onClick: () => createSettings(service.serviceName, service.templateId), disabled: service.creating, title: `Create using template: ${service.templateName}`, children: [service.creating ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-3 w-3 animate-spin" })) : (_jsx(PlusIcon, { strokeWidth: 1.5, className: "h-3 w-3" })), "Create Settings"] }))] }, service.serviceName)))] })), error && (_jsx("div", { className: "rounded-md border border-[#ffc310]/30 bg-[#ffc310]/10 p-3 text-xs whitespace-pre-wrap text-[var(--color-dark)]", children: error }))] }) }));
|
|
126
115
|
}
|
|
127
116
|
export default LocalizationSetupStep;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"AAcA,wBAAgB,kBAAkB,mDA4MjC"}
|
|
@@ -3,9 +3,6 @@ import { Button, useEditContext, SimpleTable, confirmCreateVersion, Progress, }
|
|
|
3
3
|
import { getTranslationStatus } from "../services/translationService";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { localizeItemCommand } from "../LocalizeItemCommand";
|
|
6
|
-
function isActiveTranslationStatus(status) {
|
|
7
|
-
return status === "Pending" || status === "In Progress";
|
|
8
|
-
}
|
|
9
6
|
export function TranslationSidebar() {
|
|
10
7
|
const editContext = useEditContext();
|
|
11
8
|
if (!editContext)
|
|
@@ -28,7 +25,7 @@ export function TranslationSidebar() {
|
|
|
28
25
|
});
|
|
29
26
|
};
|
|
30
27
|
const languageName = (language) => {
|
|
31
|
-
return (_jsxs("div", { className: "flex items-center gap-2 text-
|
|
28
|
+
return (_jsxs("div", { className: "flex items-center gap-2 text-[var(--color-dark)]", children: [_jsx("img", { src: language.icon, className: "h-5 rounded-sm", alt: language.languageCode }), _jsx("span", { className: "font-medium", children: language.name })] }, language.languageCode));
|
|
32
29
|
};
|
|
33
30
|
const loadTranslationStatus = async () => {
|
|
34
31
|
if (!item)
|
|
@@ -75,11 +72,7 @@ export function TranslationSidebar() {
|
|
|
75
72
|
const effectiveStatus = progress ? "In Progress" : status?.status;
|
|
76
73
|
return {
|
|
77
74
|
...x,
|
|
78
|
-
translationStatus: status
|
|
79
|
-
? { ...status, status: effectiveStatus }
|
|
80
|
-
: progress
|
|
81
|
-
? { status: "In Progress" }
|
|
82
|
-
: undefined,
|
|
75
|
+
translationStatus: status ? { ...status, status: effectiveStatus } : (progress ? { status: "In Progress" } : undefined),
|
|
83
76
|
translationProgress: progress,
|
|
84
77
|
};
|
|
85
78
|
});
|
|
@@ -92,7 +85,7 @@ export function TranslationSidebar() {
|
|
|
92
85
|
// Sort by name for languages that both have versions or both don't
|
|
93
86
|
return a.name.localeCompare(b.name);
|
|
94
87
|
});
|
|
95
|
-
return (_jsxs("div", { className: "flex h-full flex-col", "data-testid": "translation-sidebar", children: [_jsx("div", { className: "flex items-center justify-end border-b border-
|
|
88
|
+
return (_jsxs("div", { className: "flex h-full flex-col", "data-testid": "translation-sidebar", children: [_jsx("div", { className: "flex items-center justify-end border-b border-[var(--color-gray-3)] p-1 px-2", children: item && (_jsx(Button, { size: "xs", "data-testid": "translation-sidebar-localize-button", onClick: () => {
|
|
96
89
|
editContext.executeCommand({
|
|
97
90
|
command: localizeItemCommand,
|
|
98
91
|
data: {
|
|
@@ -101,23 +94,20 @@ export function TranslationSidebar() {
|
|
|
101
94
|
});
|
|
102
95
|
}, children: "Translate" })) }), _jsx("div", { className: "relative flex-1", children: _jsx("div", { className: "absolute inset-0 overflow-y-auto", children: _jsx(SimpleTable, { "data-testid": "translation-sidebar-language-table", columns: [
|
|
103
96
|
{ header: "Language", body: languageName },
|
|
104
|
-
{
|
|
105
|
-
header: "Ver.",
|
|
106
|
-
body: (x) => (_jsx("span", { className: "text-neutral-grey-100", children: x.versions.toString() })),
|
|
107
|
-
},
|
|
97
|
+
{ header: "Ver.", body: (x) => _jsx("span", { className: "text-[var(--color-gray-1)]", children: x.versions.toString() }) },
|
|
108
98
|
{
|
|
109
99
|
header: "Src",
|
|
110
|
-
body: (x) =>
|
|
100
|
+
body: (x) => _jsx("span", { className: "text-[var(--color-gray-2)]", children: x.translationStatus?.sourceLanguage }),
|
|
111
101
|
},
|
|
112
102
|
{
|
|
113
103
|
header: "Status",
|
|
114
|
-
body: (x) => (_jsxs("div", { className: "flex items-center gap-2", "data-testid": `translation-status-${x.languageCode}`, children: [
|
|
115
|
-
? "text-
|
|
104
|
+
body: (x) => (_jsxs("div", { className: "flex items-center gap-2", "data-testid": `translation-status-${x.languageCode}`, children: [x.translationStatus?.status === "In Progress" && (_jsxs("div", { className: "relative w-full", children: [_jsx(Progress, { className: "h-5", value: (x.translationProgress?.progress || 0) * 100, showValue: false, indicatorClassName: "bg-[#9650fb]", "data-testid": `translation-progress-${x.languageCode}` }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center text-white text-xs font-medium", children: x.translationProgress?.message })] })), x.translationStatus?.status !== "In Progress" && (_jsx("span", { title: x.translationStatus?.message, className: x.translationStatus?.status === "Completed"
|
|
105
|
+
? "text-green-600 font-medium"
|
|
116
106
|
: x.translationStatus?.status === "Error"
|
|
117
|
-
? "text-
|
|
118
|
-
: "text-
|
|
107
|
+
? "text-red-600 font-medium"
|
|
108
|
+
: "text-[var(--color-gray-2)]", children: x.translationStatus?.status || "Not started" }))] })),
|
|
119
109
|
},
|
|
120
110
|
], items: languageData, onRowClick: (data) => selectLanguage(data.item), rowClassName: (item) => item.languageCode == editContext.currentItemDescriptor?.language
|
|
121
|
-
? "bg-[
|
|
111
|
+
? "bg-[#f6eeff]"
|
|
122
112
|
: "" }) }) })] }));
|
|
123
113
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { TranslationStepProps } from "./types";
|
|
2
|
+
/** Example Step for metadata input testing */
|
|
3
|
+
export declare function MetadataInputStep({ stepIndex, isActive, data, setData, onStepCompleted, }: TranslationStepProps): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
//# sourceMappingURL=MetadataInputStep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetadataInputStep.d.ts","sourceRoot":"","sources":["../../src/steps/MetadataInputStep.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/C,8CAA8C;AAC9C,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,QAAe,EACf,IAAI,EACJ,OAAO,EACP,eAAe,GAChB,EAAE,oBAAoB,2CA8EtB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
/** Example Step for metadata input testing */
|
|
4
|
+
export function MetadataInputStep({ stepIndex, isActive = true, data, setData, onStepCompleted, }) {
|
|
5
|
+
// Convert Map<string, Map<string, string>> to a flat object for local state management
|
|
6
|
+
const [itemMetadata, setItemMetadata] = useState(() => {
|
|
7
|
+
const result = {};
|
|
8
|
+
data.itemMetadata.forEach((languageMap, itemId) => {
|
|
9
|
+
result[itemId] = Object.fromEntries(languageMap);
|
|
10
|
+
});
|
|
11
|
+
return result;
|
|
12
|
+
});
|
|
13
|
+
const allItems = data.includeSubitems ? data.discoveredItems : data.items;
|
|
14
|
+
const handleMetadataChange = (itemId, language, metadata) => {
|
|
15
|
+
const updated = {
|
|
16
|
+
...itemMetadata,
|
|
17
|
+
[itemId]: {
|
|
18
|
+
...(itemMetadata[itemId] || {}),
|
|
19
|
+
[language]: metadata
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
setItemMetadata(updated);
|
|
23
|
+
// Convert back to Map structure for wizard data
|
|
24
|
+
const metadataMap = new Map();
|
|
25
|
+
Object.entries(updated).forEach(([itemId, languageMap]) => {
|
|
26
|
+
metadataMap.set(itemId, new Map(Object.entries(languageMap)));
|
|
27
|
+
});
|
|
28
|
+
setData({ ...data, itemMetadata: metadataMap });
|
|
29
|
+
console.log('Updated itemMetadata:', metadataMap);
|
|
30
|
+
};
|
|
31
|
+
// Data is saved automatically on change
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
// Only update completion when this step is active
|
|
34
|
+
if (!isActive)
|
|
35
|
+
return;
|
|
36
|
+
// Mark step as completed since metadata is optional
|
|
37
|
+
onStepCompleted(true);
|
|
38
|
+
}, [isActive, onStepCompleted]); // Check when active state changes
|
|
39
|
+
// No footer actions needed since data is saved automatically
|
|
40
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 p-6", "data-testid": "metadata-input-step", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-xl font-semibold text-[var(--color-dark)] mb-2", children: "Enter Metadata Per Item Per Language" }), _jsx("p", { className: "text-sm text-[var(--color-gray-2)]", children: "Provide custom metadata for each item and language combination (optional)." })] }), _jsx("div", { className: "max-h-64 overflow-y-auto space-y-4", "data-testid": "metadata-input-container", children: allItems.map((item) => (_jsxs("div", { className: "border border-[var(--color-gray-3)] rounded-lg p-4 bg-background shadow-sm", "data-testid": `metadata-item-${item.id}`, children: [_jsx("label", { className: "block text-sm font-medium text-[var(--color-dark)] mb-3", "data-testid": `metadata-item-label-${item.id}`, children: item.name || item.id }), data.targetLanguages?.map((language) => (_jsxs("div", { className: "mb-3", "data-testid": `metadata-field-${item.id}-${language}`, children: [_jsxs("label", { className: "block text-xs font-medium mb-1.5 text-[var(--color-gray-2)]", "data-testid": `metadata-language-label-${item.id}-${language}`, children: [language.toUpperCase(), ":"] }), _jsx("textarea", { className: "w-full border border-[var(--color-gray-3)] rounded-md p-2.5 text-sm bg-[var(--color-gray-5)] text-[var(--color-dark)] focus:outline-none focus:ring-2 focus:ring-[#9650fb] focus:border-[#9650fb] transition-colors", rows: 2, value: itemMetadata[item.id]?.[language] || "", onChange: (e) => handleMetadataChange(item.id, language, e.target.value), placeholder: `Enter metadata for ${language}...`, "data-testid": `metadata-textarea-${item.id}-${language}` })] }, `${item.id}-${language}`)))] }, item.id))) })] }));
|
|
41
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { TranslationStepProps } from "./types";
|
|
2
|
-
export declare function PromptCustomizationStep({ isActive, data, setData, onStepCompleted, editContext, }: TranslationStepProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function PromptCustomizationStep({ stepIndex, isActive, data, setData, onStepCompleted, editContext, }: TranslationStepProps): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
//# sourceMappingURL=PromptCustomizationStep.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptCustomizationStep.d.ts","sourceRoot":"","sources":["../../src/steps/PromptCustomizationStep.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PromptCustomizationStep.d.ts","sourceRoot":"","sources":["../../src/steps/PromptCustomizationStep.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,SAAS,CAAC;AAEtE,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,QAAe,EACf,IAAI,EACJ,OAAO,EACP,eAAe,EACf,WAAW,GACZ,EAAE,oBAAoB,2CAqRtB"}
|