@easyling/sanity-connector 0.0.1 → 0.0.2-rc.1

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 (242) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/package.json +18 -12
  3. package/dist/actions/bulkTranslate.d.ts +0 -7
  4. package/dist/actions/bulkTranslate.d.ts.map +0 -1
  5. package/dist/actions/bulkTranslate.js +0 -543
  6. package/dist/actions/bulkTranslate.js.map +0 -1
  7. package/dist/actions/manageDNTFields.d.ts +0 -12
  8. package/dist/actions/manageDNTFields.d.ts.map +0 -1
  9. package/dist/actions/manageDNTFields.js +0 -100
  10. package/dist/actions/manageDNTFields.js.map +0 -1
  11. package/dist/actions/translateDocument.d.ts +0 -7
  12. package/dist/actions/translateDocument.d.ts.map +0 -1
  13. package/dist/actions/translateDocument.js +0 -256
  14. package/dist/actions/translateDocument.js.map +0 -1
  15. package/dist/components/RadioWithDefault.d.ts +0 -17
  16. package/dist/components/RadioWithDefault.d.ts.map +0 -1
  17. package/dist/components/RadioWithDefault.js +0 -29
  18. package/dist/components/RadioWithDefault.js.map +0 -1
  19. package/dist/components/auth/AuthNavbar.d.ts +0 -18
  20. package/dist/components/auth/AuthNavbar.d.ts.map +0 -1
  21. package/dist/components/auth/AuthNavbar.js +0 -15
  22. package/dist/components/auth/AuthNavbar.js.map +0 -1
  23. package/dist/components/auth/AuthStatus.d.ts +0 -27
  24. package/dist/components/auth/AuthStatus.d.ts.map +0 -1
  25. package/dist/components/auth/AuthStatus.js +0 -82
  26. package/dist/components/auth/AuthStatus.js.map +0 -1
  27. package/dist/components/auth/AuthStatusWrapper.d.ts +0 -15
  28. package/dist/components/auth/AuthStatusWrapper.d.ts.map +0 -1
  29. package/dist/components/auth/AuthStatusWrapper.js +0 -39
  30. package/dist/components/auth/AuthStatusWrapper.js.map +0 -1
  31. package/dist/components/auth/MigrationPrompt.d.ts +0 -20
  32. package/dist/components/auth/MigrationPrompt.d.ts.map +0 -1
  33. package/dist/components/auth/MigrationPrompt.js +0 -16
  34. package/dist/components/auth/MigrationPrompt.js.map +0 -1
  35. package/dist/components/auth/MigrationPromptWrapper.d.ts +0 -14
  36. package/dist/components/auth/MigrationPromptWrapper.d.ts.map +0 -1
  37. package/dist/components/auth/MigrationPromptWrapper.js +0 -16
  38. package/dist/components/auth/MigrationPromptWrapper.js.map +0 -1
  39. package/dist/components/auth/OAuthCallback.d.ts +0 -20
  40. package/dist/components/auth/OAuthCallback.d.ts.map +0 -1
  41. package/dist/components/auth/OAuthCallback.js +0 -12
  42. package/dist/components/auth/OAuthCallback.js.map +0 -1
  43. package/dist/components/auth/index.d.ts +0 -15
  44. package/dist/components/auth/index.d.ts.map +0 -1
  45. package/dist/components/auth/index.js +0 -12
  46. package/dist/components/auth/index.js.map +0 -1
  47. package/dist/components/config/LocaleConfigTool.d.ts +0 -17
  48. package/dist/components/config/LocaleConfigTool.d.ts.map +0 -1
  49. package/dist/components/config/LocaleConfigTool.js +0 -186
  50. package/dist/components/config/LocaleConfigTool.js.map +0 -1
  51. package/dist/components/config/LocaleConfigToolWrapper.d.ts +0 -13
  52. package/dist/components/config/LocaleConfigToolWrapper.d.ts.map +0 -1
  53. package/dist/components/config/LocaleConfigToolWrapper.js +0 -26
  54. package/dist/components/config/LocaleConfigToolWrapper.js.map +0 -1
  55. package/dist/components/config/OAuthConfig.d.ts +0 -26
  56. package/dist/components/config/OAuthConfig.d.ts.map +0 -1
  57. package/dist/components/config/OAuthConfig.js +0 -152
  58. package/dist/components/config/OAuthConfig.js.map +0 -1
  59. package/dist/components/config/OAuthConfigWrapper.d.ts +0 -13
  60. package/dist/components/config/OAuthConfigWrapper.d.ts.map +0 -1
  61. package/dist/components/config/OAuthConfigWrapper.js +0 -41
  62. package/dist/components/config/OAuthConfigWrapper.js.map +0 -1
  63. package/dist/components/config/PasswordInput.d.ts +0 -14
  64. package/dist/components/config/PasswordInput.d.ts.map +0 -1
  65. package/dist/components/config/PasswordInput.js +0 -23
  66. package/dist/components/config/PasswordInput.js.map +0 -1
  67. package/dist/components/config/index.d.ts +0 -9
  68. package/dist/components/config/index.d.ts.map +0 -1
  69. package/dist/components/config/index.js +0 -8
  70. package/dist/components/config/index.js.map +0 -1
  71. package/dist/components/config/localeConfigToolDefinition.d.ts +0 -13
  72. package/dist/components/config/localeConfigToolDefinition.d.ts.map +0 -1
  73. package/dist/components/config/localeConfigToolDefinition.js +0 -19
  74. package/dist/components/config/localeConfigToolDefinition.js.map +0 -1
  75. package/dist/components/config/oauthConfigToolDefinition.d.ts +0 -13
  76. package/dist/components/config/oauthConfigToolDefinition.d.ts.map +0 -1
  77. package/dist/components/config/oauthConfigToolDefinition.js +0 -19
  78. package/dist/components/config/oauthConfigToolDefinition.js.map +0 -1
  79. package/dist/components/dialogs/ConfirmationDialog.d.ts +0 -21
  80. package/dist/components/dialogs/ConfirmationDialog.d.ts.map +0 -1
  81. package/dist/components/dialogs/ConfirmationDialog.js +0 -28
  82. package/dist/components/dialogs/ConfirmationDialog.js.map +0 -1
  83. package/dist/components/dialogs/ErrorDialog.d.ts +0 -21
  84. package/dist/components/dialogs/ErrorDialog.d.ts.map +0 -1
  85. package/dist/components/dialogs/ErrorDialog.js +0 -28
  86. package/dist/components/dialogs/ErrorDialog.js.map +0 -1
  87. package/dist/components/dialogs/LocaleSelectionDialog.d.ts +0 -41
  88. package/dist/components/dialogs/LocaleSelectionDialog.d.ts.map +0 -1
  89. package/dist/components/dialogs/LocaleSelectionDialog.js +0 -117
  90. package/dist/components/dialogs/LocaleSelectionDialog.js.map +0 -1
  91. package/dist/components/dialogs/SuccessDialog.d.ts +0 -19
  92. package/dist/components/dialogs/SuccessDialog.d.ts.map +0 -1
  93. package/dist/components/dialogs/SuccessDialog.js +0 -37
  94. package/dist/components/dialogs/SuccessDialog.js.map +0 -1
  95. package/dist/components/dialogs/index.d.ts +0 -12
  96. package/dist/components/dialogs/index.d.ts.map +0 -1
  97. package/dist/components/dialogs/index.js +0 -8
  98. package/dist/components/dialogs/index.js.map +0 -1
  99. package/dist/components/dnt/DNTFieldBadge.d.ts +0 -16
  100. package/dist/components/dnt/DNTFieldBadge.d.ts.map +0 -1
  101. package/dist/components/dnt/DNTFieldBadge.js +0 -56
  102. package/dist/components/dnt/DNTFieldBadge.js.map +0 -1
  103. package/dist/components/dnt/DNTFieldComponent.d.ts +0 -17
  104. package/dist/components/dnt/DNTFieldComponent.d.ts.map +0 -1
  105. package/dist/components/dnt/DNTFieldComponent.js +0 -21
  106. package/dist/components/dnt/DNTFieldComponent.js.map +0 -1
  107. package/dist/components/dnt/DNTFieldInput.d.ts +0 -14
  108. package/dist/components/dnt/DNTFieldInput.d.ts.map +0 -1
  109. package/dist/components/dnt/DNTFieldInput.js +0 -76
  110. package/dist/components/dnt/DNTFieldInput.js.map +0 -1
  111. package/dist/components/dnt/index.d.ts +0 -7
  112. package/dist/components/dnt/index.d.ts.map +0 -1
  113. package/dist/components/dnt/index.js +0 -7
  114. package/dist/components/dnt/index.js.map +0 -1
  115. package/dist/config/index.d.ts +0 -6
  116. package/dist/config/index.d.ts.map +0 -1
  117. package/dist/config/index.js +0 -6
  118. package/dist/config/index.js.map +0 -1
  119. package/dist/config/pluginConfig.d.ts +0 -163
  120. package/dist/config/pluginConfig.d.ts.map +0 -1
  121. package/dist/config/pluginConfig.js +0 -548
  122. package/dist/config/pluginConfig.js.map +0 -1
  123. package/dist/index.d.ts +0 -12
  124. package/dist/index.d.ts.map +0 -1
  125. package/dist/index.js +0 -12
  126. package/dist/index.js.map +0 -1
  127. package/dist/plugin.d.ts +0 -3
  128. package/dist/plugin.d.ts.map +0 -1
  129. package/dist/plugin.js +0 -137
  130. package/dist/plugin.js.map +0 -1
  131. package/dist/services/authStateManager.d.ts +0 -94
  132. package/dist/services/authStateManager.d.ts.map +0 -1
  133. package/dist/services/authStateManager.js +0 -208
  134. package/dist/services/authStateManager.js.map +0 -1
  135. package/dist/services/contentExtractor.d.ts +0 -95
  136. package/dist/services/contentExtractor.d.ts.map +0 -1
  137. package/dist/services/contentExtractor.js +0 -516
  138. package/dist/services/contentExtractor.js.map +0 -1
  139. package/dist/services/dialogService.d.ts +0 -96
  140. package/dist/services/dialogService.d.ts.map +0 -1
  141. package/dist/services/dialogService.js +0 -244
  142. package/dist/services/dialogService.js.map +0 -1
  143. package/dist/services/dntServiceManager.d.ts +0 -44
  144. package/dist/services/dntServiceManager.d.ts.map +0 -1
  145. package/dist/services/dntServiceManager.js +0 -74
  146. package/dist/services/dntServiceManager.js.map +0 -1
  147. package/dist/services/dntStorageAdapter.d.ts +0 -73
  148. package/dist/services/dntStorageAdapter.d.ts.map +0 -1
  149. package/dist/services/dntStorageAdapter.js +0 -192
  150. package/dist/services/dntStorageAdapter.js.map +0 -1
  151. package/dist/services/documentCreationService.d.ts +0 -139
  152. package/dist/services/documentCreationService.d.ts.map +0 -1
  153. package/dist/services/documentCreationService.js +0 -938
  154. package/dist/services/documentCreationService.js.map +0 -1
  155. package/dist/services/localeService.d.ts +0 -160
  156. package/dist/services/localeService.d.ts.map +0 -1
  157. package/dist/services/localeService.js +0 -300
  158. package/dist/services/localeService.js.map +0 -1
  159. package/dist/services/localeStorageAdapter.d.ts +0 -42
  160. package/dist/services/localeStorageAdapter.d.ts.map +0 -1
  161. package/dist/services/localeStorageAdapter.js +0 -107
  162. package/dist/services/localeStorageAdapter.js.map +0 -1
  163. package/dist/services/oauthConfigStorage.d.ts +0 -46
  164. package/dist/services/oauthConfigStorage.d.ts.map +0 -1
  165. package/dist/services/oauthConfigStorage.js +0 -122
  166. package/dist/services/oauthConfigStorage.js.map +0 -1
  167. package/dist/services/oauthService.d.ts +0 -48
  168. package/dist/services/oauthService.d.ts.map +0 -1
  169. package/dist/services/oauthService.js +0 -71
  170. package/dist/services/oauthService.js.map +0 -1
  171. package/dist/services/oauthServiceManager.d.ts +0 -189
  172. package/dist/services/oauthServiceManager.d.ts.map +0 -1
  173. package/dist/services/oauthServiceManager.js +0 -380
  174. package/dist/services/oauthServiceManager.js.map +0 -1
  175. package/dist/services/tokenStorage.d.ts +0 -54
  176. package/dist/services/tokenStorage.d.ts.map +0 -1
  177. package/dist/services/tokenStorage.js +0 -140
  178. package/dist/services/tokenStorage.js.map +0 -1
  179. package/dist/services/translationService.d.ts +0 -374
  180. package/dist/services/translationService.d.ts.map +0 -1
  181. package/dist/services/translationService.js +0 -687
  182. package/dist/services/translationService.js.map +0 -1
  183. package/dist/services/unifiedConfigStorage.d.ts +0 -124
  184. package/dist/services/unifiedConfigStorage.d.ts.map +0 -1
  185. package/dist/services/unifiedConfigStorage.js +0 -304
  186. package/dist/services/unifiedConfigStorage.js.map +0 -1
  187. package/dist/test-utils.d.ts +0 -9
  188. package/dist/test-utils.d.ts.map +0 -1
  189. package/dist/test-utils.js +0 -13
  190. package/dist/test-utils.js.map +0 -1
  191. package/dist/types/dialog.d.ts +0 -107
  192. package/dist/types/dialog.d.ts.map +0 -1
  193. package/dist/types/dialog.js +0 -6
  194. package/dist/types/dialog.js.map +0 -1
  195. package/dist/types/dnt.d.ts +0 -84
  196. package/dist/types/dnt.d.ts.map +0 -1
  197. package/dist/types/dnt.js +0 -5
  198. package/dist/types/dnt.js.map +0 -1
  199. package/dist/types/index.d.ts +0 -12
  200. package/dist/types/index.d.ts.map +0 -1
  201. package/dist/types/index.js +0 -6
  202. package/dist/types/index.js.map +0 -1
  203. package/dist/types/locale.d.ts +0 -116
  204. package/dist/types/locale.d.ts.map +0 -1
  205. package/dist/types/locale.js +0 -189
  206. package/dist/types/locale.js.map +0 -1
  207. package/dist/types/oauth.d.ts +0 -90
  208. package/dist/types/oauth.d.ts.map +0 -1
  209. package/dist/types/oauth.js +0 -62
  210. package/dist/types/oauth.js.map +0 -1
  211. package/dist/types/pluginConfig.d.ts +0 -45
  212. package/dist/types/pluginConfig.d.ts.map +0 -1
  213. package/dist/types/pluginConfig.js +0 -6
  214. package/dist/types/pluginConfig.js.map +0 -1
  215. package/dist/types/translation.d.ts +0 -122
  216. package/dist/types/translation.d.ts.map +0 -1
  217. package/dist/types/translation.js +0 -6
  218. package/dist/types/translation.js.map +0 -1
  219. package/dist/utils/htmlFormatter.d.ts +0 -66
  220. package/dist/utils/htmlFormatter.d.ts.map +0 -1
  221. package/dist/utils/htmlFormatter.js +0 -191
  222. package/dist/utils/htmlFormatter.js.map +0 -1
  223. package/dist/utils/index.d.ts +0 -15
  224. package/dist/utils/index.d.ts.map +0 -1
  225. package/dist/utils/index.js +0 -16
  226. package/dist/utils/index.js.map +0 -1
  227. package/dist/utils/logger.d.ts +0 -105
  228. package/dist/utils/logger.d.ts.map +0 -1
  229. package/dist/utils/logger.js +0 -229
  230. package/dist/utils/logger.js.map +0 -1
  231. package/dist/utils/oauthErrorFeedback.d.ts +0 -76
  232. package/dist/utils/oauthErrorFeedback.d.ts.map +0 -1
  233. package/dist/utils/oauthErrorFeedback.js +0 -134
  234. package/dist/utils/oauthErrorFeedback.js.map +0 -1
  235. package/dist/utils/oauthLogger.d.ts +0 -176
  236. package/dist/utils/oauthLogger.d.ts.map +0 -1
  237. package/dist/utils/oauthLogger.js +0 -282
  238. package/dist/utils/oauthLogger.js.map +0 -1
  239. package/dist/utils/validator.d.ts +0 -67
  240. package/dist/utils/validator.d.ts.map +0 -1
  241. package/dist/utils/validator.js +0 -390
  242. package/dist/utils/validator.js.map +0 -1
