@commercetools-frontend-extensions/operations 2.0.1 → 3.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 (68) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +138 -71
  3. package/dist/commercetools-frontend-extensions-operations.cjs.dev.js +979 -143
  4. package/dist/commercetools-frontend-extensions-operations.cjs.prod.js +979 -143
  5. package/dist/commercetools-frontend-extensions-operations.esm.js +929 -140
  6. package/dist/declarations/src/@api/file-import-jobs.d.ts +7 -0
  7. package/dist/declarations/src/@api/index.d.ts +1 -0
  8. package/dist/declarations/src/@api/test-fixtures.d.ts +8 -1
  9. package/dist/declarations/src/@api/urls.d.ts +30 -0
  10. package/dist/declarations/src/@components/uploading-modal/uploading-modal.d.ts +3 -2
  11. package/dist/declarations/src/@constants/file-import-job.d.ts +1 -0
  12. package/dist/declarations/src/@constants/import-limits.d.ts +6 -0
  13. package/dist/declarations/src/@constants/index.d.ts +2 -1
  14. package/dist/declarations/src/@errors/index.d.ts +5 -4
  15. package/dist/declarations/src/@errors/polling-aborted-error.d.ts +3 -0
  16. package/dist/declarations/src/@hooks/index.d.ts +4 -0
  17. package/dist/declarations/src/@hooks/use-fetch-file-import-job-records.d.ts +18 -0
  18. package/dist/declarations/src/@hooks/use-fetch-file-import-job.d.ts +17 -0
  19. package/dist/declarations/src/@hooks/use-file-import-job-upload.d.ts +18 -0
  20. package/dist/declarations/src/@hooks/use-file-upload.d.ts +29 -0
  21. package/dist/declarations/src/@hooks/use-import-container-upload.d.ts +2 -1
  22. package/dist/declarations/src/@types/export-operation.d.ts +3 -1
  23. package/dist/declarations/src/@types/file-import-job.d.ts +99 -0
  24. package/dist/declarations/src/@types/file-upload-result.d.ts +21 -0
  25. package/dist/declarations/src/@types/file-upload.d.ts +2 -2
  26. package/dist/declarations/src/@types/index.d.ts +2 -0
  27. package/dist/declarations/src/@utils/file-import-job-helpers.d.ts +12 -0
  28. package/dist/declarations/src/@utils/file-upload.d.ts +8 -0
  29. package/dist/declarations/src/@utils/index.d.ts +2 -0
  30. package/dist/declarations/src/@utils/poll-job-until-validated.d.ts +11 -0
  31. package/package.json +12 -13
  32. package/src/@api/fetcher.ts +10 -0
  33. package/src/@api/file-import-jobs.ts +217 -0
  34. package/src/@api/file-upload.spec.ts +4 -2
  35. package/src/@api/index.ts +1 -0
  36. package/src/@api/test-fixtures.ts +127 -5
  37. package/src/@api/urls.ts +77 -1
  38. package/src/@components/uploading-modal/uploading-modal.tsx +7 -5
  39. package/src/@constants/file-import-job.ts +1 -0
  40. package/src/@constants/import-limits.ts +13 -0
  41. package/src/@constants/index.ts +2 -1
  42. package/src/@errors/index.ts +5 -4
  43. package/src/@errors/polling-aborted-error.ts +6 -0
  44. package/src/@hooks/index.ts +4 -0
  45. package/src/@hooks/use-fetch-file-import-job-records.ts +58 -0
  46. package/src/@hooks/use-fetch-file-import-job.spec.ts +131 -0
  47. package/src/@hooks/use-fetch-file-import-job.ts +38 -0
  48. package/src/@hooks/use-fetch.spec.ts +1 -9
  49. package/src/@hooks/use-fetch.ts +4 -8
  50. package/src/@hooks/use-file-import-job-upload.spec.ts +273 -0
  51. package/src/@hooks/use-file-import-job-upload.ts +101 -0
  52. package/src/@hooks/use-file-upload.ts +231 -0
  53. package/src/@hooks/use-import-container-upload.spec.ts +16 -13
  54. package/src/@hooks/use-import-container-upload.ts +6 -2
  55. package/src/@types/export-operation.ts +3 -0
  56. package/src/@types/file-import-job.ts +165 -0
  57. package/src/@types/file-upload-result.ts +23 -0
  58. package/src/@types/file-upload.ts +2 -2
  59. package/src/@types/index.ts +2 -0
  60. package/src/@utils/error-mapping.ts +10 -9
  61. package/src/@utils/file-import-job-helpers.spec.ts +147 -0
  62. package/src/@utils/file-import-job-helpers.ts +47 -0
  63. package/src/@utils/file-upload.ts +39 -0
  64. package/src/@utils/index.ts +2 -0
  65. package/src/@utils/poll-job-until-validated.ts +76 -0
  66. package/dist/declarations/src/@constants/upload-limits.d.ts +0 -10
  67. package/src/@constants/upload-limits.ts +0 -11
  68. package/src/@hooks/messages.ts +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @commercetools-frontend-extensions/operations
