@parhelia/localization 0.1.11200 → 0.1.11455

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.
Files changed (80) hide show
  1. package/README.md +33 -33
  2. package/dist/LocalizeItemCommand.js +4 -4
  3. package/dist/LocalizeItemDialog.js +7 -7
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +52 -36
  6. package/dist/setup/LocalizationSetupStep.js +6 -6
  7. package/dist/sidebar/TranslationSidebar.d.ts.map +1 -1
  8. package/dist/sidebar/TranslationSidebar.js +36 -18
  9. package/dist/steps/MetadataInputStep.d.ts.map +1 -1
  10. package/dist/steps/MetadataInputStep.js +1 -1
  11. package/dist/steps/PromptCustomizationStep.js +2 -2
  12. package/dist/steps/ServiceLanguageSelectionStep.js +4 -4
  13. package/dist/steps/SubitemDiscoveryStep.js +7 -7
  14. package/dist/translation-center/BatchTranslationView.d.ts.map +1 -1
  15. package/dist/translation-center/BatchTranslationView.js +19 -18
  16. package/dist/translation-center/RecentTranslations.d.ts.map +1 -1
  17. package/dist/translation-center/RecentTranslations.js +40 -8
  18. package/dist/translation-center/TranslationManagement.d.ts.map +1 -1
  19. package/dist/translation-center/TranslationManagement.js +3 -3
  20. package/package.json +1 -1
  21. package/dist/dist/LocalizeItemCommand.d.ts +0 -8
  22. package/dist/dist/LocalizeItemCommand.d.ts.map +0 -1
  23. package/dist/dist/LocalizeItemCommand.js +0 -48
  24. package/dist/dist/LocalizeItemDialog.d.ts +0 -4
  25. package/dist/dist/LocalizeItemDialog.d.ts.map +0 -1
  26. package/dist/dist/LocalizeItemDialog.js +0 -129
  27. package/dist/dist/LocalizeItemUtils.d.ts +0 -17
  28. package/dist/dist/LocalizeItemUtils.d.ts.map +0 -1
  29. package/dist/dist/LocalizeItemUtils.js +0 -93
  30. package/dist/dist/api/discovery.d.ts +0 -36
  31. package/dist/dist/api/discovery.d.ts.map +0 -1
  32. package/dist/dist/api/discovery.js +0 -29
  33. package/dist/dist/constants.d.ts +0 -15
  34. package/dist/dist/constants.d.ts.map +0 -1
  35. package/dist/dist/constants.js +0 -21
  36. package/dist/dist/hooks/useTranslationWizard.d.ts +0 -6
  37. package/dist/dist/hooks/useTranslationWizard.d.ts.map +0 -1
  38. package/dist/dist/hooks/useTranslationWizard.js +0 -78
  39. package/dist/dist/index.d.ts +0 -69
  40. package/dist/dist/index.d.ts.map +0 -1
  41. package/dist/dist/index.js +0 -152
  42. package/dist/dist/services/translationService.d.ts +0 -102
  43. package/dist/dist/services/translationService.d.ts.map +0 -1
  44. package/dist/dist/services/translationService.js +0 -37
  45. package/dist/dist/setup/LocalizationSetupStep.d.ts +0 -3
  46. package/dist/dist/setup/LocalizationSetupStep.d.ts.map +0 -1
  47. package/dist/dist/setup/LocalizationSetupStep.js +0 -115
  48. package/dist/dist/sidebar/TranslationSidebar.d.ts +0 -2
  49. package/dist/dist/sidebar/TranslationSidebar.d.ts.map +0 -1
  50. package/dist/dist/sidebar/TranslationSidebar.js +0 -95
  51. package/dist/dist/steps/MetadataInputStep.d.ts +0 -4
  52. package/dist/dist/steps/MetadataInputStep.d.ts.map +0 -1
  53. package/dist/dist/steps/MetadataInputStep.js +0 -38
  54. package/dist/dist/steps/ServiceLanguageSelectionStep.d.ts +0 -3
  55. package/dist/dist/steps/ServiceLanguageSelectionStep.d.ts.map +0 -1
  56. package/dist/dist/steps/ServiceLanguageSelectionStep.js +0 -120
  57. package/dist/dist/steps/SubitemDiscoveryStep.d.ts +0 -3
  58. package/dist/dist/steps/SubitemDiscoveryStep.d.ts.map +0 -1
  59. package/dist/dist/steps/SubitemDiscoveryStep.js +0 -415
  60. package/dist/dist/steps/index.d.ts +0 -5
  61. package/dist/dist/steps/index.d.ts.map +0 -1
  62. package/dist/dist/steps/index.js +0 -4
  63. package/dist/dist/steps/types.d.ts +0 -68
  64. package/dist/dist/steps/types.d.ts.map +0 -1
  65. package/dist/dist/steps/types.js +0 -1
  66. package/dist/dist/translation-center/BatchTranslationView.d.ts +0 -7
  67. package/dist/dist/translation-center/BatchTranslationView.d.ts.map +0 -1
  68. package/dist/dist/translation-center/BatchTranslationView.js +0 -507
  69. package/dist/dist/translation-center/RecentTranslations.d.ts +0 -2
  70. package/dist/dist/translation-center/RecentTranslations.d.ts.map +0 -1
  71. package/dist/dist/translation-center/RecentTranslations.js +0 -195
  72. package/dist/dist/translation-center/TranslationManagement.d.ts +0 -2
  73. package/dist/dist/translation-center/TranslationManagement.d.ts.map +0 -1
  74. package/dist/dist/translation-center/TranslationManagement.js +0 -25
  75. package/dist/dist/types.d.ts +0 -18
  76. package/dist/dist/types.d.ts.map +0 -1
  77. package/dist/dist/types.js +0 -1
  78. package/dist/dist/utils/createVersions.d.ts +0 -14
  79. package/dist/dist/utils/createVersions.d.ts.map +0 -1
  80. package/dist/dist/utils/createVersions.js +0 -26
