@open-mercato/core 0.6.8-develop.6992.1.00c90fecff → 0.6.8-develop.6998.1.d2bc46c56c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/generated/entities/sync_run/index.js +2 -0
- package/dist/generated/entities/sync_run/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +1 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +1 -1
- package/dist/modules/auth/lib/backendChrome.js +3 -3
- package/dist/modules/auth/lib/backendChrome.js.map +1 -1
- package/dist/modules/auth/services/sidebarPreferencesService.js +7 -2
- package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +1 -0
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/run.js +15 -1
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/retry.js +23 -1
- package/dist/modules/data_sync/api/runs/[id]/retry.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/route.js +1 -0
- package/dist/modules/data_sync/api/runs/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +60 -17
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js +34 -2
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +21 -15
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/data_sync/components/RunParameterFields.js +135 -0
- package/dist/modules/data_sync/components/RunParameterFields.js.map +7 -0
- package/dist/modules/data_sync/data/entities.js +3 -0
- package/dist/modules/data_sync/data/entities.js.map +2 -2
- package/dist/modules/data_sync/data/validators.js +4 -1
- package/dist/modules/data_sync/data/validators.js.map +2 -2
- package/dist/modules/data_sync/lib/run-parameters.js +108 -0
- package/dist/modules/data_sync/lib/run-parameters.js.map +7 -0
- package/dist/modules/data_sync/lib/start-run.js +1 -0
- package/dist/modules/data_sync/lib/start-run.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-engine.js +4 -2
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-run-service.js +1 -0
- package/dist/modules/data_sync/lib/sync-run-service.js.map +2 -2
- package/dist/modules/data_sync/migrations/Migration20260810120000.js +13 -0
- package/dist/modules/data_sync/migrations/Migration20260810120000.js.map +7 -0
- package/dist/modules/data_sync/workers/sync-scheduled.js +23 -2
- package/dist/modules/data_sync/workers/sync-scheduled.js.map +2 -2
- package/dist/modules/query_index/di.js +125 -48
- package/dist/modules/query_index/di.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +39 -1
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +26 -5
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/generated/entities/sync_run/index.ts +1 -0
- package/generated/entity-fields-registry.ts +1 -0
- package/package.json +7 -7
- package/src/modules/auth/api/sidebar/preferences/route.ts +2 -2
- package/src/modules/auth/lib/backendChrome.tsx +2 -2
- package/src/modules/auth/services/sidebarPreferencesService.ts +22 -3
- package/src/modules/data_sync/AGENTS.md +83 -8
- package/src/modules/data_sync/api/options.ts +1 -0
- package/src/modules/data_sync/api/run.ts +17 -0
- package/src/modules/data_sync/api/runs/[id]/retry.ts +32 -1
- package/src/modules/data_sync/api/runs/[id]/route.ts +1 -0
- package/src/modules/data_sync/backend/data-sync/page.tsx +73 -17
- package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +62 -2
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +28 -15
- package/src/modules/data_sync/components/RunParameterFields.tsx +229 -0
- package/src/modules/data_sync/data/entities.ts +4 -1
- package/src/modules/data_sync/data/validators.ts +3 -0
- package/src/modules/data_sync/i18n/de.json +10 -0
- package/src/modules/data_sync/i18n/en.json +10 -0
- package/src/modules/data_sync/i18n/es.json +10 -0
- package/src/modules/data_sync/i18n/ko.json +10 -0
- package/src/modules/data_sync/i18n/pl.json +10 -0
- package/src/modules/data_sync/lib/adapter.ts +88 -0
- package/src/modules/data_sync/lib/run-parameters.ts +196 -0
- package/src/modules/data_sync/lib/start-run.ts +2 -0
- package/src/modules/data_sync/lib/sync-engine.ts +5 -1
- package/src/modules/data_sync/lib/sync-run-service.ts +2 -0
- package/src/modules/data_sync/migrations/.snapshot-open-mercato.json +17 -1
- package/src/modules/data_sync/migrations/Migration20260810120000.ts +13 -0
- package/src/modules/data_sync/workers/sync-scheduled.ts +32 -1
- package/src/modules/query_index/di.ts +153 -56
- package/src/modules/sales/api/documents/factory.ts +62 -1
- package/src/modules/sales/commands/documents.ts +40 -4
- package/src/modules/sales/i18n/de.json +1 -0
- package/src/modules/sales/i18n/en.json +1 -0
- package/src/modules/sales/i18n/es.json +1 -0
- package/src/modules/sales/i18n/ko.json +1 -0
- package/src/modules/sales/i18n/pl.json +1 -0
|
@@ -23,6 +23,12 @@ import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
|
23
23
|
import { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
|
|
24
24
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
25
25
|
import { getSyncSummaryVariant } from '../lib/syncRunStatus'
|
|
26
|
+
import type { RunParameter } from '../lib/adapter'
|
|
27
|
+
import { getApplicableRunParameters } from '../lib/run-parameters'
|
|
28
|
+
import {
|
|
29
|
+
buildDefaultRunParameterValues,
|
|
30
|
+
hasRequiredRunParameterWithoutDefault,
|
|
31
|
+
} from './RunParameterFields'
|
|
26
32
|
import {
|
|
27
33
|
CalendarClock,
|
|
28
34
|
Play,
|
|
@@ -40,6 +46,7 @@ type SyncOption = {
|
|
|
40
46
|
runMode?: 'generic' | 'provider'
|
|
41
47
|
canStartRun?: boolean
|
|
42
48
|
supportedEntities: string[]
|
|
49
|
+
runParameters?: RunParameter[]
|
|
43
50
|
hasCredentials: boolean
|
|
44
51
|
isEnabled: boolean
|
|
45
52
|
}
|
|
@@ -223,29 +230,35 @@ export function IntegrationScheduleTab(props: IntegrationScheduleTabProps) {
|
|
|
223
230
|
return
|
|
224
231
|
}
|
|
225
232
|
|
|
233
|
+
// This table has no room for a parameter form, so a row run submits the
|
|
234
|
+
// adapter's declared defaults. A parameter the operator must fill in has no
|
|
235
|
+
// default to send, so route them to the Data Sync dashboard instead of
|
|
236
|
+
// letting the run API reject the request.
|
|
237
|
+
const runParameters = getApplicableRunParameters(option?.runParameters, direction, entityType)
|
|
238
|
+
if (hasRequiredRunParameterWithoutDefault(runParameters)) {
|
|
239
|
+
flash(t('data_sync.integrationTab.parametersRequired', 'This run needs parameters. Start it from the Data Sync dashboard.'), 'error')
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
226
243
|
setRunningKey(scheduleKey)
|
|
227
244
|
try {
|
|
228
245
|
const scheduleState = schedules[scheduleKey] ?? buildDefaultScheduleState(entityType)
|
|
246
|
+
const requestBody: Record<string, unknown> = {
|
|
247
|
+
integrationId: props.integrationId,
|
|
248
|
+
entityType,
|
|
249
|
+
direction,
|
|
250
|
+
fullSync: scheduleState.fullSync,
|
|
251
|
+
batchSize: 100,
|
|
252
|
+
}
|
|
253
|
+
if (runParameters.length > 0) requestBody.parameters = buildDefaultRunParameterValues(runParameters)
|
|
229
254
|
const call = await runMutation({
|
|
230
255
|
// optimistic-lock-exempt: starts a new sync run (create), not a concurrent record edit
|
|
231
256
|
operation: () => apiCall<{ id: string }>('/api/data_sync/run', {
|
|
232
257
|
method: 'POST',
|
|
233
258
|
headers: { 'content-type': 'application/json' },
|
|
234
|
-
body: JSON.stringify(
|
|
235
|
-
integrationId: props.integrationId,
|
|
236
|
-
entityType,
|
|
237
|
-
direction,
|
|
238
|
-
fullSync: scheduleState.fullSync,
|
|
239
|
-
batchSize: 100,
|
|
240
|
-
}),
|
|
259
|
+
body: JSON.stringify(requestBody),
|
|
241
260
|
}, { fallback: null }),
|
|
242
|
-
mutationPayload:
|
|
243
|
-
integrationId: props.integrationId,
|
|
244
|
-
entityType,
|
|
245
|
-
direction,
|
|
246
|
-
fullSync: scheduleState.fullSync,
|
|
247
|
-
batchSize: 100,
|
|
248
|
-
},
|
|
261
|
+
mutationPayload: requestBody,
|
|
249
262
|
context: {
|
|
250
263
|
operation: 'create',
|
|
251
264
|
actionId: 'start-sync-run',
|
|
@@ -264,7 +277,7 @@ export function IntegrationScheduleTab(props: IntegrationScheduleTabProps) {
|
|
|
264
277
|
} finally {
|
|
265
278
|
setRunningKey(null)
|
|
266
279
|
}
|
|
267
|
-
}, [option?.canStartRun, props.hasCredentials, props.integrationId, props.isEnabled, runMutation, schedules, t])
|
|
280
|
+
}, [option?.canStartRun, option?.runParameters, props.hasCredentials, props.integrationId, props.isEnabled, runMutation, schedules, t])
|
|
268
281
|
|
|
269
282
|
const handleSaveSchedule = React.useCallback(async (entityType: string, direction: 'import' | 'export', scheduleKey: string) => {
|
|
270
283
|
const scheduleState = schedules[scheduleKey] ?? buildDefaultScheduleState(entityType)
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { Input } from '@open-mercato/ui/primitives/input'
|
|
5
|
+
import { Label } from '@open-mercato/ui/primitives/label'
|
|
6
|
+
import {
|
|
7
|
+
Select,
|
|
8
|
+
SelectContent,
|
|
9
|
+
SelectItem,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue,
|
|
12
|
+
} from '@open-mercato/ui/primitives/select'
|
|
13
|
+
import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
14
|
+
import { useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'
|
|
15
|
+
import type { RunParameter } from '../lib/adapter'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Form-state representation of a run parameter value. Numbers are held as
|
|
19
|
+
* strings while the operator types; the run API coerces them to the declared
|
|
20
|
+
* type via `normalizeRunParameters`.
|
|
21
|
+
*/
|
|
22
|
+
export type RunParameterFormValue = string | boolean
|
|
23
|
+
|
|
24
|
+
export function buildDefaultRunParameterValues(
|
|
25
|
+
params: RunParameter[],
|
|
26
|
+
): Record<string, RunParameterFormValue> {
|
|
27
|
+
const values: Record<string, RunParameterFormValue> = {}
|
|
28
|
+
for (const param of params) {
|
|
29
|
+
if (param.type === 'boolean') {
|
|
30
|
+
values[param.key] = param.defaultValue === true
|
|
31
|
+
} else {
|
|
32
|
+
values[param.key] = param.defaultValue !== undefined && param.defaultValue !== null
|
|
33
|
+
? String(param.defaultValue)
|
|
34
|
+
: ''
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return values
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function buildRunParametersPayload(
|
|
41
|
+
params: RunParameter[],
|
|
42
|
+
values: Record<string, RunParameterFormValue>,
|
|
43
|
+
): Record<string, RunParameterFormValue> {
|
|
44
|
+
const payload: Record<string, RunParameterFormValue> = {}
|
|
45
|
+
for (const param of params) {
|
|
46
|
+
if (param.key in values) payload[param.key] = values[param.key]
|
|
47
|
+
}
|
|
48
|
+
return payload
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* True when a run cannot be started without operator input — a required
|
|
53
|
+
* parameter with no default to fall back on. Surfaces that cannot render the
|
|
54
|
+
* full parameter form (the integration schedule table) use this to point the
|
|
55
|
+
* operator at the Data Sync dashboard instead of failing with a 422.
|
|
56
|
+
*
|
|
57
|
+
* Booleans are excluded: a switch always submits `true` or `false`, so their
|
|
58
|
+
* `required` can never fail (see `RunParameter.required`). Counting them would
|
|
59
|
+
* send the operator away from a button that would in fact have worked.
|
|
60
|
+
*/
|
|
61
|
+
export function hasRequiredRunParameterWithoutDefault(params: RunParameter[]): boolean {
|
|
62
|
+
return params.some((param) => param.type !== 'boolean' && param.required && param.defaultValue === undefined)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type RunParameterErrorEntry = {
|
|
66
|
+
key?: string
|
|
67
|
+
code?: string
|
|
68
|
+
params?: { label?: string; type?: string; min?: number; max?: number; options?: string }
|
|
69
|
+
message?: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type RunFailureBody = {
|
|
73
|
+
error?: string
|
|
74
|
+
details?: { parameters?: RunParameterErrorEntry[] }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
type Translate = TranslateFn
|
|
78
|
+
|
|
79
|
+
/** Resolves an optional i18n key, falling back to the adapter's literal. */
|
|
80
|
+
export function resolveRunParameterText(
|
|
81
|
+
t: Translate,
|
|
82
|
+
key: string | undefined,
|
|
83
|
+
literal: string | undefined,
|
|
84
|
+
): string | undefined {
|
|
85
|
+
if (key) {
|
|
86
|
+
const translated = t(key, literal ?? key)
|
|
87
|
+
if (translated && translated !== key) return translated
|
|
88
|
+
}
|
|
89
|
+
return literal
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const ERROR_FALLBACKS: Record<string, string> = {
|
|
93
|
+
required: '{label} is required.',
|
|
94
|
+
type: '{label} must be a {type}.',
|
|
95
|
+
min: '{label} must be at least {min}.',
|
|
96
|
+
max: '{label} must be at most {max}.',
|
|
97
|
+
select: '{label} must be one of: {options}.',
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Picks the most specific message out of a failed run response and renders it
|
|
102
|
+
* in the operator's language. The run API reports invalid parameters per key
|
|
103
|
+
* under `details.parameters` with a machine-readable `code`; surfacing only the
|
|
104
|
+
* top-level `error` would say "Invalid run parameters" without saying which one
|
|
105
|
+
* or why, and using the server's pre-rendered `message` would put an English
|
|
106
|
+
* sentence next to a translated dashboard.
|
|
107
|
+
*/
|
|
108
|
+
export function buildRunFailureMessage(
|
|
109
|
+
failure: RunFailureBody | null | undefined,
|
|
110
|
+
fallback: string,
|
|
111
|
+
t?: Translate,
|
|
112
|
+
): string {
|
|
113
|
+
const rendered = (failure?.details?.parameters ?? [])
|
|
114
|
+
.map((entry) => {
|
|
115
|
+
if (t && entry?.code && ERROR_FALLBACKS[entry.code]) {
|
|
116
|
+
return t(`data_sync.runParameters.errors.${entry.code}`, ERROR_FALLBACKS[entry.code], {
|
|
117
|
+
...(entry.params ?? {}),
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
return entry?.message
|
|
121
|
+
})
|
|
122
|
+
.filter((message): message is string => typeof message === 'string' && message.trim().length > 0)
|
|
123
|
+
if (rendered.length > 0) return rendered.join(' ')
|
|
124
|
+
return failure?.error ?? fallback
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export type RetryFailureBody = {
|
|
128
|
+
code?: string
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Retry failures are otherwise indistinguishable to the operator, so both retry
|
|
133
|
+
* buttons flash one generic sentence. The stale-parameter refusal is the one
|
|
134
|
+
* whose remedy is not obvious from context — it is reported with a machine
|
|
135
|
+
* -readable `code` so the UI can name the way out instead of dead-ending.
|
|
136
|
+
*/
|
|
137
|
+
export function buildRetryFailureMessage(
|
|
138
|
+
failure: RetryFailureBody | null | undefined,
|
|
139
|
+
t: Translate,
|
|
140
|
+
): string {
|
|
141
|
+
if (failure?.code === 'parametersStale') {
|
|
142
|
+
return t(
|
|
143
|
+
'data_sync.runs.detail.retryParametersStale',
|
|
144
|
+
'The stored run parameters are no longer valid for this integration. Start a new run from the Data Sync dashboard.',
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
return t('data_sync.runs.detail.retryError', 'Failed to retry sync run')
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export type RunParameterFieldsProps = {
|
|
151
|
+
params: RunParameter[]
|
|
152
|
+
values: Record<string, RunParameterFormValue>
|
|
153
|
+
onChange: (key: string, value: RunParameterFormValue) => void
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function RunParameterFields({ params, values, onChange }: RunParameterFieldsProps) {
|
|
157
|
+
const t = useT()
|
|
158
|
+
return (
|
|
159
|
+
<div className="grid gap-3 sm:grid-cols-2">
|
|
160
|
+
{params.map((param) => {
|
|
161
|
+
const value = values[param.key]
|
|
162
|
+
const fieldId = `run-param-${param.key}`
|
|
163
|
+
const describedById = `${fieldId}-description`
|
|
164
|
+
const label = resolveRunParameterText(t, param.labelKey, param.label) ?? param.key
|
|
165
|
+
const description = resolveRunParameterText(t, param.descriptionKey, param.description)
|
|
166
|
+
const placeholder = resolveRunParameterText(t, param.placeholderKey, param.placeholder)
|
|
167
|
+
// No required marker on booleans: a switch always submits true/false,
|
|
168
|
+
// so `required` can never fail for them (see RunParameter.required).
|
|
169
|
+
if (param.type === 'boolean') {
|
|
170
|
+
return (
|
|
171
|
+
<div key={param.key} className="rounded-lg border bg-card p-3 sm:col-span-2">
|
|
172
|
+
<div className="flex items-center justify-between gap-3">
|
|
173
|
+
<div className="space-y-1">
|
|
174
|
+
<Label htmlFor={fieldId} className="text-sm font-medium">{label}</Label>
|
|
175
|
+
{description ? (
|
|
176
|
+
<p id={describedById} className="text-xs text-muted-foreground">{description}</p>
|
|
177
|
+
) : null}
|
|
178
|
+
</div>
|
|
179
|
+
<Switch
|
|
180
|
+
id={fieldId}
|
|
181
|
+
aria-describedby={description ? describedById : undefined}
|
|
182
|
+
checked={value === true}
|
|
183
|
+
onCheckedChange={(checked) => onChange(param.key, checked)}
|
|
184
|
+
/>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
return (
|
|
190
|
+
<div key={param.key} className="space-y-2">
|
|
191
|
+
<Label htmlFor={fieldId} className="text-sm font-medium">
|
|
192
|
+
{label}
|
|
193
|
+
{param.required ? <span className="text-status-error-text"> *</span> : null}
|
|
194
|
+
</Label>
|
|
195
|
+
{param.type === 'select' ? (
|
|
196
|
+
<Select
|
|
197
|
+
value={typeof value === 'string' && value.length > 0 ? value : undefined}
|
|
198
|
+
onValueChange={(next) => onChange(param.key, next ?? '')}
|
|
199
|
+
>
|
|
200
|
+
<SelectTrigger id={fieldId} aria-describedby={description ? describedById : undefined}>
|
|
201
|
+
<SelectValue placeholder={placeholder ?? undefined} />
|
|
202
|
+
</SelectTrigger>
|
|
203
|
+
<SelectContent>
|
|
204
|
+
{(param.options ?? []).map((option) => (
|
|
205
|
+
<SelectItem key={option.value} value={option.value}>
|
|
206
|
+
{option.label ?? option.value}
|
|
207
|
+
</SelectItem>
|
|
208
|
+
))}
|
|
209
|
+
</SelectContent>
|
|
210
|
+
</Select>
|
|
211
|
+
) : (
|
|
212
|
+
<Input
|
|
213
|
+
id={fieldId}
|
|
214
|
+
aria-describedby={description ? describedById : undefined}
|
|
215
|
+
value={typeof value === 'string' ? value : ''}
|
|
216
|
+
onChange={(event) => onChange(param.key, event.target.value)}
|
|
217
|
+
placeholder={placeholder ?? undefined}
|
|
218
|
+
inputMode={param.type === 'number' ? 'numeric' : undefined}
|
|
219
|
+
/>
|
|
220
|
+
)}
|
|
221
|
+
{description ? (
|
|
222
|
+
<p id={describedById} className="text-xs text-muted-foreground">{description}</p>
|
|
223
|
+
) : null}
|
|
224
|
+
</div>
|
|
225
|
+
)
|
|
226
|
+
})}
|
|
227
|
+
</div>
|
|
228
|
+
)
|
|
229
|
+
}
|
|
@@ -4,7 +4,7 @@ import { Entity, Index, PrimaryKey, Property } from '@mikro-orm/decorators/legac
|
|
|
4
4
|
@Entity({ tableName: 'sync_runs' })
|
|
5
5
|
@Index({ properties: ['integrationId', 'entityType', 'status', 'organizationId', 'tenantId'] })
|
|
6
6
|
export class SyncRun {
|
|
7
|
-
[OptionalProps]?: 'status' | 'cursor' | 'initialCursor' | 'createdCount' | 'updatedCount' | 'skippedCount' | 'failedCount' | 'batchesCompleted' | 'lastError' | 'progressJobId' | 'jobId' | 'triggeredBy' | 'createdAt' | 'updatedAt' | 'deletedAt'
|
|
7
|
+
[OptionalProps]?: 'status' | 'cursor' | 'initialCursor' | 'createdCount' | 'updatedCount' | 'skippedCount' | 'failedCount' | 'batchesCompleted' | 'lastError' | 'progressJobId' | 'jobId' | 'triggeredBy' | 'parameters' | 'createdAt' | 'updatedAt' | 'deletedAt'
|
|
8
8
|
@PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
|
|
9
9
|
id!: string
|
|
10
10
|
|
|
@@ -53,6 +53,9 @@ export class SyncRun {
|
|
|
53
53
|
@Property({ name: 'triggered_by', type: 'text', nullable: true })
|
|
54
54
|
triggeredBy?: string | null
|
|
55
55
|
|
|
56
|
+
@Property({ name: 'parameters', type: 'json', nullable: true })
|
|
57
|
+
parameters?: Record<string, unknown> | null
|
|
58
|
+
|
|
56
59
|
@Property({ name: 'organization_id', type: 'uuid' })
|
|
57
60
|
organizationId!: string
|
|
58
61
|
|
|
@@ -7,6 +7,9 @@ export const runSyncSchema = z.object({
|
|
|
7
7
|
fullSync: z.boolean().default(false),
|
|
8
8
|
batchSize: z.number().int().min(1).max(1000).default(100),
|
|
9
9
|
triggeredBy: z.string().optional(),
|
|
10
|
+
// Adapter-declared run parameters. Validated/coerced against the adapter's
|
|
11
|
+
// `runParameters` declaration in the run route; here we only accept a record.
|
|
12
|
+
parameters: z.record(z.string(), z.unknown()).optional(),
|
|
10
13
|
})
|
|
11
14
|
|
|
12
15
|
export type RunSyncInput = z.infer<typeof runSyncSchema>
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
"data_sync.dashboard.start.fullSync": "Run as full sync",
|
|
56
56
|
"data_sync.dashboard.start.fullSyncHelp": "Ignore the saved cursor and process the entire source again for this run.",
|
|
57
57
|
"data_sync.dashboard.start.invalidBatchSize": "Batch size must be between 1 and 1000.",
|
|
58
|
+
"data_sync.dashboard.start.parameters": "Lauf-Parameter",
|
|
59
|
+
"data_sync.dashboard.start.parametersHelp": "Optionale Werte, die diese Integration für den manuellen Lauf akzeptiert.",
|
|
58
60
|
"data_sync.dashboard.start.providerManaged": "Diese Integration startet Synchronisierungsläufe über ihren eigenen Einrichtungsablauf. Öffne die Integrationseinstellungen, um fortzufahren.",
|
|
59
61
|
"data_sync.dashboard.start.runNowDescription": "Use this for the next immediate sync. Batch size and full-sync mode apply only to this manual run.",
|
|
60
62
|
"data_sync.dashboard.start.runNowFootnote": "Manual runs show progress immediately and land on the run detail page after launch.",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"data_sync.integrationTab.integrationDisabledNotice": "The integration is disabled. You can save schedules now, but runs will stay blocked until the integration is enabled.",
|
|
86
88
|
"data_sync.integrationTab.loadError": "Failed to load sync schedules.",
|
|
87
89
|
"data_sync.integrationTab.notAvailable": "This integration is not registered as a data sync provider.",
|
|
90
|
+
"data_sync.integrationTab.parametersRequired": "Dieser Lauf benötigt Parameter. Starte ihn über das Data-Sync-Dashboard.",
|
|
88
91
|
"data_sync.integrationTab.providerManaged": "Starte diese Integration über ihren anbieterspezifischen Einrichtungsablauf.",
|
|
89
92
|
"data_sync.integrationTab.providerManagedNotice": "Dieser Anbieter benötigt einen eigenen Einrichtungsablauf, bevor ein Lauf gestartet werden kann. Verwende den Anbieter-Tab auf dieser Seite statt der generischen Zeitpläne.",
|
|
90
93
|
"data_sync.integrationTab.refresh": "Refresh",
|
|
@@ -96,6 +99,11 @@
|
|
|
96
99
|
"data_sync.integrationTab.starting": "Starting...",
|
|
97
100
|
"data_sync.integrationTab.title": "Sync schedules",
|
|
98
101
|
"data_sync.nav.title": "Datensynchronisation",
|
|
102
|
+
"data_sync.runParameters.errors.max": "{label} darf höchstens {max} betragen.",
|
|
103
|
+
"data_sync.runParameters.errors.min": "{label} muss mindestens {min} betragen.",
|
|
104
|
+
"data_sync.runParameters.errors.required": "{label} ist erforderlich.",
|
|
105
|
+
"data_sync.runParameters.errors.select": "{label} muss einer dieser Werte sein: {options}.",
|
|
106
|
+
"data_sync.runParameters.errors.type": "{label} muss vom Typ {type} sein.",
|
|
99
107
|
"data_sync.runs.detail.back": "Zurück zu Läufen",
|
|
100
108
|
"data_sync.runs.detail.cancel": "Abbrechen",
|
|
101
109
|
"data_sync.runs.detail.cancelError": "Lauf konnte nicht abgebrochen werden",
|
|
@@ -112,6 +120,7 @@
|
|
|
112
120
|
"data_sync.runs.detail.logs.time": "Zeit",
|
|
113
121
|
"data_sync.runs.detail.noLogs": "Keine Protokolleinträge",
|
|
114
122
|
"data_sync.runs.detail.notFound": "Synchronisierungslauf nicht gefunden.",
|
|
123
|
+
"data_sync.runs.detail.parameters": "Lauf-Parameter",
|
|
115
124
|
"data_sync.runs.detail.progress": "Fortschritt",
|
|
116
125
|
"data_sync.runs.detail.progress.batches": "{count} Stapel",
|
|
117
126
|
"data_sync.runs.detail.progress.eta": "{eta} verbleibend",
|
|
@@ -120,6 +129,7 @@
|
|
|
120
129
|
"data_sync.runs.detail.progress.percent": "{percent}% abgeschlossen",
|
|
121
130
|
"data_sync.runs.detail.retry": "Wiederholen",
|
|
122
131
|
"data_sync.runs.detail.retryError": "Lauf konnte nicht wiederholt werden",
|
|
132
|
+
"data_sync.runs.detail.retryParametersStale": "Die gespeicherten Laufparameter sind für diese Integration nicht mehr gültig. Starten Sie einen neuen Lauf über das Data-Sync-Dashboard.",
|
|
123
133
|
"data_sync.runs.detail.retrySuccess": "Lauf wiederholt",
|
|
124
134
|
"data_sync.runs.detail.title": "Synchronisierungslauf"
|
|
125
135
|
}
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
"data_sync.dashboard.start.fullSync": "Run as full sync",
|
|
56
56
|
"data_sync.dashboard.start.fullSyncHelp": "Ignore the saved cursor and process the entire source again for this run.",
|
|
57
57
|
"data_sync.dashboard.start.invalidBatchSize": "Batch size must be between 1 and 1000.",
|
|
58
|
+
"data_sync.dashboard.start.parameters": "Run parameters",
|
|
59
|
+
"data_sync.dashboard.start.parametersHelp": "Optional values this integration accepts for the manual run.",
|
|
58
60
|
"data_sync.dashboard.start.providerManaged": "This integration starts sync runs from its own setup flow. Open the integration settings page to continue.",
|
|
59
61
|
"data_sync.dashboard.start.runNowDescription": "Use this for the next immediate sync. Batch size and full-sync mode apply only to this manual run.",
|
|
60
62
|
"data_sync.dashboard.start.runNowFootnote": "Manual runs show progress immediately and land on the run detail page after launch.",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"data_sync.integrationTab.integrationDisabledNotice": "The integration is disabled. You can save schedules now, but runs will stay blocked until the integration is enabled.",
|
|
86
88
|
"data_sync.integrationTab.loadError": "Failed to load sync schedules.",
|
|
87
89
|
"data_sync.integrationTab.notAvailable": "This integration is not registered as a data sync provider.",
|
|
90
|
+
"data_sync.integrationTab.parametersRequired": "This run needs parameters. Start it from the Data Sync dashboard.",
|
|
88
91
|
"data_sync.integrationTab.providerManaged": "Start this integration from its provider-specific setup flow.",
|
|
89
92
|
"data_sync.integrationTab.providerManagedNotice": "This provider needs its own setup flow before a run can start. Use the provider tab on this page instead of generic schedules.",
|
|
90
93
|
"data_sync.integrationTab.refresh": "Refresh",
|
|
@@ -96,6 +99,11 @@
|
|
|
96
99
|
"data_sync.integrationTab.starting": "Starting...",
|
|
97
100
|
"data_sync.integrationTab.title": "Sync schedules",
|
|
98
101
|
"data_sync.nav.title": "Data Sync",
|
|
102
|
+
"data_sync.runParameters.errors.max": "{label} must be at most {max}.",
|
|
103
|
+
"data_sync.runParameters.errors.min": "{label} must be at least {min}.",
|
|
104
|
+
"data_sync.runParameters.errors.required": "{label} is required.",
|
|
105
|
+
"data_sync.runParameters.errors.select": "{label} must be one of: {options}.",
|
|
106
|
+
"data_sync.runParameters.errors.type": "{label} must be a {type}.",
|
|
99
107
|
"data_sync.runs.detail.back": "Back to Sync Runs",
|
|
100
108
|
"data_sync.runs.detail.cancel": "Cancel",
|
|
101
109
|
"data_sync.runs.detail.cancelError": "Failed to cancel sync run",
|
|
@@ -112,6 +120,7 @@
|
|
|
112
120
|
"data_sync.runs.detail.logs.time": "Time",
|
|
113
121
|
"data_sync.runs.detail.noLogs": "No log entries",
|
|
114
122
|
"data_sync.runs.detail.notFound": "Sync run not found.",
|
|
123
|
+
"data_sync.runs.detail.parameters": "Run parameters",
|
|
115
124
|
"data_sync.runs.detail.progress": "Progress",
|
|
116
125
|
"data_sync.runs.detail.progress.batches": "{count} batches",
|
|
117
126
|
"data_sync.runs.detail.progress.eta": "{eta} remaining",
|
|
@@ -120,6 +129,7 @@
|
|
|
120
129
|
"data_sync.runs.detail.progress.percent": "{percent}% complete",
|
|
121
130
|
"data_sync.runs.detail.retry": "Retry",
|
|
122
131
|
"data_sync.runs.detail.retryError": "Failed to retry sync run",
|
|
132
|
+
"data_sync.runs.detail.retryParametersStale": "The stored run parameters are no longer valid for this integration. Start a new run from the Data Sync dashboard.",
|
|
123
133
|
"data_sync.runs.detail.retrySuccess": "Sync run retried",
|
|
124
134
|
"data_sync.runs.detail.title": "Sync Run"
|
|
125
135
|
}
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
"data_sync.dashboard.start.fullSync": "Run as full sync",
|
|
56
56
|
"data_sync.dashboard.start.fullSyncHelp": "Ignore the saved cursor and process the entire source again for this run.",
|
|
57
57
|
"data_sync.dashboard.start.invalidBatchSize": "Batch size must be between 1 and 1000.",
|
|
58
|
+
"data_sync.dashboard.start.parameters": "Parámetros de ejecución",
|
|
59
|
+
"data_sync.dashboard.start.parametersHelp": "Valores opcionales que esta integración acepta para la ejecución manual.",
|
|
58
60
|
"data_sync.dashboard.start.providerManaged": "Esta integración inicia las sincronizaciones desde su propio flujo de configuración. Abre la página de ajustes de la integración para continuar.",
|
|
59
61
|
"data_sync.dashboard.start.runNowDescription": "Use this for the next immediate sync. Batch size and full-sync mode apply only to this manual run.",
|
|
60
62
|
"data_sync.dashboard.start.runNowFootnote": "Manual runs show progress immediately and land on the run detail page after launch.",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"data_sync.integrationTab.integrationDisabledNotice": "The integration is disabled. You can save schedules now, but runs will stay blocked until the integration is enabled.",
|
|
86
88
|
"data_sync.integrationTab.loadError": "Failed to load sync schedules.",
|
|
87
89
|
"data_sync.integrationTab.notAvailable": "This integration is not registered as a data sync provider.",
|
|
90
|
+
"data_sync.integrationTab.parametersRequired": "Esta ejecución necesita parámetros. Iníciala desde el panel de Data Sync.",
|
|
88
91
|
"data_sync.integrationTab.providerManaged": "Inicia esta integración desde su flujo de configuración específico del proveedor.",
|
|
89
92
|
"data_sync.integrationTab.providerManagedNotice": "Este proveedor necesita su propio flujo de configuración antes de poder iniciar una ejecución. Usa la pestaña del proveedor en esta página en lugar de los calendarios genéricos.",
|
|
90
93
|
"data_sync.integrationTab.refresh": "Refresh",
|
|
@@ -96,6 +99,11 @@
|
|
|
96
99
|
"data_sync.integrationTab.starting": "Starting...",
|
|
97
100
|
"data_sync.integrationTab.title": "Sync schedules",
|
|
98
101
|
"data_sync.nav.title": "Sincronización de datos",
|
|
102
|
+
"data_sync.runParameters.errors.max": "{label} debe ser como máximo {max}.",
|
|
103
|
+
"data_sync.runParameters.errors.min": "{label} debe ser como mínimo {min}.",
|
|
104
|
+
"data_sync.runParameters.errors.required": "{label} es obligatorio.",
|
|
105
|
+
"data_sync.runParameters.errors.select": "{label} debe ser uno de: {options}.",
|
|
106
|
+
"data_sync.runParameters.errors.type": "{label} debe ser de tipo {type}.",
|
|
99
107
|
"data_sync.runs.detail.back": "Volver a ejecuciones",
|
|
100
108
|
"data_sync.runs.detail.cancel": "Cancelar",
|
|
101
109
|
"data_sync.runs.detail.cancelError": "No se pudo cancelar la ejecución",
|
|
@@ -112,6 +120,7 @@
|
|
|
112
120
|
"data_sync.runs.detail.logs.time": "Hora",
|
|
113
121
|
"data_sync.runs.detail.noLogs": "Sin entradas de registro",
|
|
114
122
|
"data_sync.runs.detail.notFound": "Ejecución de sincronización no encontrada.",
|
|
123
|
+
"data_sync.runs.detail.parameters": "Parámetros de ejecución",
|
|
115
124
|
"data_sync.runs.detail.progress": "Progreso",
|
|
116
125
|
"data_sync.runs.detail.progress.batches": "{count} lotes",
|
|
117
126
|
"data_sync.runs.detail.progress.eta": "Quedan {eta}",
|
|
@@ -120,6 +129,7 @@
|
|
|
120
129
|
"data_sync.runs.detail.progress.percent": "{percent}% completado",
|
|
121
130
|
"data_sync.runs.detail.retry": "Reintentar",
|
|
122
131
|
"data_sync.runs.detail.retryError": "No se pudo reintentar la ejecución",
|
|
132
|
+
"data_sync.runs.detail.retryParametersStale": "Los parámetros de ejecución guardados ya no son válidos para esta integración. Inicia una nueva ejecución desde el panel de Data Sync.",
|
|
123
133
|
"data_sync.runs.detail.retrySuccess": "Ejecución reintentada",
|
|
124
134
|
"data_sync.runs.detail.title": "Ejecución de sincronización"
|
|
125
135
|
}
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
"data_sync.dashboard.start.fullSync": "전체 동기화로 실행",
|
|
56
56
|
"data_sync.dashboard.start.fullSyncHelp": "저장된 커서를 무시하고 이 실행에 대해 전체 소스를 다시 처리합니다.",
|
|
57
57
|
"data_sync.dashboard.start.invalidBatchSize": "배치 크기는 1에서 1000 사이여야 합니다.",
|
|
58
|
+
"data_sync.dashboard.start.parameters": "실행 매개변수",
|
|
59
|
+
"data_sync.dashboard.start.parametersHelp": "이 통합이 수동 실행에 대해 허용하는 선택적 값입니다.",
|
|
58
60
|
"data_sync.dashboard.start.providerManaged": "이 통합은 자체 설정 흐름에서 동기화 실행을 시작합니다. 계속하려면 통합 설정 페이지를 여세요.",
|
|
59
61
|
"data_sync.dashboard.start.runNowDescription": "다음 즉시 동기화에 사용하세요. 배치 크기와 전체 동기화 모드는 이 수동 실행에만 적용됩니다.",
|
|
60
62
|
"data_sync.dashboard.start.runNowFootnote": "수동 실행은 즉시 진행 상황을 표시하며 시작 후 실행 상세 페이지로 이동합니다.",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"data_sync.integrationTab.integrationDisabledNotice": "통합이 비활성화되어 있습니다. 지금 일정을 저장할 수 있지만 통합이 활성화될 때까지 실행이 차단됩니다.",
|
|
86
88
|
"data_sync.integrationTab.loadError": "동기화 일정을 불러오지 못했습니다.",
|
|
87
89
|
"data_sync.integrationTab.notAvailable": "이 통합은 데이터 동기화 제공업체로 등록되어 있지 않습니다.",
|
|
90
|
+
"data_sync.integrationTab.parametersRequired": "이 실행에는 매개변수가 필요합니다. 데이터 동기화 대시보드에서 시작하세요.",
|
|
88
91
|
"data_sync.integrationTab.providerManaged": "이 통합은 제공업체별 설정 흐름에서 시작하세요.",
|
|
89
92
|
"data_sync.integrationTab.providerManagedNotice": "이 제공업체는 실행을 시작하기 전에 자체 설정 흐름이 필요합니다. 일반 일정 대신 이 페이지의 제공업체 탭을 사용하세요.",
|
|
90
93
|
"data_sync.integrationTab.refresh": "새로고침",
|
|
@@ -96,6 +99,11 @@
|
|
|
96
99
|
"data_sync.integrationTab.starting": "시작하는 중...",
|
|
97
100
|
"data_sync.integrationTab.title": "동기화 일정",
|
|
98
101
|
"data_sync.nav.title": "데이터 동기화",
|
|
102
|
+
"data_sync.runParameters.errors.max": "{label}은(는) 최대 {max} 이하여야 합니다.",
|
|
103
|
+
"data_sync.runParameters.errors.min": "{label}은(는) 최소 {min} 이상이어야 합니다.",
|
|
104
|
+
"data_sync.runParameters.errors.required": "{label}은(는) 필수입니다.",
|
|
105
|
+
"data_sync.runParameters.errors.select": "{label}은(는) 다음 중 하나여야 합니다: {options}.",
|
|
106
|
+
"data_sync.runParameters.errors.type": "{label}은(는) {type} 형식이어야 합니다.",
|
|
99
107
|
"data_sync.runs.detail.back": "동기화 실행으로 돌아가기",
|
|
100
108
|
"data_sync.runs.detail.cancel": "취소",
|
|
101
109
|
"data_sync.runs.detail.cancelError": "동기화 실행 취소에 실패했습니다",
|
|
@@ -112,6 +120,7 @@
|
|
|
112
120
|
"data_sync.runs.detail.logs.time": "시간",
|
|
113
121
|
"data_sync.runs.detail.noLogs": "로그 항목 없음",
|
|
114
122
|
"data_sync.runs.detail.notFound": "동기화 실행을 찾을 수 없습니다.",
|
|
123
|
+
"data_sync.runs.detail.parameters": "실행 매개변수",
|
|
115
124
|
"data_sync.runs.detail.progress": "진행 상황",
|
|
116
125
|
"data_sync.runs.detail.progress.batches": "{count}개 배치",
|
|
117
126
|
"data_sync.runs.detail.progress.eta": "{eta} 남음",
|
|
@@ -120,6 +129,7 @@
|
|
|
120
129
|
"data_sync.runs.detail.progress.percent": "{percent}% 완료",
|
|
121
130
|
"data_sync.runs.detail.retry": "재시도",
|
|
122
131
|
"data_sync.runs.detail.retryError": "동기화 실행 재시도에 실패했습니다",
|
|
132
|
+
"data_sync.runs.detail.retryParametersStale": "저장된 실행 매개변수가 이 연동에 더 이상 유효하지 않습니다. Data Sync 대시보드에서 새 실행을 시작하세요.",
|
|
123
133
|
"data_sync.runs.detail.retrySuccess": "동기화 실행이 재시도되었습니다",
|
|
124
134
|
"data_sync.runs.detail.title": "동기화 실행"
|
|
125
135
|
}
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
"data_sync.dashboard.start.fullSync": "Uruchom jako pełną synchronizację",
|
|
56
56
|
"data_sync.dashboard.start.fullSyncHelp": "Zignoruj zapisany kursor i przetwórz w tym przebiegu całe źródło od nowa.",
|
|
57
57
|
"data_sync.dashboard.start.invalidBatchSize": "Rozmiar partii musi mieścić się w zakresie od 1 do 1000.",
|
|
58
|
+
"data_sync.dashboard.start.parameters": "Parametry uruchomienia",
|
|
59
|
+
"data_sync.dashboard.start.parametersHelp": "Opcjonalne wartości akceptowane przez tę integrację dla ręcznego uruchomienia.",
|
|
58
60
|
"data_sync.dashboard.start.providerManaged": "Ta integracja uruchamia synchronizacje z własnego przepływu konfiguracji. Otwórz ustawienia integracji, aby kontynuować.",
|
|
59
61
|
"data_sync.dashboard.start.runNowDescription": "Użyj tej opcji dla najbliższej natychmiastowej synchronizacji. Rozmiar partii i tryb pełnej synchronizacji dotyczą wyłącznie tego ręcznego przebiegu.",
|
|
60
62
|
"data_sync.dashboard.start.runNowFootnote": "Ręczne przebiegi od razu pokazują postęp, a po uruchomieniu przenoszą na stronę szczegółów przebiegu.",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"data_sync.integrationTab.integrationDisabledNotice": "Integracja jest wyłączona. Możesz teraz zapisać harmonogramy, ale przebiegi pozostaną zablokowane do czasu włączenia integracji.",
|
|
86
88
|
"data_sync.integrationTab.loadError": "Nie udało się załadować harmonogramów synchronizacji.",
|
|
87
89
|
"data_sync.integrationTab.notAvailable": "Ta integracja nie jest zarejestrowana jako dostawca synchronizacji danych.",
|
|
90
|
+
"data_sync.integrationTab.parametersRequired": "Ten przebieg wymaga parametrów. Uruchom go z panelu Data Sync.",
|
|
88
91
|
"data_sync.integrationTab.providerManaged": "Uruchom tę integrację z jej przepływu konfiguracji dostawcy.",
|
|
89
92
|
"data_sync.integrationTab.providerManagedNotice": "Ten dostawca wymaga własnego przepływu konfiguracji, zanim będzie można uruchomić synchronizację. Użyj karty dostawcy na tej stronie zamiast ogólnych harmonogramów.",
|
|
90
93
|
"data_sync.integrationTab.refresh": "Odśwież",
|
|
@@ -96,6 +99,11 @@
|
|
|
96
99
|
"data_sync.integrationTab.starting": "Uruchamianie...",
|
|
97
100
|
"data_sync.integrationTab.title": "Harmonogramy synchronizacji",
|
|
98
101
|
"data_sync.nav.title": "Synchronizacja danych",
|
|
102
|
+
"data_sync.runParameters.errors.max": "Pole {label} może wynosić najwyżej {max}.",
|
|
103
|
+
"data_sync.runParameters.errors.min": "Pole {label} musi wynosić co najmniej {min}.",
|
|
104
|
+
"data_sync.runParameters.errors.required": "Pole {label} jest wymagane.",
|
|
105
|
+
"data_sync.runParameters.errors.select": "Pole {label} musi mieć jedną z wartości: {options}.",
|
|
106
|
+
"data_sync.runParameters.errors.type": "Pole {label} musi mieć typ {type}.",
|
|
99
107
|
"data_sync.runs.detail.back": "Powrót do przebiegów",
|
|
100
108
|
"data_sync.runs.detail.cancel": "Anuluj",
|
|
101
109
|
"data_sync.runs.detail.cancelError": "Nie udało się anulować przebiegu",
|
|
@@ -112,6 +120,7 @@
|
|
|
112
120
|
"data_sync.runs.detail.logs.time": "Czas",
|
|
113
121
|
"data_sync.runs.detail.noLogs": "Brak wpisów w logach",
|
|
114
122
|
"data_sync.runs.detail.notFound": "Nie znaleziono przebiegu synchronizacji.",
|
|
123
|
+
"data_sync.runs.detail.parameters": "Parametry uruchomienia",
|
|
115
124
|
"data_sync.runs.detail.progress": "Postęp",
|
|
116
125
|
"data_sync.runs.detail.progress.batches": "{count} partii",
|
|
117
126
|
"data_sync.runs.detail.progress.eta": "Pozostało {eta}",
|
|
@@ -120,6 +129,7 @@
|
|
|
120
129
|
"data_sync.runs.detail.progress.percent": "{percent}% ukończono",
|
|
121
130
|
"data_sync.runs.detail.retry": "Ponów",
|
|
122
131
|
"data_sync.runs.detail.retryError": "Nie udało się ponowić przebiegu",
|
|
132
|
+
"data_sync.runs.detail.retryParametersStale": "Zapisane parametry uruchomienia nie są już poprawne dla tej integracji. Uruchom nowe zadanie z pulpitu Data Sync.",
|
|
123
133
|
"data_sync.runs.detail.retrySuccess": "Przebieg ponowiony",
|
|
124
134
|
"data_sync.runs.detail.title": "Przebieg synchronizacji"
|
|
125
135
|
}
|