@parhelia/localization 0.1.12788 → 0.1.12790

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 (57) hide show
  1. package/dist/LocalizeItemDialog.d.ts.map +1 -1
  2. package/dist/LocalizeItemDialog.js +92 -34
  3. package/dist/LocalizeItemUtils.d.ts +1 -2
  4. package/dist/LocalizeItemUtils.d.ts.map +1 -1
  5. package/dist/LocalizeItemUtils.js +44 -12
  6. package/dist/api/discovery.d.ts +25 -0
  7. package/dist/api/discovery.d.ts.map +1 -1
  8. package/dist/api/discovery.js +87 -0
  9. package/dist/index.d.ts +8 -17
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +32 -32
  12. package/dist/services/translationService.d.ts +40 -9
  13. package/dist/services/translationService.d.ts.map +1 -1
  14. package/dist/services/translationService.js +30 -4
  15. package/dist/settings/TranslationServicesPanel.d.ts.map +1 -1
  16. package/dist/settings/TranslationServicesPanel.js +18 -36
  17. package/dist/sidebar/TranslationSidebar.d.ts.map +1 -1
  18. package/dist/sidebar/TranslationSidebar.js +4 -1
  19. package/dist/steps/ItemSelectionStep.d.ts +3 -0
  20. package/dist/steps/ItemSelectionStep.d.ts.map +1 -0
  21. package/dist/steps/ItemSelectionStep.js +23 -0
  22. package/dist/steps/ItemSelectionTree.d.ts +13 -0
  23. package/dist/steps/ItemSelectionTree.d.ts.map +1 -0
  24. package/dist/steps/ItemSelectionTree.js +326 -0
  25. package/dist/steps/MetadataInputStep.d.ts.map +1 -1
  26. package/dist/steps/MetadataInputStep.js +8 -1
  27. package/dist/steps/PromptCustomizationStep.d.ts +1 -1
  28. package/dist/steps/PromptCustomizationStep.d.ts.map +1 -1
  29. package/dist/steps/PromptCustomizationStep.js +161 -56
  30. package/dist/steps/ServiceLanguageSelectionStep.d.ts +6 -1
  31. package/dist/steps/ServiceLanguageSelectionStep.d.ts.map +1 -1
  32. package/dist/steps/ServiceLanguageSelectionStep.js +53 -163
  33. package/dist/steps/WizardStepShell.d.ts +17 -0
  34. package/dist/steps/WizardStepShell.d.ts.map +1 -0
  35. package/dist/steps/WizardStepShell.js +11 -0
  36. package/dist/steps/index.d.ts +1 -0
  37. package/dist/steps/index.d.ts.map +1 -1
  38. package/dist/steps/index.js +1 -0
  39. package/dist/steps/types.d.ts +17 -1
  40. package/dist/steps/types.d.ts.map +1 -1
  41. package/dist/translation-center/TranslationBatches.d.ts +2 -0
  42. package/dist/translation-center/TranslationBatches.d.ts.map +1 -0
  43. package/dist/translation-center/TranslationBatches.js +995 -0
  44. package/dist/translation-center/TranslationManagement.d.ts.map +1 -1
  45. package/dist/translation-center/TranslationManagement.js +22 -14
  46. package/dist/translation-center/TranslationsTitlebar.d.ts +7 -0
  47. package/dist/translation-center/TranslationsTitlebar.d.ts.map +1 -0
  48. package/dist/translation-center/TranslationsTitlebar.js +16 -0
  49. package/dist/types.d.ts +1 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/package.json +1 -1
  52. package/dist/translation-center/BatchTranslationView.d.ts +0 -8
  53. package/dist/translation-center/BatchTranslationView.d.ts.map +0 -1
  54. package/dist/translation-center/BatchTranslationView.js +0 -870
  55. package/dist/translation-center/RecentTranslations.d.ts +0 -2
  56. package/dist/translation-center/RecentTranslations.d.ts.map +0 -1
  57. package/dist/translation-center/RecentTranslations.js +0 -309
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ItemSelectionStep } from "./steps/ItemSelectionStep";
2
3
  import { ServiceLanguageSelectionStep } from "./steps/ServiceLanguageSelectionStep";
