@purposeinplay/payload-ai-translate 0.1.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/LICENSE +21 -0
- package/README.md +714 -0
- package/dist/alerts-collection.d.ts +21 -0
- package/dist/alerts-collection.js +159 -0
- package/dist/api.d.ts +4 -0
- package/dist/api.js +918 -0
- package/dist/bulk-translate-batches-collection.d.ts +29 -0
- package/dist/bulk-translate-batches-collection.js +404 -0
- package/dist/bulk-translate-units-collection.d.ts +35 -0
- package/dist/bulk-translate-units-collection.js +310 -0
- package/dist/client/estimated-cost-cell.d.ts +6 -0
- package/dist/client/estimated-cost-cell.js +12 -0
- package/dist/client/excluded-fields-field.d.ts +45 -0
- package/dist/client/excluded-fields-field.js +553 -0
- package/dist/client/field-translate-button.d.ts +6 -0
- package/dist/client/field-translate-button.js +199 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +6 -0
- package/dist/client/lib/use-global-kill-switches.d.ts +20 -0
- package/dist/client/lib/use-global-kill-switches.js +58 -0
- package/dist/client/translate-button.d.ts +2 -0
- package/dist/client/translate-button.js +228 -0
- package/dist/client/translate-modal.d.ts +16 -0
- package/dist/client/translate-modal.js +549 -0
- package/dist/client/translation-progress.d.ts +10 -0
- package/dist/client/translation-progress.js +297 -0
- package/dist/components/TranslationNavGroup.d.ts +45 -0
- package/dist/components/TranslationNavGroup.js +104 -0
- package/dist/defaults.d.ts +11 -0
- package/dist/defaults.js +16 -0
- package/dist/endpoints/client-config.d.ts +44 -0
- package/dist/endpoints/client-config.js +145 -0
- package/dist/endpoints/estimate.d.ts +5 -0
- package/dist/endpoints/estimate.js +237 -0
- package/dist/endpoints/progress.d.ts +2 -0
- package/dist/endpoints/progress.js +314 -0
- package/dist/endpoints/translate.d.ts +11 -0
- package/dist/endpoints/translate.js +376 -0
- package/dist/endpoints/translation-hub/_helpers.d.ts +140 -0
- package/dist/endpoints/translation-hub/_helpers.js +297 -0
- package/dist/endpoints/translation-hub/active.d.ts +21 -0
- package/dist/endpoints/translation-hub/active.js +220 -0
- package/dist/endpoints/translation-hub/cancel.d.ts +22 -0
- package/dist/endpoints/translation-hub/cancel.js +233 -0
- package/dist/endpoints/translation-hub/enqueue.d.ts +70 -0
- package/dist/endpoints/translation-hub/enqueue.js +529 -0
- package/dist/endpoints/translation-hub/failures.d.ts +12 -0
- package/dist/endpoints/translation-hub/failures.js +67 -0
- package/dist/endpoints/translation-hub/force-reset.d.ts +20 -0
- package/dist/endpoints/translation-hub/force-reset.js +144 -0
- package/dist/endpoints/translation-hub/index.d.ts +21 -0
- package/dist/endpoints/translation-hub/index.js +20 -0
- package/dist/endpoints/translation-hub/list.d.ts +40 -0
- package/dist/endpoints/translation-hub/list.js +182 -0
- package/dist/endpoints/translation-hub/preflight.d.ts +19 -0
- package/dist/endpoints/translation-hub/preflight.js +141 -0
- package/dist/endpoints/translation-hub/retry-failed.d.ts +38 -0
- package/dist/endpoints/translation-hub/retry-failed.js +235 -0
- package/dist/endpoints/translation-hub/revert.d.ts +88 -0
- package/dist/endpoints/translation-hub/revert.js +405 -0
- package/dist/endpoints/translation-hub/status.d.ts +45 -0
- package/dist/endpoints/translation-hub/status.js +391 -0
- package/dist/endpoints/translation-hub/usage-summary.d.ts +114 -0
- package/dist/endpoints/translation-hub/usage-summary.js +481 -0
- package/dist/exports/client.d.ts +6 -0
- package/dist/exports/client.js +6 -0
- package/dist/exports/components.d.ts +6 -0
- package/dist/exports/components.js +5 -0
- package/dist/exports/index.d.ts +8 -0
- package/dist/exports/index.js +7 -0
- package/dist/exports/providers.d.ts +9 -0
- package/dist/exports/providers.js +5 -0
- package/dist/exports/views-client.d.ts +23 -0
- package/dist/exports/views-client.js +22 -0
- package/dist/exports/views.d.ts +30 -0
- package/dist/exports/views.js +29 -0
- package/dist/hooks/after-change-global.d.ts +4 -0
- package/dist/hooks/after-change-global.js +109 -0
- package/dist/hooks/after-change.d.ts +16 -0
- package/dist/hooks/after-change.js +205 -0
- package/dist/hooks/after-delete.d.ts +30 -0
- package/dist/hooks/after-delete.js +95 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/jobs-collection.d.ts +17 -0
- package/dist/jobs-collection.js +139 -0
- package/dist/lexical/classifier.d.ts +3 -0
- package/dist/lexical/classifier.js +108 -0
- package/dist/lexical/deserializer.d.ts +4 -0
- package/dist/lexical/deserializer.js +263 -0
- package/dist/lexical/placeholder-integrity.d.ts +6 -0
- package/dist/lexical/placeholder-integrity.js +21 -0
- package/dist/lexical/placeholders.d.ts +21 -0
- package/dist/lexical/placeholders.js +117 -0
- package/dist/lexical/serializer.d.ts +21 -0
- package/dist/lexical/serializer.js +233 -0
- package/dist/lexical/types.d.ts +32 -0
- package/dist/lexical/types.js +1 -0
- package/dist/lib/auth-diagnostics.d.ts +14 -0
- package/dist/lib/auth-diagnostics.js +19 -0
- package/dist/lib/batch-counts.d.ts +58 -0
- package/dist/lib/batch-counts.js +105 -0
- package/dist/lib/bulk-translate-migrations.d.ts +92 -0
- package/dist/lib/bulk-translate-migrations.js +153 -0
- package/dist/lib/coalescing-queue.d.ts +38 -0
- package/dist/lib/coalescing-queue.js +69 -0
- package/dist/lib/content-extractor.d.ts +16 -0
- package/dist/lib/content-extractor.js +410 -0
- package/dist/lib/content-hash.d.ts +1 -0
- package/dist/lib/content-hash.js +19 -0
- package/dist/lib/content-patcher.d.ts +15 -0
- package/dist/lib/content-patcher.js +293 -0
- package/dist/lib/cost-guards.d.ts +2 -0
- package/dist/lib/cost-guards.js +18 -0
- package/dist/lib/daily-spend-cap.d.ts +58 -0
- package/dist/lib/daily-spend-cap.js +233 -0
- package/dist/lib/effective-locales.d.ts +181 -0
- package/dist/lib/effective-locales.js +302 -0
- package/dist/lib/error-messages.d.ts +245 -0
- package/dist/lib/error-messages.js +626 -0
- package/dist/lib/events.d.ts +39 -0
- package/dist/lib/events.js +146 -0
- package/dist/lib/exclude-fields.d.ts +3 -0
- package/dist/lib/exclude-fields.js +64 -0
- package/dist/lib/field-breadcrumb.d.ts +31 -0
- package/dist/lib/field-breadcrumb.js +227 -0
- package/dist/lib/field-diff.d.ts +1 -0
- package/dist/lib/field-diff.js +25 -0
- package/dist/lib/field-empty.d.ts +2 -0
- package/dist/lib/field-empty.js +68 -0
- package/dist/lib/field-resolver.d.ts +3 -0
- package/dist/lib/field-resolver.js +164 -0
- package/dist/lib/group-soft-skips.d.ts +39 -0
- package/dist/lib/group-soft-skips.js +45 -0
- package/dist/lib/locale-merge.d.ts +44 -0
- package/dist/lib/locale-merge.js +357 -0
- package/dist/lib/locale-row-check.d.ts +30 -0
- package/dist/lib/locale-row-check.js +64 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +97 -0
- package/dist/lib/manual-edit-guard.d.ts +128 -0
- package/dist/lib/manual-edit-guard.js +393 -0
- package/dist/lib/output-validation.d.ts +48 -0
- package/dist/lib/output-validation.js +148 -0
- package/dist/lib/payload-read.d.ts +16 -0
- package/dist/lib/payload-read.js +51 -0
- package/dist/lib/per-doc-claim.d.ts +90 -0
- package/dist/lib/per-doc-claim.js +140 -0
- package/dist/lib/per-doc-lock.d.ts +94 -0
- package/dist/lib/per-doc-lock.js +119 -0
- package/dist/lib/persist-usage.d.ts +91 -0
- package/dist/lib/persist-usage.js +116 -0
- package/dist/lib/progress-store.d.ts +103 -0
- package/dist/lib/progress-store.js +314 -0
- package/dist/lib/rate-limiter.d.ts +3 -0
- package/dist/lib/rate-limiter.js +53 -0
- package/dist/lib/snapshot-select.d.ts +43 -0
- package/dist/lib/snapshot-select.js +108 -0
- package/dist/lib/translate-prompt.d.ts +31 -0
- package/dist/lib/translate-prompt.js +66 -0
- package/dist/lib/translation-token-bucket.d.ts +57 -0
- package/dist/lib/translation-token-bucket.js +365 -0
- package/dist/lib/truncate-source-value.d.ts +1 -0
- package/dist/lib/truncate-source-value.js +27 -0
- package/dist/manual-edit-collection.d.ts +22 -0
- package/dist/manual-edit-collection.js +124 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +934 -0
- package/dist/providers/ai-sdk-adapter.d.ts +35 -0
- package/dist/providers/ai-sdk-adapter.js +100 -0
- package/dist/providers/anthropic.d.ts +31 -0
- package/dist/providers/anthropic.js +66 -0
- package/dist/providers/custom.d.ts +36 -0
- package/dist/providers/custom.js +24 -0
- package/dist/providers/gemini.d.ts +20 -0
- package/dist/providers/gemini.js +48 -0
- package/dist/providers/mock.d.ts +2 -0
- package/dist/providers/mock.js +29 -0
- package/dist/providers/openai.d.ts +28 -0
- package/dist/providers/openai.js +69 -0
- package/dist/settings-global.d.ts +74 -0
- package/dist/settings-global.js +216 -0
- package/dist/tasks/bulk-translate-coordinator.d.ts +115 -0
- package/dist/tasks/bulk-translate-coordinator.js +708 -0
- package/dist/tasks/bulk-translate-doc-task.d.ts +142 -0
- package/dist/tasks/bulk-translate-doc-task.js +1000 -0
- package/dist/tasks/bulk-translate-janitor.d.ts +87 -0
- package/dist/tasks/bulk-translate-janitor.js +311 -0
- package/dist/tasks/translate-job-task.d.ts +51 -0
- package/dist/tasks/translate-job-task.js +154 -0
- package/dist/translate.d.ts +113 -0
- package/dist/translate.js +911 -0
- package/dist/translation-daily-spend-collection.d.ts +24 -0
- package/dist/translation-daily-spend-collection.js +133 -0
- package/dist/translation-rate-limits-collection.d.ts +30 -0
- package/dist/translation-rate-limits-collection.js +144 -0
- package/dist/types.d.ts +672 -0
- package/dist/types.js +1 -0
- package/dist/usage-collection.d.ts +14 -0
- package/dist/usage-collection.js +377 -0
- package/dist/views/BulkRunsHub/BatchRow.d.ts +32 -0
- package/dist/views/BulkRunsHub/BatchRow.js +1222 -0
- package/dist/views/BulkRunsHub/BucketRow.d.ts +62 -0
- package/dist/views/BulkRunsHub/BucketRow.js +982 -0
- package/dist/views/BulkRunsHub/BulkRunsHub.client.d.ts +18 -0
- package/dist/views/BulkRunsHub/BulkRunsHub.client.js +331 -0
- package/dist/views/BulkRunsHub/EmptyState.d.ts +6 -0
- package/dist/views/BulkRunsHub/EmptyState.js +64 -0
- package/dist/views/BulkRunsHub/FilterBar.d.ts +16 -0
- package/dist/views/BulkRunsHub/FilterBar.js +284 -0
- package/dist/views/BulkRunsHub/InFlightBanner.d.ts +14 -0
- package/dist/views/BulkRunsHub/InFlightBanner.js +59 -0
- package/dist/views/BulkRunsHub/StatusBadge.d.ts +64 -0
- package/dist/views/BulkRunsHub/StatusBadge.js +248 -0
- package/dist/views/BulkRunsHub/SummaryStrip.d.ts +22 -0
- package/dist/views/BulkRunsHub/SummaryStrip.js +249 -0
- package/dist/views/BulkRunsHub/bucket-grouping.d.ts +200 -0
- package/dist/views/BulkRunsHub/bucket-grouping.js +344 -0
- package/dist/views/BulkRunsHub/bucketFailureSummary.d.ts +9 -0
- package/dist/views/BulkRunsHub/bucketFailureSummary.js +36 -0
- package/dist/views/BulkRunsHub/dedupedStatusFetch.d.ts +5 -0
- package/dist/views/BulkRunsHub/dedupedStatusFetch.js +45 -0
- package/dist/views/BulkRunsHub/index.d.ts +17 -0
- package/dist/views/BulkRunsHub/index.js +80 -0
- package/dist/views/BulkRunsHub/urlFilters.d.ts +14 -0
- package/dist/views/BulkRunsHub/urlFilters.js +50 -0
- package/dist/views/BulkRunsHub/useBulkRunsList.d.ts +26 -0
- package/dist/views/BulkRunsHub/useBulkRunsList.js +204 -0
- package/dist/views/BulkRunsHub/useUrlFilters.d.ts +10 -0
- package/dist/views/BulkRunsHub/useUrlFilters.js +88 -0
- package/dist/views/TranslationHub/ActiveJobs.d.ts +6 -0
- package/dist/views/TranslationHub/ActiveJobs.js +320 -0
- package/dist/views/TranslationHub/AdvancedPanel.d.ts +17 -0
- package/dist/views/TranslationHub/AdvancedPanel.js +996 -0
- package/dist/views/TranslationHub/AlertBanner.d.ts +6 -0
- package/dist/views/TranslationHub/AlertBanner.js +568 -0
- package/dist/views/TranslationHub/AuditPanel.d.ts +6 -0
- package/dist/views/TranslationHub/AuditPanel.helpers.d.ts +44 -0
- package/dist/views/TranslationHub/AuditPanel.helpers.js +71 -0
- package/dist/views/TranslationHub/AuditPanel.js +1367 -0
- package/dist/views/TranslationHub/BulkTranslate.types.d.ts +242 -0
- package/dist/views/TranslationHub/BulkTranslate.types.js +36 -0
- package/dist/views/TranslationHub/BulkTranslateFailureDrawer.d.ts +19 -0
- package/dist/views/TranslationHub/BulkTranslateFailureDrawer.js +332 -0
- package/dist/views/TranslationHub/BulkTranslateMonitor.d.ts +28 -0
- package/dist/views/TranslationHub/BulkTranslateMonitor.js +305 -0
- package/dist/views/TranslationHub/BulkTranslateNarrowViewportBanner.d.ts +3 -0
- package/dist/views/TranslationHub/BulkTranslateNarrowViewportBanner.js +42 -0
- package/dist/views/TranslationHub/BulkTranslatePostEnqueueTransition.d.ts +26 -0
- package/dist/views/TranslationHub/BulkTranslatePostEnqueueTransition.js +95 -0
- package/dist/views/TranslationHub/BulkTranslatePreflightModal.d.ts +22 -0
- package/dist/views/TranslationHub/BulkTranslatePreflightModal.js +879 -0
- package/dist/views/TranslationHub/BulkTranslateTerminalCard.d.ts +29 -0
- package/dist/views/TranslationHub/BulkTranslateTerminalCard.js +445 -0
- package/dist/views/TranslationHub/BulkTranslateTrigger.d.ts +66 -0
- package/dist/views/TranslationHub/BulkTranslateTrigger.js +161 -0
- package/dist/views/TranslationHub/EditorRecentRunsPanel.d.ts +33 -0
- package/dist/views/TranslationHub/EditorRecentRunsPanel.js +290 -0
- package/dist/views/TranslationHub/Hub.client.d.ts +74 -0
- package/dist/views/TranslationHub/Hub.client.js +357 -0
- package/dist/views/TranslationHub/ModelCombobox.d.ts +14 -0
- package/dist/views/TranslationHub/ModelCombobox.js +415 -0
- package/dist/views/TranslationHub/PerCollectionConfig.d.ts +10 -0
- package/dist/views/TranslationHub/PerCollectionConfig.helpers.d.ts +16 -0
- package/dist/views/TranslationHub/PerCollectionConfig.helpers.js +19 -0
- package/dist/views/TranslationHub/PerCollectionConfig.js +759 -0
- package/dist/views/TranslationHub/SettingsRail.d.ts +11 -0
- package/dist/views/TranslationHub/SettingsRail.js +382 -0
- package/dist/views/TranslationHub/StatusStrip.d.ts +6 -0
- package/dist/views/TranslationHub/StatusStrip.js +451 -0
- package/dist/views/TranslationHub/UsageTable.d.ts +6 -0
- package/dist/views/TranslationHub/UsageTable.helpers.d.ts +69 -0
- package/dist/views/TranslationHub/UsageTable.helpers.js +49 -0
- package/dist/views/TranslationHub/UsageTable.js +1240 -0
- package/dist/views/TranslationHub/alertGrouping.d.ts +70 -0
- package/dist/views/TranslationHub/alertGrouping.js +99 -0
- package/dist/views/TranslationHub/index.d.ts +20 -0
- package/dist/views/TranslationHub/index.js +109 -0
- package/dist/views/TranslationHub/tabNavigation.d.ts +53 -0
- package/dist/views/TranslationHub/tabNavigation.js +74 -0
- package/dist/views/TranslationHub/terminalBannerVisibility.d.ts +33 -0
- package/dist/views/TranslationHub/terminalBannerVisibility.js +124 -0
- package/dist/views/TranslationHub/useBulkTranslateActive.d.ts +49 -0
- package/dist/views/TranslationHub/useBulkTranslateActive.js +251 -0
- package/dist/views/TranslationHub/useFocusTrap.d.ts +6 -0
- package/dist/views/TranslationHub/useFocusTrap.js +81 -0
- package/dist/views/TranslationHub/useTranslationHubUsageSummary.d.ts +77 -0
- package/dist/views/TranslationHub/useTranslationHubUsageSummary.js +267 -0
- package/dist/views/shared/EditorError.d.ts +97 -0
- package/dist/views/shared/EditorError.js +205 -0
- package/dist/views/shared/ModelCell.d.ts +18 -0
- package/dist/views/shared/ModelCell.js +31 -0
- package/dist/views/shared/docHref.d.ts +16 -0
- package/dist/views/shared/docHref.js +26 -0
- package/dist/views/shared/fetch-error-body.d.ts +25 -0
- package/dist/views/shared/fetch-error-body.js +42 -0
- package/dist/views/shared/filterPillStyle.d.ts +35 -0
- package/dist/views/shared/filterPillStyle.js +40 -0
- package/dist/views/shared/format.d.ts +75 -0
- package/dist/views/shared/format.js +131 -0
- package/package.json +141 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { filterPillColors } from '../shared/filterPillStyle.js';
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Shared field style
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
const FIELD_STYLE = {
|
|
8
|
+
padding: '0.3rem 0.5rem',
|
|
9
|
+
fontSize: '0.8125rem',
|
|
10
|
+
background: 'var(--theme-elevation-50)',
|
|
11
|
+
border: '1px solid var(--theme-elevation-150)',
|
|
12
|
+
borderRadius: '4px',
|
|
13
|
+
color: 'var(--theme-elevation-1000)',
|
|
14
|
+
fontFamily: 'inherit'
|
|
15
|
+
};
|
|
16
|
+
const LABEL_STYLE = {
|
|
17
|
+
display: 'flex',
|
|
18
|
+
flexDirection: 'column',
|
|
19
|
+
gap: '0.25rem',
|
|
20
|
+
fontSize: '0.6875rem',
|
|
21
|
+
fontWeight: 600,
|
|
22
|
+
textTransform: 'uppercase',
|
|
23
|
+
letterSpacing: '0.05em',
|
|
24
|
+
color: 'var(--theme-elevation-500)'
|
|
25
|
+
};
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Status quick-pick chips
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
const STATUS_CHIPS = [
|
|
30
|
+
{
|
|
31
|
+
label: 'All',
|
|
32
|
+
value: ''
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: 'Active',
|
|
36
|
+
value: 'active'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
label: 'Terminal',
|
|
40
|
+
value: 'terminal'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
label: 'Running',
|
|
44
|
+
value: 'running'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
label: 'Failed',
|
|
48
|
+
value: 'failed'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
label: 'Partial',
|
|
52
|
+
value: 'partial'
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
label: 'Cancelled',
|
|
56
|
+
value: 'cancelled'
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
const MODE_OPTIONS = [
|
|
60
|
+
{
|
|
61
|
+
label: 'All modes',
|
|
62
|
+
value: ''
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
label: 'Changed',
|
|
66
|
+
value: 'changed'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: 'Force',
|
|
70
|
+
value: 'force'
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
label: 'Canary',
|
|
74
|
+
value: 'canary'
|
|
75
|
+
}
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* NEW-19 (v1.2.6): true when both Since and Until are set but Until
|
|
79
|
+
* precedes Since. Pure helper so the inline error / aria-invalid /
|
|
80
|
+
* input min-max can all read the same source of truth.
|
|
81
|
+
*/ export function dateRangeInvalid(filters) {
|
|
82
|
+
if (!filters.since || !filters.until) return false;
|
|
83
|
+
return new Date(filters.until).getTime() < new Date(filters.since).getTime();
|
|
84
|
+
}
|
|
85
|
+
export const FilterBar = ({ filters, onChange, batches })=>{
|
|
86
|
+
// Derive distinct triggeredBy values from loaded data for autocomplete.
|
|
87
|
+
const triggeredByOptions = Array.from(new Set(batches.map((b)=>b.triggeredByEmail).filter((e)=>typeof e === 'string' && e.length > 0)));
|
|
88
|
+
const invalidDates = dateRangeInvalid(filters);
|
|
89
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
90
|
+
style: {
|
|
91
|
+
display: 'flex',
|
|
92
|
+
flexDirection: 'column',
|
|
93
|
+
gap: '0.5rem'
|
|
94
|
+
},
|
|
95
|
+
children: [
|
|
96
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
97
|
+
style: {
|
|
98
|
+
display: 'flex',
|
|
99
|
+
flexWrap: 'wrap',
|
|
100
|
+
gap: '1rem',
|
|
101
|
+
padding: '0.75rem 1rem',
|
|
102
|
+
background: 'var(--theme-elevation-50)',
|
|
103
|
+
border: '1px solid var(--theme-elevation-150)',
|
|
104
|
+
borderRadius: '6px',
|
|
105
|
+
alignItems: 'flex-end'
|
|
106
|
+
},
|
|
107
|
+
children: [
|
|
108
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
109
|
+
style: LABEL_STYLE,
|
|
110
|
+
"aria-label": "Filter the batch list by status",
|
|
111
|
+
children: [
|
|
112
|
+
"Batch status",
|
|
113
|
+
/*#__PURE__*/ _jsx("div", {
|
|
114
|
+
style: {
|
|
115
|
+
display: 'flex',
|
|
116
|
+
flexWrap: 'wrap',
|
|
117
|
+
gap: '0.25rem'
|
|
118
|
+
},
|
|
119
|
+
children: STATUS_CHIPS.map((chip)=>{
|
|
120
|
+
const isActive = filters.status === chip.value;
|
|
121
|
+
const colors = filterPillColors(isActive);
|
|
122
|
+
return /*#__PURE__*/ _jsx("button", {
|
|
123
|
+
"aria-pressed": isActive,
|
|
124
|
+
type: "button",
|
|
125
|
+
onClick: ()=>onChange({
|
|
126
|
+
status: chip.value
|
|
127
|
+
}),
|
|
128
|
+
style: {
|
|
129
|
+
padding: '0.2rem 0.55rem',
|
|
130
|
+
fontSize: '0.75rem',
|
|
131
|
+
borderRadius: '4px',
|
|
132
|
+
border: colors.border,
|
|
133
|
+
background: colors.background,
|
|
134
|
+
color: colors.color,
|
|
135
|
+
cursor: 'pointer',
|
|
136
|
+
fontWeight: isActive ? 600 : 400
|
|
137
|
+
},
|
|
138
|
+
children: chip.label
|
|
139
|
+
}, chip.value || 'all');
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
]
|
|
143
|
+
}),
|
|
144
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
145
|
+
style: LABEL_STYLE,
|
|
146
|
+
children: [
|
|
147
|
+
"Mode",
|
|
148
|
+
/*#__PURE__*/ _jsx("select", {
|
|
149
|
+
value: filters.mode,
|
|
150
|
+
onChange: (e)=>onChange({
|
|
151
|
+
mode: e.target.value
|
|
152
|
+
}),
|
|
153
|
+
style: FIELD_STYLE,
|
|
154
|
+
children: MODE_OPTIONS.map((o)=>/*#__PURE__*/ _jsx("option", {
|
|
155
|
+
value: o.value,
|
|
156
|
+
children: o.label
|
|
157
|
+
}, o.value))
|
|
158
|
+
})
|
|
159
|
+
]
|
|
160
|
+
}),
|
|
161
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
162
|
+
style: LABEL_STYLE,
|
|
163
|
+
children: [
|
|
164
|
+
"Triggered by",
|
|
165
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
166
|
+
style: {
|
|
167
|
+
position: 'relative'
|
|
168
|
+
},
|
|
169
|
+
children: [
|
|
170
|
+
/*#__PURE__*/ _jsx("input", {
|
|
171
|
+
list: "bulk-runs-triggered-by-list",
|
|
172
|
+
type: "text",
|
|
173
|
+
placeholder: "Email…",
|
|
174
|
+
value: filters.triggeredBy,
|
|
175
|
+
onChange: (e)=>onChange({
|
|
176
|
+
triggeredBy: e.target.value
|
|
177
|
+
}),
|
|
178
|
+
style: {
|
|
179
|
+
...FIELD_STYLE,
|
|
180
|
+
minWidth: '160px'
|
|
181
|
+
}
|
|
182
|
+
}),
|
|
183
|
+
/*#__PURE__*/ _jsx("datalist", {
|
|
184
|
+
id: "bulk-runs-triggered-by-list",
|
|
185
|
+
children: triggeredByOptions.map((email)=>/*#__PURE__*/ _jsx("option", {
|
|
186
|
+
value: email
|
|
187
|
+
}, email))
|
|
188
|
+
})
|
|
189
|
+
]
|
|
190
|
+
})
|
|
191
|
+
]
|
|
192
|
+
}),
|
|
193
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
194
|
+
style: LABEL_STYLE,
|
|
195
|
+
children: [
|
|
196
|
+
"Since",
|
|
197
|
+
/*#__PURE__*/ _jsx("input", {
|
|
198
|
+
type: "date",
|
|
199
|
+
value: filters.since ? filters.since.slice(0, 10) : '',
|
|
200
|
+
max: filters.until ? filters.until.slice(0, 10) : undefined,
|
|
201
|
+
onChange: (e)=>onChange({
|
|
202
|
+
since: e.target.value ? `${e.target.value}T00:00:00.000Z` : ''
|
|
203
|
+
}),
|
|
204
|
+
style: FIELD_STYLE,
|
|
205
|
+
"aria-invalid": dateRangeInvalid(filters)
|
|
206
|
+
})
|
|
207
|
+
]
|
|
208
|
+
}),
|
|
209
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
210
|
+
style: LABEL_STYLE,
|
|
211
|
+
children: [
|
|
212
|
+
"Until",
|
|
213
|
+
/*#__PURE__*/ _jsx("input", {
|
|
214
|
+
type: "date",
|
|
215
|
+
value: filters.until ? filters.until.slice(0, 10) : '',
|
|
216
|
+
min: filters.since ? filters.since.slice(0, 10) : undefined,
|
|
217
|
+
onChange: (e)=>onChange({
|
|
218
|
+
until: e.target.value ? `${e.target.value}T23:59:59.999Z` : ''
|
|
219
|
+
}),
|
|
220
|
+
style: FIELD_STYLE,
|
|
221
|
+
"aria-invalid": dateRangeInvalid(filters)
|
|
222
|
+
})
|
|
223
|
+
]
|
|
224
|
+
}),
|
|
225
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
226
|
+
style: {
|
|
227
|
+
...LABEL_STYLE,
|
|
228
|
+
flexDirection: 'row',
|
|
229
|
+
alignItems: 'center',
|
|
230
|
+
gap: '0.4rem',
|
|
231
|
+
cursor: 'pointer'
|
|
232
|
+
},
|
|
233
|
+
children: [
|
|
234
|
+
/*#__PURE__*/ _jsx("input", {
|
|
235
|
+
type: "checkbox",
|
|
236
|
+
checked: filters.hasFailures,
|
|
237
|
+
onChange: (e)=>onChange({
|
|
238
|
+
hasFailures: e.target.checked
|
|
239
|
+
}),
|
|
240
|
+
style: {
|
|
241
|
+
cursor: 'pointer'
|
|
242
|
+
}
|
|
243
|
+
}),
|
|
244
|
+
"Has failures"
|
|
245
|
+
]
|
|
246
|
+
}),
|
|
247
|
+
(filters.status || filters.mode || filters.triggeredBy || filters.since || filters.until || filters.hasFailures) && /*#__PURE__*/ _jsx("button", {
|
|
248
|
+
type: "button",
|
|
249
|
+
onClick: ()=>onChange({
|
|
250
|
+
status: '',
|
|
251
|
+
mode: '',
|
|
252
|
+
triggeredBy: '',
|
|
253
|
+
since: '',
|
|
254
|
+
until: '',
|
|
255
|
+
hasFailures: false
|
|
256
|
+
}),
|
|
257
|
+
style: {
|
|
258
|
+
padding: '0.3rem 0.6rem',
|
|
259
|
+
fontSize: '0.75rem',
|
|
260
|
+
background: 'transparent',
|
|
261
|
+
border: '1px solid var(--theme-elevation-200)',
|
|
262
|
+
borderRadius: '4px',
|
|
263
|
+
color: 'var(--theme-elevation-600)',
|
|
264
|
+
cursor: 'pointer'
|
|
265
|
+
},
|
|
266
|
+
children: "Clear filters"
|
|
267
|
+
})
|
|
268
|
+
]
|
|
269
|
+
}),
|
|
270
|
+
invalidDates && /*#__PURE__*/ _jsx("div", {
|
|
271
|
+
role: "alert",
|
|
272
|
+
style: {
|
|
273
|
+
padding: '0.5rem 0.75rem',
|
|
274
|
+
background: 'var(--theme-error-100, #fee2e2)',
|
|
275
|
+
border: '1px solid var(--theme-error-500, #b91c1c)',
|
|
276
|
+
borderRadius: '4px',
|
|
277
|
+
color: 'var(--theme-error-800, #7f1d1d)',
|
|
278
|
+
fontSize: '0.8125rem'
|
|
279
|
+
},
|
|
280
|
+
children: "Invalid date range — Until precedes Since. The table is hidden until you fix the range."
|
|
281
|
+
})
|
|
282
|
+
]
|
|
283
|
+
});
|
|
284
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { BulkTranslateBatchSummary } from '../TranslationHub/BulkTranslate.types.js';
|
|
3
|
+
interface Props {
|
|
4
|
+
batches: BulkTranslateBatchSummary[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Slim status banner shown at the top of the runs list when at least one
|
|
8
|
+
* batch is in an active status (queued / running / cancelling).
|
|
9
|
+
*
|
|
10
|
+
* The `●` glyph pulses via a CSS keyframe injected inline — consistent
|
|
11
|
+
* with the StatusBadge running animation but isolated to the banner dot.
|
|
12
|
+
*/
|
|
13
|
+
export declare const InFlightBanner: React.FC<Props>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { isActiveStatus } from '../TranslationHub/BulkTranslate.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Slim status banner shown at the top of the runs list when at least one
|
|
6
|
+
* batch is in an active status (queued / running / cancelling).
|
|
7
|
+
*
|
|
8
|
+
* The `●` glyph pulses via a CSS keyframe injected inline — consistent
|
|
9
|
+
* with the StatusBadge running animation but isolated to the banner dot.
|
|
10
|
+
*/ export const InFlightBanner = ({ batches })=>{
|
|
11
|
+
const activeCount = batches.filter((b)=>isActiveStatus(b.status)).length;
|
|
12
|
+
if (activeCount === 0) return null;
|
|
13
|
+
const label = activeCount === 1 ? '1 run in progress' : `${activeCount} runs in progress`;
|
|
14
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
15
|
+
children: [
|
|
16
|
+
/*#__PURE__*/ _jsx("style", {
|
|
17
|
+
children: `
|
|
18
|
+
@keyframes bulk-runs-dot-pulse {
|
|
19
|
+
0%, 100% { opacity: 1; }
|
|
20
|
+
50% { opacity: 0.35; }
|
|
21
|
+
}
|
|
22
|
+
@media (prefers-reduced-motion: reduce) {
|
|
23
|
+
.bulk-runs-dot { animation: none !important; }
|
|
24
|
+
}
|
|
25
|
+
`
|
|
26
|
+
}),
|
|
27
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
28
|
+
role: "status",
|
|
29
|
+
"aria-live": "polite",
|
|
30
|
+
style: {
|
|
31
|
+
display: 'flex',
|
|
32
|
+
alignItems: 'center',
|
|
33
|
+
gap: '0.5rem',
|
|
34
|
+
padding: '0.4rem 0.75rem',
|
|
35
|
+
background: 'var(--theme-elevation-50)',
|
|
36
|
+
border: '1px solid var(--theme-success-300, #86efac)',
|
|
37
|
+
borderRadius: '4px',
|
|
38
|
+
fontSize: '0.8125rem',
|
|
39
|
+
color: 'var(--theme-success-500, #16a34a)'
|
|
40
|
+
},
|
|
41
|
+
children: [
|
|
42
|
+
/*#__PURE__*/ _jsx("span", {
|
|
43
|
+
className: "bulk-runs-dot",
|
|
44
|
+
"aria-hidden": "true",
|
|
45
|
+
style: {
|
|
46
|
+
fontSize: '0.6rem',
|
|
47
|
+
animationName: 'bulk-runs-dot-pulse',
|
|
48
|
+
animationDuration: '1.4s',
|
|
49
|
+
animationTimingFunction: 'ease-in-out',
|
|
50
|
+
animationIterationCount: 'infinite'
|
|
51
|
+
},
|
|
52
|
+
children: "●"
|
|
53
|
+
}),
|
|
54
|
+
label
|
|
55
|
+
]
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { BulkTranslateBatchStatus } from '../TranslationHub/BulkTranslate.types.js';
|
|
3
|
+
/** Test-only: reset the once-per-status warning de-dupe set. */
|
|
4
|
+
export declare function __resetStatusBadgeWarnings(): void;
|
|
5
|
+
export type ResolvedBadge = {
|
|
6
|
+
kind: 'known';
|
|
7
|
+
label: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'fallback';
|
|
10
|
+
label: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Pure resolver for the batch-level status badge. Returns the display
|
|
14
|
+
* label and a `kind` discriminator so tests can pin BR-3 fallback
|
|
15
|
+
* behaviour without rendering React or relying on CSS-token strings.
|
|
16
|
+
*
|
|
17
|
+
* `kind: 'known'` — STATUS_CONFIG had an entry; label is the friendly
|
|
18
|
+
* display string (e.g. 'succeeded' for 'success',
|
|
19
|
+
* 'running' for 'running').
|
|
20
|
+
* `kind: 'fallback'` — STATUS_CONFIG had no entry; label echoes the raw
|
|
21
|
+
* input so editors still see something useful in
|
|
22
|
+
* the row (BR-3).
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveBatchStatusBadge(status: string): ResolvedBadge;
|
|
25
|
+
/**
|
|
26
|
+
* Pure resolver for unit-level status badges. Mirrors
|
|
27
|
+
* `resolveBatchStatusBadge` but uses the unit-status color map so
|
|
28
|
+
* `'completed'` (older API revision) and `'succeeded'` both normalise
|
|
29
|
+
* to the same `success` chip. Returns fallback for any value outside
|
|
30
|
+
* the known set.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveUnitStatusBadge(status: string): ResolvedBadge;
|
|
33
|
+
interface StatusBadgeProps {
|
|
34
|
+
status: BulkTranslateBatchStatus;
|
|
35
|
+
/** Render at the smaller unit-table size (0.65rem vs 0.7rem). */
|
|
36
|
+
small?: boolean;
|
|
37
|
+
}
|
|
38
|
+
interface UnitStatusBadgeProps {
|
|
39
|
+
status: string;
|
|
40
|
+
small?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Renders a status pill for a batch row.
|
|
44
|
+
* The `running` state gets a CSS pulse animation on its background.
|
|
45
|
+
* Storage value `'success'` displays as "succeeded" — matches the
|
|
46
|
+
* unit-level vocabulary used in the Hub's Recent translations table
|
|
47
|
+
* and the AuditPanel KPIs. v1.2.5 used "completed" here; v1.2.6 fixes
|
|
48
|
+
* the vocab split (BR-8).
|
|
49
|
+
*/
|
|
50
|
+
export declare const StatusBadge: React.FC<StatusBadgeProps>;
|
|
51
|
+
/**
|
|
52
|
+
* Same visual treatment but for unit-level statuses (pending / running /
|
|
53
|
+
* success / failed / skipped / reverted). Uses `succeeded` as the
|
|
54
|
+
* display label for `success` to match the rest of the surface (BR-8).
|
|
55
|
+
*/
|
|
56
|
+
export declare const UnitStatusBadge: React.FC<UnitStatusBadgeProps>;
|
|
57
|
+
/**
|
|
58
|
+
* Inject the running-badge keyframes once per page. Call this inside the
|
|
59
|
+
* client component that mounts StatusBadge. Using a `<style>` tag is the
|
|
60
|
+
* only viable approach in Payload's inline-style architecture (no CSS
|
|
61
|
+
* Modules, no Tailwind).
|
|
62
|
+
*/
|
|
63
|
+
export declare const StatusBadgeKeyframes: React.FC;
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
// Text colours pulled up to `-900` (or `-elevation-900` for neutrals) so
|
|
4
|
+
// chip text clears WCAG AA on the tinted backgrounds — v1.2.6 audit
|
|
5
|
+
// found the previous `-500` text ran 3.3–3.8:1, below the 4.5:1 bar.
|
|
6
|
+
// The `-900` token is ~rgb(19,44,58) on success and similar near-black
|
|
7
|
+
// shades on warning / error, giving 8:1+ on the `-100` tinted bg.
|
|
8
|
+
// Backgrounds stay tinted so the signal colour still reads at a glance.
|
|
9
|
+
// NEW-3.
|
|
10
|
+
const STATUS_CONFIG = {
|
|
11
|
+
queued: {
|
|
12
|
+
background: 'var(--theme-elevation-100)',
|
|
13
|
+
color: 'var(--theme-elevation-900)',
|
|
14
|
+
border: 'var(--theme-elevation-200)'
|
|
15
|
+
},
|
|
16
|
+
running: {
|
|
17
|
+
background: 'var(--theme-success-100, #dcfce7)',
|
|
18
|
+
color: 'var(--theme-success-900, #052e16)',
|
|
19
|
+
border: 'var(--theme-success-300, #86efac)',
|
|
20
|
+
animation: 'bulk-runs-pulse'
|
|
21
|
+
},
|
|
22
|
+
cancelling: {
|
|
23
|
+
background: 'var(--theme-warning-100, #fef3c7)',
|
|
24
|
+
color: 'var(--theme-warning-900, #422006)',
|
|
25
|
+
border: 'var(--theme-warning-300, #fcd34d)'
|
|
26
|
+
},
|
|
27
|
+
success: {
|
|
28
|
+
background: 'var(--theme-success-100, #dcfce7)',
|
|
29
|
+
color: 'var(--theme-success-900, #052e16)',
|
|
30
|
+
border: 'var(--theme-success-200, #bbf7d0)'
|
|
31
|
+
},
|
|
32
|
+
failed: {
|
|
33
|
+
background: 'var(--theme-error-100, #fee2e2)',
|
|
34
|
+
color: 'var(--theme-error-900, #450a0a)',
|
|
35
|
+
border: 'var(--theme-error-300, #fca5a5)'
|
|
36
|
+
},
|
|
37
|
+
partial: {
|
|
38
|
+
background: 'var(--theme-warning-100, #fef3c7)',
|
|
39
|
+
color: 'var(--theme-warning-900, #422006)',
|
|
40
|
+
border: 'var(--theme-warning-300, #fcd34d)'
|
|
41
|
+
},
|
|
42
|
+
cancelled: {
|
|
43
|
+
background: 'var(--theme-elevation-100)',
|
|
44
|
+
color: 'var(--theme-elevation-900)',
|
|
45
|
+
border: 'var(--theme-elevation-200)'
|
|
46
|
+
},
|
|
47
|
+
reverted: {
|
|
48
|
+
background: 'var(--theme-elevation-100)',
|
|
49
|
+
color: 'var(--theme-elevation-900)',
|
|
50
|
+
border: 'var(--theme-elevation-200)',
|
|
51
|
+
prefix: '↶'
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
// Unit-status badges (inside the drill-down unit table) use a narrower
|
|
55
|
+
// set. Map to the closest batch status for color reuse.
|
|
56
|
+
const UNIT_STATUS_COLOR_MAP = {
|
|
57
|
+
pending: STATUS_CONFIG.queued,
|
|
58
|
+
running: STATUS_CONFIG.running,
|
|
59
|
+
success: STATUS_CONFIG.success,
|
|
60
|
+
failed: STATUS_CONFIG.failed,
|
|
61
|
+
skipped: {
|
|
62
|
+
background: 'var(--theme-elevation-100)',
|
|
63
|
+
color: 'var(--theme-elevation-900)',
|
|
64
|
+
border: 'var(--theme-elevation-200)'
|
|
65
|
+
},
|
|
66
|
+
reverted: STATUS_CONFIG.reverted
|
|
67
|
+
};
|
|
68
|
+
// Tracks unknown status values we've already warned about so the
|
|
69
|
+
// console isn't spammed every re-render. Module-scope is fine — the
|
|
70
|
+
// set is purely diagnostic. Cleared in tests via `__resetStatusBadgeWarnings`.
|
|
71
|
+
const warnedUnknownStatuses = new Set();
|
|
72
|
+
function warnUnknownStatus(component, status) {
|
|
73
|
+
if (warnedUnknownStatuses.has(`${component}:${status}`)) return;
|
|
74
|
+
warnedUnknownStatuses.add(`${component}:${status}`);
|
|
75
|
+
// eslint-disable-next-line no-console
|
|
76
|
+
console.warn(`[ai-translate] ${component}: unknown status '${status}' — rendering raw value. ` + 'A new lifecycle state was likely added without a UI mapping; please update STATUS_CONFIG.');
|
|
77
|
+
}
|
|
78
|
+
/** Test-only: reset the once-per-status warning de-dupe set. */ export function __resetStatusBadgeWarnings() {
|
|
79
|
+
warnedUnknownStatuses.clear();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Pure resolver for the batch-level status badge. Returns the display
|
|
83
|
+
* label and a `kind` discriminator so tests can pin BR-3 fallback
|
|
84
|
+
* behaviour without rendering React or relying on CSS-token strings.
|
|
85
|
+
*
|
|
86
|
+
* `kind: 'known'` — STATUS_CONFIG had an entry; label is the friendly
|
|
87
|
+
* display string (e.g. 'succeeded' for 'success',
|
|
88
|
+
* 'running' for 'running').
|
|
89
|
+
* `kind: 'fallback'` — STATUS_CONFIG had no entry; label echoes the raw
|
|
90
|
+
* input so editors still see something useful in
|
|
91
|
+
* the row (BR-3).
|
|
92
|
+
*/ export function resolveBatchStatusBadge(status) {
|
|
93
|
+
// Normalise the legacy `'completed'` literal (pre-v1.2.5 batches) onto
|
|
94
|
+
// `'success'` so older rows render the same `SUCCEEDED` chip as the
|
|
95
|
+
// rest of the table. Mirrors `resolveUnitStatusBadge` — unit chips
|
|
96
|
+
// already aliased this; batch chips did not, which produced a single
|
|
97
|
+
// `COMPLETED` row amongst `SUCCEEDED` peers in the v1.2.6 UI sweep.
|
|
98
|
+
const normalised = status === 'completed' ? 'success' : status;
|
|
99
|
+
const cfg = STATUS_CONFIG[normalised];
|
|
100
|
+
if (!cfg) return {
|
|
101
|
+
kind: 'fallback',
|
|
102
|
+
label: status
|
|
103
|
+
};
|
|
104
|
+
return {
|
|
105
|
+
kind: 'known',
|
|
106
|
+
label: normalised === 'success' ? 'succeeded' : normalised
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Pure resolver for unit-level status badges. Mirrors
|
|
111
|
+
* `resolveBatchStatusBadge` but uses the unit-status color map so
|
|
112
|
+
* `'completed'` (older API revision) and `'succeeded'` both normalise
|
|
113
|
+
* to the same `success` chip. Returns fallback for any value outside
|
|
114
|
+
* the known set.
|
|
115
|
+
*/ export function resolveUnitStatusBadge(status) {
|
|
116
|
+
const normalised = status === 'completed' || status === 'succeeded' ? 'success' : status;
|
|
117
|
+
const cfg = UNIT_STATUS_COLOR_MAP[normalised];
|
|
118
|
+
if (!cfg) return {
|
|
119
|
+
kind: 'fallback',
|
|
120
|
+
label: status
|
|
121
|
+
};
|
|
122
|
+
const label = status === 'success' || status === 'completed' ? 'succeeded' : status;
|
|
123
|
+
return {
|
|
124
|
+
kind: 'known',
|
|
125
|
+
label
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Neutral fallback chip used when a batch arrives with a status value
|
|
130
|
+
* that isn't in STATUS_CONFIG (e.g. a future / older API revision adds
|
|
131
|
+
* a new lifecycle state). Renders the raw value so editors aren't
|
|
132
|
+
* staring at an empty cell (BR-3) and emits a one-shot console.warn
|
|
133
|
+
* per unknown value for engineering.
|
|
134
|
+
*/ const UNKNOWN_STATUS_CONFIG = {
|
|
135
|
+
background: 'var(--theme-elevation-100)',
|
|
136
|
+
color: 'var(--theme-elevation-900)',
|
|
137
|
+
border: 'var(--theme-elevation-300)'
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Renders a status pill for a batch row.
|
|
141
|
+
* The `running` state gets a CSS pulse animation on its background.
|
|
142
|
+
* Storage value `'success'` displays as "succeeded" — matches the
|
|
143
|
+
* unit-level vocabulary used in the Hub's Recent translations table
|
|
144
|
+
* and the AuditPanel KPIs. v1.2.5 used "completed" here; v1.2.6 fixes
|
|
145
|
+
* the vocab split (BR-8).
|
|
146
|
+
*/ export const StatusBadge = ({ status, small = false })=>{
|
|
147
|
+
const resolved = resolveBatchStatusBadge(status);
|
|
148
|
+
if (resolved.kind === 'fallback') {
|
|
149
|
+
// BR-3 fallback: render the raw value so the row isn't visually
|
|
150
|
+
// empty, and warn once so the next status drift is caught.
|
|
151
|
+
warnUnknownStatus('StatusBadge', status);
|
|
152
|
+
return /*#__PURE__*/ _jsx(BadgePill, {
|
|
153
|
+
cfg: UNKNOWN_STATUS_CONFIG,
|
|
154
|
+
label: resolved.label,
|
|
155
|
+
small: small
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// Normalise legacy `'completed'` onto the `'success'` config so the
|
|
159
|
+
// chip styling matches the resolver's label aliasing. The widened
|
|
160
|
+
// `string` type lets us compare against the legacy literal that isn't
|
|
161
|
+
// part of the current `BulkTranslateBatchStatus` union.
|
|
162
|
+
const normalised = status === 'completed' ? 'success' : status;
|
|
163
|
+
const cfg = STATUS_CONFIG[normalised];
|
|
164
|
+
return /*#__PURE__*/ _jsx(BadgePill, {
|
|
165
|
+
cfg: cfg,
|
|
166
|
+
label: resolved.label,
|
|
167
|
+
small: small
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Same visual treatment but for unit-level statuses (pending / running /
|
|
172
|
+
* success / failed / skipped / reverted). Uses `succeeded` as the
|
|
173
|
+
* display label for `success` to match the rest of the surface (BR-8).
|
|
174
|
+
*/ export const UnitStatusBadge = ({ status, small = false })=>{
|
|
175
|
+
const resolved = resolveUnitStatusBadge(status);
|
|
176
|
+
if (resolved.kind === 'fallback') {
|
|
177
|
+
warnUnknownStatus('UnitStatusBadge', status);
|
|
178
|
+
return /*#__PURE__*/ _jsx(BadgePill, {
|
|
179
|
+
cfg: UNKNOWN_STATUS_CONFIG,
|
|
180
|
+
label: resolved.label,
|
|
181
|
+
small: small
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
const normalised = status === 'completed' || status === 'succeeded' ? 'success' : status;
|
|
185
|
+
const cfg = UNIT_STATUS_COLOR_MAP[normalised];
|
|
186
|
+
return /*#__PURE__*/ _jsx(BadgePill, {
|
|
187
|
+
cfg: cfg,
|
|
188
|
+
label: resolved.label,
|
|
189
|
+
small: small
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// Shared pill renderer
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
const BadgePill = ({ cfg, label, small })=>{
|
|
196
|
+
// Bumped from 0.65rem / 0.7rem (~10.4 / 11.2 px) to 0.75rem / 0.8rem
|
|
197
|
+
// (12 / 12.8 px) in v1.2.6: the previous sizes were uncomfortable to
|
|
198
|
+
// read on dense list views and worked against the `-900` text /
|
|
199
|
+
// tinted background scheme we adopted for NEW-3. 12 px + weight 600
|
|
200
|
+
// is roughly the floor for comfortable status-pill readability and
|
|
201
|
+
// gives us extra contrast headroom alongside the darker text token.
|
|
202
|
+
const fontSize = small ? '0.75rem' : '0.8rem';
|
|
203
|
+
const style = {
|
|
204
|
+
display: 'inline-flex',
|
|
205
|
+
alignItems: 'center',
|
|
206
|
+
gap: cfg.prefix ? '0.25rem' : undefined,
|
|
207
|
+
padding: '0.15rem 0.5rem',
|
|
208
|
+
borderRadius: '4px',
|
|
209
|
+
fontSize,
|
|
210
|
+
fontWeight: 600,
|
|
211
|
+
textTransform: 'uppercase',
|
|
212
|
+
letterSpacing: '0.04em',
|
|
213
|
+
background: cfg.background,
|
|
214
|
+
color: cfg.color,
|
|
215
|
+
border: `1px solid ${cfg.border}`,
|
|
216
|
+
animationName: cfg.animation,
|
|
217
|
+
animationDuration: cfg.animation ? '1.8s' : undefined,
|
|
218
|
+
animationTimingFunction: cfg.animation ? 'ease-in-out' : undefined,
|
|
219
|
+
animationIterationCount: cfg.animation ? 'infinite' : undefined,
|
|
220
|
+
whiteSpace: 'nowrap'
|
|
221
|
+
};
|
|
222
|
+
return /*#__PURE__*/ _jsxs("span", {
|
|
223
|
+
style: style,
|
|
224
|
+
children: [
|
|
225
|
+
cfg.prefix ? /*#__PURE__*/ _jsx("span", {
|
|
226
|
+
"aria-hidden": "true",
|
|
227
|
+
children: cfg.prefix
|
|
228
|
+
}) : null,
|
|
229
|
+
label
|
|
230
|
+
]
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Inject the running-badge keyframes once per page. Call this inside the
|
|
235
|
+
* client component that mounts StatusBadge. Using a `<style>` tag is the
|
|
236
|
+
* only viable approach in Payload's inline-style architecture (no CSS
|
|
237
|
+
* Modules, no Tailwind).
|
|
238
|
+
*/ export const StatusBadgeKeyframes = ()=>/*#__PURE__*/ _jsx("style", {
|
|
239
|
+
children: `
|
|
240
|
+
@keyframes bulk-runs-pulse {
|
|
241
|
+
0%, 100% { background: var(--theme-success-100, #dcfce7); }
|
|
242
|
+
50% { background: var(--theme-success-50, #f0fdf4); }
|
|
243
|
+
}
|
|
244
|
+
@media (prefers-reduced-motion: reduce) {
|
|
245
|
+
.bulk-runs-pulse { animation: none; }
|
|
246
|
+
}
|
|
247
|
+
`
|
|
248
|
+
});
|