package/package.json CHANGED
@@ -1,27 +1,28 @@
1
1
  {
2
2
  "name": "@easyling/sanity-connector",
3
- "version": "0.0.1",
3
+ "version": "0.0.2-rc.1",
4
4
  "description": "A Sanity Studio plugin that enables document translation with support for single and bulk operations. Extracts document content as HTML and prepares translation requests for external services.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
- "types": "dist/index.d.ts",
7
+ "types": "dist-types/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./dist/index.d.ts",
10
+ "types": "./dist-types/index.d.ts",
11
11
  "import": "./dist/index.js",
12
12
  "require": "./dist/index.js"
13
13
  }
14
14
  },
15
15
  "files": [
16
16
  "dist",
17
+ "dist-types",
17
18
  "README.md",
18
19
  "LICENSE"
19
20
  ],
20
21
  "scripts": {
21
22
  "build": "npm run clean && tsc",
22
- "build:bundle": "npm run clean && webpack build && tsc --project tsconfig.bundle.json",
23
+ "build:bundle": "npm run clean && webpack build && tsc --project tsconfig.types.json",
23
24
  "build:watch": "tsc --watch",
24
- "clean": "rimraf dist",
25
+ "clean": "rimraf dist dist-types",
25
26
  "dev": "npm run build:watch",
26
27
  "test": "jest",
27
28
  "test:watch": "jest --watch",
@@ -53,16 +54,16 @@
53
54
  },
