@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.
Files changed (301) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +714 -0
  3. package/dist/alerts-collection.d.ts +21 -0
  4. package/dist/alerts-collection.js +159 -0
  5. package/dist/api.d.ts +4 -0
  6. package/dist/api.js +918 -0
  7. package/dist/bulk-translate-batches-collection.d.ts +29 -0
  8. package/dist/bulk-translate-batches-collection.js +404 -0
  9. package/dist/bulk-translate-units-collection.d.ts +35 -0
  10. package/dist/bulk-translate-units-collection.js +310 -0
  11. package/dist/client/estimated-cost-cell.d.ts +6 -0
  12. package/dist/client/estimated-cost-cell.js +12 -0
  13. package/dist/client/excluded-fields-field.d.ts +45 -0
  14. package/dist/client/excluded-fields-field.js +553 -0
  15. package/dist/client/field-translate-button.d.ts +6 -0
  16. package/dist/client/field-translate-button.js +199 -0
  17. package/dist/client/index.d.ts +6 -0
  18. package/dist/client/index.js +6 -0
  19. package/dist/client/lib/use-global-kill-switches.d.ts +20 -0
  20. package/dist/client/lib/use-global-kill-switches.js +58 -0
  21. package/dist/client/translate-button.d.ts +2 -0
  22. package/dist/client/translate-button.js +228 -0
  23. package/dist/client/translate-modal.d.ts +16 -0
  24. package/dist/client/translate-modal.js +549 -0
  25. package/dist/client/translation-progress.d.ts +10 -0
  26. package/dist/client/translation-progress.js +297 -0
  27. package/dist/components/TranslationNavGroup.d.ts +45 -0
  28. package/dist/components/TranslationNavGroup.js +104 -0
  29. package/dist/defaults.d.ts +11 -0
  30. package/dist/defaults.js +16 -0
  31. package/dist/endpoints/client-config.d.ts +44 -0
  32. package/dist/endpoints/client-config.js +145 -0
  33. package/dist/endpoints/estimate.d.ts +5 -0
  34. package/dist/endpoints/estimate.js +237 -0
  35. package/dist/endpoints/progress.d.ts +2 -0
  36. package/dist/endpoints/progress.js +314 -0
  37. package/dist/endpoints/translate.d.ts +11 -0
  38. package/dist/endpoints/translate.js +376 -0
  39. package/dist/endpoints/translation-hub/_helpers.d.ts +140 -0
  40. package/dist/endpoints/translation-hub/_helpers.js +297 -0
  41. package/dist/endpoints/translation-hub/active.d.ts +21 -0
  42. package/dist/endpoints/translation-hub/active.js +220 -0
  43. package/dist/endpoints/translation-hub/cancel.d.ts +22 -0
  44. package/dist/endpoints/translation-hub/cancel.js +233 -0
  45. package/dist/endpoints/translation-hub/enqueue.d.ts +70 -0
  46. package/dist/endpoints/translation-hub/enqueue.js +529 -0
  47. package/dist/endpoints/translation-hub/failures.d.ts +12 -0
  48. package/dist/endpoints/translation-hub/failures.js +67 -0
  49. package/dist/endpoints/translation-hub/force-reset.d.ts +20 -0
  50. package/dist/endpoints/translation-hub/force-reset.js +144 -0
  51. package/dist/endpoints/translation-hub/index.d.ts +21 -0
  52. package/dist/endpoints/translation-hub/index.js +20 -0
  53. package/dist/endpoints/translation-hub/list.d.ts +40 -0
  54. package/dist/endpoints/translation-hub/list.js +182 -0
  55. package/dist/endpoints/translation-hub/preflight.d.ts +19 -0
  56. package/dist/endpoints/translation-hub/preflight.js +141 -0
  57. package/dist/endpoints/translation-hub/retry-failed.d.ts +38 -0
  58. package/dist/endpoints/translation-hub/retry-failed.js +235 -0
  59. package/dist/endpoints/translation-hub/revert.d.ts +88 -0
  60. package/dist/endpoints/translation-hub/revert.js +405 -0
  61. package/dist/endpoints/translation-hub/status.d.ts +45 -0
  62. package/dist/endpoints/translation-hub/status.js +391 -0
  63. package/dist/endpoints/translation-hub/usage-summary.d.ts +114 -0
  64. package/dist/endpoints/translation-hub/usage-summary.js +481 -0
  65. package/dist/exports/client.d.ts +6 -0
  66. package/dist/exports/client.js +6 -0
  67. package/dist/exports/components.d.ts +6 -0
  68. package/dist/exports/components.js +5 -0
  69. package/dist/exports/index.d.ts +8 -0
  70. package/dist/exports/index.js +7 -0
  71. package/dist/exports/providers.d.ts +9 -0
  72. package/dist/exports/providers.js +5 -0
  73. package/dist/exports/views-client.d.ts +23 -0
  74. package/dist/exports/views-client.js +22 -0
  75. package/dist/exports/views.d.ts +30 -0
  76. package/dist/exports/views.js +29 -0
  77. package/dist/hooks/after-change-global.d.ts +4 -0
  78. package/dist/hooks/after-change-global.js +109 -0
  79. package/dist/hooks/after-change.d.ts +16 -0
  80. package/dist/hooks/after-change.js +205 -0
  81. package/dist/hooks/after-delete.d.ts +30 -0
  82. package/dist/hooks/after-delete.js +95 -0
  83. package/dist/index.d.ts +5 -0
  84. package/dist/index.js +5 -0
  85. package/dist/jobs-collection.d.ts +17 -0
  86. package/dist/jobs-collection.js +139 -0
  87. package/dist/lexical/classifier.d.ts +3 -0
  88. package/dist/lexical/classifier.js +108 -0
  89. package/dist/lexical/deserializer.d.ts +4 -0
  90. package/dist/lexical/deserializer.js +263 -0
  91. package/dist/lexical/placeholder-integrity.d.ts +6 -0
  92. package/dist/lexical/placeholder-integrity.js +21 -0
  93. package/dist/lexical/placeholders.d.ts +21 -0
  94. package/dist/lexical/placeholders.js +117 -0
  95. package/dist/lexical/serializer.d.ts +21 -0
  96. package/dist/lexical/serializer.js +233 -0
  97. package/dist/lexical/types.d.ts +32 -0
  98. package/dist/lexical/types.js +1 -0
  99. package/dist/lib/auth-diagnostics.d.ts +14 -0
  100. package/dist/lib/auth-diagnostics.js +19 -0
  101. package/dist/lib/batch-counts.d.ts +58 -0
  102. package/dist/lib/batch-counts.js +105 -0
  103. package/dist/lib/bulk-translate-migrations.d.ts +92 -0
  104. package/dist/lib/bulk-translate-migrations.js +153 -0
  105. package/dist/lib/coalescing-queue.d.ts +38 -0
  106. package/dist/lib/coalescing-queue.js +69 -0
  107. package/dist/lib/content-extractor.d.ts +16 -0
  108. package/dist/lib/content-extractor.js +410 -0
  109. package/dist/lib/content-hash.d.ts +1 -0
  110. package/dist/lib/content-hash.js +19 -0
  111. package/dist/lib/content-patcher.d.ts +15 -0
  112. package/dist/lib/content-patcher.js +293 -0
  113. package/dist/lib/cost-guards.d.ts +2 -0
  114. package/dist/lib/cost-guards.js +18 -0
  115. package/dist/lib/daily-spend-cap.d.ts +58 -0
  116. package/dist/lib/daily-spend-cap.js +233 -0
  117. package/dist/lib/effective-locales.d.ts +181 -0
  118. package/dist/lib/effective-locales.js +302 -0
  119. package/dist/lib/error-messages.d.ts +245 -0
  120. package/dist/lib/error-messages.js +626 -0
  121. package/dist/lib/events.d.ts +39 -0
  122. package/dist/lib/events.js +146 -0
  123. package/dist/lib/exclude-fields.d.ts +3 -0
  124. package/dist/lib/exclude-fields.js +64 -0
  125. package/dist/lib/field-breadcrumb.d.ts +31 -0
  126. package/dist/lib/field-breadcrumb.js +227 -0
  127. package/dist/lib/field-diff.d.ts +1 -0
  128. package/dist/lib/field-diff.js +25 -0
  129. package/dist/lib/field-empty.d.ts +2 -0
  130. package/dist/lib/field-empty.js +68 -0
  131. package/dist/lib/field-resolver.d.ts +3 -0
  132. package/dist/lib/field-resolver.js +164 -0
  133. package/dist/lib/group-soft-skips.d.ts +39 -0
  134. package/dist/lib/group-soft-skips.js +45 -0
  135. package/dist/lib/locale-merge.d.ts +44 -0
  136. package/dist/lib/locale-merge.js +357 -0
  137. package/dist/lib/locale-row-check.d.ts +30 -0
  138. package/dist/lib/locale-row-check.js +64 -0
  139. package/dist/lib/logger.d.ts +74 -0
  140. package/dist/lib/logger.js +97 -0
  141. package/dist/lib/manual-edit-guard.d.ts +128 -0
  142. package/dist/lib/manual-edit-guard.js +393 -0
  143. package/dist/lib/output-validation.d.ts +48 -0
  144. package/dist/lib/output-validation.js +148 -0
  145. package/dist/lib/payload-read.d.ts +16 -0
  146. package/dist/lib/payload-read.js +51 -0
  147. package/dist/lib/per-doc-claim.d.ts +90 -0
  148. package/dist/lib/per-doc-claim.js +140 -0
  149. package/dist/lib/per-doc-lock.d.ts +94 -0
  150. package/dist/lib/per-doc-lock.js +119 -0
  151. package/dist/lib/persist-usage.d.ts +91 -0
  152. package/dist/lib/persist-usage.js +116 -0
  153. package/dist/lib/progress-store.d.ts +103 -0
  154. package/dist/lib/progress-store.js +314 -0
  155. package/dist/lib/rate-limiter.d.ts +3 -0
  156. package/dist/lib/rate-limiter.js +53 -0
  157. package/dist/lib/snapshot-select.d.ts +43 -0
  158. package/dist/lib/snapshot-select.js +108 -0
  159. package/dist/lib/translate-prompt.d.ts +31 -0
  160. package/dist/lib/translate-prompt.js +66 -0
  161. package/dist/lib/translation-token-bucket.d.ts +57 -0
  162. package/dist/lib/translation-token-bucket.js +365 -0
  163. package/dist/lib/truncate-source-value.d.ts +1 -0
  164. package/dist/lib/truncate-source-value.js +27 -0
  165. package/dist/manual-edit-collection.d.ts +22 -0
  166. package/dist/manual-edit-collection.js +124 -0
  167. package/dist/plugin.d.ts +3 -0
  168. package/dist/plugin.js +934 -0
  169. package/dist/providers/ai-sdk-adapter.d.ts +35 -0
  170. package/dist/providers/ai-sdk-adapter.js +100 -0
  171. package/dist/providers/anthropic.d.ts +31 -0
  172. package/dist/providers/anthropic.js +66 -0
  173. package/dist/providers/custom.d.ts +36 -0
  174. package/dist/providers/custom.js +24 -0
  175. package/dist/providers/gemini.d.ts +20 -0
  176. package/dist/providers/gemini.js +48 -0
  177. package/dist/providers/mock.d.ts +2 -0
  178. package/dist/providers/mock.js +29 -0
  179. package/dist/providers/openai.d.ts +28 -0
  180. package/dist/providers/openai.js +69 -0
  181. package/dist/settings-global.d.ts +74 -0
  182. package/dist/settings-global.js +216 -0
  183. package/dist/tasks/bulk-translate-coordinator.d.ts +115 -0
  184. package/dist/tasks/bulk-translate-coordinator.js +708 -0
  185. package/dist/tasks/bulk-translate-doc-task.d.ts +142 -0
  186. package/dist/tasks/bulk-translate-doc-task.js +1000 -0
  187. package/dist/tasks/bulk-translate-janitor.d.ts +87 -0
  188. package/dist/tasks/bulk-translate-janitor.js +311 -0
  189. package/dist/tasks/translate-job-task.d.ts +51 -0
  190. package/dist/tasks/translate-job-task.js +154 -0
  191. package/dist/translate.d.ts +113 -0
  192. package/dist/translate.js +911 -0
  193. package/dist/translation-daily-spend-collection.d.ts +24 -0
  194. package/dist/translation-daily-spend-collection.js +133 -0
  195. package/dist/translation-rate-limits-collection.d.ts +30 -0
  196. package/dist/translation-rate-limits-collection.js +144 -0
  197. package/dist/types.d.ts +672 -0
  198. package/dist/types.js +1 -0
  199. package/dist/usage-collection.d.ts +14 -0
  200. package/dist/usage-collection.js +377 -0
  201. package/dist/views/BulkRunsHub/BatchRow.d.ts +32 -0
  202. package/dist/views/BulkRunsHub/BatchRow.js +1222 -0
  203. package/dist/views/BulkRunsHub/BucketRow.d.ts +62 -0
  204. package/dist/views/BulkRunsHub/BucketRow.js +982 -0
  205. package/dist/views/BulkRunsHub/BulkRunsHub.client.d.ts +18 -0
  206. package/dist/views/BulkRunsHub/BulkRunsHub.client.js +331 -0
  207. package/dist/views/BulkRunsHub/EmptyState.d.ts +6 -0
  208. package/dist/views/BulkRunsHub/EmptyState.js +64 -0
  209. package/dist/views/BulkRunsHub/FilterBar.d.ts +16 -0
  210. package/dist/views/BulkRunsHub/FilterBar.js +284 -0
  211. package/dist/views/BulkRunsHub/InFlightBanner.d.ts +14 -0
  212. package/dist/views/BulkRunsHub/InFlightBanner.js +59 -0
  213. package/dist/views/BulkRunsHub/StatusBadge.d.ts +64 -0
  214. package/dist/views/BulkRunsHub/StatusBadge.js +248 -0
  215. package/dist/views/BulkRunsHub/SummaryStrip.d.ts +22 -0
  216. package/dist/views/BulkRunsHub/SummaryStrip.js +249 -0
  217. package/dist/views/BulkRunsHub/bucket-grouping.d.ts +200 -0
  218. package/dist/views/BulkRunsHub/bucket-grouping.js +344 -0
  219. package/dist/views/BulkRunsHub/bucketFailureSummary.d.ts +9 -0
  220. package/dist/views/BulkRunsHub/bucketFailureSummary.js +36 -0
  221. package/dist/views/BulkRunsHub/dedupedStatusFetch.d.ts +5 -0
  222. package/dist/views/BulkRunsHub/dedupedStatusFetch.js +45 -0
  223. package/dist/views/BulkRunsHub/index.d.ts +17 -0
  224. package/dist/views/BulkRunsHub/index.js +80 -0
  225. package/dist/views/BulkRunsHub/urlFilters.d.ts +14 -0
  226. package/dist/views/BulkRunsHub/urlFilters.js +50 -0
  227. package/dist/views/BulkRunsHub/useBulkRunsList.d.ts +26 -0
  228. package/dist/views/BulkRunsHub/useBulkRunsList.js +204 -0
  229. package/dist/views/BulkRunsHub/useUrlFilters.d.ts +10 -0
  230. package/dist/views/BulkRunsHub/useUrlFilters.js +88 -0
  231. package/dist/views/TranslationHub/ActiveJobs.d.ts +6 -0
  232. package/dist/views/TranslationHub/ActiveJobs.js +320 -0
  233. package/dist/views/TranslationHub/AdvancedPanel.d.ts +17 -0
  234. package/dist/views/TranslationHub/AdvancedPanel.js +996 -0
  235. package/dist/views/TranslationHub/AlertBanner.d.ts +6 -0
  236. package/dist/views/TranslationHub/AlertBanner.js +568 -0
  237. package/dist/views/TranslationHub/AuditPanel.d.ts +6 -0
  238. package/dist/views/TranslationHub/AuditPanel.helpers.d.ts +44 -0
  239. package/dist/views/TranslationHub/AuditPanel.helpers.js +71 -0
  240. package/dist/views/TranslationHub/AuditPanel.js +1367 -0
  241. package/dist/views/TranslationHub/BulkTranslate.types.d.ts +242 -0
  242. package/dist/views/TranslationHub/BulkTranslate.types.js +36 -0
  243. package/dist/views/TranslationHub/BulkTranslateFailureDrawer.d.ts +19 -0
  244. package/dist/views/TranslationHub/BulkTranslateFailureDrawer.js +332 -0
  245. package/dist/views/TranslationHub/BulkTranslateMonitor.d.ts +28 -0
  246. package/dist/views/TranslationHub/BulkTranslateMonitor.js +305 -0
  247. package/dist/views/TranslationHub/BulkTranslateNarrowViewportBanner.d.ts +3 -0
  248. package/dist/views/TranslationHub/BulkTranslateNarrowViewportBanner.js +42 -0
  249. package/dist/views/TranslationHub/BulkTranslatePostEnqueueTransition.d.ts +26 -0
  250. package/dist/views/TranslationHub/BulkTranslatePostEnqueueTransition.js +95 -0
  251. package/dist/views/TranslationHub/BulkTranslatePreflightModal.d.ts +22 -0
  252. package/dist/views/TranslationHub/BulkTranslatePreflightModal.js +879 -0
  253. package/dist/views/TranslationHub/BulkTranslateTerminalCard.d.ts +29 -0
  254. package/dist/views/TranslationHub/BulkTranslateTerminalCard.js +445 -0
  255. package/dist/views/TranslationHub/BulkTranslateTrigger.d.ts +66 -0
  256. package/dist/views/TranslationHub/BulkTranslateTrigger.js +161 -0
  257. package/dist/views/TranslationHub/EditorRecentRunsPanel.d.ts +33 -0
  258. package/dist/views/TranslationHub/EditorRecentRunsPanel.js +290 -0
  259. package/dist/views/TranslationHub/Hub.client.d.ts +74 -0
  260. package/dist/views/TranslationHub/Hub.client.js +357 -0
  261. package/dist/views/TranslationHub/ModelCombobox.d.ts +14 -0
  262. package/dist/views/TranslationHub/ModelCombobox.js +415 -0
  263. package/dist/views/TranslationHub/PerCollectionConfig.d.ts +10 -0
  264. package/dist/views/TranslationHub/PerCollectionConfig.helpers.d.ts +16 -0
  265. package/dist/views/TranslationHub/PerCollectionConfig.helpers.js +19 -0
  266. package/dist/views/TranslationHub/PerCollectionConfig.js +759 -0
  267. package/dist/views/TranslationHub/SettingsRail.d.ts +11 -0
  268. package/dist/views/TranslationHub/SettingsRail.js +382 -0
  269. package/dist/views/TranslationHub/StatusStrip.d.ts +6 -0
  270. package/dist/views/TranslationHub/StatusStrip.js +451 -0
  271. package/dist/views/TranslationHub/UsageTable.d.ts +6 -0
  272. package/dist/views/TranslationHub/UsageTable.helpers.d.ts +69 -0
  273. package/dist/views/TranslationHub/UsageTable.helpers.js +49 -0
  274. package/dist/views/TranslationHub/UsageTable.js +1240 -0
  275. package/dist/views/TranslationHub/alertGrouping.d.ts +70 -0
  276. package/dist/views/TranslationHub/alertGrouping.js +99 -0
  277. package/dist/views/TranslationHub/index.d.ts +20 -0
  278. package/dist/views/TranslationHub/index.js +109 -0
  279. package/dist/views/TranslationHub/tabNavigation.d.ts +53 -0
  280. package/dist/views/TranslationHub/tabNavigation.js +74 -0
  281. package/dist/views/TranslationHub/terminalBannerVisibility.d.ts +33 -0
  282. package/dist/views/TranslationHub/terminalBannerVisibility.js +124 -0
  283. package/dist/views/TranslationHub/useBulkTranslateActive.d.ts +49 -0
  284. package/dist/views/TranslationHub/useBulkTranslateActive.js +251 -0
  285. package/dist/views/TranslationHub/useFocusTrap.d.ts +6 -0
  286. package/dist/views/TranslationHub/useFocusTrap.js +81 -0
  287. package/dist/views/TranslationHub/useTranslationHubUsageSummary.d.ts +77 -0
  288. package/dist/views/TranslationHub/useTranslationHubUsageSummary.js +267 -0
  289. package/dist/views/shared/EditorError.d.ts +97 -0
  290. package/dist/views/shared/EditorError.js +205 -0
  291. package/dist/views/shared/ModelCell.d.ts +18 -0
  292. package/dist/views/shared/ModelCell.js +31 -0
  293. package/dist/views/shared/docHref.d.ts +16 -0
  294. package/dist/views/shared/docHref.js +26 -0
  295. package/dist/views/shared/fetch-error-body.d.ts +25 -0
  296. package/dist/views/shared/fetch-error-body.js +42 -0
  297. package/dist/views/shared/filterPillStyle.d.ts +35 -0
  298. package/dist/views/shared/filterPillStyle.js +40 -0
  299. package/dist/views/shared/format.d.ts +75 -0
  300. package/dist/views/shared/format.js +131 -0
  301. package/package.json +141 -0