3
- import { SubitemDiscoveryStep } from "./steps/SubitemDiscoveryStep";
4
4
  import { PromptCustomizationStep } from "./steps/PromptCustomizationStep";
5
5
  import { localizeItemCommand } from "./LocalizeItemCommand";
6
6
  import { TranslationSidebar } from "./sidebar/TranslationSidebar";
7
7
  import { TranslationManagement } from "./translation-center/TranslationManagement";
8
- import { RecentTranslations } from "./translation-center/RecentTranslations";
8
+ import { TranslationsTitlebar } from "./translation-center/TranslationsTitlebar";
9
+ import { TranslationBatches } from "./translation-center/TranslationBatches";
9
10
  import { TranslationServicesPanel } from "./settings/TranslationServicesPanel";
10
11
  import { Languages as LucideLanguages, LayoutGrid as LucideLayoutGrid, Globe as LucideGlobe, } from "lucide-react";
11
12
  const LanguagesIcon = LucideLanguages;
@@ -14,40 +15,39 @@ const GlobeIcon = LucideGlobe;
14
15
  const DEFAULT_TRANSLATION_WIZARD_CONFIGURATION = {
15
16
  steps: [
16
17
  {
17
- id: "service-language-selection",
18
- name: "Configure Translation",
19
- description: "Select translation provider and target languages for your content.",
20
- component: ServiceLanguageSelectionStep,
18
+ id: "item-selection",
19
+ name: "Items",
20
+ description: "Select items to translate.",
21
+ component: ItemSelectionStep,
21
22
  },
22
23
  {
23
- id: "subitem-discovery",
24
- name: "Discover Subitems",
25
- description: "Find and include child items that should also be translated.",
26
- component: SubitemDiscoveryStep,
27
- skipCondition: (data) => !data.includeSubitems,
24
+ id: "language-selection",
25
+ name: "Languages",
26
+ description: "Select target languages for your content.",
27
+ component: ServiceLanguageSelectionStep,
28
28
  },
29
29
  {
30
30
  id: "prompt-customization",
31
- name: "Customize Prompt",
32
- description: "Optionally customize the translation prompt.",
31
+ name: "Provider",
32
+ description: "Choose the translation provider and provider settings.",
33
33
  component: PromptCustomizationStep,
34
- skipCondition: (data) => {
35
- // Skip if custom prompt is not enabled (checkbox unchecked)
36
- const serviceData = data.serviceCustomData?.get(data.translationProvider);
37
- return !serviceData || !serviceData.enableCustomPrompt;
38
- },
39
34
  },
40
35
  ],
41
36
  };
42
37
  const SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION = {
43
38
  steps: [
44
39
  {
45
- id: "service-language-selection",
46
- name: "Configure Translation",
47
- description: "Select translation provider and target languages for your content.",
40
+ id: "language-selection",
41
+ name: "Languages",
42
+ description: "Select target languages for your content.",
48
43
  component: ServiceLanguageSelectionStep,
49
44
  },
50
- // No SubitemDiscoveryStep - single item translation only
45
+ {
46
+ id: "prompt-customization",
47
+ name: "Provider",
48
+ description: "Choose the translation provider and provider settings.",
49
+ component: PromptCustomizationStep,
50
+ },
51
51
  ],
52
52
  };
