@focus-reactive/payload-plugin-translator 0.7.2 → 0.8.0
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/README.md +18 -3
- package/dist/client/entities/translation/api/mutations/useDismissStaleness.d.ts +12 -0
- package/dist/client/entities/translation/api/mutations/useDismissStaleness.js +40 -0
- package/dist/client/entities/translation/api/mutations/useQueueDocumentTranslation.js +6 -0
- package/dist/client/entities/translation/api/mutations/useRunDocumentTranslation.js +6 -0
- package/dist/client/entities/translation/api/queries/useDocumentStaleness.d.ts +17 -0
- package/dist/client/entities/translation/api/queries/useDocumentStaleness.js +35 -0
- package/dist/client/entities/translation/api/queries/useDocumentTranslation.js +23 -1
- package/dist/client/entities/translation/index.d.ts +12 -5
- package/dist/client/entities/translation/index.js +10 -5
- package/dist/client/entities/translation/model/panelStatus.d.ts +60 -0
- package/dist/client/entities/translation/model/panelStatus.js +101 -0
- package/dist/client/entities/translation/model/statusRows.d.ts +42 -0
- package/dist/client/entities/translation/model/statusRows.js +79 -0
- package/dist/client/entities/translation/model/types.d.ts +11 -0
- package/dist/client/entities/translation/model/types.js +1 -1
- package/dist/client/entities/translation/ui/ActionButton/ActionButton.d.ts +14 -0
- package/dist/client/entities/translation/ui/ActionButton/ActionButton.js +28 -0
- package/dist/client/entities/translation/ui/ActionButton/index.d.ts +1 -0
- package/dist/client/entities/translation/ui/ActionButton/index.js +3 -0
- package/dist/client/entities/translation/ui/ActionButton/styles.module.scss +11 -0
- package/dist/client/entities/translation/ui/PanelStatusMarker/PanelStatusMarker.d.ts +12 -0
- package/dist/client/entities/translation/ui/PanelStatusMarker/PanelStatusMarker.js +26 -0
- package/dist/client/entities/translation/ui/PanelStatusMarker/index.d.ts +1 -0
- package/dist/client/entities/translation/ui/PanelStatusMarker/index.js +3 -0
- package/dist/client/entities/translation/ui/PanelStatusMarker/styles.module.scss +12 -0
- package/dist/client/entities/translation/ui/TranslationDirection/styles.module.scss +2 -2
- package/dist/client/entities/translation/ui/TranslationStatusList/StatusBadge.d.ts +10 -0
- package/dist/client/entities/translation/ui/TranslationStatusList/StatusBadge.js +27 -0
- package/dist/client/entities/translation/ui/TranslationStatusList/TranslationStatusList.d.ts +14 -0
- package/dist/client/entities/translation/ui/TranslationStatusList/TranslationStatusList.js +194 -0
- package/dist/client/entities/translation/ui/TranslationStatusList/index.d.ts +1 -0
- package/dist/client/entities/translation/ui/TranslationStatusList/index.js +3 -0
- package/dist/client/entities/translation/ui/TranslationStatusList/styles.module.scss +72 -0
- package/dist/client/features/collection-translation-form/ui/CollectionTranslationForm.js +17 -21
- package/dist/client/features/collection-translation-form/ui/styles.module.scss +14 -14
- package/dist/client/features/collection-translation-popup/ui/CollectionTranslationPopup.d.ts +4 -2
- package/dist/client/features/collection-translation-popup/ui/CollectionTranslationPopup.js +9 -9
- package/dist/client/features/collection-translation-popup/ui/styles.module.scss +5 -3
- package/dist/client/features/collection-translation-progress/ui/CollectionTranslationProgress.d.ts +5 -1
- package/dist/client/features/collection-translation-progress/ui/CollectionTranslationProgress.js +100 -93
- package/dist/client/features/collection-translation-progress/ui/styles.module.scss +52 -3
- package/dist/client/features/open-document-translation-popup/ui/OpenDocumentTranslationPopup.d.ts +4 -1
- package/dist/client/features/open-document-translation-popup/ui/OpenDocumentTranslationPopup.js +16 -5
- package/dist/client/features/open-document-translation-popup/ui/styles.module.scss +5 -3
- package/dist/client/features/translate-document-form/ui/DocumentTranslationForm.js +5 -2
- package/dist/client/features/translate-document-form/ui/styles.module.scss +8 -2
- package/dist/client/shared/lib/assets/icons/AlertTriangleIcon.d.ts +1 -0
- package/dist/client/shared/lib/assets/icons/AlertTriangleIcon.js +14 -0
- package/dist/client/shared/lib/assets/icons/CheckIcon.d.ts +1 -0
- package/dist/client/shared/lib/assets/icons/CheckIcon.js +17 -0
- package/dist/client/shared/lib/assets/icons/CloseIcon.d.ts +1 -0
- package/dist/client/shared/lib/assets/icons/CloseIcon.js +16 -0
- package/dist/client/shared/ui/Button/Button.js +2 -1
- package/dist/client/shared/ui/ColorIndicator/ColorIndicator.d.ts +1 -1
- package/dist/client/shared/ui/ColorIndicator/styles.module.scss +4 -0
- package/dist/client/shared/ui/Label/Label.d.ts +2 -0
- package/dist/client/shared/ui/Label/Label.js +3 -2
- package/dist/client/shared/ui/Label/styles.module.scss +11 -0
- package/dist/client/shared/ui/Loading/Loading.d.ts +6 -2
- package/dist/client/shared/ui/Loading/Loading.js +4 -2
- package/dist/client/shared/ui/Loading/barCount.d.ts +3 -0
- package/dist/client/shared/ui/Loading/barCount.js +11 -0
- package/dist/client/shared/ui/Loading/styles.module.scss +20 -27
- package/dist/client/shared/ui/Popup/Popup.js +3 -0
- package/dist/client/shared/ui/Select/Select.js +1 -1
- package/dist/client/shared/ui/form/FormSelect/FormSelect.js +1 -0
- package/dist/client/widgets/bulk-translation-dashboard/ui/BulkTranslationDashboard.js +37 -17
- package/dist/client/widgets/bulk-translation-dashboard/ui/styles.module.scss +27 -0
- package/dist/client/widgets/translate-document/ui/TranslateDocument.js +53 -27
- package/dist/client/widgets/translate-document/ui/styles.module.scss +27 -0
- package/dist/composition/levels/useDocTranslationApi.d.ts +3 -2
- package/dist/composition/levels/useDocTranslationApi.js +6 -3
- package/dist/core/provenance/ProvenanceStore.interface.d.ts +18 -0
- package/dist/core/provenance/index.d.ts +1 -0
- package/dist/core/provenance/index.js +1 -1
- package/dist/core/provenance/staleness.d.ts +19 -0
- package/dist/core/provenance/staleness.js +21 -0
- package/dist/plugin.js +2 -1
- package/dist/server/features/_lib/sourceDocument.d.ts +9 -0
- package/dist/server/features/_lib/sourceDocument.js +16 -0
- package/dist/server/features/createTranslationRoutes.d.ts +12 -4
- package/dist/server/features/createTranslationRoutes.js +15 -5
- package/dist/server/features/get-document-status/model.js +7 -2
- package/dist/server/features/staleness/dismissStaleness.handler.d.ts +8 -0
- package/dist/server/features/staleness/dismissStaleness.handler.js +27 -0
- package/dist/server/features/staleness/getDocumentStaleness.handler.d.ts +12 -0
- package/dist/server/features/staleness/getDocumentStaleness.handler.js +43 -0
- package/dist/server/features/staleness/index.d.ts +2 -0
- package/dist/server/features/staleness/index.js +3 -0
- package/dist/server/features/staleness/model.d.ts +52 -0
- package/dist/server/features/staleness/model.js +17 -0
- package/dist/server/features/staleness/route.d.ts +7 -0
- package/dist/server/features/staleness/route.js +21 -0
- package/dist/server/features/staleness/service.d.ts +15 -0
- package/dist/server/features/staleness/service.js +78 -0
- package/dist/server/features/translate-document/handler.js +22 -8
- package/dist/server/modules/provenance/PayloadProvenanceStore.d.ts +2 -0
- package/dist/server/modules/provenance/PayloadProvenanceStore.js +37 -14
- package/dist/server/modules/translation-levels/PluginConfigBuilder.d.ts +3 -0
- package/dist/server/modules/translation-levels/PluginConfigBuilder.js +2 -0
- package/dist/server/modules/translation-levels/types.d.ts +3 -0
- package/dist/server/shared/http/index.d.ts +1 -0
- package/dist/server/shared/http/index.js +1 -0
- package/dist/server/shared/http/toClientErrorMessage.d.ts +15 -0
- package/dist/server/shared/http/toClientErrorMessage.js +26 -0
- package/dist/server/shared/index.d.ts +1 -1
- package/dist/server/shared/index.js +1 -1
- package/package.json +1 -1
- package/dist/client/entities/translation/ui/CompletedTranslationStatus/CompletedTranslationStatus.d.ts +0 -7
- package/dist/client/entities/translation/ui/CompletedTranslationStatus/CompletedTranslationStatus.js +0 -45
- package/dist/client/entities/translation/ui/CompletedTranslationStatus/index.d.ts +0 -1
- package/dist/client/entities/translation/ui/CompletedTranslationStatus/index.js +0 -3
- package/dist/client/entities/translation/ui/CompletedTranslationStatus/styles.module.scss +0 -3
- package/dist/client/entities/translation/ui/FailedTranslationStatus/FailedTranslationStatus.d.ts +0 -9
- package/dist/client/entities/translation/ui/FailedTranslationStatus/FailedTranslationStatus.js +0 -54
- package/dist/client/entities/translation/ui/FailedTranslationStatus/index.d.ts +0 -1
- package/dist/client/entities/translation/ui/FailedTranslationStatus/index.js +0 -3
- package/dist/client/entities/translation/ui/FailedTranslationStatus/styles.module.scss +0 -3
- package/dist/client/entities/translation/ui/PendingTranslationStatus/PendingTranslationStatus.d.ts +0 -11
- package/dist/client/entities/translation/ui/PendingTranslationStatus/PendingTranslationStatus.js +0 -83
- package/dist/client/entities/translation/ui/PendingTranslationStatus/index.d.ts +0 -1
- package/dist/client/entities/translation/ui/PendingTranslationStatus/index.js +0 -3
- package/dist/client/entities/translation/ui/RunningTranslationStatus/RunningTranslationStatus.d.ts +0 -10
- package/dist/client/entities/translation/ui/RunningTranslationStatus/RunningTranslationStatus.js +0 -66
- package/dist/client/entities/translation/ui/RunningTranslationStatus/index.d.ts +0 -1
- package/dist/client/entities/translation/ui/RunningTranslationStatus/index.js +0 -3
- package/dist/client/features/document-translation-progress-failed/index.d.ts +0 -1
- package/dist/client/features/document-translation-progress-failed/index.js +0 -3
- package/dist/client/features/document-translation-progress-failed/ui/DocumentTranslationProgressFailed.d.ts +0 -6
- package/dist/client/features/document-translation-progress-failed/ui/DocumentTranslationProgressFailed.js +0 -28
- package/dist/client/features/document-translation-progress-pending/index.d.ts +0 -1
- package/dist/client/features/document-translation-progress-pending/index.js +0 -3
- package/dist/client/features/document-translation-progress-pending/ui/DocumentTranslationProgressPending.d.ts +0 -6
- package/dist/client/features/document-translation-progress-pending/ui/DocumentTranslationProgressPending.js +0 -44
- package/dist/client/features/document-translation-progress-running/index.d.ts +0 -1
- package/dist/client/features/document-translation-progress-running/index.js +0 -3
- package/dist/client/features/document-translation-progress-running/ui/DocumentTranslationProgressRunning.d.ts +0 -6
- package/dist/client/features/document-translation-progress-running/ui/DocumentTranslationProgressRunning.js +0 -28
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// `button.action` (element + class) outranks the Button variant's own single-class rules, so the
|
|
2
|
+
// neutral colour + visible border win regardless of stylesheet order.
|
|
3
|
+
button.action {
|
|
4
|
+
color: var(--theme-elevation-600, #666);
|
|
5
|
+
border: 1px solid var(--theme-elevation-150, #d9d9d9);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
button.action:hover:not(:disabled) {
|
|
9
|
+
color: var(--theme-text, #222);
|
|
10
|
+
border-color: var(--theme-elevation-300, #b3b3b3);
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MarkerTone } from "../../model/panelStatus";
|
|
2
|
+
/**
|
|
3
|
+
* The aggregate status dot overlaid on a translate trigger's top-right corner. Uses the SAME
|
|
4
|
+
* coloured-dot vocabulary as the popup's per-locale status list ({@link MARKER_DOT}), so the panel
|
|
5
|
+
* badge and the popup rows read as one system. Shared by the document and collection triggers.
|
|
6
|
+
*
|
|
7
|
+
* Colour is not the sole cue: the host button carries a `title` + `aria-label` naming the exact
|
|
8
|
+
* state for assistive tech (this dot is `aria-hidden`), and in-progress carries a pulse.
|
|
9
|
+
*/
|
|
10
|
+
export declare function PanelStatusMarker({ tone }: {
|
|
11
|
+
tone?: MarkerTone;
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import ColorIndicator from "../../../../shared/ui/ColorIndicator";
|
|
3
|
+
import { MARKER_DOT } from "../../model/panelStatus";
|
|
4
|
+
import styles from "./styles.module.scss";
|
|
5
|
+
/**
|
|
6
|
+
* The aggregate status dot overlaid on a translate trigger's top-right corner. Uses the SAME
|
|
7
|
+
* coloured-dot vocabulary as the popup's per-locale status list ({@link MARKER_DOT}), so the panel
|
|
8
|
+
* badge and the popup rows read as one system. Shared by the document and collection triggers.
|
|
9
|
+
*
|
|
10
|
+
* Colour is not the sole cue: the host button carries a `title` + `aria-label` naming the exact
|
|
11
|
+
* state for assistive tech (this dot is `aria-hidden`), and in-progress carries a pulse.
|
|
12
|
+
*/ export function PanelStatusMarker({ tone }) {
|
|
13
|
+
if (!tone) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return /*#__PURE__*/ _jsx("span", {
|
|
17
|
+
className: styles.marker,
|
|
18
|
+
"aria-hidden": "true",
|
|
19
|
+
children: /*#__PURE__*/ _jsx(ColorIndicator, {
|
|
20
|
+
$color: MARKER_DOT[tone].color,
|
|
21
|
+
$animated: MARKER_DOT[tone].animated
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=PanelStatusMarker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PanelStatusMarker } from "./PanelStatusMarker";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Aggregate status dot at the trigger's top-right corner. Positioning + a ring in the panel
|
|
2
|
+
// background so the dot reads as a badge against the button fill.
|
|
3
|
+
.marker {
|
|
4
|
+
position: absolute;
|
|
5
|
+
top: -2px;
|
|
6
|
+
right: -2px;
|
|
7
|
+
display: flex;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.marker > div {
|
|
11
|
+
box-shadow: 0 0 0 2px var(--theme-elevation-0, #fff);
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TranslationRowState } from "../../model/statusRows";
|
|
2
|
+
/** Human label per state — also the row's accessible name (state is not conveyed by colour alone). */
|
|
3
|
+
export declare const STATE_LABEL: Record<TranslationRowState, string>;
|
|
4
|
+
/**
|
|
5
|
+
* Small per-row status dot. The colour is a secondary cue only — every row carries the state as
|
|
6
|
+
* text ({@link STATE_LABEL}) in its meta line, so the dot never conveys state by colour alone.
|
|
7
|
+
*/
|
|
8
|
+
export declare function StatusBadge({ state }: {
|
|
9
|
+
state: TranslationRowState;
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import ColorIndicator from "../../../../shared/ui/ColorIndicator";
|
|
3
|
+
import { STATE_DOT } from "../../model/statusRows";
|
|
4
|
+
import styles from "./styles.module.scss";
|
|
5
|
+
/** Human label per state — also the row's accessible name (state is not conveyed by colour alone). */ export const STATE_LABEL = {
|
|
6
|
+
failed: "Failed",
|
|
7
|
+
running: "Translating",
|
|
8
|
+
pending: "Queued",
|
|
9
|
+
stale: "Out of date",
|
|
10
|
+
translated: "Translated"
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Small per-row status dot. The colour is a secondary cue only — every row carries the state as
|
|
14
|
+
* text ({@link STATE_LABEL}) in its meta line, so the dot never conveys state by colour alone.
|
|
15
|
+
*/ export function StatusBadge({ state }) {
|
|
16
|
+
const dot = STATE_DOT[state];
|
|
17
|
+
return /*#__PURE__*/ _jsx("span", {
|
|
18
|
+
className: styles.badge,
|
|
19
|
+
"aria-hidden": "true",
|
|
20
|
+
children: /*#__PURE__*/ _jsx(ColorIndicator, {
|
|
21
|
+
$color: dot.color,
|
|
22
|
+
$animated: dot.animated
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=StatusBadge.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CollectionSlug } from "payload";
|
|
2
|
+
import type { TranslationStatusRow } from "../../model/statusRows";
|
|
3
|
+
type TranslationStatusListProps = {
|
|
4
|
+
rows: TranslationStatusRow[];
|
|
5
|
+
collection: CollectionSlug;
|
|
6
|
+
id: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* The unified per-locale status list: one consistent row per target locale
|
|
10
|
+
* (`[badge] [en→fr] [when] [action]`). Replaces the old corner chip, the "out of date" column, and
|
|
11
|
+
* the separate running/pending/failed chips. Row actions reuse the existing mutation hooks.
|
|
12
|
+
*/
|
|
13
|
+
export declare function TranslationStatusList({ rows, collection, id }: TranslationStatusListProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { toast } from "@payloadcms/ui";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { CheckIcon } from "../../../../shared/lib/assets/icons/CheckIcon";
|
|
5
|
+
import { CloseIcon } from "../../../../shared/lib/assets/icons/CloseIcon";
|
|
6
|
+
import { ReloadIcon } from "../../../../shared/lib/assets/icons/ReloadIcon";
|
|
7
|
+
import { useCancelDocumentTranslation } from "../../api/mutations/useCancelDocumentTranslation";
|
|
8
|
+
import { useDismissStaleness } from "../../api/mutations/useDismissStaleness";
|
|
9
|
+
import { useQueueDocumentTranslation } from "../../api/mutations/useQueueDocumentTranslation";
|
|
10
|
+
import { useRunDocumentTranslation } from "../../api/mutations/useRunDocumentTranslation";
|
|
11
|
+
import { ActionButton } from "../ActionButton";
|
|
12
|
+
import { TranslationDirection } from "../TranslationDirection";
|
|
13
|
+
import { STATE_LABEL, StatusBadge } from "./StatusBadge";
|
|
14
|
+
import styles from "./styles.module.scss";
|
|
15
|
+
const shortDate = (iso)=>new Date(iso).toLocaleDateString(undefined, {
|
|
16
|
+
month: "short",
|
|
17
|
+
day: "numeric"
|
|
18
|
+
});
|
|
19
|
+
const fullDate = (iso)=>new Date(iso).toLocaleString(undefined, {
|
|
20
|
+
year: "numeric",
|
|
21
|
+
month: "short",
|
|
22
|
+
day: "numeric",
|
|
23
|
+
hour: "2-digit",
|
|
24
|
+
minute: "2-digit"
|
|
25
|
+
});
|
|
26
|
+
const withToast = async (run, fallback)=>{
|
|
27
|
+
try {
|
|
28
|
+
await run();
|
|
29
|
+
} catch (e) {
|
|
30
|
+
toast.error(e instanceof Error ? e.message : fallback);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The unified per-locale status list: one consistent row per target locale
|
|
35
|
+
* (`[badge] [en→fr] [when] [action]`). Replaces the old corner chip, the "out of date" column, and
|
|
36
|
+
* the separate running/pending/failed chips. Row actions reuse the existing mutation hooks.
|
|
37
|
+
*/ export function TranslationStatusList({ rows, collection, id }) {
|
|
38
|
+
const runApi = useRunDocumentTranslation();
|
|
39
|
+
const cancelApi = useCancelDocumentTranslation();
|
|
40
|
+
const dismissApi = useDismissStaleness();
|
|
41
|
+
const queueApi = useQueueDocumentTranslation();
|
|
42
|
+
const [dismissing, setDismissing] = useState(new Set());
|
|
43
|
+
const dismiss = async (targetLocale)=>{
|
|
44
|
+
setDismissing((prev)=>new Set(prev).add(targetLocale));
|
|
45
|
+
await withToast(()=>dismissApi.mutateAsync({
|
|
46
|
+
collection,
|
|
47
|
+
id,
|
|
48
|
+
target_lng: targetLocale
|
|
49
|
+
}), "Failed to dismiss out-of-date notice");
|
|
50
|
+
setDismissing((prev)=>{
|
|
51
|
+
const next = new Set(prev);
|
|
52
|
+
next.delete(targetLocale);
|
|
53
|
+
return next;
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
// Re-translate one locale in place: a fresh source→target job (overwrite). Reuses the same queue
|
|
57
|
+
// endpoint as the form; onSuccess invalidation refreshes this list.
|
|
58
|
+
const reTranslate = (row)=>withToast(()=>queueApi.mutateAsync({
|
|
59
|
+
source_lng: row.sourceLocale,
|
|
60
|
+
target_lng: row.targetLocale,
|
|
61
|
+
collection_slug: collection,
|
|
62
|
+
collection_id: [
|
|
63
|
+
id
|
|
64
|
+
],
|
|
65
|
+
strategy: "overwrite"
|
|
66
|
+
}), "Failed to queue translation");
|
|
67
|
+
const retry = (row)=>row.jobId && withToast(()=>runApi.mutateAsync({
|
|
68
|
+
id: row.jobId
|
|
69
|
+
}), "Error retrying");
|
|
70
|
+
const runNow = (row)=>row.jobId && withToast(()=>runApi.mutateAsync({
|
|
71
|
+
id: row.jobId
|
|
72
|
+
}), "Error running");
|
|
73
|
+
const cancel = (row)=>row.jobId && withToast(()=>cancelApi.mutateAsync({
|
|
74
|
+
id: row.jobId
|
|
75
|
+
}), "Error cancelling");
|
|
76
|
+
const renderAction = (row)=>{
|
|
77
|
+
switch(row.state){
|
|
78
|
+
case "failed":
|
|
79
|
+
return /*#__PURE__*/ _jsx("span", {
|
|
80
|
+
className: styles.actions,
|
|
81
|
+
children: /*#__PURE__*/ _jsx(ActionButton, {
|
|
82
|
+
icon: /*#__PURE__*/ _jsx(ReloadIcon, {}),
|
|
83
|
+
title: "Retry",
|
|
84
|
+
onClick: ()=>retry(row),
|
|
85
|
+
loading: runApi.isPending
|
|
86
|
+
})
|
|
87
|
+
});
|
|
88
|
+
case "running":
|
|
89
|
+
return /*#__PURE__*/ _jsx("span", {
|
|
90
|
+
className: styles.actions,
|
|
91
|
+
children: /*#__PURE__*/ _jsx(ActionButton, {
|
|
92
|
+
icon: /*#__PURE__*/ _jsx(CloseIcon, {}),
|
|
93
|
+
title: "Cancel",
|
|
94
|
+
onClick: ()=>cancel(row),
|
|
95
|
+
loading: cancelApi.isPending
|
|
96
|
+
})
|
|
97
|
+
});
|
|
98
|
+
case "pending":
|
|
99
|
+
return /*#__PURE__*/ _jsxs("span", {
|
|
100
|
+
className: styles.actions,
|
|
101
|
+
children: [
|
|
102
|
+
/*#__PURE__*/ _jsx(ActionButton, {
|
|
103
|
+
icon: /*#__PURE__*/ _jsx(ReloadIcon, {}),
|
|
104
|
+
title: "Run now",
|
|
105
|
+
onClick: ()=>runNow(row),
|
|
106
|
+
loading: runApi.isPending
|
|
107
|
+
}),
|
|
108
|
+
/*#__PURE__*/ _jsx(ActionButton, {
|
|
109
|
+
icon: /*#__PURE__*/ _jsx(CloseIcon, {}),
|
|
110
|
+
title: "Cancel",
|
|
111
|
+
onClick: ()=>cancel(row),
|
|
112
|
+
loading: cancelApi.isPending
|
|
113
|
+
})
|
|
114
|
+
]
|
|
115
|
+
});
|
|
116
|
+
case "stale":
|
|
117
|
+
return /*#__PURE__*/ _jsxs("span", {
|
|
118
|
+
className: styles.actions,
|
|
119
|
+
children: [
|
|
120
|
+
/*#__PURE__*/ _jsx(ActionButton, {
|
|
121
|
+
icon: /*#__PURE__*/ _jsx(ReloadIcon, {}),
|
|
122
|
+
title: `Re-translate from ${row.sourceLocale}`,
|
|
123
|
+
onClick: ()=>reTranslate(row),
|
|
124
|
+
loading: queueApi.isPending
|
|
125
|
+
}),
|
|
126
|
+
/*#__PURE__*/ _jsx(ActionButton, {
|
|
127
|
+
icon: /*#__PURE__*/ _jsx(CheckIcon, {}),
|
|
128
|
+
title: "Keep as is — hide until the source changes again",
|
|
129
|
+
onClick: ()=>dismiss(row.targetLocale),
|
|
130
|
+
disabled: dismissing.has(row.targetLocale),
|
|
131
|
+
loading: dismissing.has(row.targetLocale)
|
|
132
|
+
})
|
|
133
|
+
]
|
|
134
|
+
});
|
|
135
|
+
default:
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
return /*#__PURE__*/ _jsx("ul", {
|
|
140
|
+
className: styles.list,
|
|
141
|
+
children: rows.map((row)=>/*#__PURE__*/ _jsxs("li", {
|
|
142
|
+
className: styles.row,
|
|
143
|
+
"aria-label": `${STATE_LABEL[row.state]}: ${row.sourceLocale} to ${row.targetLocale}` + (row.error ? ` — ${row.error}` : ""),
|
|
144
|
+
children: [
|
|
145
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
146
|
+
className: styles.top,
|
|
147
|
+
children: [
|
|
148
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
149
|
+
className: styles.lead,
|
|
150
|
+
children: [
|
|
151
|
+
/*#__PURE__*/ _jsx(StatusBadge, {
|
|
152
|
+
state: row.state
|
|
153
|
+
}),
|
|
154
|
+
/*#__PURE__*/ _jsx(TranslationDirection, {
|
|
155
|
+
sourceLocale: row.sourceLocale,
|
|
156
|
+
targetLocale: row.targetLocale
|
|
157
|
+
})
|
|
158
|
+
]
|
|
159
|
+
}),
|
|
160
|
+
renderAction(row)
|
|
161
|
+
]
|
|
162
|
+
}),
|
|
163
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
164
|
+
className: styles.meta,
|
|
165
|
+
children: [
|
|
166
|
+
/*#__PURE__*/ _jsx("span", {
|
|
167
|
+
children: STATE_LABEL[row.state]
|
|
168
|
+
}),
|
|
169
|
+
row.at && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
170
|
+
children: [
|
|
171
|
+
/*#__PURE__*/ _jsx("span", {
|
|
172
|
+
"aria-hidden": "true",
|
|
173
|
+
children: "·"
|
|
174
|
+
}),
|
|
175
|
+
/*#__PURE__*/ _jsx("time", {
|
|
176
|
+
dateTime: row.at,
|
|
177
|
+
title: fullDate(row.at),
|
|
178
|
+
children: shortDate(row.at)
|
|
179
|
+
})
|
|
180
|
+
]
|
|
181
|
+
})
|
|
182
|
+
]
|
|
183
|
+
}),
|
|
184
|
+
row.state === "failed" && row.error && /*#__PURE__*/ _jsx("p", {
|
|
185
|
+
className: styles.error,
|
|
186
|
+
title: row.error,
|
|
187
|
+
children: row.error
|
|
188
|
+
})
|
|
189
|
+
]
|
|
190
|
+
}, row.targetLocale))
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
//# sourceMappingURL=TranslationStatusList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TranslationStatusList } from "./TranslationStatusList";
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.list {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 0.5rem;
|
|
5
|
+
margin: 0;
|
|
6
|
+
padding: 0;
|
|
7
|
+
list-style: none;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.row {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: 0.125rem;
|
|
14
|
+
font-size: 0.8125rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// First line: [dot + direction] on the left, action on the right.
|
|
18
|
+
.top {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
gap: 0.5rem;
|
|
23
|
+
// Constant first-line height (with or without an action button) keeps vertical rhythm even.
|
|
24
|
+
min-height: 1.5rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Dot + direction share one flex line so they centre together regardless of the action's height.
|
|
28
|
+
.lead {
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
gap: 0.5rem;
|
|
32
|
+
min-width: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.meta {
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
gap: 0.35rem;
|
|
39
|
+
// Align under the direction: dot width (8px) + .lead gap (0.5rem).
|
|
40
|
+
padding-left: calc(8px + 0.5rem);
|
|
41
|
+
font-size: 0.6875rem;
|
|
42
|
+
color: var(--theme-elevation-500, #8c8c8c);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Failure reason for a failed row. Sparing red: a 2px accent rule + red dot carry the semantics,
|
|
46
|
+
// the message text stays caption-neutral so the row never becomes a red block. Clamped to 2 lines;
|
|
47
|
+
// full text lives in the native title (and the row's aria-label).
|
|
48
|
+
.error {
|
|
49
|
+
margin: 0.125rem 0 0 calc(8px + 0.5rem);
|
|
50
|
+
padding-left: 0.5rem;
|
|
51
|
+
border-left: 2px solid var(--theme-error-600, #dc2626);
|
|
52
|
+
font-size: 0.6875rem;
|
|
53
|
+
font-weight: 400;
|
|
54
|
+
line-height: 1.35;
|
|
55
|
+
color: var(--theme-elevation-500, #8c8c8c);
|
|
56
|
+
display: -webkit-box;
|
|
57
|
+
-webkit-line-clamp: 2;
|
|
58
|
+
-webkit-box-orient: vertical;
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Inline wrapper so the dot centres on the direction line via .lead's align-items.
|
|
63
|
+
.badge {
|
|
64
|
+
display: inline-flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
flex-shrink: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.actions {
|
|
70
|
+
display: inline-flex;
|
|
71
|
+
gap: 0.25rem;
|
|
72
|
+
}
|
|
@@ -16,30 +16,22 @@ export function CollectionTranslationForm({ form, onSubmit, selectedCount, hasDr
|
|
|
16
16
|
/*#__PURE__*/ _jsxs("div", {
|
|
17
17
|
className: styles.row,
|
|
18
18
|
children: [
|
|
19
|
-
/*#__PURE__*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
label: "From",
|
|
24
|
-
className: styles["select-locale-field"],
|
|
25
|
-
size: "md",
|
|
26
|
-
name: FORM_FIELDS.SOURCE_LNG
|
|
27
|
-
}),
|
|
28
|
-
/*#__PURE__*/ _jsx(FormSelectLocale, {
|
|
29
|
-
label: "To",
|
|
30
|
-
className: styles["select-locale-field"],
|
|
31
|
-
size: "md",
|
|
32
|
-
name: FORM_FIELDS.TARGET_LNG
|
|
33
|
-
})
|
|
34
|
-
]
|
|
19
|
+
/*#__PURE__*/ _jsx(FormSelectLocale, {
|
|
20
|
+
size: "sm",
|
|
21
|
+
label: "From",
|
|
22
|
+
name: FORM_FIELDS.SOURCE_LNG
|
|
35
23
|
}),
|
|
36
|
-
/*#__PURE__*/ _jsx(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
/*#__PURE__*/ _jsx(FormSelectLocale, {
|
|
25
|
+
size: "sm",
|
|
26
|
+
label: "To",
|
|
27
|
+
name: FORM_FIELDS.TARGET_LNG
|
|
40
28
|
})
|
|
41
29
|
]
|
|
42
30
|
}),
|
|
31
|
+
/*#__PURE__*/ _jsx(FormSelectStrategy, {
|
|
32
|
+
size: "sm",
|
|
33
|
+
name: FORM_FIELDS.STRATEGY
|
|
34
|
+
}),
|
|
43
35
|
hasDrafts && /*#__PURE__*/ _jsx(FormCheckboxPublish, {
|
|
44
36
|
name: FORM_FIELDS.PUBLISH_ON_TRANSLATION
|
|
45
37
|
}),
|
|
@@ -53,10 +45,14 @@ export function CollectionTranslationForm({ form, onSubmit, selectedCount, hasDr
|
|
|
53
45
|
className: styles["submit-button"],
|
|
54
46
|
onClick: form.handleSubmit(onSubmit),
|
|
55
47
|
type: "submit",
|
|
56
|
-
$size: "
|
|
48
|
+
$size: "sm",
|
|
57
49
|
$isLoading: form.formState.isSubmitting,
|
|
58
50
|
$startContent: /*#__PURE__*/ _jsx(SendIcon, {}),
|
|
59
51
|
children: selectedCount ? `Queue ${selectedCount} translations` : "Queue translations"
|
|
52
|
+
}),
|
|
53
|
+
selectedCount === 0 && /*#__PURE__*/ _jsx("p", {
|
|
54
|
+
className: styles.caption,
|
|
55
|
+
children: "Select rows in the list to translate."
|
|
60
56
|
})
|
|
61
57
|
]
|
|
62
58
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.fieldset {
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
|
-
gap: 0.
|
|
4
|
+
gap: 0.5rem;
|
|
5
5
|
border-width: 0;
|
|
6
6
|
margin: 0;
|
|
7
7
|
padding: 0;
|
|
@@ -9,23 +9,23 @@
|
|
|
9
9
|
|
|
10
10
|
.row {
|
|
11
11
|
display: flex;
|
|
12
|
-
|
|
13
|
-
gap: 0.75rem;
|
|
12
|
+
gap: 0.5rem;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.select-locale-field {
|
|
22
|
-
min-width: 70px;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.strategy-field {
|
|
26
|
-
min-width: 150px;
|
|
15
|
+
// From / To share the row equally and are allowed to shrink with the narrow popup.
|
|
16
|
+
.row > * {
|
|
17
|
+
flex: 1 1 0;
|
|
18
|
+
min-width: 0;
|
|
27
19
|
}
|
|
28
20
|
|
|
29
21
|
.submit-button {
|
|
22
|
+
margin: 0;
|
|
30
23
|
width: 100%;
|
|
31
24
|
}
|
|
25
|
+
|
|
26
|
+
// Empty-state hint: only shown when nothing is selected, so the disabled button isn't a dead end.
|
|
27
|
+
.caption {
|
|
28
|
+
margin: 0;
|
|
29
|
+
font-size: 0.6875rem;
|
|
30
|
+
color: var(--theme-elevation-500, #8c8c8c);
|
|
31
|
+
}
|
package/dist/client/features/collection-translation-popup/ui/CollectionTranslationPopup.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { PropsWithChildren } from "react";
|
|
2
|
+
import type { PanelStatus } from "../../../entities/translation";
|
|
2
3
|
type CollectionTranslationPopupProps = PropsWithChildren<{
|
|
3
|
-
|
|
4
|
+
/** Aggregate status across the collection's jobs → the corner marker (same as the document trigger). */
|
|
5
|
+
status?: PanelStatus;
|
|
4
6
|
selectedCount: number;
|
|
5
7
|
}>;
|
|
6
|
-
declare function CollectionTranslationPopup({ children,
|
|
8
|
+
declare function CollectionTranslationPopup({ children, status, selectedCount, }: CollectionTranslationPopupProps): import("react/jsx-runtime").JSX.Element;
|
|
7
9
|
export default CollectionTranslationPopup;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { describePanelStatus, PanelStatusMarker } from "../../../entities/translation";
|
|
3
4
|
import { LanguageTranslateIcon } from "../../../shared/lib/assets/icons/LanguageTranslateIcon";
|
|
4
5
|
import { useToggle } from "../../../shared/lib/utils/react/useToggle";
|
|
5
6
|
import Button from "../../../shared/ui/Button";
|
|
6
|
-
import ColorIndicator from "../../../shared/ui/ColorIndicator";
|
|
7
7
|
import Popup from "../../../shared/ui/Popup";
|
|
8
8
|
import styles from "./styles.module.scss";
|
|
9
|
-
function CollectionTranslationPopup({ children,
|
|
9
|
+
function CollectionTranslationPopup({ children, status, selectedCount }) {
|
|
10
10
|
const [isPopupOpen, popupOpen] = useToggle();
|
|
11
|
+
const { tone, title } = describePanelStatus(status, "Bulk translation");
|
|
11
12
|
return /*#__PURE__*/ _jsx(Popup, {
|
|
12
13
|
$align: "start",
|
|
13
14
|
onOpenChange: popupOpen.setValue,
|
|
@@ -15,16 +16,12 @@ function CollectionTranslationPopup({ children, translationInProgress, selectedC
|
|
|
15
16
|
$size: "md",
|
|
16
17
|
$variant: "outlined-light",
|
|
17
18
|
className: styles["popup-trigger-button"],
|
|
18
|
-
"aria-label":
|
|
19
|
+
"aria-label": `Open translation options — ${title}`,
|
|
20
|
+
title: title,
|
|
19
21
|
onClick: popupOpen.setTrue,
|
|
20
22
|
children: [
|
|
21
|
-
translationInProgress && /*#__PURE__*/ _jsx(ColorIndicator, {
|
|
22
|
-
title: "Translations In Progress",
|
|
23
|
-
$animated: true,
|
|
24
|
-
$color: "blue"
|
|
25
|
-
}),
|
|
26
23
|
/*#__PURE__*/ _jsx(LanguageTranslateIcon, {}),
|
|
27
|
-
selectedCount > 0 &&
|
|
24
|
+
selectedCount > 0 && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
28
25
|
children: [
|
|
29
26
|
/*#__PURE__*/ _jsx("span", {
|
|
30
27
|
className: styles.arrow,
|
|
@@ -33,6 +30,9 @@ function CollectionTranslationPopup({ children, translationInProgress, selectedC
|
|
|
33
30
|
}),
|
|
34
31
|
selectedCount
|
|
35
32
|
]
|
|
33
|
+
}),
|
|
34
|
+
/*#__PURE__*/ _jsx(PanelStatusMarker, {
|
|
35
|
+
tone: tone
|
|
36
36
|
})
|
|
37
37
|
]
|
|
38
38
|
}),
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
.popup-content {
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
|
-
gap:
|
|
5
|
-
padding:
|
|
6
|
-
|
|
4
|
+
gap: 0.75rem;
|
|
5
|
+
padding: 0.75rem;
|
|
6
|
+
width: 18rem; // match the document popup — same form shape, so same width
|
|
7
|
+
max-width: calc(100vw - 24px);
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
.popup-trigger-button {
|
|
10
11
|
font-size: 1.3rem;
|
|
11
12
|
display: flex;
|
|
12
13
|
gap: 0.25rem;
|
|
14
|
+
position: relative; // anchor for the corner status marker
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
.arrow {
|
package/dist/client/features/collection-translation-progress/ui/CollectionTranslationProgress.d.ts
CHANGED
|
@@ -4,5 +4,9 @@ type CollectionTranslationProgressProps = {
|
|
|
4
4
|
data: GroupedCollectionTranslationStatus | undefined;
|
|
5
5
|
isPending: boolean;
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Collection status as a compact list of grouped counts — one `[dot] label … count` row per
|
|
9
|
+
* non-zero group, mirroring the document popup's per-locale list rhythm (dot vocabulary shared).
|
|
10
|
+
*/
|
|
11
|
+
export declare function CollectionTranslationProgress({ collection, data, isPending, }: CollectionTranslationProgressProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
12
|
export {};
|