@parhelia/localization 0.1.12772 → 0.1.12774
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LocalizeItemDialog.d.ts.map +1 -1
- package/dist/LocalizeItemDialog.js +8 -11
- package/dist/sidebar/TranslationSidebar.d.ts.map +1 -1
- package/dist/sidebar/TranslationSidebar.js +2 -2
- package/dist/steps/ServiceLanguageSelectionStep.d.ts.map +1 -1
- package/dist/steps/ServiceLanguageSelectionStep.js +35 -35
- package/dist/steps/SubitemDiscoveryStep.d.ts.map +1 -1
- package/dist/steps/SubitemDiscoveryStep.js +85 -85
- package/package.json +1 -1
|
@@ -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,
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, Button, cn, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@parhelia/core";
|
|
3
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { AlertTriangle as LucideAlertTriangle } from "lucide-react";
|
|
5
5
|
import { useTranslationWizard } from "./hooks/useTranslationWizard";
|
|
6
6
|
import { performDefaultTranslation, generateBatchId } from "./LocalizeItemUtils";
|
|
@@ -9,7 +9,7 @@ const AlertTriangleIcon = LucideAlertTriangle;
|
|
|
9
9
|
const LARGE_BATCH_WARNING_THRESHOLD = 100;
|
|
10
10
|
// Note: DialogButtons is an internal component that might need to be added to core exports
|
|
11
11
|
// For now, we'll implement it inline
|
|
12
|
-
const DialogButtons = ({ children, ...props }) => (_jsx("div", { className: "mt-auto flex
|
|
12
|
+
const DialogButtons = ({ children, ...props }) => (_jsx("div", { className: "mt-auto flex shrink-0 items-center gap-3 border-t border-gray-3 bg-background px-6 py-4", ...props, children: children }));
|
|
13
13
|
export function LocalizeItemDialog(props) {
|
|
14
14
|
const editContext = props.editContext;
|
|
15
15
|
const configuration = editContext.configuration.translationWizard;
|
|
@@ -223,20 +223,17 @@ export function LocalizeItemDialog(props) {
|
|
|
223
223
|
}, 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
224
|
width: "min(90vw, 1280px)",
|
|
225
225
|
height: "min(85vh, 900px)",
|
|
226
|
-
}, children: [
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
? "overflow-hidden text-[#9650fb] max-md:pointer-events-none max-md:max-w-0 max-md:opacity-0"
|
|
232
|
-
: "overflow-hidden text-[var(--color-gray-2)] max-md:pointer-events-none max-md:max-w-0 max-md:opacity-0"), "data-testid": `step-indicator-label-${step.id}`, children: _jsx("span", { className: cn(isCurrent ? "whitespace-normal break-words md:whitespace-nowrap" : "whitespace-nowrap"), children: step.name }) })] }, step.id));
|
|
233
|
-
}) }) }), _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) => {
|
|
226
|
+
}, children: [_jsx(DialogTitle, { className: "sr-only", "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." }), _jsx(DialogHeader, { className: "border-b border-gray-3 bg-background px-6 py-4 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) => {
|
|
234
231
|
const StepComponent = step.component;
|
|
235
232
|
const isActive = index === currentStepIndex;
|
|
236
233
|
if (!StepComponent)
|
|
237
234
|
return null;
|
|
238
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));
|
|
239
|
-
}) }) }), _jsxs(DialogButtons, { "data-testid": "translation-wizard-dialog-buttons", children: [_jsx(Button, { onClick: () => props.onClose?.(null), variant: "outline", size: "default", className: "
|
|
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: (() => {
|
|
240
237
|
const { itemCount, languageCount, totalTranslations } = calculateTranslationCounts(wizardData);
|
|
241
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?"] }));
|
|
242
239
|
})() })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isSubmitting, children: "Cancel" }), _jsx(AlertDialogAction, { onClick: handleLargeBatchConfirm, disabled: isSubmitting, children: isSubmitting ? "Starting..." : "Continue" })] })] }) })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"AAcA,wBAAgB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"TranslationSidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/TranslationSidebar.tsx"],"names":[],"mappings":"AAcA,wBAAgB,kBAAkB,mDA4MjC"}
|
|
@@ -85,14 +85,14 @@ export function TranslationSidebar() {
|
|
|
85
85
|
// Sort by name for languages that both have versions or both don't
|
|
86
86
|
return a.name.localeCompare(b.name);
|
|
87
87
|
});
|
|
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 && (
|
|
88
|
+
return (_jsxs("div", { className: "flex h-full flex-col", "data-testid": "translation-sidebar", children: [_jsx("div", { className: "flex items-center justify-end border-b border-[var(--color-gray-3)] p-1 px-2", children: item && (_jsx(Button, { size: "xs", "data-testid": "translation-sidebar-localize-button", onClick: () => {
|
|
89
89
|
editContext.executeCommand({
|
|
90
90
|
command: localizeItemCommand,
|
|
91
91
|
data: {
|
|
92
92
|
items: [item],
|
|
93
93
|
},
|
|
94
94
|
});
|
|
95
|
-
}, children:
|
|
95
|
+
}, children: "Localize" })) }), _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: [
|
|
96
96
|
{ header: "Language", body: languageName },
|
|
97
97
|
{ header: "Ver.", body: (x) => _jsx("span", { className: "text-[var(--color-gray-1)]", children: x.versions.toString() }) },
|
|
98
98
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceLanguageSelectionStep.d.ts","sourceRoot":"","sources":["../../src/steps/ServiceLanguageSelectionStep.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,SAAS,CAAC;AAkBtE,wBAAgB,4BAA4B,CAAC,EAAE,SAAS,EAAE,QAAe,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"ServiceLanguageSelectionStep.d.ts","sourceRoot":"","sources":["../../src/steps/ServiceLanguageSelectionStep.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,SAAS,CAAC;AAkBtE,wBAAgB,4BAA4B,CAAC,EAAE,SAAS,EAAE,QAAe,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,oBAAoB,2CAuZ7K"}
|
|
@@ -203,39 +203,39 @@ export function ServiceLanguageSelectionStep({ stepIndex, isActive = true, data,
|
|
|
203
203
|
const serviceData = data.serviceCustomData?.get("OpenAI");
|
|
204
204
|
return serviceData?.enableCustomPrompt === true;
|
|
205
205
|
}, [data.translationProvider, data.serviceCustomData]);
|
|
206
|
-
return (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
206
|
+
return (_jsx("div", { className: "p-6 space-y-6 h-full flex flex-col", "data-testid": "service-language-selection-step", children: _jsxs("div", { className: "space-y-6 flex-1", children: [_jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsx("h3", { className: "text-sm font-medium text-[var(--color-dark)] mb-2", children: "Translation Provider" }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mb-3", children: "Choose how to translate your content. \"Create Versions\" will create new language versions without automatic translation." }), _jsxs("select", { value: data.translationProvider || "", onChange: handleProviderChange, className: "block w-full px-3 py-2 border border-[var(--color-gray-3)] rounded-md bg-[var(--color-gray-5)] text-[var(--color-dark)] text-sm focus:outline-none focus:ring-2 focus:ring-[#9650fb] focus:border-[#9650fb] transition-colors", "data-testid": "translation-provider-select", children: [_jsx("option", { value: "", disabled: true, children: "Select a provider..." }), data.translationProviders.map((provider) => (_jsx("option", { value: provider.name, children: provider.displayName || provider.name }, provider.name)))] })] }), multiItemEnabled && (_jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsxs("label", { className: "flex items-center cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: data.includeSubitems, onChange: handleSubitemsToggle, className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": "include-subitems-checkbox" }), _jsx("span", { className: "ml-2 text-sm text-[var(--color-dark)] font-medium", children: "Include subitems" })] }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mt-1.5 ml-6", children: "Also translate any child components and nested content within this item." })] })), data.translationProvider === "OpenAI" && (_jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsxs("label", { className: "flex items-center cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: isPromptCustomizationEnabled, onChange: (e) => {
|
|
207
|
+
const isChecked = e.target.checked;
|
|
208
|
+
// Always create a new Map instance to ensure React detects the change
|
|
209
|
+
const newServiceCustomData = new Map();
|
|
210
|
+
if (data.serviceCustomData) {
|
|
211
|
+
data.serviceCustomData.forEach((value, key) => {
|
|
212
|
+
newServiceCustomData.set(key, value);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (isChecked) {
|
|
216
|
+
newServiceCustomData.set("OpenAI", {
|
|
217
|
+
enableCustomPrompt: true,
|
|
218
|
+
customPrompt: "",
|
|
219
|
+
promptCustomizationType: "extend",
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// Remove the service data when unchecked
|
|
224
|
+
newServiceCustomData.delete("OpenAI");
|
|
225
|
+
}
|
|
226
|
+
const newData = {
|
|
227
|
+
...data,
|
|
228
|
+
serviceCustomData: newServiceCustomData
|
|
229
|
+
};
|
|
230
|
+
setData(newData);
|
|
231
|
+
}, className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": "enable-custom-prompt-checkbox" }), _jsx("span", { className: "ml-2 text-sm text-[var(--color-dark)] font-medium", children: "Customize translation prompt" })] }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mt-1.5 ml-6", children: "Enable advanced prompt customization for the translation service." })] })), _jsxs("div", { className: "bg-background rounded-lg border border-[var(--color-gray-3)] p-4", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("h3", { className: "text-sm font-medium text-[var(--color-dark)]", children: "Target Languages" }), allLanguages.length > 1 && (_jsxs("label", { className: "flex items-center cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: areAllLanguagesSelected, ref: (input) => {
|
|
232
|
+
if (input) {
|
|
233
|
+
input.indeterminate = areSomeLanguagesSelected && !areAllLanguagesSelected;
|
|
234
|
+
}
|
|
235
|
+
}, onChange: handleSelectAllLanguages, className: "h-4 w-4 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": "select-all-languages-checkbox" }), _jsx("span", { className: "ml-2 text-xs text-[var(--color-gray-2)]", children: "Select All" })] }))] }), _jsx("p", { className: "text-xs text-[var(--color-gray-2)] mb-3", children: "Select the languages you want to translate this content into." }), _jsx("div", { className: "border border-[var(--color-gray-3)] rounded-lg min-h-[200px] max-h-64 overflow-y-auto bg-[var(--color-gray-5)]", children: data.translationProviders.length === 0 || allLanguages.length === 0 ? (
|
|
236
|
+
// Loading skeleton
|
|
237
|
+
_jsx("div", { className: "p-3 space-y-2", children: [...Array(4)].map((_, i) => (_jsxs("div", { className: "flex items-center animate-pulse", children: [_jsx("div", { className: "h-4 w-4 bg-[var(--color-gray-3)] rounded" }), _jsx("div", { className: "ml-2 h-4 bg-[var(--color-gray-3)] rounded w-32" }), _jsx("div", { className: "ml-auto h-4 bg-[var(--color-gray-3)] rounded w-16" })] }, i))) })) : (_jsx("div", { className: "p-3 grid grid-cols-1 gap-2", children: allLanguages.map((lang) => {
|
|
238
|
+
const statusLabel = lang.translationStatus?.status || "Not started";
|
|
239
|
+
return (_jsxs("label", { className: "flex items-start gap-2 py-1.5 px-2 rounded-md hover:bg-[var(--color-gray-4)] transition-colors cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: languageSelection[lang.code] || false, onChange: () => handleLanguageToggle(lang.code), className: "mt-0.5 h-4 w-4 shrink-0 text-[#9650fb] focus:ring-[#9650fb] border-[var(--color-gray-3)] rounded accent-[#9650fb]", "data-testid": `language-checkbox-${lang.code}` }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "text-sm text-[var(--color-dark)]", children: [lang.name, " (", lang.code, ")"] }), _jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-[var(--color-gray-2)]", children: [lang.sourceLanguage && _jsxs("span", { children: ["from: ", lang.sourceLanguage] }), !lang.hasVersions && (_jsx("span", { className: "text-2xs text-orange-600 bg-orange-100 px-2 py-1 rounded-full font-medium", children: "No versions" })), lang.hasVersions && (_jsx("span", { title: lang.translationStatus?.message, className: `text-2xs px-2 py-1 rounded-full font-medium ${getTranslationStatusBadgeClass(statusLabel)}`, "data-testid": `translation-status-badge-${lang.code}`, children: statusLabel }))] })] })] }, lang.code));
|
|
240
|
+
}) })) })] })] }) }));
|
|
241
241
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubitemDiscoveryStep.d.ts","sourceRoot":"","sources":["../../src/steps/SubitemDiscoveryStep.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW/C,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,QAAe,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"SubitemDiscoveryStep.d.ts","sourceRoot":"","sources":["../../src/steps/SubitemDiscoveryStep.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW/C,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,QAAe,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,oBAAoB,2CA6Z5L"}
|
|
@@ -223,92 +223,92 @@ export function SubitemDiscoveryStep({ stepIndex, isActive = true, data, setData
|
|
|
223
223
|
setIsDiscovering(false);
|
|
224
224
|
setDiscoveryComplete(true);
|
|
225
225
|
};
|
|
226
|
-
return (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
226
|
+
return (_jsx("div", { className: "flex min-h-0 flex-col gap-4 p-6", "data-testid": "subitem-discovery-step", children: _jsxs("div", { className: "flex w-full min-w-0 shrink-0 flex-col rounded-lg border border-[var(--color-gray-3)] bg-background p-4 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...' :
|
|
227
|
+
discoveryComplete ? 'Discovery Complete' :
|
|
228
|
+
'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"] }), _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 flex flex-col", children: !isDiscovering && discoveryComplete && treeInitialized && allDiscoveredItems.length > 0 && treeNodes.length > 0 ? (_jsxs("div", { className: "flex w-full min-w-0 flex-col", "data-testid": "item-selection-section", children: [_jsxs("div", { className: "mb-3 flex flex-col gap-2 border-t border-[var(--color-gray-3)] pt-4", children: [_jsx("h3", { className: "text-lg font-semibold text-[var(--color-dark)]", children: "Select Items to Translate" }), _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" }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
229
|
+
if (!isActive)
|
|
230
|
+
return;
|
|
231
|
+
const allIds = new Set();
|
|
232
|
+
const walk = (nodes) => {
|
|
233
|
+
nodes.forEach(node => {
|
|
234
|
+
allIds.add(node.key);
|
|
235
|
+
if (node.children)
|
|
236
|
+
walk(node.children);
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
walk(treeNodes);
|
|
240
|
+
setUserHasInteracted(true);
|
|
241
|
+
setSelectedItemIds(allIds);
|
|
242
|
+
onStepCompleted(allIds.size > 0);
|
|
243
|
+
}, "data-testid": "select-all-items-button", children: "Select All" }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => {
|
|
244
|
+
if (!isActive)
|
|
245
|
+
return;
|
|
246
|
+
setUserHasInteracted(true);
|
|
247
|
+
setSelectedItemIds(new Set());
|
|
248
|
+
onStepCompleted(false);
|
|
249
|
+
}, "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: "h-80 w-full min-w-0 shrink-0 overflow-auto rounded-lg border border-[var(--color-gray-3)] bg-[var(--color-gray-5)]", "data-testid": "item-tree-view", children: _jsx(PerfectTree, { nodes: treeNodes, expandedKeys: expandedKeys, selectedKeys: selectedKeys, onToggleExpand: (key) => {
|
|
250
|
+
setExpandedIds(prev => {
|
|
251
|
+
const next = new Set(prev);
|
|
252
|
+
if (next.has(key))
|
|
253
|
+
next.delete(key);
|
|
254
|
+
else
|
|
255
|
+
next.add(key);
|
|
256
|
+
return next;
|
|
257
|
+
});
|
|
258
|
+
}, onSelect: (key, event) => {
|
|
259
|
+
if (!isActive)
|
|
260
|
+
return; // Don't handle selection when inactive
|
|
261
|
+
setUserHasInteracted(true);
|
|
262
|
+
const targetNode = key;
|
|
263
|
+
const shift = event?.shiftKey === true;
|
|
264
|
+
const next = new Set(selectedItemIds);
|
|
265
|
+
const findNode = (nodes) => {
|
|
266
|
+
for (const n of nodes) {
|
|
267
|
+
if (n.key === targetNode)
|
|
268
|
+
return n;
|
|
269
|
+
if (n.children) {
|
|
270
|
+
const f = findNode(n.children);
|
|
271
|
+
if (f)
|
|
272
|
+
return f;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return null;
|
|
276
|
+
};
|
|
277
|
+
const n = findNode(treeNodes);
|
|
278
|
+
if (!n)
|
|
279
|
+
return;
|
|
280
|
+
const ids = shift ? [key, ...getDescendantIds(key)] : [key];
|
|
281
|
+
if (!next.has(key))
|
|
282
|
+
ids.forEach((id) => next.add(id));
|
|
283
|
+
else
|
|
284
|
+
ids.forEach((id) => next.delete(id));
|
|
285
|
+
setSelectedItemIds(next);
|
|
286
|
+
// Update completion when user changes selection
|
|
287
|
+
onStepCompleted(next.size > 0);
|
|
288
|
+
}, renderNode: (node) => {
|
|
289
|
+
const isChecked = selectedItemIds.has(node.key);
|
|
290
|
+
const icon = node?.data?.icon;
|
|
291
|
+
return (_jsxs("div", { className: "flex items-center gap-2", children: [icon && (_jsx("img", { src: icon, alt: "", className: "w-4 h-4" })), _jsx("input", { type: "checkbox", checked: isChecked, "data-testid": `tree-item-checkbox-${node.key}`, onMouseDown: (e) => {
|
|
292
|
+
shiftToggleRef.current = e.shiftKey;
|
|
293
|
+
}, onChange: (e) => {
|
|
244
294
|
if (!isActive)
|
|
245
295
|
return;
|
|
246
296
|
setUserHasInteracted(true);
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
const next = new Set(selectedItemIds);
|
|
265
|
-
const findNode = (nodes) => {
|
|
266
|
-
for (const n of nodes) {
|
|
267
|
-
if (n.key === targetNode)
|
|
268
|
-
return n;
|
|
269
|
-
if (n.children) {
|
|
270
|
-
const f = findNode(n.children);
|
|
271
|
-
if (f)
|
|
272
|
-
return f;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return null;
|
|
276
|
-
};
|
|
277
|
-
const n = findNode(treeNodes);
|
|
278
|
-
if (!n)
|
|
279
|
-
return;
|
|
280
|
-
const ids = shift ? [key, ...getDescendantIds(key)] : [key];
|
|
281
|
-
if (!next.has(key))
|
|
282
|
-
ids.forEach((id) => next.add(id));
|
|
283
|
-
else
|
|
284
|
-
ids.forEach((id) => next.delete(id));
|
|
285
|
-
setSelectedItemIds(next);
|
|
286
|
-
// Update completion when user changes selection
|
|
287
|
-
onStepCompleted(next.size > 0);
|
|
288
|
-
}, renderNode: (node) => {
|
|
289
|
-
const isChecked = selectedItemIds.has(node.key);
|
|
290
|
-
const icon = node?.data?.icon;
|
|
291
|
-
return (_jsxs("div", { className: "flex items-center gap-2", children: [icon && (_jsx("img", { src: icon, alt: "", className: "w-4 h-4" })), _jsx("input", { type: "checkbox", checked: isChecked, "data-testid": `tree-item-checkbox-${node.key}`, onMouseDown: (e) => {
|
|
292
|
-
shiftToggleRef.current = e.shiftKey;
|
|
293
|
-
}, onChange: (e) => {
|
|
294
|
-
if (!isActive)
|
|
295
|
-
return;
|
|
296
|
-
setUserHasInteracted(true);
|
|
297
|
-
const next = new Set(selectedItemIds);
|
|
298
|
-
const withDesc = shiftToggleRef.current && (node.children?.length ?? 0) > 0;
|
|
299
|
-
const ids = withDesc ? [node.key, ...getDescendantIds(node.key)] : [node.key];
|
|
300
|
-
if (e.currentTarget.checked)
|
|
301
|
-
ids.forEach((id) => next.add(id));
|
|
302
|
-
else
|
|
303
|
-
ids.forEach((id) => next.delete(id));
|
|
304
|
-
setSelectedItemIds(next);
|
|
305
|
-
shiftToggleRef.current = false;
|
|
306
|
-
// Update completion when user changes selection
|
|
307
|
-
onStepCompleted(next.size > 0);
|
|
308
|
-
} }), _jsx("span", { children: node.label })] }));
|
|
309
|
-
} }) }))] })) : isDiscovering ? (
|
|
310
|
-
// Loading skeleton for discovery results
|
|
311
|
-
_jsxs("div", { className: "flex w-full min-w-0 flex-col", 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: "mb-3 flex flex-col gap-2", children: [_jsx("div", { className: "h-6 bg-[var(--color-gray-3)] rounded w-48 animate-pulse" }), _jsx("div", { className: "h-4 bg-[var(--color-gray-3)] rounded w-40 animate-pulse" }), _jsxs("div", { className: "flex flex-wrap 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 shrink-0 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))) }) })] })] })) : (
|
|
312
|
-
// Empty state
|
|
313
|
-
_jsx("div", { className: "flex h-80 shrink-0 items-center justify-center overflow-auto rounded-lg border border-[var(--color-gray-3)] 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" })] }) })) })] })] }));
|
|
297
|
+
const next = new Set(selectedItemIds);
|
|
298
|
+
const withDesc = shiftToggleRef.current && (node.children?.length ?? 0) > 0;
|
|
299
|
+
const ids = withDesc ? [node.key, ...getDescendantIds(node.key)] : [node.key];
|
|
300
|
+
if (e.currentTarget.checked)
|
|
301
|
+
ids.forEach((id) => next.add(id));
|
|
302
|
+
else
|
|
303
|
+
ids.forEach((id) => next.delete(id));
|
|
304
|
+
setSelectedItemIds(next);
|
|
305
|
+
shiftToggleRef.current = false;
|
|
306
|
+
// Update completion when user changes selection
|
|
307
|
+
onStepCompleted(next.size > 0);
|
|
308
|
+
} }), _jsx("span", { children: node.label })] }));
|
|
309
|
+
} }) }))] })) : isDiscovering ? (
|
|
310
|
+
// Loading skeleton for discovery results
|
|
311
|
+
_jsxs("div", { className: "flex w-full min-w-0 flex-col", 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: "mb-3 flex flex-col gap-2", children: [_jsx("div", { className: "h-6 bg-[var(--color-gray-3)] rounded w-48 animate-pulse" }), _jsx("div", { className: "h-4 bg-[var(--color-gray-3)] rounded w-40 animate-pulse" }), _jsxs("div", { className: "flex flex-wrap 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 shrink-0 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))) }) })] })] })) : (
|
|
312
|
+
// Empty state
|
|
313
|
+
_jsx("div", { className: "flex h-80 shrink-0 items-center justify-center overflow-auto rounded-lg border border-[var(--color-gray-3)] 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" })] }) })) })] }) }));
|
|
314
314
|
}
|