@@ -0,0 +1,18 @@
1
+ import type React from 'react';
2
+ interface BulkRunsHubClientProps {
3
+ /**
4
+ * 1.2.8: viewer role. Editors see the same table layout, but the
5
+ * action menu on each row (cancel / retry / revert) is hidden on
6
+ * rows where `triggeredByUserId !== currentUserId`. Cost / token /
7
+ * model fields are absent from the response (server-side field
8
+ * masking on the batches collection) so the editor variant of the
9
+ * row simply has fewer columns; no client-side filtering needed.
10
+ */
11
+ role?: 'admin' | 'editor';
12
+ /** 1.2.8: current user id (stringified). Used for ownership chip. */
13
+ currentUserId?: string | null;
14
+ /** 1.2.8: current user email. Used in modal copy. */
15
+ currentUserEmail?: string | null;
16
+ }
17
+ export declare const BulkRunsHubClient: React.FC<BulkRunsHubClientProps>;
18
+ export {};
@@ -0,0 +1,331 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useMemo, useState } from 'react';
4
+ import { BatchRow } from './BatchRow.js';
5
+ import { EmptyState } from './EmptyState.js';
6
+ import { dateRangeInvalid, FilterBar } from './FilterBar.js';
7
+ import { InFlightBanner } from './InFlightBanner.js';
8
+ import { StatusBadgeKeyframes } from './StatusBadge.js';
9
+ import { SummaryStrip } from './SummaryStrip.js';
10
+ import { useBulkRunsList } from './useBulkRunsList.js';
11
+ import { DEFAULT_FILTERS, useUrlFilters } from './useUrlFilters.js';
12
+ // ---------------------------------------------------------------------------
13
+ // Helpers
14
+ // ---------------------------------------------------------------------------
15
+ function getBasePath() {
16
+ if (typeof window === 'undefined') return '';
17
+ const idx = window.location.pathname.indexOf('/admin/');
18
+ return idx > 0 ? window.location.pathname.slice(0, idx) : '';
19
+ }
20
+ const TABLE_COL_COUNT = 7;
21
+ const TH_STYLE = {
22
+ textAlign: 'left',
23
+ padding: '0.5rem 0.5rem',
24
+ fontSize: '0.7rem',
25
+ fontWeight: 600,
26
+ textTransform: 'uppercase',
27
+ letterSpacing: '0.05em',
28
+ color: 'var(--theme-elevation-500)',
29
+ borderBottom: '1px solid var(--theme-elevation-150)',
30
+ whiteSpace: 'nowrap'
31
+ };
32
+ export const BulkRunsHubClient = ({ role = 'admin', currentUserId = null, currentUserEmail = null })=>{
33
+ // 1.2.8: pre-mark currently unused identity props for future
34
+ // table-row gating (Phase 6). Reference them here so the linter
35
+ // doesn't flag them as dead.
36
+ void currentUserId;
37
+ void currentUserEmail;
38
+ void role;
39
+ const basePath = useMemo(getBasePath, []);
40
+ // BR-7 (v1.2.6): filter + time-range state live in the URL so the
41
+ // view is refresh-stable and shareable. `useUrlFilters` reads from
42
+ // `useSearchParams()` and writes via `router.replace({ scroll: false })`.
43
+ const { filters, timeRange, setFilters, setTimeRange } = useUrlFilters();
44
+ const [expandedBatchId, setExpandedBatchId] = useState(null);
45
+ // NEW-19 (v1.2.6): if Since > Until, the filter is illogical — we
46
+ // pass DEFAULT_FILTERS to the table hook to avoid sending a bad
47
+ // request and surface an explanation alongside the inline message
48
+ // that FilterBar renders.
49
+ const invalidDates = dateRangeInvalid(filters);
50
+ const effectiveTableFilters = invalidDates ? DEFAULT_FILTERS : filters;
51
+ const { data, loading, error, isOffline, refetch, loadMore, loadingMore } = useBulkRunsList(basePath, effectiveTableFilters);
52
+ // BR-6 (v1.2.6): the SummaryStrip KPIs above the table are scoped to
53
+ // the time-range pill, NOT the table filter. Before, clicking the
54
+ // "Failed" status pill silently re-pointed the "Last 7 days cost"
55
+ // card at filtered-only-failed rows ($0.00) while the caption kept
56
+ // claiming "Last 7 days". Decoupling means a second `useBulkRunsList`
57
+ // call with no filters so the KPIs stay tied to the window.
58
+ // Polling cost is the same shape (one extra GET per 5s tick); the
59
+ // table-filtered list still drives the batch rows.
60
+ const { data: unfilteredData } = useBulkRunsList(basePath, DEFAULT_FILTERS);
61
+ const batches = data?.batches ?? [];
62
+ const total = data?.total ?? 0;
63
+ const unfilteredBatches = unfilteredData?.batches ?? [];
64
+ const unfilteredTotal = unfilteredData?.total ?? 0;
65
+ function patchFilters(patch) {
66
+ setFilters(patch);
67
+ // When filters change, collapse any open row so the user isn't looking
68
+ // at stale drill-down data.
69
+ setExpandedBatchId(null);
70
+ }
71
+ function toggleExpanded(batchId) {
72
+ setExpandedBatchId((prev)=>prev === batchId ? null : batchId);
73
+ }
74
+ return /*#__PURE__*/ _jsxs("div", {
75
+ style: {
76
+ padding: '1.5rem 2rem',
77
+ maxWidth: '1400px',
78
+ margin: '0 auto'
79
+ },
80
+ children: [
81
+ /*#__PURE__*/ _jsx(StatusBadgeKeyframes, {}),
82
+ /*#__PURE__*/ _jsxs("header", {
83
+ style: {
84
+ marginBottom: '1.5rem'
85
+ },
86
+ children: [
87
+ /*#__PURE__*/ _jsx("div", {
88
+ style: {
89
+ display: 'flex',
90
+ alignItems: 'baseline',
91
+ justifyContent: 'space-between',
92
+ marginBottom: '0.25rem'
93
+ },
94
+ children: /*#__PURE__*/ _jsx("h1", {
95
+ style: {
96
+ fontSize: '1.5rem',
97
+ margin: 0,
98
+ color: 'var(--theme-elevation-1000)'
99
+ },
100
+ children: "Translation Runs"
101
+ })
102
+ }),
103
+ /*#__PURE__*/ _jsx("p", {
104
+ style: {
105
+ margin: 0,
106
+ color: 'var(--theme-elevation-500)',
107
+ fontSize: '0.875rem'
108
+ },
109
+ children: "History and status of every bulk translate batch. Click a row to drill into per-unit detail."
110
+ })
111
+ ]
112
+ }),
113
+ /*#__PURE__*/ _jsxs("main", {
114
+ style: {
115
+ display: 'flex',
116
+ flexDirection: 'column',
117
+ gap: '1rem'
118
+ },
119
+ children: [
120
+ isOffline && /*#__PURE__*/ _jsxs("div", {
121
+ role: "status",
122
+ style: {
123
+ padding: '0.5rem 0.75rem',
124
+ background: 'var(--theme-warning-100, #fef3c7)',
125
+ border: '1px solid var(--theme-warning-500, #d97706)',
126
+ borderRadius: '4px',
127
+ display: 'flex',
128
+ alignItems: 'center',
129
+ justifyContent: 'space-between',
130
+ fontSize: '0.8125rem',
131
+ color: 'var(--theme-warning-500, #d97706)'
132
+ },
133
+ children: [
134
+ /*#__PURE__*/ _jsx("span", {
135
+ children: "Connection lost — data may be stale"
136
+ }),
137
+ /*#__PURE__*/ _jsx("button", {
138
+ type: "button",
139
+ onClick: refetch,
140
+ style: {
141
+ background: 'transparent',
142
+ border: 'none',
143
+ color: 'inherit',
144
+ textDecoration: 'underline',
145
+ cursor: 'pointer',
146
+ fontSize: 'inherit'
147
+ },
148
+ children: "Retry now"
149
+ })
150
+ ]
151
+ }),
152
+ error && /*#__PURE__*/ _jsxs("div", {
153
+ style: {
154
+ padding: '0.75rem 1rem',
155
+ background: 'var(--theme-error-100, #fee2e2)',
156
+ border: '1px solid var(--theme-error-500, #b91c1c)',
157
+ borderRadius: '4px',
158
+ color: 'var(--theme-error-500, #b91c1c)',
159
+ fontSize: '0.875rem'
160
+ },
161
+ children: [
162
+ "Failed to load runs: ",
163
+ error
164
+ ]
165
+ }),
166
+ /*#__PURE__*/ _jsx(SummaryStrip, {
167
+ batches: unfilteredBatches,
168
+ total: unfilteredTotal,
169
+ timeRange: timeRange,
170
+ onTimeRangeChange: setTimeRange,
171
+ hasCustomDateFilter: Boolean(filters.since || filters.until)
172
+ }),
173
+ /*#__PURE__*/ _jsx(InFlightBanner, {
174
+ batches: batches
175
+ }),
176
+ /*#__PURE__*/ _jsx(FilterBar, {
177
+ filters: filters,
178
+ onChange: patchFilters,
179
+ batches: batches
180
+ }),
181
+ loading && /*#__PURE__*/ _jsx("div", {
182
+ role: "status",
183
+ "aria-live": "polite",
184
+ style: {
185
+ padding: '2rem',
186
+ textAlign: 'center',
187
+ color: 'var(--theme-elevation-500)',
188
+ fontSize: '0.875rem'
189
+ },
190
+ children: "Loading runs…"
191
+ }),
192
+ !loading && !invalidDates && total === 0 && !error && /*#__PURE__*/ _jsx(EmptyState, {
193
+ basePath: basePath
194
+ }),
195
+ !loading && !invalidDates && batches.length > 0 && /*#__PURE__*/ _jsxs("div", {
196
+ style: {
197
+ background: 'var(--theme-elevation-50)',
198
+ border: '1px solid var(--theme-elevation-150)',
199
+ borderRadius: '6px',
200
+ overflow: 'hidden'
201
+ },
202
+ children: [
203
+ /*#__PURE__*/ _jsx("div", {
204
+ style: {
205
+ overflowX: 'auto'
206
+ },
207
+ children: /*#__PURE__*/ _jsxs("table", {
208
+ style: {
209
+ width: '100%',
210
+ borderCollapse: 'collapse',
211
+ fontSize: '0.875rem',
212
+ color: 'var(--theme-elevation-800)'
213
+ },
214
+ children: [
215
+ /*#__PURE__*/ _jsx("thead", {
216
+ children: /*#__PURE__*/ _jsxs("tr", {
217
+ children: [
218
+ /*#__PURE__*/ _jsx("th", {
219
+ style: {
220
+ ...TH_STYLE,
221
+ width: '140px'
222
+ },
223
+ children: "Status"
224
+ }),
225
+ /*#__PURE__*/ _jsx("th", {
226
+ style: {
227
+ ...TH_STYLE,
228
+ minWidth: '160px'
229
+ },
230
+ children: "Batch / trigger"
231
+ }),
232
+ /*#__PURE__*/ _jsx("th", {
233
+ style: {
234
+ ...TH_STYLE,
235
+ width: '120px'
236
+ },
237
+ children: "Mode"
238
+ }),
239
+ /*#__PURE__*/ _jsx("th", {
240
+ style: {
241
+ ...TH_STYLE,
242
+ width: '160px'
243
+ },
244
+ children: "Progress"
245
+ }),
246
+ /*#__PURE__*/ _jsx("th", {
247
+ style: {
248
+ ...TH_STYLE,
249
+ width: '80px',
250
+ textAlign: 'right'
251
+ },
252
+ children: "Cost"
253
+ }),
254
+ /*#__PURE__*/ _jsx("th", {
255
+ style: {
256
+ ...TH_STYLE,
257
+ width: '70px',
258
+ textAlign: 'right'
259
+ },
260
+ title: "Wallclock between when the worker first picked up the batch and when the last unit landed. Includes queue waits — for active-work time expand a row.",
261
+ children: "Wallclock"
262
+ }),
263
+ /*#__PURE__*/ _jsx("th", {
264
+ style: {
265
+ ...TH_STYLE,
266
+ width: '90px',
267
+ textAlign: 'right'
268
+ },
269
+ children: "When"
270
+ })
271
+ ]
272
+ })
273
+ }),
274
+ /*#__PURE__*/ _jsx("tbody", {
275
+ children: batches.map((batch)=>/*#__PURE__*/ _jsx(BatchRow, {
276
+ basePath: basePath,
277
+ batch: batch,
278
+ isExpanded: expandedBatchId === batch.id,
279
+ onToggle: ()=>toggleExpanded(batch.id),
280
+ onAfterAction: refetch,
281
+ colCount: TABLE_COL_COUNT
282
+ }, batch.id))
283
+ })
284
+ ]
285
+ })
286
+ }),
287
+ data?.nextCursor && /*#__PURE__*/ _jsxs("div", {
288
+ style: {
289
+ padding: '0.75rem 1rem',
290
+ borderTop: '1px solid var(--theme-elevation-100)',
291
+ display: 'flex',
292
+ alignItems: 'center',
293
+ gap: '0.75rem'
294
+ },
295
+ children: [
296
+ /*#__PURE__*/ _jsx("button", {
297
+ type: "button",
298
+ disabled: loadingMore,
299
+ onClick: ()=>loadMore(),
300
+ style: {
301
+ padding: '0.35rem 0.85rem',
302
+ background: 'transparent',
303
+ border: '1px solid var(--theme-elevation-300)',
304
+ borderRadius: '4px',
305
+ color: 'var(--theme-elevation-800)',
306
+ fontSize: '0.8125rem',
307
+ cursor: loadingMore ? 'not-allowed' : 'pointer'
308
+ },
309
+ children: loadingMore ? 'Loading…' : 'Load more'
310
+ }),
311
+ /*#__PURE__*/ _jsxs("span", {
312
+ style: {
313
+ fontSize: '0.75rem',
314
+ color: 'var(--theme-elevation-500)'
315
+ },
316
+ children: [
317
+ "Showing ",
318
+ batches.length,
319
+ " of ",
320
+ total
321
+ ]
322
+ })
323
+ ]
324
+ })
325
+ ]
326
+ })
327
+ ]
328
+ })
329
+ ]
330
+ });
331
+ };
@@ -0,0 +1,6 @@
1
+ import type React from 'react';
2
+ interface Props {
3
+ basePath: string;
4
+ }
5
+ export declare const EmptyState: React.FC<Props>;
6
+ export {};
@@ -0,0 +1,64 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ export const EmptyState = ({ basePath })=>/*#__PURE__*/ _jsxs("div", {
4
+ style: {
5
+ display: 'flex',
6
+ flexDirection: 'column',
7
+ alignItems: 'center',
8
+ justifyContent: 'center',
9
+ padding: '4rem 2rem',
10
+ textAlign: 'center',
11
+ background: 'var(--theme-elevation-50)',
12
+ border: '1px solid var(--theme-elevation-150)',
13
+ borderRadius: '6px'
14
+ },
15
+ children: [
16
+ /*#__PURE__*/ _jsx("p", {
17
+ style: {
18
+ fontSize: '2rem',
19
+ margin: '0 0 0.5rem',
20
+ color: 'var(--theme-elevation-300)',
21
+ lineHeight: 1,
22
+ userSelect: 'none'
23
+ },
24
+ "aria-hidden": "true",
25
+ children: "○"
26
+ }),
27
+ /*#__PURE__*/ _jsx("h2", {
28
+ style: {
29
+ margin: '0 0 0.5rem',
30
+ fontSize: '1rem',
31
+ fontWeight: 600,
32
+ color: 'var(--theme-elevation-1000)'
33
+ },
34
+ children: "No bulk translate runs yet."
35
+ }),
36
+ /*#__PURE__*/ _jsx("p", {
37
+ style: {
38
+ margin: '0 0 1.25rem',
39
+ fontSize: '0.875rem',
40
+ color: 'var(--theme-elevation-500)',
41
+ maxWidth: '360px',
42
+ lineHeight: 1.5
43
+ },
44
+ children: "Start a bulk run from the Translation Hub overview tab to translate all content in a collection at once."
45
+ }),
46
+ /*#__PURE__*/ _jsx("a", {
47
+ href: `${basePath}/admin/translation`,
48
+ style: {
49
+ display: 'inline-flex',
50
+ alignItems: 'center',
51
+ gap: '0.25rem',
52
+ padding: '0.4rem 0.85rem',
53
+ background: 'transparent',
54
+ border: '1px solid var(--theme-elevation-300)',
55
+ borderRadius: '4px',
56
+ color: 'var(--theme-elevation-800)',
57
+ fontSize: '0.8125rem',
58
+ textDecoration: 'none',
59
+ fontWeight: 500
60
+ },
61
+ children: "Go to Translation Hub →"
62
+ })
63
+ ]
64
+ });
@@ -0,0 +1,16 @@
1
+ import type React from 'react';
2
+ import type { BulkRunsFilterState, BulkTranslateBatchSummary } from '../TranslationHub/BulkTranslate.types.js';
3
+ /**
4
+ * NEW-19 (v1.2.6): true when both Since and Until are set but Until
5
+ * precedes Since. Pure helper so the inline error / aria-invalid /
6
+ * input min-max can all read the same source of truth.
7
+ */
8
+ export declare function dateRangeInvalid(filters: BulkRunsFilterState): boolean;
9
+ interface Props {
10
+ filters: BulkRunsFilterState;
11
+ onChange: (patch: Partial<BulkRunsFilterState>) => void;
12
+ /** Loaded batches — used to build the triggered-by autocomplete list. */
13
+ batches: BulkTranslateBatchSummary[];
14
+ }
15
+ export declare const FilterBar: React.FC<Props>;
16
+ export {};