@parhelia/localization 0.1.12789 → 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 (54) 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 +29 -30
  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 +6 -23
  46. package/dist/types.d.ts +1 -0
  47. package/dist/types.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/dist/translation-center/BatchTranslationView.d.ts +0 -8
  50. package/dist/translation-center/BatchTranslationView.d.ts.map +0 -1
  51. package/dist/translation-center/BatchTranslationView.js +0 -890
  52. package/dist/translation-center/RecentTranslations.d.ts +0 -2
  53. package/dist/translation-center/RecentTranslations.d.ts.map +0 -1
  54. package/dist/translation-center/RecentTranslations.js +0 -309
@@ -1 +1 @@
1
- {"version":3,"file":"LocalizeItemDialog.d.ts","sourceRoot":"","sources":["../src/LocalizeItemDialog.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EAExB,MAAM,eAAe,CAAC;AAuBvB,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAAG,WAAW,CAAC,uBAAuB,CAAC,2CAybtE"}
1
+ {"version":3,"file":"LocalizeItemDialog.d.ts","sourceRoot":"","sources":["../src/LocalizeItemDialog.tsx"],"names":[],"mappings":"AA8BA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EAExB,MAAM,eAAe,CAAC;AAkCvB,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAAG,WAAW,CAAC,uBAAuB,CAAC,2CAogBtE"}
@@ -1,10 +1,12 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Dialog, DialogContent, DialogHeader, DialogTitle, Button, cn, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@parhelia/core";
3
- import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
4
- import { AlertTriangle as LucideAlertTriangle } from "lucide-react";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Dialog, DialogContent, StyledDialogTitle, Button, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@parhelia/core";
3
+ import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
4
+ import { AlertTriangle as LucideAlertTriangle, ArrowRight as LucideArrowRight, Globe as LucideGlobe, } from "lucide-react";
5
5
  import { useTranslationWizard } from "./hooks/useTranslationWizard";
6
- import { performDefaultTranslation, generateBatchId } from "./LocalizeItemUtils";
6
+ import { performDefaultTranslation, } from "./LocalizeItemUtils";
7
7
  const AlertTriangleIcon = LucideAlertTriangle;
8
+ const GlobeIcon = LucideGlobe;
9
+ const ArrowRightIcon = LucideArrowRight;
8
10
  // Threshold for warning about large batch translations
9
11
  const LARGE_BATCH_WARNING_THRESHOLD = 100;
10
12
  // Note: DialogButtons is an internal component that might need to be added to core exports
@@ -33,7 +35,12 @@ export function LocalizeItemDialog(props) {
33
35
  // Provide stable callbacks to steps to avoid update loops
34
36
  const lastActionsSigRef = useRef("");
35
37
  const provideFooterActions = useCallback((actions) => {
36
- const normalized = (actions || []).map(a => ({ key: a.key, label: a.label, disabled: !!a.disabled, signature: a.signature || "" }));
38
+ const normalized = (actions || []).map((a) => ({
39
+ key: a.key,
40
+ label: a.label,
41
+ disabled: !!a.disabled,
42
+ signature: a.signature || "",
43
+ }));
37
44
  const signature = JSON.stringify(normalized);
38
45
  if (signature === lastActionsSigRef.current)
39
46
  return;
@@ -45,7 +52,6 @@ export function LocalizeItemDialog(props) {
45
52
  }, [props.onClose]);
46
53
  // Memoize activeSteps to prevent unnecessary recalculations and new object references
47
54
  // This prevents infinite loops when wizardData changes but skip conditions don't
48
- // The skip condition for subitem-discovery step checks includeSubitems
49
55
  // The skip condition for prompt-customization step checks serviceCustomData and translationProvider
50
56
  const activeSteps = useMemo(() => {
51
57
  const steps = configuration.steps.filter((step) => !step.skipCondition || !step.skipCondition(wizardData));
@@ -54,13 +60,13 @@ export function LocalizeItemDialog(props) {
54
60
  configuration.steps,
55
61
  wizardData.includeSubitems,
56
62
  wizardData.serviceCustomData,
57
- wizardData.translationProvider
63
+ wizardData.translationProvider,
58
64
  ]); // Depend on what affects skip conditions
59
65
  const currentStep = activeSteps[currentStepIndex];
60
66
  // Refs for stable callbacks - updated during render to avoid dependency issues
61
67
  const currentStepIdRef = useRef(currentStep?.id);
62
68
  const currentStepIndexRef = useRef(currentStepIndex);
63
- const lastSetWizardDataRef = useRef('');
69
+ const lastSetWizardDataRef = useRef("");
64
70
  // Track step changes for logging
65
71
  if (currentStepIdRef.current !== currentStep?.id) {
66
72
  currentStepIdRef.current = currentStep?.id;
@@ -84,7 +90,7 @@ export function LocalizeItemDialog(props) {
84
90
  const isLastStep = currentStepIndex === activeSteps.length - 1;
85
91
  const canProceed = stepCompleted >= currentStepIndex;
86
92
  const handleNext = async () => {
87
- if (beforeNextCallback && typeof beforeNextCallback === 'function') {
93
+ if (beforeNextCallback && typeof beforeNextCallback === "function") {
88
94
  const canProceed = await beforeNextCallback();
89
95
  if (!canProceed)
90
96
  return;
@@ -106,13 +112,40 @@ export function LocalizeItemDialog(props) {
106
112
  switchStep(currentStepIndex - 1);
107
113
  }
108
114
  };
109
- // Calculate translation counts for large batch warning
115
+ // Calculate translation counts for the Start Translation button and
116
+ // the large-batch warning. Sums each selected item plus its streamed
117
+ // subitem count (when includeSubitems is on). `isStreaming` is true
118
+ // while any selected-and-flagged item is still being counted, so the
119
+ // UI can append a "+" to indicate the total is not yet final.
110
120
  const calculateTranslationCounts = useCallback((data) => {
111
- const itemsToTranslate = data.includeSubitems ? data.discoveredItems : data.items;
112
- const itemCount = itemsToTranslate.length;
113
121
  const languageCount = data.targetLanguages.length;
122
+ const subitemCounts = data.subitemCounts ?? {};
123
+ let itemCount = 0;
124
+ let isStreaming = false;
125
+ if (data.selectionTreeItems && data.selectionTreeItems.length > 0) {
126
+ for (const entry of data.selectionTreeItems) {
127
+ itemCount += 1;
128
+ if (!entry.includeSubitems)
129
+ continue;
130
+ const c = subitemCounts[entry.descriptor.id];
131
+ if (c === undefined || c === "loading") {
132
+ isStreaming = true;
133
+ }
134
+ else if (c !== "error") {
135
+ itemCount += c.count;
136
+ if (!c.complete)
137
+ isStreaming = true;
138
+ }
139
+ }
140
+ }
141
+ else {
142
+ const baseItems = data.discoveredItems && data.discoveredItems.length > 0
143
+ ? data.discoveredItems
144
+ : data.items;
145
+ itemCount = baseItems.length;
146
+ }
114
147
  const totalTranslations = itemCount * languageCount;
115
- return { itemCount, languageCount, totalTranslations };
148
+ return { itemCount, languageCount, totalTranslations, isStreaming };
116
149
  }, []);
117
150
  const executeTranslation = useCallback(async () => {
118
151
  setIsSubmitting(true);
@@ -124,33 +157,33 @@ export function LocalizeItemDialog(props) {
124
157
  targetLanguages: currentWizardData.targetLanguages,
125
158
  includeSubitems: currentWizardData.includeSubitems,
126
159
  discoveredItems: currentWizardData.discoveredItems,
160
+ selectionTreeItems: currentWizardData.selectionTreeItems,
127
161
  };
128
162
  try {
129
- const batchId = generateBatchId();
130
- const translationResult = await performDefaultTranslation(currentWizardData, editContext, batchId);
163
+ const translationResult = await performDefaultTranslation(currentWizardData, editContext);
131
164
  // Include batchId in result for navigation to translation management
132
- const resultWithBatch = { ...result, batchId };
165
+ const resultWithBatch = { ...result, batchId: translationResult.batchId };
133
166
  // Close dialog and let parent component handle navigation to translation management
134
167
  props.onClose?.(resultWithBatch);
135
168
  }
136
169
  catch (error) {
137
170
  // Handle specific error types
138
- if (error.name === 'NoTranslationsNeededError') {
171
+ if (error.name === "NoTranslationsNeededError") {
139
172
  // Show user-friendly message via toast and close dialog
140
- editContext.showToast?.('No translations needed. All selected target languages match the source languages of the items.');
173
+ editContext.showToast?.("No translations needed. All selected target languages match the source languages of the items.");
141
174
  props.onClose?.(result);
142
175
  return;
143
176
  }
144
177
  // For other errors, show toast and stay in dialog
145
- console.error('Translation failed:', error);
146
- const errorMessage = error.message || 'Translation request failed. Please try again.';
178
+ console.error("Translation failed:", error);
179
+ const errorMessage = error.message || "Translation request failed. Please try again.";
147
180
  editContext.showToast?.(errorMessage);
148
181
  // Don't close the dialog - let user try again or cancel
149
182
  }
150
183
  }
151
184
  catch (error) {
152
- console.error('Unexpected error in translation:', error);
153
- editContext.showToast?.('An unexpected error occurred. Please try again.');
185
+ console.error("Unexpected error in translation:", error);
186
+ editContext.showToast?.("An unexpected error occurred. Please try again.");
154
187
  // Don't close the dialog on error
155
188
  }
156
189
  finally {
@@ -181,18 +214,40 @@ export function LocalizeItemDialog(props) {
181
214
  : null;
182
215
  // Serialize metadata for comparison (supports both string and object formats)
183
216
  const metadataKey = newData.metadata
184
- ? (typeof newData.metadata === 'string'
217
+ ? typeof newData.metadata === "string"
185
218
  ? newData.metadata
186
- : JSON.stringify(newData.metadata))
219
+ : JSON.stringify(newData.metadata)
187
220
  : null;
188
221
  const dataKey = JSON.stringify({
189
222
  translationProvider: newData.translationProvider,
190
223
  targetLanguages: [...newData.targetLanguages].sort(),
191
224
  includeSubitems: newData.includeSubitems,
192
- discoveredItemsCount: newData.discoveredItems?.length || 0,
225
+ discoveredItemIds: (newData.discoveredItems || [])
226
+ .map((item) => item?.descriptor?.id || item?.id)
227
+ .filter(Boolean)
228
+ .sort(),
193
229
  itemsCount: newData.items?.length || 0,
194
230
  serviceCustomData: serviceCustomDataKey,
195
231
  metadata: metadataKey,
232
+ // batchName must be part of the key — otherwise the PromptCustomizationStep's
233
+ // setData({...prev, batchName}) call sees an "unchanged" key here and the
234
+ // update is silently dropped, so the user-entered name never reaches submit.
235
+ batchName: newData.batchName ?? "",
236
+ // subitemCounts must be part of the key — otherwise live count
237
+ // updates from the subitem-count stream are silently dropped and
238
+ // the Start Translation button can't reflect them.
239
+ subitemCounts: newData.subitemCounts
240
+ ? Object.keys(newData.subitemCounts)
241
+ .sort()
242
+ .map((id) => {
243
+ const c = newData.subitemCounts[id];
244
+ if (c === undefined)
245
+ return [id, "missing"];
246
+ if (c === "loading" || c === "error")
247
+ return [id, c];
248
+ return [id, c.count, c.complete];
249
+ })
250
+ : null,
196
251
  });
197
252
  // Skip if data hasn't actually changed
198
253
  if (lastSetWizardDataRef.current === dataKey) {
@@ -223,18 +278,21 @@ export function LocalizeItemDialog(props) {
223
278
  }, children: [_jsxs(DialogContent, { className: "flex h-[85vh] max-h-[900px] min-h-0 w-[90vw] max-w-5xl flex-col overflow-hidden md:min-h-[700px]", "data-testid": "translation-wizard-dialog", onPointerDownOutside: (e) => e.preventDefault(), onEscapeKeyDown: (e) => e.preventDefault(), "aria-describedby": "translation-wizard-description", style: {
224
279
  width: "min(90vw, 1280px)",
225
280
  height: "min(85vh, 900px)",
226
- }, children: [_jsx(DialogHeader, { className: "border-b border-gray-3 bg-background px-6 py-4 pr-14", children: _jsx(DialogTitle, { "data-testid": "translation-wizard-title", children: "Translate" }) }), _jsx("div", { id: "translation-wizard-description", className: "sr-only", children: currentStep?.description || "Configure and start translation for your content." }), _jsx("div", { className: "border-b border-gray-3 bg-background px-6 py-3 pr-14", children: _jsx("div", { "data-testid": "translation-wizard-step-navigation", children: _jsx("div", { className: "flex min-w-0 flex-nowrap items-center overflow-x-auto", children: activeSteps.map((step, index) => {
227
- const isCurrent = currentStepIndex === index;
228
- const isCompleted = currentStepIndex > index;
229
- return (_jsxs(Fragment, { children: [_jsxs("div", { className: "flex shrink-0 items-center gap-2", "data-testid": `step-indicator-${step.id}`, "aria-current": isCurrent ? "step" : undefined, children: [_jsx("div", { className: cn("flex h-7 w-7 shrink-0 items-center justify-center rounded-full border text-sm font-medium transition-colors", isCurrent && "border-theme-secondary bg-theme-secondary-light text-theme-secondary", isCompleted && "border-theme-secondary bg-theme-secondary text-white", !isCurrent && !isCompleted && "border-gray-3 bg-background text-gray-2"), "data-testid": `step-indicator-circle-${step.id}`, "aria-label": step.name, children: isCompleted ? "✓" : index + 1 }), _jsx("span", { className: cn("whitespace-nowrap text-sm transition-colors", isCurrent && "font-medium text-theme-secondary", isCompleted && "text-theme-secondary", !isCurrent && !isCompleted && "text-gray-2"), "data-testid": `step-indicator-label-${step.id}`, children: step.name })] }), index < activeSteps.length - 1 && (_jsx("div", { className: cn("mx-3 h-px w-8 shrink-0 transition-colors", currentStepIndex > index ? "bg-theme-secondary" : "bg-gray-3") }))] }, step.id));
230
- }) }) }) }), _jsxs("div", { className: "flex flex-1 flex-col min-h-0", children: [_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) => {
281
+ }, children: [_jsx(StyledDialogTitle, { icon: _jsx(GlobeIcon, { strokeWidth: 1.5 }), title: `Translate · ${currentStep?.name ?? ""}`, subtitle: currentStep?.description ||
282
+ "Configure and start translation for your content" }), _jsx("div", { id: "translation-wizard-description", className: "sr-only", children: currentStep?.description ||
283
+ "Configure and start translation for your content." }), _jsxs("div", { className: "flex flex-1 flex-col min-h-0", children: [_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) => {
231
284
  const StepComponent = step.component;
232
285
  const isActive = index === currentStepIndex;
233
286
  if (!StepComponent)
234
287
  return null;
235
- return (_jsx("div", { className: "h-full", style: { display: isActive ? 'block' : 'none' }, "aria-hidden": !isActive, "data-testid": `step-content-${step.id}`, children: _jsx(StepComponent, { stepIndex: index, isActive: isActive, data: wizardData, setData: setWizardDataStable, editContext: editContext, onStepCompleted: (completed) => handleStepCompleted(completed, index), setBeforeNextCallback: isActive ? setBeforeNextCallbackStable : undefined, setFooterActions: isActive ? provideFooterActions : undefined, requestClose: isActive ? requestCloseCb : undefined }) }, step.id));
236
- }) }) }), _jsxs(DialogButtons, { "data-testid": "translation-wizard-dialog-buttons", children: [_jsx(Button, { onClick: () => props.onClose?.(null), variant: "outline", size: "default", className: "w-auto min-w-24 flex-none", "data-testid": "translation-wizard-cancel-button", children: "Cancel" }), _jsxs("div", { className: "ml-auto flex min-w-0 flex-wrap items-center justify-end gap-3", children: [currentStepIndex > 0 && (_jsx(Button, { onClick: handlePrevious, variant: "outline", size: "default", className: "w-auto min-w-32 flex-none", "data-testid": "translation-wizard-previous-button", children: "Previous" })), footerActions.map((a) => (_jsx(Button, { onClick: a.onClick, disabled: !!a.disabled, variant: "default", size: "default", className: "w-auto min-w-32 flex-none", "data-testid": `translation-wizard-footer-action-${a.key}`, children: a.label }, a.key))), _jsx(Button, { onClick: handleNext, disabled: !canProceed || isSubmitting, variant: "default", size: "default", className: "w-auto min-w-40 flex-none", "data-testid": "translation-wizard-next-button", children: isSubmitting ? "Starting..." : isLastStep ? "Start Translation" : "Next" })] })] })] })] }), _jsx(AlertDialog, { open: showLargeBatchWarning, onOpenChange: setShowLargeBatchWarning, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { className: "flex items-center gap-2", children: [_jsx(AlertTriangleIcon, { className: "h-5 w-5 text-amber-500" }), "Large Translation Batch"] }), _jsx(AlertDialogDescription, { children: (() => {
288
+ return (_jsx("div", { className: "h-full", style: { display: isActive ? "block" : "none" }, "aria-hidden": !isActive, "data-testid": `step-content-${step.id}`, children: _jsx(StepComponent, { stepIndex: index, isActive: isActive, data: wizardData, setData: setWizardDataStable, editContext: editContext, onStepCompleted: (completed) => handleStepCompleted(completed, index), setBeforeNextCallback: isActive ? setBeforeNextCallbackStable : undefined, setFooterActions: isActive ? provideFooterActions : undefined, requestClose: isActive ? requestCloseCb : undefined }) }, step.id));
289
+ }) }) }), _jsxs(DialogButtons, { "data-testid": "translation-wizard-dialog-buttons", children: [_jsx(Button, { onClick: () => props.onClose?.(null), variant: "outline", size: "default", className: "w-auto min-w-24 flex-none", "data-testid": "translation-wizard-cancel-button", children: "Cancel" }), _jsxs("div", { className: "ml-auto flex min-w-0 flex-wrap items-center justify-end gap-3", children: [currentStepIndex > 0 && (_jsx(Button, { onClick: handlePrevious, variant: "outline", size: "default", className: "w-auto min-w-32 flex-none", "data-testid": "translation-wizard-previous-button", children: "Previous" })), footerActions.map((a) => (_jsx(Button, { onClick: a.onClick, disabled: !!a.disabled, variant: "default", size: "default", className: "w-auto min-w-32 flex-none", "data-testid": `translation-wizard-footer-action-${a.key}`, children: a.label }, a.key))), _jsx(Button, { onClick: handleNext, disabled: !canProceed || isSubmitting, variant: "default", size: "default", className: "w-auto min-w-40 flex-none gap-2", "data-testid": "translation-wizard-next-button", children: isSubmitting ? ("Starting...") : isLastStep ? ((() => {
290
+ const { totalTranslations, isStreaming } = calculateTranslationCounts(wizardData);
291
+ if (totalTranslations <= 0)
292
+ return "Start Translation";
293
+ return `Start Translation (${totalTranslations}${isStreaming ? "+" : ""})`;
294
+ })()) : (_jsxs(_Fragment, { children: [activeSteps[currentStepIndex + 1]?.name ?? "Next", _jsx(ArrowRightIcon, { className: "h-4 w-4", strokeWidth: 2 })] })) })] })] })] })] }), _jsx(AlertDialog, { open: showLargeBatchWarning, onOpenChange: setShowLargeBatchWarning, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { className: "flex items-center gap-2", children: [_jsx(AlertTriangleIcon, { className: "h-5 w-5 text-amber-500" }), "Large Translation Batch"] }), _jsx(AlertDialogDescription, { children: (() => {
237
295
  const { itemCount, languageCount, totalTranslations } = calculateTranslationCounts(wizardData);
238
- return (_jsxs(_Fragment, { children: ["You are about to start ", _jsxs("strong", { children: [totalTranslations, " translations"] }), " (", itemCount, " items \u00D7 ", languageCount, " languages). Large batches may take a significant amount of time to process.", _jsx("br", {}), _jsx("br", {}), "Are you sure you want to continue?"] }));
296
+ return (_jsxs(_Fragment, { children: ["You are about to start", " ", _jsxs("strong", { children: [totalTranslations, " translations"] }), " (", itemCount, " items \u00D7 ", languageCount, " languages). Large batches may take a significant amount of time to process.", _jsx("br", {}), _jsx("br", {}), "Are you sure you want to continue?"] }));
239
297
  })() })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isSubmitting, children: "Cancel" }), _jsx(AlertDialogAction, { onClick: handleLargeBatchConfirm, disabled: isSubmitting, children: isSubmitting ? "Starting..." : "Continue" })] })] }) })] }));