2
2
 
3
+ ## 3.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1669](https://github.com/commercetools/merchant-center-operations/pull/1669) [`a4a9c65`](https://github.com/commercetools/merchant-center-operations/commit/a4a9c6513e9a0b6da7d0681f044d7640ad8f0132) Thanks [@yassinejebli](https://github.com/yassinejebli)! - feat(useFileUpload): add `total` to `validationProgress` for tracking validation progress
8
+
9
+ The `validationProgress` object returned by `useFileUpload` now includes a `total` field representing the total number of unique resources in the CSV file (counted by unique keys). This allows consumers to display progress like "Validating X of Y resources" during the job-based validation flow.
10
+
11
+ - [#1669](https://github.com/commercetools/merchant-center-operations/pull/1669) [`a4a9c65`](https://github.com/commercetools/merchant-center-operations/commit/a4a9c6513e9a0b6da7d0681f044d7640ad8f0132) Thanks [@yassinejebli](https://github.com/yassinejebli)! - feat(import): server side pagination for new import flow errors
12
+
13
+ ### Patch Changes
14
+
15
+ - [#1669](https://github.com/commercetools/merchant-center-operations/pull/1669) [`a4a9c65`](https://github.com/commercetools/merchant-center-operations/commit/a4a9c6513e9a0b6da7d0681f044d7640ad8f0132) Thanks [@yassinejebli](https://github.com/yassinejebli)! - feat: add `total` for tracking validation progress
16
+
17
+ ## 3.0.0
18
+
19
+ ### Major Changes
20
+
21
+ - [#1646](https://github.com/commercetools/merchant-center-operations/pull/1646) [`c1c381d`](https://github.com/commercetools/merchant-center-operations/commit/c1c381da4aa5c47c6fcc63940f164defe08170bd) Thanks [@yassinejebli](https://github.com/yassinejebli)! - feat: introduce the new Import job flow
22
+
3
23
  ## 2.0.1
4
24
 
5
25
  ### Patch Changes
package/README.md CHANGED
@@ -2,75 +2,97 @@
2
2
 
3
3
  Shared functionality for import/export operations across multiple frontend applications and extensions.
4
4
 
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @commercetools-frontend-extensions/operations
9
+ ```
10
+
5
11
  ## Hooks
6
12
 
7
- ### `useImportContainerUpload`
13
+ ### `useFileUpload`
8
14
 
9
- Handles file upload to import containers with automatic cleanup on errors.
15
+ A unified hook for file uploads that handles both the old flow (import container) and new flow (file import job).
10
16
 
11
17
  ```typescript
12
- const { upload, abort, isUploading, progress } = useImportContainerUpload({
13
- projectKey: string
18
+ const { upload, isUploading, progress, validationProgress } = useFileUpload({
19
+ projectKey: string,
20
+ useJobBasedFlow?: boolean,
21
+ pollingInterval?: number,
22
+ maxPollingAttempts?: number
14
23
  })
15
24
  ```
16
25
 
17
26
  **Parameters:**
18
27
  - `projectKey` (required): The commercetools project key
28
+ - `useJobBasedFlow` (optional): Whether to use the job-based flow. Default: `false`
29
+ - `pollingInterval` (optional): Polling interval in ms for job-based flow. Default: `5000`
30
+ - `maxPollingAttempts` (optional): Maximum polling attempts. Default: `120`
19
31
 
20
32
  **Returns:**
21
- - `upload`: Function to start file upload
22
- - `abort`: Function to cancel ongoing upload
23
- - `isUploading`: Boolean indicating upload state
24
- - `progress`: Upload progress (0-100)
33
+ - `upload` - Function to start the upload
34
+ - `isUploading` - Whether upload is in progress
35
+ - `progress` - Upload progress (0-100)
36
+ - `validationProgress` - `{ processed: number, total: number, isValidating: boolean }` (job-based flow only)
37
+ - `processed`: Number of resources validated so far (from backend)
38
+ - `total`: Total number of unique resources in the file (counted by unique keys in the CSV)
39
+ - `isValidating`: Whether validation is in progress
25
40
 
26
41
  **Usage:**
27
42
  ```typescript
28
- const projectKey = useApplicationContext((context) => context.project?.key)
29
- const { upload, isUploading, progress } = useImportContainerUpload({
30
- projectKey: projectKey!
43
+ import { useFileUpload } from '@commercetools-frontend-extensions/operations'
44
+
45
+ const { upload, isUploading, progress, validationProgress } = useFileUpload({
46
+ projectKey,
47
+ useJobBasedFlow: isFeatureFlagEnabled
31
48
  })
32
49
 
50
+ const abortController = new AbortController()
51
+
33
52
  await upload({
34
53
  file: File,
35
54
  resourceType: 'product' | 'category' | ...,
36
55
  settings?: {
37
56
  format?: 'CSV' | 'JSON',
38
57
  decimalSeparator?: '.' | ',',
39
- resourceType?: string, // example: 'product-draft' for products
58
+ resourceType?: 'product-draft' | 'category' | ...,
40
59
  options?: {
41
- publishAllChanges?: boolean, // product-specific
42
- unpublishAllChanges?: boolean // product-specific
60
+ publishAllChanges?: boolean,
61
+ unpublishAllChanges?: boolean
43
62
  }
44
63
  },
45
- onSuccess: (response, containerKey) => { /* ... */ },
64
+ abortSignal: abortController.signal,
65
+ onSuccess: (result) => {
66
+ // result.containerKey - Import container key
67
+ // result.summary - { total, valid, invalid, fields, ignoredFields, results }
68
+ // result.jobId - Job ID (job-based flow only)
69
+ // result.job - Full job object (job-based flow only)
70
+ },
46
71
  onError: (error) => { /* ... */ },
47
- onProgress: (progress) => { /* ... */ }
72
+ onProgress: (progress) => { /* 0-100 */ },
73
+ onValidationProgress: (job) => { /* job-based flow only */ }
48
74
  })
75
+
76
+ // To cancel:
77
+ abortController.abort()
49
78
  ```
50
79
 
51
80
  ---
52
81
 
53
82
  ### `useFetchImportOperations`
54
83
 
55
- Fetches import operations for a specific container with optional polling.
84
+ Fetches import operations for a container with optional polling.
56
85
 
57
86
  ```typescript
58
- const { data, error, isLoading, refetch, lastFetchTime } = useFetchImportOperations({
59
- projectKey: string,
60
- importContainerKey: string,
61
- queryParams?: ImportOperationQueryParams,
87
+ const { data, error, isLoading, refetch } = useFetchImportOperations({
88
+ projectKey,
89
+ importContainerKey,
90
+ queryParams?: { limit, offset, ... },
62
91
  pollingInterval?: number,
63
92
  shouldContinuePolling?: (data) => boolean
64
93
  })
65
94
  ```
66
95
 
67
- **Parameters:**
68
- - `projectKey` (required): The commercetools project key
69
- - `importContainerKey` (required): The import container key
70
- - `queryParams`: Optional query parameters (limit, offset, etc.)
71
- - `pollingInterval`: Polling interval in milliseconds
72
- - `shouldContinuePolling`: Function to determine if polling should continue
73
-
74
96
  ---
75
97
 
76
98
  ### `useFetchImportSummaries`
@@ -78,41 +100,29 @@ const { data, error, isLoading, refetch, lastFetchTime } = useFetchImportOperati
78
100
  Fetches import summaries (containers) with optional polling.
79
101
 
80
102
  ```typescript
81
- const { data, error, isLoading, refetch, lastFetchTime } = useFetchImportSummaries({
82
- projectKey: string,
83
- queryParams?: ImportContainerQueryParams,
103
+ const { data, error, isLoading, refetch } = useFetchImportSummaries({
104
+ projectKey,
105
+ queryParams?: { limit, offset, states, ... },
84
106
  pollingInterval?: number,
85
107
  shouldContinuePolling?: (data) => boolean
86
108
  })
87
109
  ```
88
110
 
89
- **Parameters:**
90
- - `projectKey` (required): The commercetools project key
91
- - `queryParams`: Optional query parameters (limit, offset, states, etc.)
92
- - `pollingInterval`: Polling interval in milliseconds
93
- - `shouldContinuePolling`: Function to determine if polling should continue
94
-
95
111
  ---
96
112
 
97
113
  ### `useFetchImportContainerDetails`
98
114
 
99
- Fetches details for a specific import container with optional polling.
115
+ Fetches details for a specific import container.
100
116
 
101
117
  ```typescript
102
- const { data, error, isLoading, refetch, lastFetchTime } = useFetchImportContainerDetails({
103
- projectKey: string,
104
- importContainerKey: string,
118
+ const { data, error, isLoading, refetch } = useFetchImportContainerDetails({
119
+ projectKey,
120
+ importContainerKey,
105
121
  pollingInterval?: number,
106
122
  shouldContinuePolling?: (data) => boolean
107
123
  })
108
124
  ```
109
125
 
110
- **Parameters:**
111
- - `projectKey` (required): The commercetools project key
112
- - `importContainerKey` (required): The import container key
113
- - `pollingInterval`: Polling interval in milliseconds
114
- - `shouldContinuePolling`: Function to determine if polling should continue
115
-
116
126
  ---
117
127
 
118
128
  ### `useFetchExportOperations`
@@ -120,50 +130,107 @@ const { data, error, isLoading, refetch, lastFetchTime } = useFetchImportContain
120
130
  Fetches export operations with optional polling.
121
131
 
122
132
  ```typescript
123
- const { data, error, isLoading, refetch, lastFetchTime } = useFetchExportOperations({
124
- projectKey: string,
125
- queryParams?: ExportOperationQueryParams,
133
+ const { data, error, isLoading, refetch } = useFetchExportOperations({
134
+ projectKey,
135
+ queryParams?: { limit, offset, resourceTypes, ... },
126
136
  pollingInterval?: number,
127
137
  shouldContinuePolling?: (data) => boolean
128
138
  })
129
139
  ```
130
140
 
131
- **Parameters:**
132
- - `projectKey` (required): The commercetools project key
133
- - `queryParams`: Optional query parameters (limit, offset, resourceTypes, etc.)
134
- - `pollingInterval`: Polling interval in milliseconds
135
- - `shouldContinuePolling`: Function to determine if polling should continue
136
-
137
141
  ---
138
142
 
139
- ## Notes
143
+ ### `useFetchFileImportJob`
144
+
145
+ Polls a File Import Job for status updates.
140
146
 
141
- - **All hooks require `projectKey`** to be passed explicitly (retrieved from `useApplicationContext`)
142
- - **Polling is opt-in** via `pollingInterval` parameter
143
- - **Standard return structure**: All fetch hooks return `{ data, error, isLoading, refetch, lastFetchTime }`
144
- - **Automatic cleanup**: `useImportContainerUpload` automatically cleans up containers on upload errors
145
- - **File upload limits**: The package exports backend-recommended limits enforced in frontend validation:
146
- - `MAX_FILE_SIZE_MB` (35 MB)
147
- - `MAX_ROW_COUNT` (80,000)
148
- - **Internal use only**: This package also exports additional components, utilities, types, and API functions that are intended for internal use within the operations repository (operations app and frontend extensions). Only the hooks documented above are considered stable public API for external consumption.
147
+ ```typescript
148
+ const { data, error, isLoading, refetch } = useFetchFileImportJob({
149
+ projectKey,
150
+ importContainerKey,
151
+ jobId,
152
+ pollingInterval?: number,
153
+ shouldContinuePolling?: (job) => boolean
154
+ })
155
+ ```
156
+
157
+ **Job states:** `queued` → `processing` → `validated` → `initialising` → `ready`
149
158
 
150
159
  ---
151
160
 
152
- ## Common patterns
161
+ ### `useFetchFileImportJobRecords`
153
162
 
154
- ### Polling example
163
+ Fetches records (errors or valid entries) from a File Import Job with pagination support. Keeps previous data visible while loading new pages.
164
+
165
+ ```typescript
166
+ const { data, error, isLoading, refetch } = useFetchFileImportJobRecords({
167
+ projectKey,
168
+ importContainerKey,
169
+ jobId,
170
+ limit?: number,
171
+ offset?: number,
172
+ isValid?: boolean,
173
+ skip?: boolean
174
+ })
175
+ ```
176
+
177
+ **Parameters:**
178
+ - `projectKey`: The commercetools project key
179
+ - `importContainerKey`: The import container key
180
+ - `jobId`: The file import job ID
181
+ - `limit` (optional): Number of records to fetch per page
182
+ - `offset` (optional): Offset for pagination
183
+ - `isValid` (optional): Filter by valid (`true`) or invalid (`false`) records
184
+ - `skip` (optional): Skip fetching (useful for conditional fetching)
185
+
186
+ **Returns:**
187
+ - `data` - `{ results, total, limit, offset, count }` or `null`
188
+ - `error` - Error object if fetch failed
189
+ - `isLoading` - Whether fetch is in progress
190
+ - `refetch` - Function to manually trigger a refetch
155
191
 
192
+ **Usage example (paginated error table):**
156
193
  ```typescript
157
- const POLL_INTERVAL = 5000 // 5 seconds
194
+ const pagination = usePaginationState()
195
+ const offset = (pagination.page.value - 1) * pagination.perPage.value
158
196
 
197
+ const { data, isLoading } = useFetchFileImportJobRecords({
198
+ projectKey,
199
+ importContainerKey: containerKey,
200
+ jobId,
201
+ offset,
202
+ limit: pagination.perPage.value,
203
+ isValid: false, // Fetch only invalid records (errors)
204
+ })
205
+
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Helper Functions
211
+
212
+ ```typescript
213
+ import {
214
+ isImportJobQueued,
215
+ isImportJobProcessing,
216
+ isImportJobValidated,
217
+ isImportJobInitializing,
218
+ isImportJobReady,
219
+ shouldContinuePollingForImportValidation
220
+ } from '@commercetools-frontend-extensions/operations'
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Polling Example
226
+
227
+ ```typescript
159
228
  const { data, isLoading } = useFetchImportOperations({
160
229
  projectKey,
161
230
  importContainerKey,
162
- pollingInterval: POLL_INTERVAL,
231
+ pollingInterval: 5000,
163
232
  shouldContinuePolling: (data) => {
164
- // Stop polling when all operations are completed
165
233
  return data?.results?.some(op => op.state === 'processing') ?? false
166
234
  }
167
235
  })
168
236
  ```
169
-