package/README.md CHANGED
@@ -1,33 +1,33 @@
1
- # @parhelia/localization
2
-
3
- Localization and translation features for Parhelia visual editor.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @parhelia/localization
9
- ```
10
-
11
- ## Usage
12
-
13
- ```typescript
14
- import { LocalizeItemDialog, TranslationSidebar } from '@parhelia/localization';
15
- import '@parhelia/localization/styles.css';
16
- ```
17
-
18
- ## Features
19
-
20
- - Translation wizard
21
- - Localization setup
22
- - Translation center
23
- - Multi-language content management
24
- - Version creation for localized content
25
-
26
- ## License
27
-
28
- See LICENSE file for details.
29
-
30
- ## Documentation
31
-
32
- For complete documentation, visit [https://parhelia.ai](https://parhelia.ai)
33
-
1
+ # @parhelia/localization
2
+
3
+ Localization and translation features for Parhelia visual editor.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @parhelia/localization
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { LocalizeItemDialog, TranslationSidebar } from '@parhelia/localization';
15
+ import '@parhelia/localization/styles.css';
16
+ ```
17
+
18
+ ## Features
19
+
20
+ - Translation wizard
21
+ - Localization setup
22
+ - Translation center
23
+ - Multi-language content management
24
+ - Version creation for localized content
25
+
26
+ ## License
27
+
28
+ See LICENSE file for details.
29
+
30
+ ## Documentation
31
+
32
+ For complete documentation, visit [https://parhelia.ai](https://parhelia.ai)
33
+
@@ -33,14 +33,14 @@ export const localizeItemCommand = {
33
33
  if (result?.batchId) {
34
34
  const translationManagementEnabled = context.editContext?.configuration?.localization?.translationManagement !== false;
35
35
  if (translationManagementEnabled) {
36
- // Synchronous URL update to avoid race with view URL sync
36
+ // Synchronous URL update to avoid race with workspace URL sync
37
37
  const params = new URLSearchParams(window.location.search);
38
- params.set("view", "translation-management");
38
+ params.set("workspace", "translation-management");
39
39
  params.set("batchId", result.batchId);
40
40
  const newUrl = `${window.location.pathname}?${params.toString()}`;
41
41
  window.history.pushState(null, "", newUrl);
42
- // Now switch the view; URL already contains batchId
43
- context.editContext.switchView("translation-management");
42
+ // Now switch the workspace; URL already contains batchId
43
+ context.editContext.switchWorkspace("translation-management");
44
44
  }
45
45
  }
46
46
  return result;
@@ -7,7 +7,7 @@ import { performDefaultTranslation, generateBatchId } from "./LocalizeItemUtils"
7
7
  const ChevronRightIcon = LucideChevronRight;
8
8
  // Note: DialogButtons is an internal component that might need to be added to core exports
9
9
  // For now, we'll implement it inline
10
- const DialogButtons = ({ children, ...props }) => (_jsx("div", { className: "flex justify-end gap-2 pt-4 border-t mt-auto px-6 pb-6", ...props, children: children }));
10
+ const DialogButtons = ({ children, ...props }) => (_jsx("div", { className: "flex justify-end gap-2 pt-4 border-t border-[var(--color-gray-3)] mt-auto px-6 pb-6 bg-background", ...props, children: children }));
11
11
  export function LocalizeItemDialog(props) {
12
12
  const editContext = props.editContext;
13
13
  const configuration = editContext.configuration.translationWizard;
@@ -184,13 +184,13 @@ export function LocalizeItemDialog(props) {
184
184
  width: 'min(90vw, 1280px)',
185
185
  height: 'min(85vh, 900px)',
186
186
  minHeight: '700px'
187
- }, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { "data-testid": "translation-wizard-title", children: "Translation Wizard" }), _jsx("div", { id: "translation-wizard-description", className: "sr-only", children: currentStep?.description || "Configure and start translation for your content." })] }), _jsxs("div", { className: "flex flex-1 flex-col min-h-0", children: [_jsx("div", { className: "border-b border-gray-300 bg-white px-4", "data-testid": "translation-wizard-step-navigation", children: _jsx("div", { className: "flex items-center gap-3 py-2", children: activeSteps.map((step, index) => (_jsxs("div", { className: "flex items-center gap-2", "data-testid": `step-indicator-${step.id}`, children: [_jsx("div", { className: cn("flex h-8 w-8 items-center justify-center rounded-full border text-sm font-medium", currentStepIndex === index &&
188
- "border-blue-500 text-blue-500 bg-blue-50", currentStepIndex < index && "border-gray-300 text-gray-400", currentStepIndex > index &&
189
- "bg-blue-500 text-white border-blue-500"), "data-testid": `step-indicator-circle-${step.id}`, children: currentStepIndex > index ? "✓" : index + 1 }), _jsx("span", { className: cn("text-sm", currentStepIndex === index
190
- ? "text-blue-600 font-medium"
187
+ }, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { "data-testid": "translation-wizard-title", children: "Translation Wizard" }), _jsx("div", { id: "translation-wizard-description", className: "sr-only", children: currentStep?.description || "Configure and start translation for your content." })] }), _jsxs("div", { className: "flex flex-1 flex-col min-h-0", children: [_jsx("div", { className: "border-b border-[var(--color-gray-3)] bg-background px-6", "data-testid": "translation-wizard-step-navigation", children: _jsx("div", { className: "flex items-center gap-3 py-3", children: activeSteps.map((step, index) => (_jsxs("div", { className: "flex items-center gap-2", "data-testid": `step-indicator-${step.id}`, children: [_jsx("div", { className: cn("flex h-8 w-8 items-center justify-center rounded-full border text-sm font-medium transition-colors", currentStepIndex === index &&
188
+ "border-[#9650fb] text-[#9650fb] bg-[#f6eeff]", currentStepIndex < index && "border-[var(--color-gray-3)] text-[var(--color-gray-2)]", currentStepIndex > index &&
189
+ "bg-[#9650fb] text-white border-[#9650fb]"), "data-testid": `step-indicator-circle-${step.id}`, children: currentStepIndex > index ? "✓" : index + 1 }), _jsx("span", { className: cn("text-sm", currentStepIndex === index
190
+ ? "text-[#9650fb] font-medium"
191
191
  : currentStepIndex > index
192
- ? "text-blue-600"
193
- : "text-gray-400"), "data-testid": `step-indicator-label-${step.id}`, children: step.name }), index < activeSteps.length - 1 && (_jsx(ChevronRightIcon, { className: "w-4 h-4 text-gray-400 mx-2" }))] }, step.id))) }) }), _jsx("div", { className: "flex-1 overflow-y-auto min-h-0", "data-testid": "translation-wizard-step-content", children: _jsx("div", { className: "h-full relative", children: activeSteps.map((step, index) => {
192
+ ? "text-[#9650fb]"
193
+ : "text-[var(--color-gray-2)]"), "data-testid": `step-indicator-label-${step.id}`, children: step.name }), index < activeSteps.length - 1 && (_jsx(ChevronRightIcon, { className: "w-4 h-4 text-[var(--color-gray-3)] mx-2", strokeWidth: 1 }))] }, step.id))) }) }), _jsx("div", { className: "flex-1 overflow-y-auto min-h-0 bg-[var(--color-gray-5)]", "data-testid": "translation-wizard-step-content", children: _jsx("div", { className: "h-full relative", children: activeSteps.map((step, index) => {
194
194
  const StepComponent = step.component;
195
195
  const isActive = index === currentStepIndex;
196
196
  if (!StepComponent)
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAWtD,OAAO,EAAE,mBAAmB,EAAsB,MAAM,gBAAgB,CAAC;AASzE,QAAA,MAAM,wCAAwC;;;;;;;;;;;;8BAalB,qBAAqB;;CAchD,CAAC;AAEF,QAAA,MAAM,4CAA4C;;;;;;;CAUjD,CAAC;AAEF,OAAO,EAAE,wCAAwC,EAAE,4CAA4C,EAAE,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhF,MAAM,MAAM,yBAAyB,GAAG;IACtC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,mBAAmB,EAClC,OAAO,CAAC,EAAE,yBAAyB,uBAmGpC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAYtD,OAAO,EACL,mBAAmB,EAGpB,MAAM,gBAAgB,CAAC;AAUxB,QAAA,MAAM,wCAAwC;;;;;;;;;;;;8BAalB,qBAAqB;;CAchD,CAAC;AAEF,QAAA,MAAM,4CAA4C;;;;;;;CAUjD,CAAC;AAkCF,OAAO,EAAE,wCAAwC,EAAE,4CAA4C,EAAE,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhF,MAAM,MAAM,yBAAyB,GAAG;IACtC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,mBAAmB,EAClC,OAAO,CAAC,EAAE,yBAAyB,uBAqFpC"}
package/dist/index.js CHANGED
@@ -7,10 +7,10 @@ import { TranslationSidebar } from "./sidebar/TranslationSidebar";
7
7
  import { TranslationManagement } from "./translation-center/TranslationManagement";
8
8
  import { RecentTranslations } from "./translation-center/RecentTranslations";
9
9
  import { LocalizationSetupStep } from "./setup/LocalizationSetupStep";
10
- import { Languages as LucideLanguages, LayoutGrid as LucideLayoutGrid, } from "lucide-react";
11
- import { pageEditorViewBase } from "@parhelia/core";
10
+ import { Languages as LucideLanguages, LayoutGrid as LucideLayoutGrid, Globe as LucideGlobe, } from "lucide-react";
12
11
  const LanguagesIcon = LucideLanguages;
13
12
  const LayoutGridIcon = LucideLayoutGrid;
13
+ const GlobeIcon = LucideGlobe;
14
14
  const DEFAULT_TRANSLATION_WIZARD_CONFIGURATION = {
15
15
  steps: [
16
16
  {
@@ -50,6 +50,36 @@ const SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION = {
50
50
  // No SubitemDiscoveryStep - single item translation only
51
51
  ],
52
52
  };
53
+ /**
54
+ * Translation sidebar definition for the Editor workspace
55
+ */
56
+ const translateSidebar = {
57
+ id: "translate",
58
+ title: "Languages & Versions",
59
+ icon: _jsx(LanguagesIcon, { strokeWidth: 1 }),
60
+ position: "left",
61
+ sortOrder: 55, // After workbox (50), before dictionary (60)
62
+ panels: [
63
+ {
64
+ name: "translation",
65
+ title: "Languages & Versions",
66
+ content: _jsx(TranslationSidebar, {}),
67
+ initialSize: 100,
68
+ },
69
+ ],
70
+ };
71
+ /**
72
+ * Translation Management workspace definition
73
+ */
74
+ const translationManagementWorkspace = {
75
+ id: "translation-management",
76
+ title: "Translation Management",
77
+ icon: _jsx(GlobeIcon, { strokeWidth: 1 }),
78
+ component: _jsx(TranslationManagement, {}),
79
+ menuBar: _jsx(_Fragment, {}),
80
+ supportsSidebars: false,
81
+ sortOrder: 30,
82
+ };
53
83
  export { DEFAULT_TRANSLATION_WIZARD_CONFIGURATION, SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION };
54
84
  export { LocalizeItemDialog } from "./LocalizeItemDialog";
55
85
  export { localizeItemCommand } from "./LocalizeItemCommand";
@@ -77,6 +107,7 @@ export * from "./steps/types";
77
107
  */
78
108
  export function configureLocalization(configuration, options) {
79
109
  const enableMultiItem = options?.multiItem !== false; // Default to true
110
+ const enableTranslationManagement = options?.translationManagement !== false; // Default to true
80
111
  // Add localization setup step
81
112
  if (!configuration.setup) {
82
113
  configuration.setup = { steps: [] };
@@ -97,7 +128,7 @@ export function configureLocalization(configuration, options) {
97
128
  configuration.localization = {};
98
129
  }
99
130
  configuration.localization.multiItem = enableMultiItem;
100
- configuration.localization.translationManagement = options?.translationManagement !== false;
131
+ configuration.localization.translationManagement = enableTranslationManagement;
101
132
  if (!configuration.commands.allItemCommands) {
102
133
  configuration.commands.allItemCommands = [];
103
134
  }
@@ -106,30 +137,17 @@ export function configureLocalization(configuration, options) {
106
137
  if (!hasLocalizeCommand) {
107
138
  configuration.commands.allItemCommands.push(localizeItemCommand);
108
139
  }
109
- // Add Translation view to the editor views
110
- if (configuration.editor && configuration.editor.views) {
111
- const hasTranslateView = configuration.editor.views.some((view) => view.name === "translate");
112
- if (!hasTranslateView) {
113
- configuration.editor.views.push({
114
- name: "translate",
115
- icon: _jsx(LanguagesIcon, { strokeWidth: 1 }),
116
- title: "Translate",
117
- leftSidebar: {
118
- panels: [
119
- {
120
- name: "translation",
121
- title: "Languages & Versions",
122
- content: _jsx(TranslationSidebar, {}),
123
- initialSize: 20,
124
- },
125
- ],
126
- },
127
- ...pageEditorViewBase,
128
- });
129
- }
140
+ // Register translate sidebar in the Editor workspace
141
+ const sidebars = configuration.editor?.sidebars || [];
142
+ const hasTranslateSidebar = sidebars.some((s) => s.id === "translate");
143
+ if (!hasTranslateSidebar) {
144
+ configuration.editor = {
145
+ ...configuration.editor,
146
+ sidebars: [...sidebars, translateSidebar],
147
+ };
130
148
  }
131
- // Add Translation Management view if enabled
132
- if (options?.translationManagement && configuration.editor?.views) {
149
+ // Add Translation Management workspace if enabled
150
+ if (enableTranslationManagement) {
133
151
  // Create Translation Center configuration
134
152
  configuration.translationCenter = {
135
153
  groups: [
@@ -145,16 +163,14 @@ export function configureLocalization(configuration, options) {
145
163
  },
146
164
  ],
147
165
  };
148
- // Add Translation Management view
149
- const hasManagementView = configuration.editor.views.some((view) => view.name === "translation-management");
150
- if (!hasManagementView) {
151
- configuration.editor.views.push({
152
- name: "translation-management",
153
- icon: _jsx(LayoutGridIcon, { strokeWidth: 1 }),
154
- title: "Translation Management",
155
- defaultCenterPanelView: _jsx(TranslationManagement, {}),
156
- menuBar: _jsx(_Fragment, {}),
157
- });
166
+ // Register workspace
167
+ const workspaces = configuration.editor?.workspaces || [];
168
+ const hasManagementWorkspace = workspaces.some((w) => w.id === "translation-management");
169
+ if (!hasManagementWorkspace) {
170
+ configuration.editor = {
171
+ ...configuration.editor,
172
+ workspaces: [...workspaces, translationManagementWorkspace],
173
+ };
158
174
  }
159
175
  }
160
176
  return configuration;
@@ -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 _jsx(CheckCircleIcon, { className: "h-4 w-4 text-green-600", strokeWidth: 1 });
18
+ return _jsx(CheckCircleIcon, { className: "h-4 w-4 text-[#8ae048]", strokeWidth: 1 });
19
19
  if (state === "error")
20
- return _jsx(AlertCircleIcon, { className: "h-4 w-4 text-red-600", strokeWidth: 1 });
20
+ return _jsx(AlertCircleIcon, { className: "h-4 w-4 text-destructive", strokeWidth: 1 });
21
21
  if (state === "partial")
22
- return _jsx(AlertCircleIcon, { className: "h-4 w-4 text-amber-600", strokeWidth: 1 });
23
- return (_jsx(RefreshCwIcon, { className: "h-4 w-4 animate-spin text-amber-600", strokeWidth: 1 }));
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 {
@@ -100,7 +100,7 @@ export function LocalizationSetupStep() {
100
100
  }, [checkLocalization]);
101
101
  const configuredCount = services.filter(s => s.isConfigured).length;
102
102
  const totalCount = services.length;
103
- 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-gray-700", children: state === "success"
103
+ 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"
104
104
  ? `All ${totalCount} translation service${totalCount !== 1 ? 's' : ''} configured`
105
105
  : state === "partial"
106
106
  ? `${configuredCount} of ${totalCount} services configured`
@@ -108,6 +108,6 @@ export function LocalizationSetupStep() {
108
108
  ? `${totalCount} service${totalCount !== 1 ? 's' : ''} found, none configured`
109
109
  : state === "error"
110
110
  ? "No services found"
111
- : "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 border border-gray-200 bg-gray-50 p-3", children: [_jsx("div", { className: "text-xs font-semibold text-gray-600 uppercase", children: "Translation Services" }), services.map((service) => (_jsxs("div", { className: "flex items-center justify-between rounded bg-white p-2 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-2", children: [service.isConfigured ? (_jsx(CheckCircleIcon, { className: "h-3.5 w-3.5 text-green-600", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-3.5 w-3.5 text-amber-600", strokeWidth: 1.5 })), _jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-gray-800", children: service.displayName || service.serviceName }), service.displayName && service.displayName !== service.serviceName && (_jsxs("div", { className: "text-xs text-gray-500", children: ["Service: ", service.serviceName] })), service.isConfigured && service.supportedLanguages && service.supportedLanguages.length > 0 && (_jsxs("div", { className: "text-xs text-gray-500", 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 border border-yellow-200 bg-yellow-50 p-2 text-xs whitespace-pre-wrap text-yellow-800", children: error }))] }) }));
111
+ : "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 }))] }) }));
112
112
  }
113
113
  export default LocalizationSetupStep;
@@ -1 +1 @@
1
- {"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"AAcA,wBAAgB,kBAAkB,mDAuLjC"}
1
+ {"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"AAcA,wBAAgB,kBAAkB,mDA+MjC"}
@@ -25,7 +25,7 @@ export function TranslationSidebar() {
25
25
  });
26
26
  };
27
27
  const languageName = (language) => {
28
- return (_jsxs("div", { className: "flex items-center gap-2", onClick: () => selectLanguage(language), children: [_jsx("img", { src: language.icon, className: "h-5" }), " ", language.name] }, language.languageCode));
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));
29
29
  };
30
30
  const loadTranslationStatus = async () => {
31
31
  if (!item)
@@ -44,6 +44,14 @@ export function TranslationSidebar() {
44
44
  message.type === "translation-error") {
45
45
  if (message.payload.itemId === item?.descriptor.id) {
46
46
  loadTranslationStatus();
47
+ // Clear progress when finished or error
48
+ if (message.type !== "translation-started") {
49
+ setTranslationProgress((prev) => {
50
+ const next = new Map(prev);
51
+ next.delete(message.payload.language);
52
+ return next;
53
+ });
54
+ }
47
55
  }
48
56
  }
49
57
  if (message.type === "translation-progress") {
@@ -57,11 +65,17 @@ export function TranslationSidebar() {
57
65
  });
58
66
  return removeSocketMessageListener;
59
67
  }, [editContext, setTranslationProgress]);
60
- const languageData = languages.map((x) => ({
61
- ...x,
62
- translationStatus: translationStatus?.find((y) => y.targetLanguage === x.languageCode),
63
- translationProgress: translationProgress.get(x.languageCode),
64
- }));
68
+ const languageData = languages.map((x) => {
69
+ const progress = translationProgress.get(x.languageCode);
70
+ const status = translationStatus?.find((y) => y.targetLanguage === x.languageCode);
71
+ // If we have live progress, treat it as In Progress even if the DB doesn't know yet
72
+ const effectiveStatus = progress ? "In Progress" : status?.status;
73
+ return {
74
+ ...x,
75
+ translationStatus: status ? { ...status, status: effectiveStatus } : (progress ? { status: "In Progress" } : undefined),
76
+ translationProgress: progress,
77
+ };
78
+ });
65
79
  languageData.sort((a, b) => {
66
80
  // Sort languages with 0 versions to bottom
67
81
  if (a.versions === 0 && b.versions > 0)
@@ -71,25 +85,29 @@ export function TranslationSidebar() {
71
85
  // Sort by name for languages that both have versions or both don't
72
86
  return a.name.localeCompare(b.name);
73
87
  });
74
- return (_jsxs("div", { className: "flex h-full flex-col gap-2", "data-testid": "translation-sidebar", children: [_jsxs("div", { className: "flex w-full flex-wrap items-center justify-between gap-2 bg-gray-50 p-3", children: [_jsx("div", { className: "flex items-center gap-2 text-sm", children: _jsx("span", { className: "text-gray-500 font-medium", children: "Current Item Languages & Versions" }) }), item && (_jsxs(Button, { size: "sm", "data-testid": "translation-sidebar-localize-button", onClick: () => {
75
- editContext.executeCommand({
76
- command: localizeItemCommand,
77
- data: {
78
- items: [item],
79
- },
80
- });
81
- }, children: [_jsx("i", { className: "pi pi-plus" }), "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: [
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 && (_jsxs(Button, { size: "xs", variant: "ghost", className: "text-theme-secondary hover:text-theme-secondary/80 hover:bg-theme-secondary-light font-semibold", "data-testid": "translation-sidebar-localize-button", onClick: () => {
89
+ editContext.executeCommand({
90
+ command: localizeItemCommand,
91
+ data: {
92
+ items: [item],
93
+ },
94
+ });
95
+ }, children: [_jsx("i", { className: "pi pi-plus" }), "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: [
82
96
  { header: "Language", body: languageName },
83
- { header: "Ver.", body: (x) => x.versions.toString() },
97
+ { header: "Ver.", body: (x) => _jsx("span", { className: "text-[var(--color-gray-1)]", children: x.versions.toString() }) },
84
98
  {
85
99
  header: "Src",
86
- body: (x) => x.translationStatus?.sourceLanguage,
100
+ body: (x) => _jsx("span", { className: "text-[var(--color-gray-2)]", children: x.translationStatus?.sourceLanguage }),
87
101
  },
88
102
  {
89
103
  header: "Status",
90
- 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, "data-testid": `translation-progress-${x.languageCode}` }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center text-white text-xs", children: x.translationProgress?.message })] })), x.translationStatus?.status !== "In Progress" && (_jsx("div", { title: x.translationStatus?.message, children: x.translationStatus?.status || "Not started" }))] })),
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"
106
+ : x.translationStatus?.status === "Error"
107
+ ? "text-red-600 font-medium"
108
+ : "text-[var(--color-gray-2)]", children: x.translationStatus?.status || "Not started" }))] })),
91
109
  },
92
110
  ], items: languageData, onRowClick: (data) => selectLanguage(data.item), rowClassName: (item) => item.languageCode == editContext.currentItemDescriptor?.language
93
- ? "bg-neutral-100"
111
+ ? "bg-[#f6eeff]"
94
112
  : "" }) }) })] }));
95
113
  }
@@ -1 +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,2CA4EtB"}
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"}
@@ -37,5 +37,5 @@ export function MetadataInputStep({ stepIndex, isActive = true, data, setData, o
37
37
  onStepCompleted(true);
38
38
  }, [isActive, onStepCompleted]); // Check when active state changes
39
39
  // No footer actions needed since data is saved automatically
40
- return (_jsxs("div", { className: "flex flex-col gap-4 p-4", "data-testid": "metadata-input-step", children: [_jsx("h3", { className: "text-lg font-medium", children: "Enter Metadata Per Item Per Language" }), _jsx("p", { className: "text-sm text-gray-600", 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 rounded p-3", "data-testid": `metadata-item-${item.id}`, children: [_jsx("label", { className: "block text-sm font-medium mb-2", "data-testid": `metadata-item-label-${item.id}`, children: item.name || item.id }), data.targetLanguages?.map((language) => (_jsxs("div", { className: "mb-2", "data-testid": `metadata-field-${item.id}-${language}`, children: [_jsxs("label", { className: "block text-xs font-medium mb-1 text-gray-600", "data-testid": `metadata-language-label-${item.id}-${language}`, children: [language.toUpperCase(), ":"] }), _jsx("textarea", { className: "w-full border rounded p-2 text-sm", 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))) })] }));
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
41
  }
@@ -94,9 +94,9 @@ export function PromptCustomizationStep({ stepIndex, isActive = true, data, setD
94
94
  }, [isActive, onStepCompleted]);
95
95
  // Skip condition: hide step when checkbox is disabled
96
96
  // This is handled by skipCondition in wizard config
97
- return (_jsxs("div", { className: "p-6 space-y-6 h-full flex flex-col", "data-testid": "prompt-customization-step", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-xl font-semibold mb-2", children: "Customize Translation Prompt" }), _jsxs("p", { className: "text-sm text-gray-600 mb-6", children: ["Optionally customize the prompt used for translation. This allows you to provide specific instructions or context for the translation service.", _jsx("br", {}), _jsx("span", { className: "text-xs text-gray-500 mt-1 block", children: "Note: Your custom prompt will be appended to the system instructions that ensure proper translation structure." })] })] }), _jsxs("div", { className: "space-y-6 flex-1", children: [!enableCustomPrompt && (_jsx("div", { className: "border border-gray-200 rounded-md p-4 bg-gray-50", children: _jsx("p", { className: "text-sm text-gray-600", children: "Enable \"Customize translation prompt\" in the previous step to customize the prompt." }) })), enableCustomPrompt && (_jsxs(_Fragment, { children: [hasDefaultPrompt && (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-gray-900 mb-2", children: "Default Prompt" }), _jsx("div", { className: "border border-gray-200 rounded-md p-3 bg-gray-50", children: _jsx("pre", { className: "text-xs text-gray-700 whitespace-pre-wrap font-mono", children: defaultPrompt }) })] }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-gray-900 mb-2", children: "Customization Type" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "flex items-center", children: [_jsx("input", { type: "radio", name: "customizationType", value: "extend", checked: customizationType === "extend", onChange: () => setCustomizationType("extend"), className: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300", "data-testid": "customization-type-extend" }), _jsx("span", { className: "ml-2 text-sm text-gray-900", children: "Extend (append to default)" })] }), _jsxs("label", { className: "flex items-center", children: [_jsx("input", { type: "radio", name: "customizationType", value: "replace", checked: customizationType === "replace", onChange: () => setCustomizationType("replace"), className: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300", "data-testid": "customization-type-replace" }), _jsx("span", { className: "ml-2 text-sm text-gray-900", children: "Replace (use custom prompt only)" })] })] })] })] })), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-gray-900 mb-2", children: "Custom Prompt" }), _jsx("textarea", { value: customPrompt, onChange: (e) => setCustomPrompt(e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm font-mono", rows: 6, placeholder: "Enter your custom prompt instructions here...", "data-testid": "custom-prompt-textarea" }), _jsx("p", { className: "text-xs text-gray-500 mt-1", children: hasDefaultPrompt
97
+ return (_jsxs("div", { className: "p-6 space-y-6 h-full flex flex-col", "data-testid": "prompt-customization-step", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-xl font-semibold text-[var(--color-dark)] mb-2", children: "Customize Translation Prompt" }), _jsxs("p", { className: "text-sm text-[var(--color-gray-2)] mb-6", children: ["Optionally customize the prompt used for translation. This allows you to provide specific instructions or context for the translation service.", _jsx("br", {}), _jsx("span", { className: "text-xs text-[var(--color-gray-2)] mt-1 block", children: "Note: Your custom prompt will be appended to the system instructions that ensure proper translation structure." })] })] }), _jsxs("div", { className: "space-y-6 flex-1", children: [!enableCustomPrompt && (_jsx("div", { className: "border border-[var(--color-gray-3)] rounded-lg p-4 bg-[var(--color-gray-5)]", children: _jsx("p", { className: "text-sm text-[var(--color-gray-2)]", children: "Enable \"Customize translation prompt\" in the previous step to customize the prompt." }) })), enableCustomPrompt && (_jsxs(_Fragment, { children: [hasDefaultPrompt && (_jsxs(_Fragment, { 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: "Default Prompt" }), _jsx("div", { className: "border border-[var(--color-gray-3)] rounded-md p-3 bg-[var(--color-gray-5)]", children: _jsx("pre", { className: "text-xs text-[var(--color-gray-1)] whitespace-pre-wrap font-mono", children: defaultPrompt }) })] }), _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-3", children: "Customization Type" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("label", { className: "flex items-center cursor-pointer py-1.5 px-2 rounded-md hover:bg-[var(--color-gray-5)] transition-colors", children: [_jsx("input", { type: "radio", name: "customizationType", value: "extend", checked: customizationType === "extend", onChange: () => setCustomizationType("extend"), className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] accent-[#9650fb]", "data-testid": "customization-type-extend" }), _jsx("span", { className: "ml-2 text-sm text-[var(--color-dark)]", children: "Extend (append to default)" })] }), _jsxs("label", { className: "flex items-center cursor-pointer py-1.5 px-2 rounded-md hover:bg-[var(--color-gray-5)] transition-colors", children: [_jsx("input", { type: "radio", name: "customizationType", value: "replace", checked: customizationType === "replace", onChange: () => setCustomizationType("replace"), className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] accent-[#9650fb]", "data-testid": "customization-type-replace" }), _jsx("span", { className: "ml-2 text-sm text-[var(--color-dark)]", children: "Replace (use custom prompt only)" })] })] })] })] })), _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: "Custom Prompt" }), _jsx("textarea", { value: customPrompt, onChange: (e) => setCustomPrompt(e.target.value), className: "w-full px-3 py-2.5 border border-[var(--color-gray-3)] rounded-md bg-[var(--color-gray-5)] text-[var(--color-dark)] focus:outline-none focus:ring-2 focus:ring-[#9650fb] focus:border-[#9650fb] text-sm font-mono transition-colors", rows: 6, placeholder: "Enter your custom prompt instructions here...", "data-testid": "custom-prompt-textarea" }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mt-2", children: hasDefaultPrompt
98
98
  ? customizationType === "extend"
99
99
  ? "This will be appended to the default prompt. The final prompt (default + custom) will then be appended to the system instructions on the backend."
100
100
  : "This will replace the default prompt. The custom prompt will then be appended to the system instructions on the backend."
101
- : "Your custom prompt will be appended to the system instructions on the backend." })] }), hasDefaultPrompt && _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-gray-900 mb-2", children: "Preview" }), _jsx("div", { className: "border border-gray-200 rounded-md p-3 bg-gray-50 max-h-64 overflow-y-auto", children: _jsx("pre", { className: "text-xs text-gray-700 whitespace-pre-wrap font-mono", children: previewPrompt }) }), _jsx("p", { className: "text-xs text-gray-500 mt-1", children: "This is how the final prompt will look when sent to the translation service." })] })] }))] })] }));
101
+ : "Your custom prompt will be appended to the system instructions on the backend." })] }), hasDefaultPrompt && _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: "Preview" }), _jsx("div", { className: "border border-[var(--color-gray-3)] rounded-md p-3 bg-[var(--color-gray-5)] max-h-64 overflow-y-auto", children: _jsx("pre", { className: "text-xs text-[var(--color-gray-1)] whitespace-pre-wrap font-mono", children: previewPrompt }) }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mt-2", children: "This is how the final prompt will look when sent to the translation service." })] })] }))] })] }));
102
102
  }
@@ -186,7 +186,7 @@ export function ServiceLanguageSelectionStep({ stepIndex, isActive = true, data,
186
186
  const serviceData = data.serviceCustomData?.get("OpenAI");
187
187
  return serviceData?.enableCustomPrompt === true;
188
188
  }, [data.translationProvider, data.serviceCustomData]);
189
- return (_jsxs("div", { className: "p-6 space-y-6 h-full flex flex-col", "data-testid": "service-language-selection-step", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-xl font-semibold mb-2", children: "Configure Translation" }), _jsx("p", { className: "text-sm text-gray-600 mb-6", children: "Select translation provider and target languages for your content." })] }), _jsxs("div", { className: "space-y-6 flex-1", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-gray-900 mb-2", children: "Translation Provider" }), _jsx("p", { className: "text-xs text-gray-600 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-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm", "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", { children: [_jsxs("label", { className: "flex items-center", children: [_jsx("input", { type: "checkbox", checked: data.includeSubitems, onChange: handleSubitemsToggle, className: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded", "data-testid": "include-subitems-checkbox" }), _jsx("span", { className: "ml-2 text-sm text-gray-900", children: "Include subitems" })] }), _jsx("p", { className: "text-xs text-gray-500 mt-1 ml-6", children: "Also translate any child components and nested content within this item." })] })), data.translationProvider === "OpenAI" && (_jsxs("div", { children: [_jsxs("label", { className: "flex items-center", children: [_jsx("input", { type: "checkbox", checked: isPromptCustomizationEnabled, onChange: (e) => {
189
+ return (_jsxs("div", { className: "p-6 space-y-6 h-full flex flex-col", "data-testid": "service-language-selection-step", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-xl font-semibold text-[var(--color-dark)] mb-2", children: "Configure Translation" }), _jsx("p", { className: "text-sm text-[var(--color-gray-2)] mb-6", children: "Select translation provider and target languages for your content." })] }), _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) => {
190
190
  const isChecked = e.target.checked;
191
191
  // Always create a new Map instance to ensure React detects the change
192
192
  const newServiceCustomData = new Map();
@@ -211,11 +211,11 @@ export function ServiceLanguageSelectionStep({ stepIndex, isActive = true, data,
211
211
  serviceCustomData: newServiceCustomData
212
212
  };
213
213
  setData(newData);
214
- }, className: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded", "data-testid": "enable-custom-prompt-checkbox" }), _jsx("span", { className: "ml-2 text-sm text-gray-900", children: "Customize translation prompt" })] }), _jsx("p", { className: "text-xs text-gray-500 mt-1 ml-6", children: "Enable advanced prompt customization for the translation service." })] })), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("h3", { className: "text-sm font-medium text-gray-900", children: "Target Languages" }), allLanguages.length > 1 && (_jsxs("label", { className: "flex items-center cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: areAllLanguagesSelected, ref: (input) => {
214
+ }, 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) => {
215
215
  if (input) {
216
216
  input.indeterminate = areSomeLanguagesSelected && !areAllLanguagesSelected;
217
217
  }
218
- }, onChange: handleSelectAllLanguages, className: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded", "data-testid": "select-all-languages-checkbox" }), _jsx("span", { className: "ml-2 text-xs text-gray-600", children: "Select All" })] }))] }), _jsx("p", { className: "text-xs text-gray-600 mb-3", children: "Select the languages you want to translate this content into." }), _jsx("div", { className: "border border-gray-200 rounded-md min-h-[200px] max-h-64 overflow-y-auto", children: data.translationProviders.length === 0 || allLanguages.length === 0 ? (
218
+ }, 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 ? (
219
219
  // Loading skeleton
220
- _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-gray-200 rounded" }), _jsx("div", { className: "ml-2 h-4 bg-gray-200 rounded w-32" }), _jsx("div", { className: "ml-auto h-4 bg-gray-200 rounded w-16" })] }, i))) })) : (_jsx("div", { className: "p-3 grid grid-cols-1 gap-2", children: allLanguages.map((lang) => (_jsxs("label", { className: "flex items-center", children: [_jsx("input", { type: "checkbox", checked: languageSelection[lang.code] || false, onChange: () => handleLanguageToggle(lang.code), className: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded", "data-testid": `language-checkbox-${lang.code}` }), _jsxs("span", { className: "ml-2 text-sm text-gray-900 flex items-center gap-2", children: [_jsxs("span", { children: [lang.name, " (", lang.code, ")"] }), lang.sourceLanguage && (_jsxs("span", { className: "text-xs text-gray-500", children: ["from: ", lang.sourceLanguage] }))] }), !lang.hasVersions && (_jsx("span", { className: "ml-auto text-xs text-orange-600 bg-orange-100 px-2 py-1 rounded", children: "No versions" }))] }, lang.code))) })) })] })] })] }));
220
+ _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) => (_jsxs("label", { className: "flex items-center 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: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": `language-checkbox-${lang.code}` }), _jsxs("span", { className: "ml-2 text-sm text-[var(--color-dark)] flex items-center gap-2", children: [_jsxs("span", { children: [lang.name, " (", lang.code, ")"] }), lang.sourceLanguage && (_jsxs("span", { className: "text-xs text-[var(--color-gray-2)]", children: ["from: ", lang.sourceLanguage] }))] }), !lang.hasVersions && (_jsx("span", { className: "ml-auto text-2xs text-orange-600 bg-orange-100 px-2 py-1 rounded-full font-medium", children: "No versions" }))] }, lang.code))) })) })] })] })] }));
221
221
  }