54
55
  "homepage": "",
55
56
  "peerDependencies": {
56
- "react": "^18.0.0",
57
- "react-dom": "^18.0.0",
58
- "sanity": "^3.0.0"
57
+ "react": "^19.0.0",
58
+ "react-dom": "^19.0.0",
59
+ "sanity": "^4.0.0"
59
60
  },
60
61
  "devDependencies": {
61
62
  "@testing-library/jest-dom": "^6.9.1",
62
63
  "@testing-library/react": "^16.3.0",
63
64
  "@types/jest": "^29.0.0",
64
- "@types/react": "^18.0.0",
65
- "@types/react-dom": "^18.0.0",
65
+ "@types/react": "^19.0.0",
66
+ "@types/react-dom": "^19.0.0",
66
67
  "@typescript-eslint/eslint-plugin": "^6.21.0",
67
68
  "@typescript-eslint/parser": "^6.21.0",
68
69
  "eslint": "^8.0.0",
@@ -74,7 +75,12 @@
74
75
  "ts-loader": "^9.5.4",
75
76
  "typescript": "^5.0.0",
76
77
  "webpack": "^5.103.0",
77
- "webpack-cli": "^6.0.1",
78
- "@easyling/sanity": "^1.0.6"
78
+ "@easyling/sanity": "^1.0.6",
79
+ "webpack-cli": "^6.0.1"
80
+ },
81
+ "dependencies": {
82
+ "@sanity/icons": "^2.0.0",
83
+ "@sanity/ui": "^1.0.0",
84
+ "protobufjs": "^7.5.4"
79
85
  }
80
86
  }
