@open-mercato/core 0.6.4-develop.4363.1.2f376570ae → 0.6.4-develop.4371.1.8f3030407e
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/modules/catalog/backend/catalog/categories/[id]/edit/page.js +66 -44
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +124 -103
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +5 -1
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
- package/dist/modules/customers/data/validators.js +4 -4
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +26 -4
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +24 -4
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +35 -6
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +67 -47
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +29 -6
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +29 -6
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +33 -4
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +33 -4
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +37 -8
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +3 -3
- package/dist/modules/workflows/backend/definitions/[id]/page.js +24 -6
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +39 -8
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +38 -6
- package/src/modules/catalog/i18n/de.json +2 -0
- package/src/modules/catalog/i18n/en.json +2 -0
- package/src/modules/catalog/i18n/es.json +2 -0
- package/src/modules/catalog/i18n/pl.json +2 -0
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +5 -1
- package/src/modules/customers/data/validators.ts +4 -4
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +30 -4
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +28 -6
- package/src/modules/directory/i18n/de.json +2 -0
- package/src/modules/directory/i18n/en.json +2 -0
- package/src/modules/directory/i18n/es.json +2 -0
- package/src/modules/directory/i18n/pl.json +2 -0
- package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +44 -4
- package/src/modules/planner/i18n/de.json +1 -0
- package/src/modules/planner/i18n/en.json +1 -0
- package/src/modules/planner/i18n/es.json +1 -0
- package/src/modules/planner/i18n/pl.json +1 -0
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +36 -7
- 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/pl.json +1 -0
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +33 -6
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +33 -6
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +44 -4
- package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +44 -4
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +44 -4
- package/src/modules/staff/i18n/de.json +5 -0
- package/src/modules/staff/i18n/en.json +5 -0
- package/src/modules/staff/i18n/es.json +5 -0
- package/src/modules/staff/i18n/pl.json +5 -0
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +26 -3
- package/src/modules/workflows/i18n/de.json +1 -0
- package/src/modules/workflows/i18n/en.json +1 -0
- package/src/modules/workflows/i18n/es.json +1 -0
- package/src/modules/workflows/i18n/pl.json +1 -0
|
@@ -5,7 +5,7 @@ import { useRouter } from 'next/navigation'
|
|
|
5
5
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
6
6
|
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
7
7
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
8
|
-
import { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'
|
|
8
|
+
import { LoadingMessage, ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'
|
|
9
9
|
import { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'
|
|
10
10
|
import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
|
|
11
11
|
import { updateCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
@@ -20,11 +20,12 @@ export default function StaffMyLeaveRequestDetailPage({ params }: { params?: { i
|
|
|
20
20
|
const router = useRouter()
|
|
21
21
|
const [isLoading, setIsLoading] = React.useState(true)
|
|
22
22
|
const [error, setError] = React.useState<string | null>(null)
|
|
23
|
+
const [isNotFound, setIsNotFound] = React.useState(false)
|
|
23
24
|
const [record, setRecord] = React.useState<NormalizedLeaveRequest | null>(null)
|
|
24
25
|
|
|
25
26
|
React.useEffect(() => {
|
|
26
27
|
if (!id) {
|
|
27
|
-
|
|
28
|
+
setIsNotFound(true)
|
|
28
29
|
setIsLoading(false)
|
|
29
30
|
return
|
|
30
31
|
}
|
|
@@ -33,6 +34,7 @@ export default function StaffMyLeaveRequestDetailPage({ params }: { params?: { i
|
|
|
33
34
|
async function load() {
|
|
34
35
|
setIsLoading(true)
|
|
35
36
|
setError(null)
|
|
37
|
+
setIsNotFound(false)
|
|
36
38
|
try {
|
|
37
39
|
const params = new URLSearchParams({ page: '1', pageSize: '1', ids: requestId })
|
|
38
40
|
const payload = await readApiResultOrThrow<LeaveRequestsResponse>(
|
|
@@ -41,15 +43,26 @@ export default function StaffMyLeaveRequestDetailPage({ params }: { params?: { i
|
|
|
41
43
|
{ errorMessage: t('staff.leaveRequests.errors.load', 'Failed to load leave request.') },
|
|
42
44
|
)
|
|
43
45
|
const entry = Array.isArray(payload.items) ? payload.items[0] : null
|
|
44
|
-
if (!entry)
|
|
46
|
+
if (!entry) {
|
|
47
|
+
if (!cancelled) {
|
|
48
|
+
setIsNotFound(true)
|
|
49
|
+
setRecord(null)
|
|
50
|
+
}
|
|
51
|
+
return
|
|
52
|
+
}
|
|
45
53
|
if (!cancelled) {
|
|
46
54
|
setRecord(normalizeLeaveRequest(entry))
|
|
47
55
|
}
|
|
48
56
|
} catch (err) {
|
|
49
57
|
if (!cancelled) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
if ((err as { status?: number }).status === 404) {
|
|
59
|
+
setIsNotFound(true)
|
|
60
|
+
setRecord(null)
|
|
61
|
+
} else {
|
|
62
|
+
const message = err instanceof Error ? err.message : t('staff.leaveRequests.errors.load', 'Failed to load leave request.')
|
|
63
|
+
setError(message)
|
|
64
|
+
setRecord(null)
|
|
65
|
+
}
|
|
53
66
|
}
|
|
54
67
|
} finally {
|
|
55
68
|
if (!cancelled) setIsLoading(false)
|
|
@@ -93,6 +106,20 @@ const handleSubmit = React.useCallback(async (values: LeaveRequestFormValues) =>
|
|
|
93
106
|
)
|
|
94
107
|
}
|
|
95
108
|
|
|
109
|
+
if (isNotFound) {
|
|
110
|
+
return (
|
|
111
|
+
<Page>
|
|
112
|
+
<PageBody>
|
|
113
|
+
<RecordNotFoundState
|
|
114
|
+
label={t('staff.leaveRequests.errors.notFound', 'Leave request not found.')}
|
|
115
|
+
backHref="/backend/staff/my-leave-requests"
|
|
116
|
+
backLabel={t('staff.leaveRequests.actions.backToMyList', 'Back to my leave requests')}
|
|
117
|
+
/>
|
|
118
|
+
</PageBody>
|
|
119
|
+
</Page>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
96
123
|
if (error || !record) {
|
|
97
124
|
return (
|
|
98
125
|
<Page>
|
|
@@ -17,6 +17,7 @@ import { TeamMemberForm, buildTeamMemberPayload, type TeamMemberFormValues } fro
|
|
|
17
17
|
import { NotesSection } from '@open-mercato/ui/backend/detail'
|
|
18
18
|
import { ActivitiesSection, type SectionAction } from '@open-mercato/ui/backend/detail'
|
|
19
19
|
import { AddressesSection as SharedAddressesSection } from '@open-mercato/ui/backend/detail'
|
|
20
|
+
import { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'
|
|
20
21
|
import { renderDictionaryColor, renderDictionaryIcon, ICON_SUGGESTIONS } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'
|
|
21
22
|
import { createStaffNotesAdapter } from '@open-mercato/core/modules/staff/components/detail/notesAdapter'
|
|
22
23
|
import { createStaffActivitiesAdapter } from '@open-mercato/core/modules/staff/components/detail/activitiesAdapter'
|
|
@@ -70,6 +71,8 @@ export default function StaffTeamMemberDetailPage({ params }: { params?: { id?:
|
|
|
70
71
|
const searchParams = useSearchParams()
|
|
71
72
|
const [initialValues, setInitialValues] = React.useState<TeamMemberFormValues | null>(null)
|
|
72
73
|
const [memberRecord, setMemberRecord] = React.useState<TeamMemberRecord | null>(null)
|
|
74
|
+
const [error, setError] = React.useState<string | null>(null)
|
|
75
|
+
const [isNotFound, setIsNotFound] = React.useState(false)
|
|
73
76
|
const [availabilityRuleSetId, setAvailabilityRuleSetId] = React.useState<string | null>(null)
|
|
74
77
|
const [activePanel, setActivePanel] = React.useState<'details' | 'availability' | 'jobHistory'>('details')
|
|
75
78
|
const [activeTab, setActiveTab] = React.useState<'notes' | 'activities' | 'addresses'>('notes')
|
|
@@ -194,6 +197,10 @@ export default function StaffTeamMemberDetailPage({ params }: { params?: { id?:
|
|
|
194
197
|
const memberIdValue = memberId
|
|
195
198
|
let cancelled = false
|
|
196
199
|
async function loadMember() {
|
|
200
|
+
if (!cancelled) {
|
|
201
|
+
setError(null)
|
|
202
|
+
setIsNotFound(false)
|
|
203
|
+
}
|
|
197
204
|
try {
|
|
198
205
|
const params = new URLSearchParams({ page: '1', pageSize: '1', ids: memberIdValue })
|
|
199
206
|
const payload = await readApiResultOrThrow<TeamMemberResponse>(
|
|
@@ -202,7 +209,10 @@ export default function StaffTeamMemberDetailPage({ params }: { params?: { id?:
|
|
|
202
209
|
{ errorMessage: t('staff.teamMembers.form.errors.load', 'Failed to load team member.') },
|
|
203
210
|
)
|
|
204
211
|
const record = Array.isArray(payload.items) ? payload.items[0] : null
|
|
205
|
-
if (!record)
|
|
212
|
+
if (!record) {
|
|
213
|
+
if (!cancelled) setIsNotFound(true)
|
|
214
|
+
return
|
|
215
|
+
}
|
|
206
216
|
const customFields = extractCustomFieldEntries(record)
|
|
207
217
|
if (!cancelled) {
|
|
208
218
|
const resolvedTeamId = record.teamId ?? record.team_id ?? null
|
|
@@ -227,9 +237,15 @@ export default function StaffTeamMemberDetailPage({ params }: { params?: { id?:
|
|
|
227
237
|
: null,
|
|
228
238
|
)
|
|
229
239
|
}
|
|
230
|
-
} catch (
|
|
231
|
-
|
|
232
|
-
|
|
240
|
+
} catch (err) {
|
|
241
|
+
if (!cancelled) {
|
|
242
|
+
if ((err as { status?: number }).status === 404) {
|
|
243
|
+
setIsNotFound(true)
|
|
244
|
+
} else {
|
|
245
|
+
const message = err instanceof Error ? err.message : t('staff.teamMembers.form.errors.load', 'Failed to load team member.')
|
|
246
|
+
setError(message)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
233
249
|
}
|
|
234
250
|
}
|
|
235
251
|
void loadMember()
|
|
@@ -304,6 +320,30 @@ export default function StaffTeamMemberDetailPage({ params }: { params?: { id?:
|
|
|
304
320
|
: [t('staff.teamMembers.detail.roles.unassigned', 'No roles assigned')]
|
|
305
321
|
const userEmail = memberRecord?.user?.email ?? null
|
|
306
322
|
|
|
323
|
+
if (isNotFound) {
|
|
324
|
+
return (
|
|
325
|
+
<Page>
|
|
326
|
+
<PageBody>
|
|
327
|
+
<RecordNotFoundState
|
|
328
|
+
label={t('staff.teamMembers.form.errors.notFound', 'Team member not found.')}
|
|
329
|
+
backHref="/backend/staff/team-members"
|
|
330
|
+
backLabel={t('staff.teamMembers.actions.backToList', 'Back to team members')}
|
|
331
|
+
/>
|
|
332
|
+
</PageBody>
|
|
333
|
+
</Page>
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (error && !initialValues) {
|
|
338
|
+
return (
|
|
339
|
+
<Page>
|
|
340
|
+
<PageBody>
|
|
341
|
+
<ErrorMessage label={error} />
|
|
342
|
+
</PageBody>
|
|
343
|
+
</Page>
|
|
344
|
+
)
|
|
345
|
+
}
|
|
346
|
+
|
|
307
347
|
return (
|
|
308
348
|
<Page>
|
|
309
349
|
<PageBody>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { useRouter } from 'next/navigation'
|
|
5
5
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
6
|
+
import { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'
|
|
6
7
|
import { readApiResultOrThrow, apiCall } from '@open-mercato/ui/backend/utils/apiCall'
|
|
7
8
|
import { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
8
9
|
import { flash } from '@open-mercato/ui/backend/FlashMessages'
|
|
@@ -38,6 +39,8 @@ export default function StaffTeamRoleEditPage({ params }: { params?: { id?: stri
|
|
|
38
39
|
const router = useRouter()
|
|
39
40
|
const scopeVersion = useOrganizationScopeVersion()
|
|
40
41
|
const [initialValues, setInitialValues] = React.useState<TeamRoleFormValues | null>(null)
|
|
42
|
+
const [error, setError] = React.useState<string | null>(null)
|
|
43
|
+
const [isNotFound, setIsNotFound] = React.useState(false)
|
|
41
44
|
const [teams, setTeams] = React.useState<TeamRoleOption[]>([])
|
|
42
45
|
|
|
43
46
|
React.useEffect(() => {
|
|
@@ -45,6 +48,10 @@ export default function StaffTeamRoleEditPage({ params }: { params?: { id?: stri
|
|
|
45
48
|
const roleIdValue = roleId
|
|
46
49
|
let cancelled = false
|
|
47
50
|
async function loadRole() {
|
|
51
|
+
if (!cancelled) {
|
|
52
|
+
setError(null)
|
|
53
|
+
setIsNotFound(false)
|
|
54
|
+
}
|
|
48
55
|
try {
|
|
49
56
|
const params = new URLSearchParams({ page: '1', pageSize: '1', ids: roleIdValue })
|
|
50
57
|
const payload = await readApiResultOrThrow<TeamRoleResponse>(
|
|
@@ -53,7 +60,10 @@ export default function StaffTeamRoleEditPage({ params }: { params?: { id?: stri
|
|
|
53
60
|
{ errorMessage: t('staff.teamRoles.errors.load', 'Failed to load team role.') },
|
|
54
61
|
)
|
|
55
62
|
const record = Array.isArray(payload.items) ? payload.items[0] : null
|
|
56
|
-
if (!record)
|
|
63
|
+
if (!record) {
|
|
64
|
+
if (!cancelled) setIsNotFound(true)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
57
67
|
const customFields = extractCustomFieldEntries(record)
|
|
58
68
|
const appearanceIcon = typeof record.appearanceIcon === 'string'
|
|
59
69
|
? record.appearanceIcon
|
|
@@ -79,9 +89,15 @@ export default function StaffTeamRoleEditPage({ params }: { params?: { id?: stri
|
|
|
79
89
|
...customFields,
|
|
80
90
|
})
|
|
81
91
|
}
|
|
82
|
-
} catch (
|
|
83
|
-
|
|
84
|
-
|
|
92
|
+
} catch (err) {
|
|
93
|
+
if (!cancelled) {
|
|
94
|
+
if ((err as { status?: number }).status === 404) {
|
|
95
|
+
setIsNotFound(true)
|
|
96
|
+
} else {
|
|
97
|
+
const message = err instanceof Error ? err.message : t('staff.teamRoles.errors.load', 'Failed to load team role.')
|
|
98
|
+
setError(message)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
85
101
|
}
|
|
86
102
|
}
|
|
87
103
|
loadRole()
|
|
@@ -131,6 +147,30 @@ export default function StaffTeamRoleEditPage({ params }: { params?: { id?: stri
|
|
|
131
147
|
router.push('/backend/staff/team-roles')
|
|
132
148
|
}, [roleId, router, t])
|
|
133
149
|
|
|
150
|
+
if (isNotFound) {
|
|
151
|
+
return (
|
|
152
|
+
<Page>
|
|
153
|
+
<PageBody>
|
|
154
|
+
<RecordNotFoundState
|
|
155
|
+
label={t('staff.teamRoles.errors.notFound', 'Team role not found.')}
|
|
156
|
+
backHref="/backend/staff/team-roles"
|
|
157
|
+
backLabel={t('staff.teamRoles.actions.backToList', 'Back to team roles')}
|
|
158
|
+
/>
|
|
159
|
+
</PageBody>
|
|
160
|
+
</Page>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (error && !initialValues) {
|
|
165
|
+
return (
|
|
166
|
+
<Page>
|
|
167
|
+
<PageBody>
|
|
168
|
+
<ErrorMessage label={error} />
|
|
169
|
+
</PageBody>
|
|
170
|
+
</Page>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
134
174
|
return (
|
|
135
175
|
<Page>
|
|
136
176
|
<PageBody>
|
|
@@ -5,6 +5,7 @@ import Link from 'next/link'
|
|
|
5
5
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
6
6
|
import type { ColumnDef, SortingState } from '@tanstack/react-table'
|
|
7
7
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
8
|
+
import { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'
|
|
8
9
|
import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
|
|
9
10
|
import { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
10
11
|
import { DataTable, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'
|
|
@@ -59,6 +60,8 @@ export default function StaffTeamEditPage({ params }: { params?: { id?: string }
|
|
|
59
60
|
const searchParams = useSearchParams()
|
|
60
61
|
const scopeVersion = useOrganizationScopeVersion()
|
|
61
62
|
const [initialValues, setInitialValues] = React.useState<TeamFormValues | null>(null)
|
|
63
|
+
const [error, setError] = React.useState<string | null>(null)
|
|
64
|
+
const [isNotFound, setIsNotFound] = React.useState(false)
|
|
62
65
|
const [activeTab, setActiveTab] = React.useState<'details' | 'members'>('details')
|
|
63
66
|
const [memberRows, setMemberRows] = React.useState<TeamMemberRow[]>([])
|
|
64
67
|
const [memberPage, setMemberPage] = React.useState(1)
|
|
@@ -168,6 +171,10 @@ export default function StaffTeamEditPage({ params }: { params?: { id?: string }
|
|
|
168
171
|
const teamIdValue = teamId
|
|
169
172
|
let cancelled = false
|
|
170
173
|
async function loadTeam() {
|
|
174
|
+
if (!cancelled) {
|
|
175
|
+
setError(null)
|
|
176
|
+
setIsNotFound(false)
|
|
177
|
+
}
|
|
171
178
|
try {
|
|
172
179
|
const params = new URLSearchParams({ page: '1', pageSize: '1', ids: teamIdValue })
|
|
173
180
|
const payload = await readApiResultOrThrow<TeamResponse>(
|
|
@@ -176,7 +183,10 @@ export default function StaffTeamEditPage({ params }: { params?: { id?: string }
|
|
|
176
183
|
{ errorMessage: t('staff.teams.errors.load', 'Failed to load team.') },
|
|
177
184
|
)
|
|
178
185
|
const record = Array.isArray(payload.items) ? payload.items[0] : null
|
|
179
|
-
if (!record)
|
|
186
|
+
if (!record) {
|
|
187
|
+
if (!cancelled) setIsNotFound(true)
|
|
188
|
+
return
|
|
189
|
+
}
|
|
180
190
|
const customFields = extractCustomFieldEntries(record)
|
|
181
191
|
const isActive = typeof record.isActive === 'boolean'
|
|
182
192
|
? record.isActive
|
|
@@ -192,9 +202,15 @@ export default function StaffTeamEditPage({ params }: { params?: { id?: string }
|
|
|
192
202
|
...customFields,
|
|
193
203
|
})
|
|
194
204
|
}
|
|
195
|
-
} catch (
|
|
196
|
-
|
|
197
|
-
|
|
205
|
+
} catch (err) {
|
|
206
|
+
if (!cancelled) {
|
|
207
|
+
if ((err as { status?: number }).status === 404) {
|
|
208
|
+
setIsNotFound(true)
|
|
209
|
+
} else {
|
|
210
|
+
const message = err instanceof Error ? err.message : t('staff.teams.errors.load', 'Failed to load team.')
|
|
211
|
+
setError(message)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
198
214
|
}
|
|
199
215
|
}
|
|
200
216
|
loadTeam()
|
|
@@ -288,6 +304,30 @@ export default function StaffTeamEditPage({ params }: { params?: { id?: string }
|
|
|
288
304
|
router.push('/backend/staff/teams')
|
|
289
305
|
}, [teamId, router, t])
|
|
290
306
|
|
|
307
|
+
if (isNotFound) {
|
|
308
|
+
return (
|
|
309
|
+
<Page>
|
|
310
|
+
<PageBody>
|
|
311
|
+
<RecordNotFoundState
|
|
312
|
+
label={t('staff.teams.errors.notFound', 'Team not found.')}
|
|
313
|
+
backHref="/backend/staff/teams"
|
|
314
|
+
backLabel={t('staff.teams.actions.backToList', 'Back to teams')}
|
|
315
|
+
/>
|
|
316
|
+
</PageBody>
|
|
317
|
+
</Page>
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (error && !initialValues) {
|
|
322
|
+
return (
|
|
323
|
+
<Page>
|
|
324
|
+
<PageBody>
|
|
325
|
+
<ErrorMessage label={error} />
|
|
326
|
+
</PageBody>
|
|
327
|
+
</Page>
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
|
|
291
331
|
return (
|
|
292
332
|
<Page>
|
|
293
333
|
<PageBody>
|
|
@@ -214,6 +214,8 @@
|
|
|
214
214
|
"staff.errors.unauthorized": "Nicht autorisiert",
|
|
215
215
|
"staff.leaveRequests.actions.accept": "Genehmigen",
|
|
216
216
|
"staff.leaveRequests.actions.add": "Neuer Antrag",
|
|
217
|
+
"staff.leaveRequests.actions.backToList": "Zurück zu Urlaubsanträgen",
|
|
218
|
+
"staff.leaveRequests.actions.backToMyList": "Zurück zu meinen Urlaubsanträgen",
|
|
217
219
|
"staff.leaveRequests.actions.createProfile": "Mein Profil erstellen",
|
|
218
220
|
"staff.leaveRequests.actions.refresh": "Aktualisieren",
|
|
219
221
|
"staff.leaveRequests.actions.reject": "Ablehnen",
|
|
@@ -444,6 +446,7 @@
|
|
|
444
446
|
"staff.services.table.search": "Leistungen suchen...",
|
|
445
447
|
"staff.services.table.tags": "Schlagworte",
|
|
446
448
|
"staff.teamMembers.actions.add": "Teammitglied hinzufügen",
|
|
449
|
+
"staff.teamMembers.actions.backToList": "Zurück zu Teammitgliedern",
|
|
447
450
|
"staff.teamMembers.actions.delete": "Löschen",
|
|
448
451
|
"staff.teamMembers.actions.deleteConfirm": "Teammitglied \"{{name}}\" löschen?",
|
|
449
452
|
"staff.teamMembers.actions.edit": "Bearbeiten",
|
|
@@ -854,6 +857,7 @@
|
|
|
854
857
|
"staff.teamMembers.tags.title": "Schlagworte",
|
|
855
858
|
"staff.teamMembers.tags.updateError": "Tags konnten nicht aktualisiert werden.",
|
|
856
859
|
"staff.teamRoles.actions.add": "Teamrolle hinzufügen",
|
|
860
|
+
"staff.teamRoles.actions.backToList": "Zurück zu Teamrollen",
|
|
857
861
|
"staff.teamRoles.actions.delete": "Löschen",
|
|
858
862
|
"staff.teamRoles.actions.deleteConfirm": "Teamrolle \"{{name}}\" löschen?",
|
|
859
863
|
"staff.teamRoles.actions.edit": "Bearbeiten",
|
|
@@ -897,6 +901,7 @@
|
|
|
897
901
|
"staff.teamRoles.table.search": "Rollen suchen...",
|
|
898
902
|
"staff.teamRoles.table.updatedAt": "Aktualisiert",
|
|
899
903
|
"staff.teams.actions.add": "Team hinzufügen",
|
|
904
|
+
"staff.teams.actions.backToList": "Zurück zu Teams",
|
|
900
905
|
"staff.teams.actions.delete": "Löschen",
|
|
901
906
|
"staff.teams.actions.deleteConfirm": "Team \"{{name}}\" löschen?",
|
|
902
907
|
"staff.teams.actions.edit": "Bearbeiten",
|
|
@@ -214,6 +214,8 @@
|
|
|
214
214
|
"staff.errors.unauthorized": "Unauthorized",
|
|
215
215
|
"staff.leaveRequests.actions.accept": "Approve",
|
|
216
216
|
"staff.leaveRequests.actions.add": "New request",
|
|
217
|
+
"staff.leaveRequests.actions.backToList": "Back to leave requests",
|
|
218
|
+
"staff.leaveRequests.actions.backToMyList": "Back to my leave requests",
|
|
217
219
|
"staff.leaveRequests.actions.createProfile": "Create my profile",
|
|
218
220
|
"staff.leaveRequests.actions.refresh": "Refresh",
|
|
219
221
|
"staff.leaveRequests.actions.reject": "Reject",
|
|
@@ -444,6 +446,7 @@
|
|
|
444
446
|
"staff.services.table.search": "Search services...",
|
|
445
447
|
"staff.services.table.tags": "Tags",
|
|
446
448
|
"staff.teamMembers.actions.add": "Add team member",
|
|
449
|
+
"staff.teamMembers.actions.backToList": "Back to team members",
|
|
447
450
|
"staff.teamMembers.actions.delete": "Delete",
|
|
448
451
|
"staff.teamMembers.actions.deleteConfirm": "Delete team member \"{{name}}\"?",
|
|
449
452
|
"staff.teamMembers.actions.edit": "Edit",
|
|
@@ -854,6 +857,7 @@
|
|
|
854
857
|
"staff.teamMembers.tags.title": "Tags",
|
|
855
858
|
"staff.teamMembers.tags.updateError": "Failed to update tags.",
|
|
856
859
|
"staff.teamRoles.actions.add": "Add team role",
|
|
860
|
+
"staff.teamRoles.actions.backToList": "Back to team roles",
|
|
857
861
|
"staff.teamRoles.actions.delete": "Delete",
|
|
858
862
|
"staff.teamRoles.actions.deleteConfirm": "Delete team role \"{{name}}\"?",
|
|
859
863
|
"staff.teamRoles.actions.edit": "Edit",
|
|
@@ -897,6 +901,7 @@
|
|
|
897
901
|
"staff.teamRoles.table.search": "Search roles...",
|
|
898
902
|
"staff.teamRoles.table.updatedAt": "Updated",
|
|
899
903
|
"staff.teams.actions.add": "Add team",
|
|
904
|
+
"staff.teams.actions.backToList": "Back to teams",
|
|
900
905
|
"staff.teams.actions.delete": "Delete",
|
|
901
906
|
"staff.teams.actions.deleteConfirm": "Delete team \"{{name}}\"?",
|
|
902
907
|
"staff.teams.actions.edit": "Edit",
|
|
@@ -214,6 +214,8 @@
|
|
|
214
214
|
"staff.errors.unauthorized": "No autorizado",
|
|
215
215
|
"staff.leaveRequests.actions.accept": "Aprobar",
|
|
216
216
|
"staff.leaveRequests.actions.add": "Nueva solicitud",
|
|
217
|
+
"staff.leaveRequests.actions.backToList": "Volver a solicitudes de ausencia",
|
|
218
|
+
"staff.leaveRequests.actions.backToMyList": "Volver a mis solicitudes de ausencia",
|
|
217
219
|
"staff.leaveRequests.actions.createProfile": "Crear mi perfil",
|
|
218
220
|
"staff.leaveRequests.actions.refresh": "Actualizar",
|
|
219
221
|
"staff.leaveRequests.actions.reject": "Rechazar",
|
|
@@ -444,6 +446,7 @@
|
|
|
444
446
|
"staff.services.table.search": "Buscar servicios...",
|
|
445
447
|
"staff.services.table.tags": "Etiquetas",
|
|
446
448
|
"staff.teamMembers.actions.add": "Agregar miembro",
|
|
449
|
+
"staff.teamMembers.actions.backToList": "Volver a miembros del equipo",
|
|
447
450
|
"staff.teamMembers.actions.delete": "Eliminar",
|
|
448
451
|
"staff.teamMembers.actions.deleteConfirm": "¿Eliminar al miembro \"{{name}}\"?",
|
|
449
452
|
"staff.teamMembers.actions.edit": "Editar",
|
|
@@ -854,6 +857,7 @@
|
|
|
854
857
|
"staff.teamMembers.tags.title": "Etiquetas",
|
|
855
858
|
"staff.teamMembers.tags.updateError": "No se pudieron actualizar las etiquetas.",
|
|
856
859
|
"staff.teamRoles.actions.add": "Agregar rol",
|
|
860
|
+
"staff.teamRoles.actions.backToList": "Volver a roles del equipo",
|
|
857
861
|
"staff.teamRoles.actions.delete": "Eliminar",
|
|
858
862
|
"staff.teamRoles.actions.deleteConfirm": "¿Eliminar el rol \"{{name}}\"?",
|
|
859
863
|
"staff.teamRoles.actions.edit": "Editar",
|
|
@@ -897,6 +901,7 @@
|
|
|
897
901
|
"staff.teamRoles.table.search": "Buscar roles...",
|
|
898
902
|
"staff.teamRoles.table.updatedAt": "Actualizado",
|
|
899
903
|
"staff.teams.actions.add": "Agregar equipo",
|
|
904
|
+
"staff.teams.actions.backToList": "Volver a equipos",
|
|
900
905
|
"staff.teams.actions.delete": "Eliminar",
|
|
901
906
|
"staff.teams.actions.deleteConfirm": "¿Eliminar el equipo \"{{name}}\"?",
|
|
902
907
|
"staff.teams.actions.edit": "Editar",
|
|
@@ -214,6 +214,8 @@
|
|
|
214
214
|
"staff.errors.unauthorized": "Brak autoryzacji",
|
|
215
215
|
"staff.leaveRequests.actions.accept": "Zatwierdź",
|
|
216
216
|
"staff.leaveRequests.actions.add": "Nowy wniosek",
|
|
217
|
+
"staff.leaveRequests.actions.backToList": "Powrót do wniosków urlopowych",
|
|
218
|
+
"staff.leaveRequests.actions.backToMyList": "Powrót do moich wniosków urlopowych",
|
|
217
219
|
"staff.leaveRequests.actions.createProfile": "Utwórz mój profil",
|
|
218
220
|
"staff.leaveRequests.actions.refresh": "Odśwież",
|
|
219
221
|
"staff.leaveRequests.actions.reject": "Odrzuć",
|
|
@@ -444,6 +446,7 @@
|
|
|
444
446
|
"staff.services.table.search": "Szukaj usług...",
|
|
445
447
|
"staff.services.table.tags": "Tagi",
|
|
446
448
|
"staff.teamMembers.actions.add": "Dodaj członka",
|
|
449
|
+
"staff.teamMembers.actions.backToList": "Powrót do członków zespołu",
|
|
447
450
|
"staff.teamMembers.actions.delete": "Usuń",
|
|
448
451
|
"staff.teamMembers.actions.deleteConfirm": "Usunąć członka \"{{name}}\"?",
|
|
449
452
|
"staff.teamMembers.actions.edit": "Edytuj",
|
|
@@ -854,6 +857,7 @@
|
|
|
854
857
|
"staff.teamMembers.tags.title": "Tagi",
|
|
855
858
|
"staff.teamMembers.tags.updateError": "Nie udało się zaktualizować tagów.",
|
|
856
859
|
"staff.teamRoles.actions.add": "Dodaj rolę",
|
|
860
|
+
"staff.teamRoles.actions.backToList": "Powrót do ról zespołu",
|
|
857
861
|
"staff.teamRoles.actions.delete": "Usuń",
|
|
858
862
|
"staff.teamRoles.actions.deleteConfirm": "Usunąć rolę \"{{name}}\"?",
|
|
859
863
|
"staff.teamRoles.actions.edit": "Edytuj",
|
|
@@ -897,6 +901,7 @@
|
|
|
897
901
|
"staff.teamRoles.table.search": "Szukaj ról...",
|
|
898
902
|
"staff.teamRoles.table.updatedAt": "Zaktualizowano",
|
|
899
903
|
"staff.teams.actions.add": "Dodaj zespół",
|
|
904
|
+
"staff.teams.actions.backToList": "Powrót do zespołów",
|
|
900
905
|
"staff.teams.actions.delete": "Usuń",
|
|
901
906
|
"staff.teams.actions.deleteConfirm": "Usunąć zespół \"{{name}}\"?",
|
|
902
907
|
"staff.teams.actions.edit": "Edytuj",
|
|
@@ -8,6 +8,7 @@ import { CrudForm } from '@open-mercato/ui/backend/CrudForm'
|
|
|
8
8
|
import { Spinner } from '@open-mercato/ui/primitives/spinner'
|
|
9
9
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
10
10
|
import { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'
|
|
11
|
+
import { ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'
|
|
11
12
|
import { apiFetch } from '@open-mercato/ui/backend/utils/api'
|
|
12
13
|
import { readJsonSafe } from '@open-mercato/ui/backend/utils/serverErrors'
|
|
13
14
|
import { formatWorkflowValidationError } from '../../../lib/format-validation-error'
|
|
@@ -49,14 +50,22 @@ export default function EditWorkflowDefinitionPage() {
|
|
|
49
50
|
queryFn: async () => {
|
|
50
51
|
const response = await apiFetch(`/api/workflows/definitions/${definitionId}`)
|
|
51
52
|
if (!response.ok) {
|
|
52
|
-
|
|
53
|
+
const err = new Error(t('workflows.errors.fetchFailed')) as Error & { status?: number }
|
|
54
|
+
err.status = response.status
|
|
55
|
+
throw err
|
|
53
56
|
}
|
|
54
57
|
const result = await response.json()
|
|
55
58
|
return result.data
|
|
56
59
|
},
|
|
57
60
|
enabled: !!definitionId,
|
|
61
|
+
retry: (failureCount, err) => {
|
|
62
|
+
if ((err as { status?: number }).status === 404) return false
|
|
63
|
+
return failureCount < 2
|
|
64
|
+
},
|
|
58
65
|
})
|
|
59
66
|
|
|
67
|
+
const isNotFound = (error as { status?: number } | null)?.status === 404
|
|
68
|
+
|
|
60
69
|
const initialValues = React.useMemo(() => {
|
|
61
70
|
if (definition) {
|
|
62
71
|
return parseWorkflowToFormValues(definition)
|
|
@@ -209,12 +218,26 @@ export default function EditWorkflowDefinitionPage() {
|
|
|
209
218
|
)
|
|
210
219
|
}
|
|
211
220
|
|
|
221
|
+
if (isNotFound) {
|
|
222
|
+
return (
|
|
223
|
+
<Page>
|
|
224
|
+
<PageBody>
|
|
225
|
+
<RecordNotFoundState
|
|
226
|
+
label={t('workflows.errors.notFound', t('workflows.errors.loadFailed'))}
|
|
227
|
+
backHref="/backend/definitions"
|
|
228
|
+
backLabel={t('workflows.backToList')}
|
|
229
|
+
/>
|
|
230
|
+
</PageBody>
|
|
231
|
+
</Page>
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
|
|
212
235
|
if (error || !definition) {
|
|
213
236
|
return (
|
|
214
237
|
<Page>
|
|
215
238
|
<PageBody>
|
|
216
|
-
<
|
|
217
|
-
|
|
239
|
+
<ErrorMessage label={t('workflows.errors.loadFailed')} />
|
|
240
|
+
<div className="mt-4 flex justify-center">
|
|
218
241
|
<Button asChild variant="outline">
|
|
219
242
|
<a href="/backend/definitions">{t('workflows.backToList')}</a>
|
|
220
243
|
</Button>
|
|
@@ -402,6 +402,7 @@
|
|
|
402
402
|
"workflows.errors.createFailed": "Workflow konnte nicht erstellt werden",
|
|
403
403
|
"workflows.errors.fetchFailed": "Workflow konnte nicht abgerufen werden",
|
|
404
404
|
"workflows.errors.loadFailed": "Workflow konnte nicht geladen werden. Bitte versuchen Sie es erneut.",
|
|
405
|
+
"workflows.errors.notFound": "Workflow nicht gefunden.",
|
|
405
406
|
"workflows.errors.updateFailed": "Workflow konnte nicht aktualisiert werden",
|
|
406
407
|
"workflows.events.backToList": "Zurück zu Ereignissen",
|
|
407
408
|
"workflows.events.detail.eventData": "Ereignisdaten",
|
|
@@ -402,6 +402,7 @@
|
|
|
402
402
|
"workflows.errors.createFailed": "Failed to create workflow",
|
|
403
403
|
"workflows.errors.fetchFailed": "Failed to fetch workflow",
|
|
404
404
|
"workflows.errors.loadFailed": "Failed to load workflow. Please try again.",
|
|
405
|
+
"workflows.errors.notFound": "Workflow not found.",
|
|
405
406
|
"workflows.errors.updateFailed": "Failed to update workflow",
|
|
406
407
|
"workflows.events.backToList": "Back to Events",
|
|
407
408
|
"workflows.events.detail.eventData": "Event Data",
|
|
@@ -402,6 +402,7 @@
|
|
|
402
402
|
"workflows.errors.createFailed": "No se pudo crear el flujo de trabajo",
|
|
403
403
|
"workflows.errors.fetchFailed": "No se pudo obtener el flujo de trabajo",
|
|
404
404
|
"workflows.errors.loadFailed": "No se pudo cargar el flujo de trabajo. Intentalo de nuevo.",
|
|
405
|
+
"workflows.errors.notFound": "Flujo de trabajo no encontrado.",
|
|
405
406
|
"workflows.errors.updateFailed": "No se pudo actualizar el flujo de trabajo",
|
|
406
407
|
"workflows.events.backToList": "Volver a eventos",
|
|
407
408
|
"workflows.events.detail.eventData": "Datos del evento",
|
|
@@ -402,6 +402,7 @@
|
|
|
402
402
|
"workflows.errors.createFailed": "Nie udało się utworzyć przepływu",
|
|
403
403
|
"workflows.errors.fetchFailed": "Nie udało się pobrać przepływu",
|
|
404
404
|
"workflows.errors.loadFailed": "Nie udało się załadować przepływu. Spróbuj ponownie.",
|
|
405
|
+
"workflows.errors.notFound": "Nie znaleziono przepływu pracy.",
|
|
405
406
|
"workflows.errors.updateFailed": "Nie udało się zaktualizować przepływu",
|
|
406
407
|
"workflows.events.backToList": "Powrót do Zdarzeń",
|
|
407
408
|
"workflows.events.detail.eventData": "Dane Zdarzenia",
|