@@ -4,7 +4,7 @@ import { Button, PerfectTree } from "@parhelia/core";
4
4
  import { convertFullItemToStub, convertStubToFullItem } from "@parhelia/core";
5
5
  import { discoverItemsTree, convertBackendTreeToTreeNodes, flattenPagesFromBackendTrees } from "../api/discovery";
6
6
  // We need to implement a basic Spinner component since it's not in core
7
- const Spinner = ({ ...props }) => (_jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600", ...props }));
7
+ const Spinner = ({ ...props }) => (_jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-[#9650fb]", ...props }));
8
8
  export function SubitemDiscoveryStep({ stepIndex, isActive = true, data, setData, editContext, onStepCompleted, setBeforeNextCallback, setFooterActions, requestClose }) {
9
9
  // Core state - simplified
10
10
  const [isDiscovering, setIsDiscovering] = useState(false);
@@ -264,9 +264,9 @@ export function SubitemDiscoveryStep({ stepIndex, isActive = true, data, setData
264
264
  setIsDiscovering(false);
265
265
  setDiscoveryComplete(true);
266
266
  };
267
- return (_jsxs("div", { className: "flex flex-col gap-4 p-6 h-full", "data-testid": "subitem-discovery-step", children: [_jsxs("div", { className: "mb-2", children: [_jsx("h3", { className: "text-lg font-medium mb-1", children: "Discover Subitems" }), _jsx("p", { className: "text-sm text-gray-600", children: "Scanning for subitems to include in translation..." })] }), _jsxs("div", { className: "border rounded p-4 bg-gray-50 min-h-[120px]", "data-testid": "discovery-status-container", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [isDiscovering && _jsx(Spinner, { "data-testid": "discovery-spinner" }), _jsx("span", { className: "font-medium", "data-testid": "discovery-status-text", children: isDiscovering ? 'Discovering subitems...' :
267
+ return (_jsxs("div", { className: "flex flex-col gap-4 p-6 h-full", "data-testid": "subitem-discovery-step", children: [_jsxs("div", { className: "mb-2", children: [_jsx("h3", { className: "text-lg font-semibold text-[var(--color-dark)] mb-1", children: "Discover Subitems" }), _jsx("p", { className: "text-sm text-[var(--color-gray-2)]", children: "Scanning for subitems to include in translation..." })] }), _jsxs("div", { className: "border border-[var(--color-gray-3)] rounded-lg p-4 bg-background min-h-[120px] shadow-sm", "data-testid": "discovery-status-container", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [isDiscovering && _jsx(Spinner, { "data-testid": "discovery-spinner" }), _jsx("span", { className: "font-medium text-[var(--color-dark)]", "data-testid": "discovery-status-text", children: isDiscovering ? 'Discovering subitems...' :
268
268
  discoveryComplete ? 'Discovery Complete' :
269
- 'Ready to discover' })] }), isDiscovering && (_jsx(Button, { size: "sm", onClick: handleCancel, "data-testid": "discovery-cancel-button", children: "Cancel" }))] }), _jsx("div", { className: "text-sm text-gray-600 mb-3", "data-testid": "discovery-summary", children: discoveredCount > 0 ? (_jsxs("p", { "data-testid": "discovery-total-count", children: [_jsxs("span", { className: "font-medium text-blue-600", children: [totalItemsCount, " total items found"] }), totalItemsCount !== translatableItemsCount && (_jsxs(_Fragment, { children: [_jsx("br", {}), _jsxs("span", { className: "text-xs", children: ["Translatable items: ", translatableItemsCount, " | Non-translatable: ", totalItemsCount - translatableItemsCount] })] })), _jsx("br", {}), _jsxs("span", { className: "text-xs", children: ["Original items: ", data.items.length, " | Subitems discovered: ", Math.max(0, totalItemsCount - data.items.length)] }), isDiscovering && (_jsxs(_Fragment, { children: [_jsx("br", {}), _jsx("span", { className: "text-xs text-gray-500 italic", children: "Item tree will appear when discovery completes" })] }))] })) : (_jsx("p", { children: "No items discovered yet." })) }), _jsx("div", { className: "mt-4 min-h-[400px]", children: !isDiscovering && discoveryComplete && treeInitialized && allDiscoveredItems.length > 0 && treeNodes.length > 0 ? (_jsx("div", { children: _jsxs("div", { className: "border-t pt-4", "data-testid": "item-selection-section", children: [_jsxs("div", { className: "flex items-center justify-between mb-3", children: [_jsx("h3", { className: "text-lg font-medium", children: "Select Items to Translate" }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("span", { className: "text-sm text-gray-600", "data-testid": "selection-summary-header", children: selectedItemIds.size > 0 ? `${selectedItemIds.size} selected` : "No items selected" }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => {
269
+ 'Ready to discover' })] }), isDiscovering && (_jsx(Button, { size: "sm", variant: "outline", onClick: handleCancel, "data-testid": "discovery-cancel-button", children: "Cancel" }))] }), _jsx("div", { className: "text-sm text-[var(--color-gray-2)] mb-3", "data-testid": "discovery-summary", children: discoveredCount > 0 ? (_jsxs("p", { "data-testid": "discovery-total-count", children: [_jsxs("span", { className: "font-medium text-[#9650fb]", children: [totalItemsCount, " total items found"] }), totalItemsCount !== translatableItemsCount && (_jsxs(_Fragment, { children: [_jsx("br", {}), _jsxs("span", { className: "text-xs text-[var(--color-gray-2)]", children: ["Translatable items: ", translatableItemsCount, " | Non-translatable: ", totalItemsCount - translatableItemsCount] })] })), _jsx("br", {}), _jsxs("span", { className: "text-xs text-[var(--color-gray-2)]", children: ["Original items: ", data.items.length, " | Subitems discovered: ", Math.max(0, totalItemsCount - data.items.length)] }), isDiscovering && (_jsxs(_Fragment, { children: [_jsx("br", {}), _jsx("span", { className: "text-xs text-[var(--color-gray-2)] italic", children: "Item tree will appear when discovery completes" })] }))] })) : (_jsx("p", { className: "text-[var(--color-gray-2)]", children: "No items discovered yet." })) }), _jsx("div", { className: "mt-4 min-h-[400px]", children: !isDiscovering && discoveryComplete && treeInitialized && allDiscoveredItems.length > 0 && treeNodes.length > 0 ? (_jsx("div", { children: _jsxs("div", { className: "border-t border-[var(--color-gray-3)] pt-4", "data-testid": "item-selection-section", children: [_jsxs("div", { className: "flex items-center justify-between mb-3", children: [_jsx("h3", { className: "text-lg font-semibold text-[var(--color-dark)]", children: "Select Items to Translate" }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("span", { className: "text-sm text-[var(--color-gray-2)]", "data-testid": "selection-summary-header", children: selectedItemIds.size > 0 ? _jsxs(_Fragment, { children: [_jsx("span", { className: "font-medium text-[#9650fb]", children: selectedItemIds.size }), " selected"] }) : "No items selected" }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => {
270
270
  if (!isActive)
271
271
  return;
272
272
  // Only select translatable items
@@ -284,13 +284,13 @@ export function SubitemDiscoveryStep({ stepIndex, isActive = true, data, setData
284
284
  setUserHasInteracted(true);
285
285
  setSelectedItemIds(translatableIds);
286
286
  onStepCompleted(translatableIds.size > 0);
287
- }, "data-testid": "select-all-items-button", children: "Select All" }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => {
287
+ }, "data-testid": "select-all-items-button", children: "Select All" }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => {
288
288
  if (!isActive)
289
289
  return;
290
290
  setUserHasInteracted(true);
291
291
  setSelectedItemIds(new Set());
292
292
  onStepCompleted(false);
293
- }, "data-testid": "select-none-items-button", children: "Select None" })] })] }), _jsx("div", { className: "text-sm text-gray-600 mb-3", "data-testid": "selection-summary", children: _jsx("span", { className: "text-gray-500", children: "Tip: Hold Shift and click a checkbox to toggle all descendants." }) }), treeNodes.length > 0 && (_jsx("div", { className: "border rounded-lg h-80 overflow-auto", "data-testid": "item-tree-view", children: _jsx(PerfectTree, { nodes: treeNodes, expandedKeys: expandedKeys, selectedKeys: selectedKeys, onToggleExpand: (key) => {
293
+ }, "data-testid": "select-none-items-button", children: "Select None" })] })] }), _jsx("div", { className: "text-xs text-[var(--color-gray-2)] mb-3", "data-testid": "selection-summary", children: _jsx("span", { children: "Tip: Hold Shift and click a checkbox to toggle all descendants." }) }), treeNodes.length > 0 && (_jsx("div", { className: "border border-[var(--color-gray-3)] rounded-lg h-80 overflow-auto bg-[var(--color-gray-5)]", "data-testid": "item-tree-view", children: _jsx(PerfectTree, { nodes: treeNodes, expandedKeys: expandedKeys, selectedKeys: selectedKeys, onToggleExpand: (key) => {
294
294
  setExpandedIds(prev => {
295
295
  const next = new Set(prev);
296
296
  if (next.has(key))
@@ -389,7 +389,7 @@ export function SubitemDiscoveryStep({ stepIndex, isActive = true, data, setData
389
389
  } }), _jsx("span", { className: `${!isTranslatable ? 'opacity-70 italic' : ''}`, children: node.label })] }));
390
390
  } }) }))] }) })) : isDiscovering ? (
391
391
  // Loading skeleton for discovery results
392
- _jsxs("div", { children: [_jsx("div", { className: "p-3 bg-blue-50 border border-blue-200 rounded mb-4", children: _jsx("div", { className: "h-4 bg-blue-200 rounded w-64 animate-pulse" }) }), _jsxs("div", { className: "border-t pt-4", children: [_jsxs("div", { className: "flex items-center justify-between mb-3", children: [_jsx("div", { className: "h-6 bg-gray-200 rounded w-48 animate-pulse" }), _jsxs("div", { className: "flex gap-2", children: [_jsx("div", { className: "h-8 bg-gray-200 rounded w-20 animate-pulse" }), _jsx("div", { className: "h-8 bg-gray-200 rounded w-20 animate-pulse" })] })] }), _jsx("div", { className: "h-4 bg-gray-200 rounded w-64 mb-3 animate-pulse" }), _jsx("div", { className: "border rounded-lg h-80 overflow-auto", children: _jsx("div", { className: "p-3 space-y-2", children: [...Array(8)].map((_, i) => (_jsxs("div", { className: "flex items-center gap-3 animate-pulse", children: [_jsx("div", { className: "h-4 w-4 bg-gray-200 rounded" }), _jsx("div", { className: "h-4 bg-gray-200 rounded w-48" })] }, i))) }) })] })] })) : (
392
+ _jsxs("div", { children: [_jsx("div", { className: "p-3 bg-[#f6eeff] border border-[#9650fb]/20 rounded-lg mb-4", children: _jsx("div", { className: "h-4 bg-[#9650fb]/20 rounded w-64 animate-pulse" }) }), _jsxs("div", { className: "border-t border-[var(--color-gray-3)] pt-4", children: [_jsxs("div", { className: "flex items-center justify-between mb-3", children: [_jsx("div", { className: "h-6 bg-[var(--color-gray-3)] rounded w-48 animate-pulse" }), _jsxs("div", { className: "flex gap-2", children: [_jsx("div", { className: "h-8 bg-[var(--color-gray-3)] rounded w-20 animate-pulse" }), _jsx("div", { className: "h-8 bg-[var(--color-gray-3)] rounded w-20 animate-pulse" })] })] }), _jsx("div", { className: "h-4 bg-[var(--color-gray-3)] rounded w-64 mb-3 animate-pulse" }), _jsx("div", { className: "border border-[var(--color-gray-3)] rounded-lg h-80 overflow-auto bg-[var(--color-gray-5)]", children: _jsx("div", { className: "p-3 space-y-2", children: [...Array(8)].map((_, i) => (_jsxs("div", { className: "flex items-center gap-3 animate-pulse", children: [_jsx("div", { className: "h-4 w-4 bg-[var(--color-gray-3)] rounded" }), _jsx("div", { className: "h-4 bg-[var(--color-gray-3)] rounded w-48" })] }, i))) }) })] })] })) : (
393
393
  // Empty state
394
- _jsx("div", { className: "flex items-center justify-center h-80 border rounded-lg bg-gray-50", children: _jsxs("div", { className: "text-center text-gray-500", children: [_jsx("p", { children: "Ready to discover subitems" }), _jsx("p", { className: "text-sm", children: "Discovery will start automatically" })] }) })) })] })] }));
394
+ _jsx("div", { className: "flex items-center justify-center h-80 border border-[var(--color-gray-3)] rounded-lg bg-[var(--color-gray-5)]", children: _jsxs("div", { className: "text-center text-[var(--color-gray-2)]", children: [_jsx("p", { className: "font-medium text-[var(--color-gray-1)]", children: "Ready to discover subitems" }), _jsx("p", { className: "text-sm mt-1", children: "Discovery will start automatically" })] }) })) })] })] }));
395
395
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BatchTranslationView.d.ts","sourceRoot":"","sources":["../../src/translation-center/BatchTranslationView.tsx"],"names":[],"mappings":"AAwBA,OAAO,qCAAqC,CAAC;AAa7C,UAAU,yBAAyB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAoCD,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,yBAAyB,2CA07BlF"}
1
+ {"version":3,"file":"BatchTranslationView.d.ts","sourceRoot":"","sources":["../../src/translation-center/BatchTranslationView.tsx"],"names":[],"mappings":"AAwBA,OAAO,qCAAqC,CAAC;AAa7C,UAAU,yBAAyB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAoCD,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,yBAAyB,2CAq8BlF"}