240
298
  }
@@ -2,7 +2,6 @@ import { TranslationStatus } from "./types";
2
2
  import { FullItem } from "@parhelia/core";
3
3
  import { TranslationWizardData } from "./steps/types";
4
4
  import { EditContextType } from "@parhelia/core";
5
- export declare function generateBatchId(): string;
6
5
  export type StartedTranslation = {
7
6
  itemId: string;
8
7
  targetLanguage: string;
@@ -12,6 +11,6 @@ export type TranslationResult = {
12
11
  started: StartedTranslation[];
13
12
  batchId?: string;
14
13
  };
15
- export declare function performDefaultTranslation(wizardData: TranslationWizardData, editContext: EditContextType, predefinedBatchId?: string): Promise<TranslationResult>;
14
+ export declare function performDefaultTranslation(wizardData: TranslationWizardData, editContext: EditContextType): Promise<TranslationResult>;
16
15
  export declare const defaultTranslateAll: (languageCodes: string[], translationStatus: TranslationStatus[], sessionId: string, item: FullItem, translationProvider: string) => Promise<TranslationResult>;
17
16
  //# sourceMappingURL=LocalizeItemUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocalizeItemUtils.d.ts","sourceRoot":"","sources":["../src/LocalizeItemUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAC,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIjD,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,qBAAqB,EACjC,WAAW,EAAE,eAAe,EAC5B,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,iBAAiB,CAAC,CAyH5B;AAGD,eAAO,MAAM,mBAAmB,GAAU,eAAe,MAAM,EAAE,EAAE,mBAAmB,iBAAiB,EAAE,EAAE,WAAW,MAAM,EAAE,MAAM,QAAQ,EAAE,qBAAqB,MAAM,+BA0BxK,CAAC"}
1
+ {"version":3,"file":"LocalizeItemUtils.d.ts","sourceRoot":"","sources":["../src/LocalizeItemUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAC,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA8CjD,MAAM,MAAM,kBAAkB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,qBAAqB,EACjC,WAAW,EAAE,eAAe,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAyH5B;AAGD,eAAO,MAAM,mBAAmB,GAAU,eAAe,MAAM,EAAE,EAAE,mBAAmB,iBAAiB,EAAE,EAAE,WAAW,MAAM,EAAE,MAAM,QAAQ,EAAE,qBAAqB,MAAM,+BA0BxK,CAAC"}
@@ -1,15 +1,42 @@
1
1
  import { requestBatchTranslation } from "./services/translationService";
2
- // Shared utility for generating unique batch IDs
3
- export function generateBatchId() {
4
- return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}-${performance.now().toString(36).substring(2, 8)}`;
2
+ import { discoverItemsTree, flattenSelectableItemsFromBackendTrees } from "./api/discovery";
3
+ /**
4
+ * Resolve the final list of item IDs to translate, expanding subitems for
5
+ * any selection-tree item whose includeSubitems flag is true.
6
+ *
7
+ * Selection priority:
8
+ * 1. `selectionTreeItems` (new model) — per-item flags drive expansion
9
+ * 2. `discoveredItems` (legacy fallback) — used as-is
10
+ * 3. `items` (initial wizard input) — used as-is
11
+ */
12
+ async function resolveItemIdsToTranslate(wizardData, sessionId) {
13
+ if (wizardData.selectionTreeItems && wizardData.selectionTreeItems.length > 0) {
14
+ const directIds = [];
15
+ const rootsToExpand = [];
16
+ for (const entry of wizardData.selectionTreeItems) {
17
+ if (entry.includeSubitems) {
18
+ rootsToExpand.push(entry.descriptor.id);
19
+ }
20
+ else {
21
+ directIds.push(entry.descriptor.id);
22
+ }
23
+ }
24
+ const expandedIds = [];
25
+ if (rootsToExpand.length > 0) {
26
+ const language = wizardData.selectionTreeItems[0]?.descriptor.language;
27
+ const tree = await discoverItemsTree({ rootItemIds: rootsToExpand, language }, sessionId);
28
+ expandedIds.push(...flattenSelectableItemsFromBackendTrees(tree.trees).map((n) => n.id));
29
+ }
30
+ return Array.from(new Set([...directIds, ...expandedIds]));
31
+ }
32
+ const fallback = wizardData.discoveredItems && wizardData.discoveredItems.length > 0
33
+ ? wizardData.discoveredItems
34
+ : wizardData.items;
35
+ return fallback.map((item) => item.descriptor.id);
5
36
  }
6
37
  // Unified translation function that handles both single and batch translations
7
38
  // Now always uses batch logic for traceability in recentTranslation view
8
- export async function performDefaultTranslation(wizardData, editContext, predefinedBatchId) {
9
- const batchId = predefinedBatchId || generateBatchId();
10
- const itemsToTranslate = wizardData.includeSubitems
11
- ? wizardData.discoveredItems
12
- : wizardData.items;
39
+ export async function performDefaultTranslation(wizardData, editContext) {
13
40
  // Build language mappings (source -> target) from the wizard data
14
41
  // The source language is consistent for each target language across all items
15
42
  const languageMappings = [];
@@ -24,8 +51,8 @@ export async function performDefaultTranslation(wizardData, editContext, predefi
24
51
  targetLanguage: language,
25
52
  });
26
53
  }
27
- // Extract item IDs
28
- const itemIds = itemsToTranslate.map(item => item.descriptor.id);
54
+ // Resolve item IDs, expanding subitems per-item-flag where applicable.
55
+ const itemIds = await resolveItemIdsToTranslate(wizardData, editContext.sessionId);
29
56
  // Validate that we have translation requests to process
30
57
  if (languageMappings.length === 0 || itemIds.length === 0) {
31
58
  const error = new Error('No translations needed. All selected target languages match the source languages of the items.');
@@ -48,6 +75,12 @@ export async function performDefaultTranslation(wizardData, editContext, predefi
48
75
  metadataObj = { ...wizardData.metadata };
49
76
  }
50
77
  }
78
+ // Embed the user/AI-provided batch name so it surfaces in Recent
79
+ // Translations and the batch detail view.
80
+ const trimmedName = wizardData.batchName?.trim();
81
+ if (trimmedName) {
82
+ metadataObj.name = trimmedName;
83
+ }
51
84
  // Merge service-specific custom data (e.g., custom prompts for OpenAI)
52
85
  if (wizardData.serviceCustomData && wizardData.serviceCustomData.size > 0) {
53
86
  const serviceData = wizardData.serviceCustomData.get(wizardData.translationProvider);
@@ -79,7 +112,6 @@ export async function performDefaultTranslation(wizardData, editContext, predefi
79
112
  const batchMetadata = Object.keys(metadataObj).length > 0 ? JSON.stringify(metadataObj) : undefined;
80
113
  const batchResult = await requestBatchTranslation({
81
114
  sessionId: editContext.sessionId,
82
- batchId,
83
115
  provider: wizardData.translationProvider,
84
116
  batchMetadata,
85
117
  languageMappings,
@@ -108,7 +140,7 @@ export async function performDefaultTranslation(wizardData, editContext, predefi
108
140
  if (batchResponse.skipped && batchResponse.skipped.length > 0) {
109
141
  console.warn('Some translations were skipped:', batchResponse.skipped);
110
142
  }
111
- return { started, batchId };
143
+ return { started, batchId: batchResponse.id };
112
144
  }
113
145
  // Legacy function for backward compatibility
114
146
  export const defaultTranslateAll = async (languageCodes, translationStatus, sessionId, item, translationProvider) => {
@@ -1,3 +1,8 @@
1
+ export declare function suggestBatchName(req: {
2
+ itemIds: string[];
3
+ targetLanguages: string[];
4
+ includeSubitems?: boolean;
5
+ }, sessionId?: string): Promise<string | null>;
1
6
  export type DiscoveredItem = {
2
7
  id: string;
3
8
  name: string;
@@ -31,4 +36,24 @@ export type DiscoverItemsTreeResponse = {
31
36
  export declare function discoverItemsTree(req: DiscoverItemsTreeRequest, sessionId?: string): Promise<DiscoverItemsTreeResponse>;
32
37
  export declare function convertBackendTreeToTreeNodes(trees: BackendTreeNode[]): TreeNode[];
33
38
  export declare function flattenSelectableItemsFromBackendTrees(trees: BackendTreeNode[]): DiscoveredItem[];
39
+ export type SubitemCountUpdate = {
40
+ count: number;
41
+ complete: boolean;
42
+ };
43
+ /**
44
+ * Streams the running subitem count for a given root item from the
45
+ * backend. The endpoint returns newline-delimited JSON; each parsed line
46
+ * triggers `onProgress` so the UI can show the count climbing. Filtered
47
+ * server-side via IItemExportFilter + excluded templates.
48
+ *
49
+ * Pass an `AbortSignal` to cancel mid-stream (e.g. user toggles the
50
+ * subitems flag off again).
51
+ */
52
+ export declare function streamSubitemCount(req: {
53
+ itemId: string;
54
+ language?: string;
55
+ }, onProgress: (update: SubitemCountUpdate) => void, options?: {
56
+ sessionId?: string;
57
+ signal?: AbortSignal;
58
+ }): Promise<number>;
34
59
  //# sourceMappingURL=discovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/api/discovery.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC;AAInG,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,wBAAwB,EAC7B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,yBAAyB,CAAC,CAWpC;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,QAAQ,EAAE,CAQlF;AAED,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,cAAc,EAAE,CAQjG"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/api/discovery.ts"],"names":[],"mappings":"AAEA,wBAAsB,gBAAgB,CACpC,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,EAChF,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAaxB;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC;AAInG,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,wBAAwB,EAC7B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,yBAAyB,CAAC,CAWpC;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,QAAQ,EAAE,CAQlF;AAED,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,cAAc,EAAE,CAQjG;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1C,UAAU,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,EAChD,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GACrD,OAAO,CAAC,MAAM,CAAC,CAiEjB"}
@@ -1,4 +1,15 @@
1
1
  import { post } from "@parhelia/core";
2
+ export async function suggestBatchName(req, sessionId) {
3
+ const { data, type } = await post("/parhelia/translation/suggestBatchName", {
4
+ ItemIds: req.itemIds,
5
+ TargetLanguages: req.targetLanguages,
6
+ IncludeSubitems: !!req.includeSubitems,
7
+ }, sessionId);
8
+ if (type !== "success")
9
+ return null;
10
+ const name = data?.name?.trim();
11
+ return name && name.length > 0 ? name : null;
12
+ }
2
13
  export async function discoverItemsTree(req, sessionId) {
3
14
  const { data, type, details } = await post("/parhelia/translation/discoveritemstree", {
4
15
  RootItemIds: req.rootItemIds,
@@ -26,3 +37,79 @@ export function flattenSelectableItemsFromBackendTrees(trees) {
26
37
  trees.forEach(walk);
27
38
  return out;
28
39
  }
40
+ /**
41
+ * Streams the running subitem count for a given root item from the
42
+ * backend. The endpoint returns newline-delimited JSON; each parsed line
43
+ * triggers `onProgress` so the UI can show the count climbing. Filtered
44
+ * server-side via IItemExportFilter + excluded templates.
45
+ *
46
+ * Pass an `AbortSignal` to cancel mid-stream (e.g. user toggles the
47
+ * subitems flag off again).
48
+ */
49
+ export async function streamSubitemCount(req, onProgress, options) {
50
+ let url = "/parhelia/translation/discoverSubitemCountStream";
51
+ if (options?.sessionId)
52
+ url += "?sessionId=" + options.sessionId;
53
+ const response = await fetch(url, {
54
+ method: "POST",
55
+ body: JSON.stringify({ ItemId: req.itemId, Language: req.language }),
56
+ credentials: "include",
57
+ headers: { "Content-Type": "application/json", Accept: "application/x-ndjson" },
58
+ signal: options?.signal,
59
+ });
60
+ if (!response.ok || !response.body) {
61
+ throw new Error(`Failed to start subitem count stream (${response.status})`);
62
+ }
63
+ const reader = response.body.getReader();
64
+ const decoder = new TextDecoder();
65
+ let buffer = "";
66
+ let lastCount = 0;
67
+ try {
68
+ while (true) {
69
+ const { value, done } = await reader.read();
70
+ if (done)
71
+ break;
72
+ buffer += decoder.decode(value, { stream: true });
73
+ let newlineIndex;
74
+ while ((newlineIndex = buffer.indexOf("\n")) >= 0) {
75
+ const line = buffer.slice(0, newlineIndex).trim();
76
+ buffer = buffer.slice(newlineIndex + 1);
77
+ if (!line)
78
+ continue;
79
+ try {
80
+ const parsed = JSON.parse(line);
81
+ if (typeof parsed.count === "number") {
82
+ lastCount = parsed.count;
83
+ onProgress({ count: parsed.count, complete: !!parsed.complete });
84
+ }
85
+ }
86
+ catch {
87
+ // Ignore malformed line; keep streaming.
88
+ }
89
+ }
90
+ }
91
+ // Flush any trailing partial line.
92
+ const tail = buffer.trim();
93
+ if (tail) {
94
+ try {
95
+ const parsed = JSON.parse(tail);
96
+ if (typeof parsed.count === "number") {
97
+ lastCount = parsed.count;
98
+ onProgress({ count: parsed.count, complete: !!parsed.complete });
99
+ }
100
+ }
101
+ catch {
102
+ // Drop malformed trailing data.
103
+ }
104
+ }
105
+ }
106
+ finally {
107
+ try {
108
+ reader.releaseLock();
109
+ }
110
+ catch {
111
+ // already released
112
+ }
113
+ }
114
+ return lastCount;
115
+ }
package/dist/index.d.ts CHANGED
@@ -1,21 +1,13 @@
1
+ import { ItemSelectionStep } from "./steps/ItemSelectionStep";
1
2
  import { ServiceLanguageSelectionStep } from "./steps/ServiceLanguageSelectionStep";
2
- import { SubitemDiscoveryStep } from "./steps/SubitemDiscoveryStep";
3
- import { TranslationWizardData } from "./steps/types";
4
3
  import { EditorConfiguration } from "@parhelia/core";
5
4
  declare const DEFAULT_TRANSLATION_WIZARD_CONFIGURATION: {
6
- steps: ({
7
- id: string;
8
- name: string;
9
- description: string;
10
- component: typeof ServiceLanguageSelectionStep;
11
- skipCondition?: undefined;
12
- } | {
5
+ steps: {
13
6
  id: string;
14
7
  name: string;
15
8
  description: string;
16
- component: typeof SubitemDiscoveryStep;
17
- skipCondition: (data: TranslationWizardData) => boolean;
18
- })[];
9
+ component: typeof ItemSelectionStep;
10
+ }[];
19
11
  };
20
12
  declare const SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION: {
21
13
  steps: {
@@ -25,16 +17,15 @@ declare const SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION: {
25
17
  component: typeof ServiceLanguageSelectionStep;
26
18
  }[];
27
19
  };
28
- export { DEFAULT_TRANSLATION_WIZARD_CONFIGURATION, SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION };
20
+ export { DEFAULT_TRANSLATION_WIZARD_CONFIGURATION, SINGLE_ITEM_TRANSLATION_WIZARD_CONFIGURATION, };
29
21
  export { LocalizeItemDialog } from "./LocalizeItemDialog";
30
22
  export { localizeItemCommand } from "./LocalizeItemCommand";
31
23
  export { TranslationManagement } from "./translation-center/TranslationManagement";
32
- export { RecentTranslations } from "./translation-center/RecentTranslations";
33
- export { BatchTranslationView } from "./translation-center/BatchTranslationView";
24
+ export { TranslationBatches } from "./translation-center/TranslationBatches";
34
25
  export { LocalizationSetupStep } from "./setup/LocalizationSetupStep";
35
26
  export { TranslationServicesPanel } from "./settings/TranslationServicesPanel";
36
- export type { LocalizeItemCommand, LocalizeItemCommandContext, LocalizeItemCommandData } from "./LocalizeItemCommand";
37
- export { defaultTranslateAll, generateBatchId, performDefaultTranslation, type StartedTranslation, type TranslationResult } from "./LocalizeItemUtils";
27
+ export type { LocalizeItemCommand, LocalizeItemCommandContext, LocalizeItemCommandData, } from "./LocalizeItemCommand";
28
+ export { defaultTranslateAll, performDefaultTranslation, type StartedTranslation, type TranslationResult, } from "./LocalizeItemUtils";
38
29
  export * from "./steps/types";
39
30
  export type { TranslationProviderInfo, TranslationStatus } from "./steps/types";
40
31
  export type LocalizationConfigOptions = {
@@ -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;AActD,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,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,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,uBAsHpC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAepF,OAAO,EACL,mBAAmB,EAGpB,MAAM,gBAAgB,CAAC;AAUxB,QAAA,MAAM,wCAAwC;;;;;;;CAqB7C,CAAC;AAEF,QAAA,MAAM,4CAA4C;;;;;;;CAejD,CAAC;AAkCF,OAAO,EACL,wCAAwC,EACxC,4CAA4C,GAC7C,CAAC;AACF,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,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,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,uBAyHpC"}