53
53
  /**
@@ -76,19 +76,18 @@ const translationManagementWorkspace = {
76
76
  title: "Translation Management",
77
77
  icon: _jsx(GlobeIcon, { strokeWidth: 1 }),
78
78
  component: _jsx(TranslationManagement, {}),
79
- menuBar: _jsx(_Fragment, {}),
79
+ titlebar: _jsx(TranslationsTitlebar, {}),
80
80
  supportsSidebars: false,
81
81
  sortOrder: 30,
82
82
  };
83
- export { DEFAULT_TRANSLATION_WIZARD_CONFIGURATION, SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION };
83
+ export { DEFAULT_TRANSLATION_WIZARD_CONFIGURATION, SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION, };
84
84
  export { LocalizeItemDialog } from "./LocalizeItemDialog";
85
85
  export { localizeItemCommand } from "./LocalizeItemCommand";
86
86
  export { TranslationManagement } from "./translation-center/TranslationManagement";
87
- export { RecentTranslations } from "./translation-center/RecentTranslations";
88
- export { BatchTranslationView } from "./translation-center/BatchTranslationView";
87
+ export { TranslationBatches } from "./translation-center/TranslationBatches";
89
88
  export { LocalizationSetupStep } from "./setup/LocalizationSetupStep";
90
89
  export { TranslationServicesPanel } from "./settings/TranslationServicesPanel";
91
- export { defaultTranslateAll, generateBatchId, performDefaultTranslation } from "./LocalizeItemUtils";
90
+ export { defaultTranslateAll, performDefaultTranslation, } from "./LocalizeItemUtils";
92
91
  export * from "./steps/types";
93
92
  /**
94
93
  * Configures the localization extension for the editor.
@@ -120,7 +119,8 @@ export function configureLocalization(configuration, options) {
120
119
  configuration.localization = {};
121
120
  }
122
121
  configuration.localization.multiItem = enableMultiItem;
123
- configuration.localization.translationManagement = enableTranslationManagement;
122
+ configuration.localization.translationManagement =
123
+ enableTranslationManagement;
124
124
  if (!configuration.commands.allItemCommands) {
125
125
  configuration.commands.allItemCommands = [];
126
126
  }
@@ -147,9 +147,9 @@ export function configureLocalization(configuration, options) {
147
147
  label: "Translation Status",
148
148
  panels: [
149
149
  {
150
- id: "recent-translations",
151
- label: "Recent Translations",
152
- content: _jsx(RecentTranslations, {}),
150
+ id: "translation-batches",
151
+ label: "Translation Batches",
152
+ content: _jsx(TranslationBatches, {}),
153
153
  },
154
154
  ],
155
155
  },
@@ -53,7 +53,8 @@ export type TranslationStructureResponse = {
53
53
  export declare function getTranslationStructure(settings: TranslationStructureSettings): Promise<import("@parhelia/core").ExecutionResult<TranslationApiResponse<TranslationStructureResponse>>>;
54
54
  export declare function ensureTranslationStructure(settings: TranslationStructureSettings): Promise<import("@parhelia/core").ExecutionResult<TranslationApiResponse<TranslationStructureResponse>>>;
55
55
  export type TranslationJobRecord = {
56
- id?: number;
56
+ id?: string;
57
+ sequenceId?: number;
57
58
  itemId: string;
58
59
  targetLanguage: string;
59
60
  sourceLanguage: string;
@@ -63,10 +64,17 @@ export type TranslationJobRecord = {
63
64
  message?: string;
64
65
  batchId?: string;
65
66
  metadata?: string | null;
67
+ itemName?: string | null;
68
+ itemPath?: string | null;
69
+ workerInstanceId?: string | null;
70
+ claimedAtUtc?: string | null;
71
+ lastHeartbeatUtc?: string | null;
72
+ attemptCount?: number;
73
+ totalCost?: number | null;
66
74
  };
67
75
  export declare function listBatchTranslationJobs(batchId: string): Promise<import("@parhelia/core").ExecutionResult<TranslationJobRecord[]>>;
68
76
  export type TranslationBatchInfo = {
69
- batchId: string;
77
+ id: string;
70
78
  createdAtUtc?: string;
71
79
  startedAtUtc?: string;
72
80
  completedAtUtc?: string;
@@ -79,10 +87,34 @@ export type TranslationBatchInfo = {
79
87
  errorJobs?: number;
80
88
  metadata?: string | null;
81
89
  lastUpdatedUtc?: string;
90
+ totalCost?: number | null;
82
91
  exists?: boolean;
83
92
  };
84
93
  export declare function getBatchInfo(batchId: string): Promise<import("@parhelia/core").ExecutionResult<TranslationBatchInfo>>;
85
- export declare function listBatches(take?: number, skip?: number): Promise<import("@parhelia/core").ExecutionResult<TranslationBatchInfo[]>>;
94
+ export type ListBatchesFilters = {
95
+ fromUtc?: string;
96
+ status?: string;
97
+ user?: string;
98
+ provider?: string;
99
+ targetLanguage?: string;
100
+ itemIdOrPath?: string;
101
+ itemIncludeSubitems?: boolean;
102
+ };
103
+ export declare function listBatches(take?: number, skip?: number, filters?: ListBatchesFilters): Promise<import("@parhelia/core").ExecutionResult<TranslationBatchInfo[]>>;
104
+ export type DeleteBatchResponse = {
105
+ success: boolean;
106
+ id: string;
107
+ deletedJobs: number;
108
+ };
109
+ export declare function deleteBatch(id: string): Promise<import("@parhelia/core").ExecutionResult<DeleteBatchResponse>>;
110
+ export type AbortTranslationResponse = {
111
+ success: boolean;
112
+ batchId: string;
113
+ id?: string;
114
+ abortedJobs: number;
115
+ };
116
+ export declare function abortJob(id: string): Promise<import("@parhelia/core").ExecutionResult<AbortTranslationResponse>>;
117
+ export declare function abortBatch(id: string): Promise<import("@parhelia/core").ExecutionResult<AbortTranslationResponse>>;
86
118
  export declare function subscribeToBatch(batchId: string, sessionId: string): Promise<import("@parhelia/core").ExecutionResult<{
87
119
  success: boolean;
88
120
  message: string;
@@ -106,27 +138,26 @@ export type BatchTranslationError = {
106
138
  error: string;
107
139
  };
108
140
  export type BatchTranslationResponse = {
109
- batchId: string;
141
+ id: string;
110
142
  started: BatchTranslationResult[];
111
143
  skipped: BatchTranslationError[];
112
144
  };
113
- export declare function requestBatchTranslation({ sessionId, batchId, provider, batchMetadata, languageMappings, itemIds }: {
145
+ export declare function requestBatchTranslation({ sessionId, provider, batchMetadata, languageMappings, itemIds }: {
114
146
  sessionId: string;
115
- batchId: string;
116
147
  provider: string;
117
148
  batchMetadata?: string;
118
149
  languageMappings: LanguageMapping[];
119
150
  itemIds: string[];
120
151
  }): Promise<import("@parhelia/core").ExecutionResult<BatchTranslationResponse>>;
121
152
  export type RetryBatchTranslationJobRequest = {
122
- sourceTranslationId?: number;
153
+ sourceTranslationId?: string;
123
154
  itemId: string;
124
155
  sourceLanguage: string;
125
156
  targetLanguage: string;
126
157
  metadata?: string | null;
127
158
  };
128
159
  export type RetryBatchTranslationStartedJob = {
129
- sourceTranslationId?: number;
160
+ sourceTranslationId?: string;
130
161
  itemId: string;
131
162
  sourceLanguage: string;
132
163
  targetLanguage: string;
@@ -134,7 +165,7 @@ export type RetryBatchTranslationStartedJob = {
134
165
  jobId: string;
135
166
  };
136
167
  export type RetryBatchTranslationSkippedJob = {
137
- sourceTranslationId?: number;
168
+ sourceTranslationId?: string;
138
169
  itemId: string;
139
170
  sourceLanguage: string;
140
171
  targetLanguage: string;
@@ -1 +1 @@
1
- {"version":3,"file":"translationService.d.ts","sourceRoot":"","sources":["../../src/services/translationService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"translationService.d.ts","sourceRoot":"","sources":["../../src/services/translationService.ts"],"names":[],"mappings":"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"}
@@ -44,8 +44,34 @@ export async function listBatchTranslationJobs(batchId) {
44
44
  export async function getBatchInfo(batchId) {
45
45
  return await get(`/parhelia/translation/batchInfo?batchId=${encodeURIComponent(batchId)}`);
46
46
  }
47
- export async function listBatches(take = 100, skip = 0) {
48
- return await get(`/parhelia/translation/batches?take=${take}&skip=${skip}`);
47
+ export async function listBatches(take = 100, skip = 0, filters = {}) {
48
+ const params = new URLSearchParams();
49
+ params.set("take", String(take));
50
+ params.set("skip", String(skip));
51
+ if (filters.fromUtc)
52
+ params.set("fromUtc", filters.fromUtc);
53
+ if (filters.status)
54
+ params.set("status", filters.status);
55
+ if (filters.user)
56
+ params.set("user", filters.user);
57
+ if (filters.provider)
58
+ params.set("provider", filters.provider);
59
+ if (filters.targetLanguage)
60
+ params.set("targetLanguage", filters.targetLanguage);
61
+ if (filters.itemIdOrPath)
62
+ params.set("itemIdOrPath", filters.itemIdOrPath);
63
+ if (filters.itemIncludeSubitems)
64
+ params.set("itemIncludeSubitems", "true");
65
+ return await get(`/parhelia/translation/batches?${params.toString()}`);
66
+ }
67
+ export async function deleteBatch(id) {
68
+ return await post("/parhelia/translation/deleteBatch", { id });
69
+ }
70
+ export async function abortJob(id) {
71
+ return await post("/parhelia/translation/abortJob", { id });
72
+ }
73
+ export async function abortBatch(id) {
74
+ return await post("/parhelia/translation/abortBatch", { id });
49
75
  }
50
76
  export async function subscribeToBatch(batchId, sessionId) {
51
77
  return await post("/parhelia/translation/subscribeToBatch", { batchId, sessionId });
@@ -53,8 +79,8 @@ export async function subscribeToBatch(batchId, sessionId) {
53
79
  export async function unsubscribeFromBatch(batchId, sessionId) {
54
80
  return await post("/parhelia/translation/unsubscribeFromBatch", { batchId, sessionId });
55
81
  }
56
- export async function requestBatchTranslation({ sessionId, batchId, provider, batchMetadata, languageMappings, itemIds }) {
57
- return await post("/parhelia/translation/requestBatchTranslation", { sessionId, batchId, provider, batchMetadata: batchMetadata || "", languageMappings, itemIds });
82
+ export async function requestBatchTranslation({ sessionId, provider, batchMetadata, languageMappings, itemIds }) {
83
+ return await post("/parhelia/translation/requestBatchTranslation", { sessionId, provider, batchMetadata: batchMetadata || "", languageMappings, itemIds });
58
84
  }
59
85
  export async function retryBatchTranslation({ sessionId, sourceBatchId, provider, jobs, }) {
60
86
  return await post("/parhelia/translation/retryBatchTranslation", { sessionId, sourceBatchId, provider, jobs });
@@ -1 +1 @@
1
- {"version":3,"file":"TranslationServicesPanel.d.ts","sourceRoot":"","sources":["../../src/settings/TranslationServicesPanel.tsx"],"names":[],"mappings":"AAgEA;;;GAGG;AACH,wBAAgB,wBAAwB,4CAotBvC;AAED,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"TranslationServicesPanel.d.ts","sourceRoot":"","sources":["../../src/settings/TranslationServicesPanel.tsx"],"names":[],"mappings":"AA+DA;;;GAGG;AACH,wBAAgB,wBAAwB,4CA2rBvC;AAED,eAAe,wBAAwB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useState, useEffect, } from "react";
3
3
  import { Button, useEditContext, Splitter, ItemConfigPanel, } from "@parhelia/core";
4
4
  import { CheckCircle as LucideCheckCircle, AlertCircle as LucideAlertCircle, RefreshCw as LucideRefreshCw, Plus as LucidePlus, Settings as LucideSettings, Trash2 as LucideTrash2, } from "lucide-react";
@@ -236,46 +236,28 @@ export function TranslationServicesPanel() {
236
236
  useEffect(() => {
237
237
  loadData();
238
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
- };
246
239
  const configuredCount = services.filter((s) => s.isConfigured).length;
247
240
  const totalCount = services.length;
248
241
  const translationFolderExists = !!structureState?.translationFolder?.exists;
249
242
  const providersFolderExists = !!structureState?.translationProvidersFolder?.exists;
250
243
  // Build the services list content
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) => {
270
- const isSelected = selectedConfigTarget?.key ===
271
- `service:${service.serviceName}`;
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 }))] }) }) }) }));
244
+ const servicesListContent = (_jsx("div", { className: "flex h-full flex-col p-4", "data-testid": "translation-services-panel", children: _jsxs("div", { className: "mx-auto flex w-full flex-1 flex-col gap-10 overflow-hidden", children: [_jsxs("div", { className: "shrink-0", "data-testid": "translation-services-prerequisites", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3 border-b border-gray-100 px-4 py-3", children: [_jsx("h2", { className: "shrink-0 text-sm font-semibold text-gray-900", children: "Prerequisites" }), _jsx("div", { className: "flex items-center gap-1.5 text-xs text-gray-500", children: translationFolderExists && providersFolderExists ? (_jsxs(_Fragment, { children: [_jsx(CheckCircleIcon, { className: "h-3.5 w-3.5 text-green-600", strokeWidth: 1.5 }), "All parent items found"] })) : (_jsxs(_Fragment, { children: [_jsx(AlertCircleIcon, { className: "h-3.5 w-3.5 text-amber-500", strokeWidth: 1.5 }), "Parent items missing"] })) }), _jsxs("div", { className: "ml-auto flex items-center gap-1", children: [_jsx(Button, { size: "sm", variant: "outline", onClick: loadStructure, disabled: structureLoading || ensuringStructure, title: "Refresh", children: _jsx(RefreshCwIcon, { strokeWidth: 1, className: `h-4 w-4 ${structureLoading ? "animate-spin" : ""}` }) }), !providersFolderExists && (_jsxs(Button, { size: "sm", variant: "default", onClick: ensureStructure, disabled: ensuringStructure || structureLoading, children: [ensuringStructure ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "mr-1 h-4 w-4 animate-spin" })) : (_jsx(PlusIcon, { strokeWidth: 1.75, className: "mr-1 h-4 w-4" })), "Ensure items"] }))] })] }), _jsxs("div", { className: "divide-y divide-gray-100", children: [_jsxs("div", { "data-testid": "translation-structure-folder", className: `flex items-center gap-3 px-3 py-3 text-sm transition-colors ${selectedConfigTarget?.key ===
245
+ `structure:${structureState?.translationFolder?.itemId}`
246
+ ? "bg-blue-50"
247
+ : "bg-white"}`, children: [translationFolderExists ? (_jsx(CheckCircleIcon, { className: "h-4 w-4 shrink-0 text-green-600", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-4 w-4 shrink-0 text-amber-500", strokeWidth: 1.5 })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-gray-900", children: "Translation folder" }), _jsx("div", { className: "mt-0.5 truncate font-mono text-xs text-gray-500", children: structureSettings.translationFolderPath })] }), translationFolderExists &&
248
+ structureState?.translationFolder?.itemId && (_jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleOpenStructureConfig(structureState.translationFolder.itemId, "Configure: Translation folder"), title: "Configure", children: _jsx(SettingsIcon, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }))] }), _jsxs("div", { "data-testid": "translation-structure-providers-folder", className: `flex items-center gap-3 px-3 py-3 text-sm transition-colors ${selectedConfigTarget?.key ===
249
+ `structure:${structureState?.translationProvidersFolder?.itemId}`
250
+ ? "bg-blue-50"
251
+ : "bg-white"}`, children: [providersFolderExists ? (_jsx(CheckCircleIcon, { className: "h-4 w-4 shrink-0 text-green-600", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-4 w-4 shrink-0 text-amber-500", strokeWidth: 1.5 })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-gray-900", children: "Translation providers folder" }), _jsx("div", { className: "mt-0.5 truncate font-mono text-xs text-gray-500", children: structureSettings.translationProvidersPath })] }), providersFolderExists &&
252
+ structureState?.translationProvidersFolder?.itemId && (_jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleOpenStructureConfig(structureState.translationProvidersFolder.itemId, "Configure: Translation Providers folder"), title: "Configure", children: _jsx(SettingsIcon, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }))] })] })] }), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden rounded-lg bg-white shadow-sm", children: [_jsxs("div", { className: "shrink-0 border-b border-gray-100 px-4 py-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsxs("h2", { className: "shrink-0 text-sm font-semibold text-gray-900", children: ["Translation providers", " ", _jsxs("span", { className: "font-normal text-gray-500", children: ["(", configuredCount, " of ", totalCount, " configured)"] })] }), _jsx("div", { className: "ml-auto flex items-center gap-1", children: _jsx(Button, { size: "sm", variant: "outline", onClick: loadData, disabled: state === "loading", title: "Refresh", children: _jsx(RefreshCwIcon, { strokeWidth: 1, className: `h-4 w-4 ${state === "loading" ? "animate-spin" : ""}` }) }) })] }), totalCount === 0 && state === "success" && (_jsx("div", { className: "mt-2 rounded border border-yellow-200 bg-yellow-50 p-2 text-xs text-yellow-800", children: "No translation services are registered in dependency injection. Please check the server configuration." })), error && (_jsx("div", { className: "mt-2 rounded border border-red-200 bg-red-50 p-2 text-xs whitespace-pre-wrap text-red-700", children: error }))] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", "data-testid": "translation-services-providers", children: services.length > 0 && (_jsx("div", { className: "divide-y divide-gray-100", children: services.map((service) => {
253
+ const isSelected = selectedConfigTarget?.key ===
254
+ `service:${service.serviceName}`;
255
+ const isConfigured = service.isConfigured;
256
+ return (_jsxs("div", { className: `group flex items-center gap-3 px-3 py-3 text-sm transition-colors ${isSelected ? "bg-blue-50" : "bg-white hover:bg-gray-50"}`, children: [isConfigured ? (_jsx(CheckCircleIcon, { className: "h-4 w-4 shrink-0 text-green-600", strokeWidth: 1.5 })) : (_jsx(AlertCircleIcon, { className: "h-4 w-4 shrink-0 text-amber-500", strokeWidth: 1.5 })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [_jsx("span", { className: "truncate font-medium text-gray-900", children: service.displayName || service.serviceName }), service.displayName &&
257
+ service.displayName !== service.serviceName && (_jsx("span", { className: "shrink-0 rounded bg-gray-100 px-1.5 py-0.5 text-[10px] font-medium tracking-wide text-gray-600 uppercase", children: service.serviceName })), !isConfigured && (_jsx("span", { className: "shrink-0 rounded bg-amber-100 px-1.5 py-0.5 text-[10px] font-medium text-amber-700", children: "Not configured" }))] }), isConfigured &&
258
+ service.supportedLanguages &&
259
+ service.supportedLanguages.length > 0 && (_jsxs("div", { className: "mt-0.5 truncate text-xs text-gray-500", children: ["Languages:", " ", service.supportedLanguages.join(", ")] }))] }), _jsx("div", { className: "flex shrink-0 items-center gap-0.5", children: isConfigured && service.settingsItemId ? (_jsxs("div", { className: "flex items-center gap-0.5 opacity-60 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleOpenConfig(service), disabled: service.deleting, title: "Configure", children: _jsx(SettingsIcon, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => deleteSettings(service), className: "text-red-600 hover:bg-red-50 hover:text-red-700", disabled: service.deleting, title: `Delete settings for ${service.displayName || service.serviceName}`, children: service.deleting ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(Trash2Icon, { className: "h-3.5 w-3.5", strokeWidth: 1.5 })) })] })) : (_jsxs(Button, { size: "sm", variant: "default", onClick: () => createSettings(service.serviceName, service.templateId), disabled: service.creating, title: `Create settings using template: ${service.templateName}`, children: [service.creating ? (_jsx(RefreshCwIcon, { strokeWidth: 1, className: "mr-1 h-3.5 w-3.5 animate-spin" })) : (_jsx(PlusIcon, { strokeWidth: 1.75, className: "mr-1 h-3.5 w-3.5" })), "Create"] })) })] }, service.serviceName));
260
+ }) })) })] })] }) }));
279
261
  // Build splitter panels - only show config panel when a service is selected
280
262
  const panels = selectedConfigTarget?.itemId
281
263
  ? [
@@ -1 +1 @@
1
- {"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"AAcA,wBAAgB,kBAAkB,mDA4MjC"}
1
+ {"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,kBAAkB,mDA4MjC"}
@@ -3,6 +3,9 @@ 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
+ }
6
9
  export function TranslationSidebar() {
7
10
  const editContext = useEditContext();
8
11
  if (!editContext)
@@ -101,7 +104,7 @@ export function TranslationSidebar() {
101
104
  },
102
105
  {
103
106
  header: "Status",
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"
107
+ body: (x) => (_jsxs("div", { className: "flex items-center gap-2", "data-testid": `translation-status-${x.languageCode}`, children: [isActiveTranslationStatus(x.translationStatus?.status) && (_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 })] })), !isActiveTranslationStatus(x.translationStatus?.status) && (_jsx("span", { title: x.translationStatus?.message, className: x.translationStatus?.status === "Completed"
105
108
  ? "text-green-600 font-medium"
106
109
  : x.translationStatus?.status === "Error"
107
110
  ? "text-red-600 font-medium"
@@ -0,0 +1,3 @@
1
+ import { TranslationStepProps } from "./types";
2
+ export declare function ItemSelectionStep({ isActive, data, setData, onStepCompleted, editContext, }: TranslationStepProps): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=ItemSelectionStep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemSelectionStep.d.ts","sourceRoot":"","sources":["../../src/steps/ItemSelectionStep.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAI/C,wBAAgB,iBAAiB,CAAC,EAChC,QAAe,EACf,IAAI,EACJ,OAAO,EACP,eAAe,EACf,WAAW,GACZ,EAAE,oBAAoB,2CAmCtB"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { ItemSelectionTree } from "./ItemSelectionTree";
4
+ import { WizardStepShell } from "./WizardStepShell";
5
+ export function ItemSelectionStep({ isActive = true, data, setData, onStepCompleted, editContext, }) {
6
+ const multiItemEnabled = editContext?.configuration?.localization?.multiItem !== false;
7
+ const [itemSelectionValid, setItemSelectionValid] = useState(!multiItemEnabled || (data.selectionTreeItems?.length ?? data.items.length) > 0);
8
+ const onStepCompletedRef = useRef(onStepCompleted);
9
+ useEffect(() => {
10
+ onStepCompletedRef.current = onStepCompleted;
11
+ }, [onStepCompleted]);
12
+ const lastCompletionRef = useRef(null);
13
+ useEffect(() => {
14
+ if (!isActive)
15
+ return;
16
+ const completed = !multiItemEnabled || itemSelectionValid;
17
+ if (lastCompletionRef.current !== completed) {
18
+ lastCompletionRef.current = completed;
19
+ onStepCompletedRef.current(completed);
20
+ }
21
+ }, [isActive, itemSelectionValid, multiItemEnabled]);
22
+ return (_jsx(WizardStepShell, { fillHeight: true, testId: "item-selection-step", children: _jsx(ItemSelectionTree, { data: data, setData: setData, editContext: editContext, isActive: isActive, onSelectionValidChange: setItemSelectionValid, height: "100%" }) }));
23
+ }
@@ -0,0 +1,13 @@
1
+ import { type EditContextType } from "@parhelia/core";
2
+ import type { TranslationWizardData } from "./types";
3
+ type ItemSelectionTreeProps = {
4
+ data: TranslationWizardData;
5
+ setData: (data: TranslationWizardData) => void;
6
+ editContext: EditContextType;
7
+ isActive?: boolean;
8
+ onSelectionValidChange?: (valid: boolean) => void;
9
+ height?: number | string;
10
+ };
11
+ export declare function ItemSelectionTree({ data, setData, editContext, isActive, onSelectionValidChange, height, }: ItemSelectionTreeProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=ItemSelectionTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemSelectionTree.d.ts","sourceRoot":"","sources":["../../src/steps/ItemSelectionTree.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EAMrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAGrD,KAAK,sBAAsB,GAAG;IAC5B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC/C,WAAW,EAAE,eAAe,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B,CAAC;AAkEF,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,OAAO,EACP,WAAW,EACX,QAAe,EACf,sBAAsB,EACtB,MAAY,GACb,EAAE,sBAAsB,2CAqVxB"}