@@ -1,7 +0,0 @@
1
- import { Tool } from 'sanity';
2
- /**
3
- * Bulk Translation Tool Definition
4
- * Requirements: 2.1, 2.5, 4.1, 4.2
5
- */
6
- export declare const bulkTranslateTool: Tool;
7
- //# sourceMappingURL=bulkTranslate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bulkTranslate.d.ts","sourceRoot":"","sources":["../../src/actions/bulkTranslate.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAA6B,MAAM,QAAQ,CAAC;AA8lCzD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAK/B,CAAC"}
@@ -1,543 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useCallback, useEffect } from 'react';
3
- import { useClient } from 'sanity';
4
- import { TranslateIcon, CheckmarkIcon, CloseIcon, WarningOutlineIcon, RefreshIcon, ChevronDownIcon, ChevronRightIcon } from '@sanity/icons';
5
- import { Card, Stack, Text, Button, Flex, Box, Spinner, Badge, Checkbox } from '@sanity/ui';
6
- import { ContentExtractor } from '../services/contentExtractor';
7
- import { DocumentCreationService } from '../services/documentCreationService';
8
- import { LocaleService } from '../services/localeService';
9
- import { SanityLocaleStorageAdapter } from '../services/localeStorageAdapter';
10
- import { useDialogService } from '../services/dialogService';
11
- import { OAuthServiceManager } from '../services/oauthServiceManager';
12
- /**
13
- * Bulk Translation Tool Component
14
- * Requirements: 2.2, 2.4, 3.1, 3.4, 4.1, 4.3
15
- */
16
- const BulkTranslateTool = () => {
17
- const client = useClient();
18
- const dialogService = useDialogService();
19
- const [state, setState] = useState({
20
- isProcessing: false,
21
- isLoadingDocuments: false,
22
- selectedDocuments: [],
23
- availableDocuments: {},
24
- selectedTypes: new Set(),
25
- selectedDocumentIds: new Set(),
26
- expandedTypes: new Set(),
27
- summary: null,
28
- error: null,
29
- processingStatus: [],
30
- currentProcessingIndex: -1,
31
- createDocuments: false,
32
- documentCreationResult: null,
33
- selectedLocales: null
34
- });
35
- /**
36
- * Fetch all documents from Sanity, grouped by type and ordered by creation date
37
- */
38
- const fetchDocuments = useCallback(async () => {
39
- setState(prev => ({ ...prev, isLoadingDocuments: true, error: null }));
40
- try {
41
- // Query all documents, excluding system documents, Sanity internal documents, and plugin internal types (EL_*)
42
- const query = `*[!(_id in path("_.**")) && !(_type match "sanity.**") && !(_type match "EL_*")] | order(_createdAt desc) {
43
- _id,
44
- _type,
45
- _createdAt,
46
- _updatedAt,
47
- _rev,
48
- title,
49
- name,
50
- heading,
51
- label,
52
- ...
53
- }`;
54
- console.log('Fetching documents from Sanity...');
55
- const documents = await client.fetch(query);
56
- console.log(`Fetched ${documents.length} documents`);
57
- // Group documents by type
58
- const documentsByType = {};
59
- documents.forEach(doc => {
60
- if (!documentsByType[doc._type]) {
61
- documentsByType[doc._type] = [];
62
- }
63
- documentsByType[doc._type].push(doc);
64
- });
65
- // Log the grouping for debugging
66
- Object.keys(documentsByType).forEach(type => {
67
- console.log(`Type "${type}": ${documentsByType[type].length} documents`);
68
- });
69
- setState(prev => ({
70
- ...prev,
71
- availableDocuments: documentsByType,
72
- isLoadingDocuments: false
73
- }));
74
- }
75
- catch (error) {
76
- console.error('Failed to fetch documents:', error);
77
- setState(prev => ({
78
- ...prev,
79
- error: error instanceof Error ? error.message : 'Failed to fetch documents',
80
- isLoadingDocuments: false
81
- }));
82
- }
83
- }, [client]);
84
- // Load documents on component mount
85
- useEffect(() => {
86
- fetchDocuments();
87
- }, [fetchDocuments]);
88
- /**
89
- * Handle document type selection (select/deselect all documents of a type)
90
- */
91
- const handleTypeSelection = useCallback((type, selected) => {
92
- setState(prev => {
93
- const newSelectedTypes = new Set(prev.selectedTypes);
94
- const newSelectedDocumentIds = new Set(prev.selectedDocumentIds);
95
- if (selected) {
96
- newSelectedTypes.add(type);
97
- // Add all documents of this type to selected documents
98
- if (prev.availableDocuments[type]) {
99
- prev.availableDocuments[type].forEach(doc => {
100
- newSelectedDocumentIds.add(doc._id);
101
- });
102
- }
103
- }
104
- else {
105
- newSelectedTypes.delete(type);
106
- // Remove all documents of this type from selected documents
107
- if (prev.availableDocuments[type]) {
108
- prev.availableDocuments[type].forEach(doc => {
109
- newSelectedDocumentIds.delete(doc._id);
110
- });
111
- }
112
- }
113
- // Update selected documents array based on selected IDs
114
- const newSelectedDocuments = Object.values(prev.availableDocuments)
115
- .flat()
116
- .filter(doc => newSelectedDocumentIds.has(doc._id));
117
- // Create processing status for selected documents
118
- const processingStatus = newSelectedDocuments.map(doc => ({
119
- documentId: doc._id,
120
- title: getDocumentTitle(doc),
121
- status: 'pending'
122
- }));
123
- return {
124
- ...prev,
125
- selectedTypes: newSelectedTypes,
126
- selectedDocumentIds: newSelectedDocumentIds,
127
- selectedDocuments: newSelectedDocuments,
128
- processingStatus,
129
- summary: null,
130
- error: null,
131
- currentProcessingIndex: -1
132
- };
133
- });
134
- }, []);
135
- /**
136
- * Handle individual document selection
137
- */
138
- const handleDocumentSelection = useCallback((document, selected) => {
139
- setState(prev => {
140
- const newSelectedDocumentIds = new Set(prev.selectedDocumentIds);
141
- const newSelectedTypes = new Set(prev.selectedTypes);
142
- if (selected) {
143
- newSelectedDocumentIds.add(document._id);
144
- }
145
- else {
146
- newSelectedDocumentIds.delete(document._id);
147
- // If no documents of this type are selected, remove the type from selectedTypes
148
- const typeDocuments = prev.availableDocuments[document._type] || [];
149
- const hasOtherSelectedInType = typeDocuments.some(doc => doc._id !== document._id && newSelectedDocumentIds.has(doc._id));
150
- if (!hasOtherSelectedInType) {
151
- newSelectedTypes.delete(document._type);
152
- }
153
- }
154
- // Check if all documents of this type are now selected
155
- const typeDocuments = prev.availableDocuments[document._type] || [];
156
- const allTypeDocumentsSelected = typeDocuments.every(doc => newSelectedDocumentIds.has(doc._id));
157
- if (allTypeDocumentsSelected && typeDocuments.length > 0) {
158
- newSelectedTypes.add(document._type);
159
- }
160
- // Update selected documents array
161
- const newSelectedDocuments = Object.values(prev.availableDocuments)
162
- .flat()
163
- .filter(doc => newSelectedDocumentIds.has(doc._id));
164
- // Create processing status for selected documents
165
- const processingStatus = newSelectedDocuments.map(doc => ({
166
- documentId: doc._id,
167
- title: getDocumentTitle(doc),
168
- status: 'pending'
169
- }));
170
- return {
171
- ...prev,
172
- selectedTypes: newSelectedTypes,
173
- selectedDocumentIds: newSelectedDocumentIds,
174
- selectedDocuments: newSelectedDocuments,
175
- processingStatus,
176
- summary: null,
177
- error: null,
178
- currentProcessingIndex: -1
179
- };
180
- });
181
- }, []);
182
- /**
183
- * Toggle expansion of document type to show individual documents
184
- */
185
- const handleTypeExpansion = useCallback((type) => {
186
- setState(prev => {
187
- const newExpandedTypes = new Set(prev.expandedTypes);
188
- if (newExpandedTypes.has(type)) {
189
- newExpandedTypes.delete(type);
190
- }
191
- else {
192
- newExpandedTypes.add(type);
193
- }
194
- return {
195
- ...prev,
196
- expandedTypes: newExpandedTypes
197
- };
198
- });
199
- }, []);
200
- /**
201
- * Select all documents of all types
202
- */
203
- const handleSelectAll = useCallback(() => {
204
- const allTypes = Object.keys(state.availableDocuments);
205
- const allDocuments = Object.values(state.availableDocuments).flat();
206
- const allDocumentIds = new Set(allDocuments.map(doc => doc._id));
207
- const processingStatus = allDocuments.map(doc => ({
208
- documentId: doc._id,
209
- title: getDocumentTitle(doc),
210
- status: 'pending'
211
- }));
212
- setState(prev => ({
213
- ...prev,
214
- selectedTypes: new Set(allTypes),
215
- selectedDocumentIds: allDocumentIds,
216
- selectedDocuments: allDocuments,
217
- processingStatus,
218
- summary: null,
219
- error: null,
220
- currentProcessingIndex: -1,
221
- documentCreationResult: null
222
- }));
223
- }, [state.availableDocuments]);
224
- /**
225
- * Clear all selections
226
- */
227
- const handleClearSelection = useCallback(() => {
228
- setState(prev => ({
229
- ...prev,
230
- selectedTypes: new Set(),
231
- selectedDocumentIds: new Set(),
232
- selectedDocuments: [],
233
- processingStatus: [],
234
- summary: null,
235
- error: null,
236
- currentProcessingIndex: -1,
237
- documentCreationResult: null
238
- }));
239
- }, []);
240
- /**
241
- * Get document title from various possible fields
242
- */
243
- const getDocumentTitle = (doc) => {
244
- const titleFields = ['title', 'name', 'heading', 'label'];
245
- for (const field of titleFields) {
246
- if (doc[field] && typeof doc[field] === 'string') {
247
- return doc[field];
248
- }
249
- }
250
- return `${doc._type} (${doc._id})`;
251
- };
252
- const handleBulkTranslate = useCallback(async () => {
253
- if (state.selectedDocuments.length === 0) {
254
- await dialogService.showError({
255
- title: 'No Documents Selected',
256
- message: 'Please select at least one document to translate.',
257
- error: new Error('No documents selected for translation')
258
- });
259
- return;
260
- }
261
- try {
262
- // Get OAuth service manager and check authentication
263
- // Requirements: 4.1, 4.2, 4.3, 10.5
264
- const serviceManager = OAuthServiceManager.getInstance(client);
265
- const authStateManager = serviceManager.getAuthStateManager();
266
- const authState = authStateManager.getState();
267
- // If OAuth is configured but not authenticated, prompt user to authenticate
268
- if (serviceManager.isOAuthConfigured() && authState.state !== 'authenticated') {
269
- await dialogService.showError({
270
- title: 'Authentication Required',
271
- message: 'You need to configure your Easyling credentials to use translation services.',
272
- error: new Error('Please go to the Easyling Configuration tool to enter your access token and project ID.')
273
- });
274
- return;
275
- }
276
- // Initialize locale service
277
- const storageAdapter = new SanityLocaleStorageAdapter(client);
278
- const localeService = new LocaleService(storageAdapter);
279
- // Load locale configuration
280
- await localeService.loadConfig();
281
- const enabledLocales = localeService.getEnabledLocales();
282
- // Check if locales are configured
283
- if (enabledLocales.length === 0) {
284
- await dialogService.showError({
285
- title: 'No Locales Configured',
286
- message: 'Please configure target locales before translating documents.',
287
- error: new Error('No translation locales have been configured. Please use the Locale Configuration tool to add target languages.')
288
- });
289
- return;
290
- }
291
- // Show locale selection dialog
292
- const selectedLocalesResult = await dialogService.showLocaleSelection({
293
- title: 'Select Target Locales',
294
- message: `Choose the languages to translate ${state.selectedDocuments.length} document${state.selectedDocuments.length !== 1 ? 's' : ''} into:`,
295
- availableLocales: enabledLocales,
296
- selectedLocales: [],
297
- selectedDocuments: state.selectedDocuments,
298
- mode: 'bulk',
299
- allowMultiple: true,
300
- required: true,
301
- showCreationModeOption: true,
302
- defaultCreationMode: 'draft'
303
- });
304
- // User cancelled locale selection
305
- if (!selectedLocalesResult || !selectedLocalesResult.locales || selectedLocalesResult.locales.length === 0) {
306
- return;
307
- }
308
- const selectedLocales = selectedLocalesResult.locales;
309
- const creationMode = selectedLocalesResult.creationMode || 'draft';
310
- // Ask user if they want to create new documents
311
- const shouldCreateDocuments = await dialogService.showConfirmation({
312
- title: 'Confirm Bulk Translation',
313
- message: `Translate ${state.selectedDocuments.length} document${state.selectedDocuments.length !== 1 ? 's' : ''} to ${selectedLocales.length} locale${selectedLocales.length !== 1 ? 's' : ''}?`,
314
- details: `This will:\n• Send translation requests for all selected documents\n• Create new documents with translated content for successful translations\n• Preserve the original document structures\n\nTarget locales: ${selectedLocales.join(', ')}`,
315
- confirmText: 'Translate & Create Documents',
316
- cancelText: 'Cancel',
317
- tone: 'primary'
318
- });
319
- // User cancelled confirmation
320
- if (!shouldCreateDocuments) {
321
- return;
322
- }
323
- setState(prev => ({
324
- ...prev,
325
- isProcessing: true,
326
- error: null,
327
- summary: null,
328
- currentProcessingIndex: 0,
329
- createDocuments: shouldCreateDocuments,
330
- documentCreationResult: null,
331
- selectedLocales
332
- }));
333
- // Initialize services
334
- const contentExtractor = new ContentExtractor();
335
- const translationService = serviceManager.getTranslationService();
336
- const documentCreationService = new DocumentCreationService(client);
337
- console.log(`Starting bulk translation for ${state.selectedDocuments.length} documents`);
338
- // Extract content from all selected documents
339
- const extractedContents = await contentExtractor.extractBulkStructuredContent(state.selectedDocuments);
340
- // Filter out documents with no content and update status
341
- const validContents = extractedContents.filter(content => {
342
- const hasContent = content.htmlContent && content.htmlContent.trim().length > 0;
343
- if (!hasContent) {
344
- // Update status for documents with no content
345
- setState(prev => ({
346
- ...prev,
347
- processingStatus: prev.processingStatus.map(status => status.documentId === content.documentId
348
- ? { ...status, status: 'failed', error: 'No translatable content found' }
349
- : status)
350
- }));
351
- }
352
- return hasContent;
353
- });
354
- if (validContents.length === 0) {
355
- throw new Error('No translatable content found in selected documents');
356
- }
357
- console.log(`Processing ${validContents.length} documents with valid content`);
358
- // Process documents one by one with progress updates
359
- const summary = {
360
- totalDocuments: state.selectedDocuments.length,
361
- processedDocuments: 0,
362
- failedDocuments: 0,
363
- requests: [],
364
- responses: []
365
- };
366
- for (let i = 0; i < validContents.length; i++) {
367
- const content = validContents[i];
368
- // Update current processing index and document status
369
- setState(prev => ({
370
- ...prev,
371
- currentProcessingIndex: i,
372
- processingStatus: prev.processingStatus.map(status => status.documentId === content.documentId
373
- ? { ...status, status: 'processing' }
374
- : status)
375
- }));
376
- try {
377
- // Prepare and send translation request with selected locales
378
- const request = translationService.prepareTranslationRequest(content, undefined, // documentType - use default
379
- undefined, // sourceLanguage - use default
380
- undefined, // targetLanguage - not used for multi-locale
381
- selectedLocales // targetLocales array
382
- );
383
- const response = await translationService.sendTranslationRequest(request);
384
- // Update summary
385
- summary.requests.push(request);
386
- summary.responses.push(response);
387
- if (response.success) {
388
- summary.processedDocuments++;
389
- // Update document status to completed
390
- setState(prev => ({
391
- ...prev,
392
- processingStatus: prev.processingStatus.map(status => status.documentId === content.documentId
393
- ? { ...status, status: 'completed', response }
394
- : status)
395
- }));
396
- }
397
- else {
398
- summary.failedDocuments++;
399
- // Update document status to failed
400
- setState(prev => ({
401
- ...prev,
402
- processingStatus: prev.processingStatus.map(status => status.documentId === content.documentId
403
- ? { ...status, status: 'failed', error: response.error, response }
404
- : status)
405
- }));
406
- }
407
- // Add a small delay to make progress visible
408
- await new Promise(resolve => setTimeout(resolve, 500));
409
- }
410
- catch (error) {
411
- console.error(`Failed to process document ${content.documentId}:`, error);
412
- summary.failedDocuments++;
413
- const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
414
- summary.responses.push({
415
- success: false,
416
- error: errorMessage
417
- });
418
- // Update document status to failed
419
- setState(prev => ({
420
- ...prev,
421
- processingStatus: prev.processingStatus.map(status => status.documentId === content.documentId
422
- ? { ...status, status: 'failed', error: errorMessage }
423
- : status)
424
- }));
425
- }
426
- }
427
- // Create documents if user requested and we have successful translations
428
- let documentCreationResult = null;
429
- if (shouldCreateDocuments && summary.processedDocuments > 0) {
430
- console.log('Creating new documents from successful translations...');
431
- // Get successful translations and their corresponding original documents
432
- const successfulResponses = summary.responses.filter(response => response.success);
433
- const successfulDocuments = state.selectedDocuments.filter(doc => {
434
- const responseIndex = summary.responses.findIndex((_, index) => {
435
- const request = summary.requests[index];
436
- return request && request.documentId === doc._id;
437
- });
438
- return responseIndex >= 0 && summary.responses[responseIndex].success;
439
- });
440
- if (successfulDocuments.length > 0 && successfulResponses.length > 0) {
441
- documentCreationResult = await documentCreationService.createBulkDocumentsFromTranslations(successfulDocuments, successfulResponses, {
442
- targetLanguage: 'translated',
443
- createAsVariant: true,
444
- creationMode: creationMode
445
- });
446
- console.log('Document Creation Summary:', {
447
- totalDocuments: documentCreationResult.totalDocuments,
448
- successfulCreations: documentCreationResult.successfulCreations,
449
- failedCreations: documentCreationResult.failedCreations,
450
- errors: documentCreationResult.errors
451
- });
452
- }
453
- }
454
- // Log bulk operation summary
455
- console.log('Bulk Translation Summary:', {
456
- timestamp: new Date().toISOString(),
457
- totalDocuments: summary.totalDocuments,
458
- processedDocuments: summary.processedDocuments,
459
- failedDocuments: summary.failedDocuments,
460
- successRate: summary.totalDocuments > 0
461
- ? ((summary.processedDocuments / summary.totalDocuments) * 100).toFixed(2) + '%'
462
- : '0%'
463
- });
464
- setState(prev => ({
465
- ...prev,
466
- summary,
467
- documentCreationResult,
468
- isProcessing: false,
469
- currentProcessingIndex: -1
470
- }));
471
- console.log('Bulk translation completed:', summary);
472
- // Show completion message to user
473
- if (shouldCreateDocuments && documentCreationResult) {
474
- dialogService.showSuccess({
475
- title: 'Bulk Translation Completed',
476
- message: `Successfully translated ${summary.processedDocuments} of ${summary.totalDocuments} documents to ${selectedLocales.length} locale${selectedLocales.length !== 1 ? 's' : ''}`,
477
- details: `Translations: ${summary.processedDocuments}/${summary.totalDocuments} successful\nDocuments created: ${documentCreationResult.successfulCreations}/${documentCreationResult.totalDocuments} successful\nTarget locales: ${selectedLocales.join(', ')}\n\nCheck the console for detailed results and new document structures.`
478
- });
479
- }
480
- else {
481
- dialogService.showSuccess({
482
- title: 'Bulk Translation Completed',
483
- message: `Successfully translated ${summary.processedDocuments} of ${summary.totalDocuments} documents`,
484
- details: `Translations: ${summary.processedDocuments}/${summary.totalDocuments} successful\nTarget locales: ${selectedLocales.join(', ')}\n\nTranslation responses have been logged to the console for verification.`
485
- });
486
- }
487
- }
488
- catch (error) {
489
- console.error('Bulk translation failed:', error);
490
- // Show error dialog
491
- await dialogService.showError({
492
- title: 'Bulk Translation Failed',
493
- message: 'An error occurred during bulk translation.',
494
- error: error instanceof Error ? error : new Error('An unexpected error occurred')
495
- });
496
- setState(prev => ({
497
- ...prev,
498
- error: error instanceof Error ? error.message : 'An unexpected error occurred',
499
- isProcessing: false,
500
- currentProcessingIndex: -1
501
- }));
502
- }
503
- }, [state.selectedDocuments, client, dialogService]);
504
- return (_jsx(Card, { padding: 4, children: _jsxs(Stack, { space: 4, children: [_jsx(Text, { size: 2, weight: "semibold", children: "Bulk Document Translation" }), _jsx(Text, { size: 1, muted: true, children: "Select multiple documents to translate them in batch. Translation requests will be logged to the console for verification." }), _jsx(Card, { padding: 3, border: true, children: _jsxs(Stack, { space: 3, children: [_jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, weight: "medium", children: "Document Selection" }), _jsxs(Flex, { gap: 2, children: [_jsx(Button, { text: "Refresh", icon: RefreshIcon, onClick: fetchDocuments, disabled: state.isLoadingDocuments, mode: "ghost", fontSize: 1 }), state.selectedDocuments.length > 0 && (_jsx(Button, { text: "Clear All", tone: "critical", mode: "ghost", onClick: handleClearSelection, fontSize: 1 }))] })] }), state.isLoadingDocuments ? (_jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Spinner, { size: 1 }), _jsx(Text, { size: 1, muted: true, children: "Loading documents..." })] })) : Object.keys(state.availableDocuments).length === 0 ? (_jsx(Text, { size: 1, muted: true, children: "No documents found" })) : (_jsxs(Stack, { space: 3, children: [_jsxs(Flex, { align: "center", justify: "space-between", children: [_jsxs(Text, { size: 1, children: ["Selected: ", state.selectedDocuments.length, " documents from ", state.selectedTypes.size, " types"] }), _jsx(Button, { text: "Select All Types", onClick: handleSelectAll, mode: "ghost", fontSize: 1 })] }), _jsxs(Stack, { space: 2, children: [_jsx(Text, { size: 1, weight: "medium", children: "Document Types" }), Object.entries(state.availableDocuments)
505
- .sort(([a], [b]) => a.localeCompare(b))
506
- .map(([type, documents]) => {
507
- const isExpanded = state.expandedTypes.has(type);
508
- const selectedInType = documents.filter(doc => state.selectedDocumentIds.has(doc._id)).length;
509
- const isPartiallySelected = selectedInType > 0 && selectedInType < documents.length;
510
- const isFullySelected = selectedInType === documents.length;
511
- return (_jsx(Card, { padding: 2, border: true, children: _jsxs(Stack, { space: 2, children: [_jsxs(Flex, { align: "center", justify: "space-between", children: [_jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Checkbox, { checked: isFullySelected, indeterminate: isPartiallySelected, onChange: (event) => handleTypeSelection(type, event.currentTarget.checked) }), _jsx(Button, { icon: isExpanded ? ChevronDownIcon : ChevronRightIcon, mode: "ghost", onClick: () => handleTypeExpansion(type), style: { minWidth: 'auto', padding: '4px' } }), _jsxs(Box, { children: [_jsx(Text, { size: 1, weight: "medium", children: type }), _jsxs(Text, { size: 0, muted: true, children: [selectedInType, "/", documents.length, " selected \u2022 Latest: ", new Date(documents[0]._createdAt).toLocaleDateString()] })] })] }), _jsx(Badge, { tone: selectedInType > 0 ? "positive" : "primary", fontSize: 0, children: selectedInType > 0 ? `${selectedInType}/${documents.length}` : documents.length })] }), isExpanded && (_jsx(Box, { style: { marginLeft: '32px' }, children: _jsx(Stack, { space: 1, children: documents.map((doc) => (_jsx(Card, { padding: 2, tone: "transparent", border: true, children: _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Checkbox, { checked: state.selectedDocumentIds.has(doc._id), onChange: (event) => handleDocumentSelection(doc, event.currentTarget.checked) }), _jsxs(Box, { children: [_jsx(Text, { size: 1, children: getDocumentTitle(doc) }), _jsxs(Text, { size: 0, muted: true, children: [doc._id, " \u2022 ", new Date(doc._createdAt).toLocaleDateString()] })] })] }), state.selectedDocumentIds.has(doc._id) && (_jsx(Badge, { tone: "positive", fontSize: 0, children: "Selected" }))] }) }, doc._id))) }) }))] }) }, type));
512
- })] }), state.selectedDocuments.length > 0 && (_jsxs(Stack, { space: 2, children: [_jsxs(Text, { size: 1, weight: "medium", children: ["Selected Documents (", state.selectedDocuments.length, ")"] }), _jsx(Box, { style: { maxHeight: '200px', overflowY: 'auto' }, children: _jsxs(Stack, { space: 1, children: [state.selectedDocuments.slice(0, 10).map((doc) => (_jsx(Card, { padding: 2, tone: "primary", children: _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { size: 1, weight: "medium", children: getDocumentTitle(doc) }), _jsxs(Text, { size: 0, muted: true, children: [doc._type, " \u2022 ", new Date(doc._createdAt).toLocaleDateString()] })] }), _jsx(Badge, { tone: "primary", fontSize: 0, children: doc._type })] }) }, doc._id))), state.selectedDocuments.length > 10 && (_jsxs(Text, { size: 0, muted: true, style: { textAlign: 'center', padding: '8px' }, children: ["... and ", state.selectedDocuments.length - 10, " more documents"] }))] }) })] }))] }))] }) }), state.selectedDocuments.length > 0 && (_jsx(Card, { padding: 3, border: true, children: _jsxs(Stack, { space: 3, children: [_jsx(Text, { size: 1, weight: "medium", children: "Translation Action" }), state.selectedLocales && state.selectedLocales.length > 0 && (_jsx(Card, { padding: 2, tone: "primary", children: _jsxs(Text, { size: 1, children: ["Target Locales: ", state.selectedLocales.join(', ')] }) })), _jsx(Button, { text: state.isProcessing ? 'Processing...' : `Translate ${state.selectedDocuments.length} Documents`, icon: state.isProcessing ? Spinner : TranslateIcon, onClick: handleBulkTranslate, tone: "primary", disabled: state.isProcessing })] }) })), state.isProcessing && state.processingStatus.length > 0 && (_jsx(Card, { padding: 3, border: true, children: _jsxs(Stack, { space: 3, children: [_jsx(Text, { size: 1, weight: "medium", children: "Translation Progress" }), _jsxs(Stack, { space: 2, children: [_jsxs(Flex, { align: "center", justify: "space-between", children: [_jsxs(Text, { size: 1, children: ["Overall Progress: ", state.currentProcessingIndex + 1, " of ", state.selectedDocuments.length] }), _jsx(Text, { size: 1, muted: true, children: state.currentProcessingIndex >= 0
513
- ? `${Math.round(((state.currentProcessingIndex + 1) / state.selectedDocuments.length) * 100)}%`
514
- : '0%' })] }), _jsx(Box, { style: {
515
- width: '100%',
516
- height: '8px',
517
- backgroundColor: '#e0e0e0',
518
- borderRadius: '4px',
519
- overflow: 'hidden'
520
- }, children: _jsx(Box, { style: {
521
- width: `${state.currentProcessingIndex >= 0
522
- ? ((state.currentProcessingIndex + 1) / state.selectedDocuments.length) * 100
523
- : 0}%`,
524
- height: '100%',
525
- backgroundColor: '#0066cc',
526
- transition: 'width 0.3s ease'
527
- } }) })] }), _jsxs(Stack, { space: 2, children: [_jsx(Text, { size: 1, weight: "medium", children: "Document Status" }), state.processingStatus.map((status) => (_jsx(Card, { padding: 2, border: true, children: _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsxs(Box, { flex: 1, children: [_jsx(Text, { size: 1, weight: "medium", children: status.title }), _jsxs(Text, { size: 0, muted: true, children: ["ID: ", status.documentId] }), status.error && (_jsxs(Text, { size: 0, style: { color: 'red' }, children: ["Error: ", status.error] }))] }), _jsxs(Box, { children: [status.status === 'pending' && (_jsx(Badge, { tone: "default", fontSize: 0, children: "Pending" })), status.status === 'processing' && (_jsx(Badge, { tone: "primary", fontSize: 0, children: _jsxs(Flex, { align: "center", gap: 1, children: [_jsx(Spinner, { size: 0 }), "Processing"] }) })), status.status === 'completed' && (_jsx(Badge, { tone: "positive", fontSize: 0, children: _jsxs(Flex, { align: "center", gap: 1, children: [_jsx(CheckmarkIcon, {}), "Completed"] }) })), status.status === 'failed' && (_jsx(Badge, { tone: "critical", fontSize: 0, children: _jsxs(Flex, { align: "center", gap: 1, children: [_jsx(CloseIcon, {}), "Failed"] }) }))] })] }) }, status.documentId)))] })] }) })), state.error && (_jsx(Card, { padding: 3, tone: "critical", border: true, children: _jsxs(Text, { size: 1, weight: "medium", children: ["Error: ", state.error] }) })), state.summary && (_jsx(Card, { padding: 3, tone: state.summary.failedDocuments === 0 ? "positive" : "caution", border: true, children: _jsxs(Stack, { space: 3, children: [_jsxs(Flex, { align: "center", gap: 2, children: [state.summary.failedDocuments === 0 ? (_jsx(CheckmarkIcon, { style: { color: 'green' } })) : (_jsx(WarningOutlineIcon, { style: { color: 'orange' } })), _jsx(Text, { size: 1, weight: "medium", children: "Translation Summary" })] }), _jsxs(Stack, { space: 2, children: [_jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Total Documents:" }), _jsx(Badge, { tone: "primary", children: state.summary.totalDocuments })] }), _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Successfully Processed:" }), _jsx(Badge, { tone: "positive", children: state.summary.processedDocuments })] }), _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Failed:" }), _jsx(Badge, { tone: "critical", children: state.summary.failedDocuments })] }), _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Success Rate:" }), _jsx(Badge, { tone: state.summary.failedDocuments === 0 ? "positive" : "caution", children: state.summary.totalDocuments > 0
528
- ? `${((state.summary.processedDocuments / state.summary.totalDocuments) * 100).toFixed(1)}%`
529
- : '0%' })] })] }), state.processingStatus.length > 0 && (_jsxs(Stack, { space: 2, children: [_jsx(Text, { size: 1, weight: "medium", children: "Detailed Results" }), state.processingStatus.map((status) => (_jsx(Card, { padding: 2, border: true, children: _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsxs(Box, { flex: 1, children: [_jsx(Text, { size: 1, weight: "medium", children: status.title }), _jsxs(Text, { size: 0, muted: true, children: ["ID: ", status.documentId] }), status.error && (_jsxs(Text, { size: 0, style: { color: 'red' }, children: ["Error: ", status.error] }))] }), _jsxs(Box, { children: [status.status === 'pending' && (_jsx(Badge, { tone: "default", fontSize: 0, children: "Pending" })), status.status === 'processing' && (_jsx(Badge, { tone: "primary", fontSize: 0, children: _jsxs(Flex, { align: "center", gap: 1, children: [_jsx(Spinner, { size: 0 }), "Processing"] }) })), status.status === 'completed' && (_jsx(Badge, { tone: "positive", fontSize: 0, children: _jsxs(Flex, { align: "center", gap: 1, children: [_jsx(CheckmarkIcon, {}), "Completed"] }) })), status.status === 'failed' && (_jsx(Badge, { tone: "critical", fontSize: 0, children: _jsxs(Flex, { align: "center", gap: 1, children: [_jsx(CloseIcon, {}), "Failed"] }) }))] })] }) }, status.documentId)))] }))] }) })), state.documentCreationResult && (_jsx(Card, { padding: 3, tone: state.documentCreationResult.failedCreations === 0 ? "positive" : "caution", border: true, children: _jsxs(Stack, { space: 3, children: [_jsxs(Flex, { align: "center", gap: 2, children: [state.documentCreationResult.failedCreations === 0 ? (_jsx(CheckmarkIcon, { style: { color: 'green' } })) : (_jsx(WarningOutlineIcon, { style: { color: 'orange' } })), _jsx(Text, { size: 1, weight: "medium", children: "Document Creation Summary" })] }), _jsxs(Stack, { space: 2, children: [_jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Documents to Create:" }), _jsx(Badge, { tone: "primary", children: state.documentCreationResult.totalDocuments })] }), _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Successfully Created:" }), _jsx(Badge, { tone: "positive", children: state.documentCreationResult.successfulCreations })] }), _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Failed to Create:" }), _jsx(Badge, { tone: "critical", children: state.documentCreationResult.failedCreations })] }), _jsxs(Flex, { align: "center", justify: "space-between", children: [_jsx(Text, { size: 1, children: "Creation Success Rate:" }), _jsx(Badge, { tone: state.documentCreationResult.failedCreations === 0 ? "positive" : "caution", children: state.documentCreationResult.totalDocuments > 0
530
- ? `${((state.documentCreationResult.successfulCreations / state.documentCreationResult.totalDocuments) * 100).toFixed(1)}%`
531
- : '0%' })] })] }), state.documentCreationResult.errors.length > 0 && (_jsxs(Stack, { space: 2, children: [_jsx(Text, { size: 1, weight: "medium", children: "Creation Errors" }), _jsx(Box, { style: { maxHeight: '150px', overflowY: 'auto' }, children: _jsx(Stack, { space: 1, children: state.documentCreationResult.errors.map((error, index) => (_jsx(Card, { padding: 2, tone: "critical", children: _jsx(Text, { size: 0, style: { color: 'red' }, children: error }) }, index))) }) })] }))] }) }))] }) }));
532
- };
533
- /**
534
- * Bulk Translation Tool Definition
535
- * Requirements: 2.1, 2.5, 4.1, 4.2
536
- */
537
- export const bulkTranslateTool = {
538
- name: 'bulk-translate',
539
- title: 'Bulk Translate',
540
- icon: TranslateIcon,
541
- component: BulkTranslateTool
542
- };
543
- //# sourceMappingURL=bulkTranslate.js.map