@open-mercato/core 0.6.6-develop.6256.1.9fc16aedc4 → 0.6.6-develop.6286.1.d985c5c374
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 +2 -2
- package/dist/generated/entities/carrier_shipment_idempotency_key/index.js +19 -0
- package/dist/generated/entities/carrier_shipment_idempotency_key/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +2 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +10 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/catalog/lib/productResolution.js +45 -0
- package/dist/modules/catalog/lib/productResolution.js.map +7 -0
- package/dist/modules/communication_channels/workers/channel-import-history.js +1 -1
- package/dist/modules/communication_channels/workers/channel-import-history.js.map +2 -2
- package/dist/modules/currencies/api/fetch-configs/route.js +34 -0
- package/dist/modules/currencies/api/fetch-configs/route.js.map +2 -2
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js +17 -15
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +176 -161
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/route.js +75 -59
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +17 -10
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesAddNewMenu.js +6 -4
- package/dist/modules/customers/components/detail/ActivitiesAddNewMenu.js.map +2 -2
- package/dist/modules/customers/components/detail/AiActionChips.js +5 -2
- package/dist/modules/customers/components/detail/AiActionChips.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +19 -21
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/cancel.js +1 -1
- package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +9 -45
- 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 +11 -17
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +12 -10
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/data_sync/lib/id-mapping.js +46 -1
- package/dist/modules/data_sync/lib/id-mapping.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-engine.js +2 -2
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/lib/syncRunStatus.js +30 -0
- package/dist/modules/data_sync/lib/syncRunStatus.js.map +7 -0
- package/dist/modules/entities/api/records.js +6 -0
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/feature_toggles/api/global/route.js +17 -15
- package/dist/modules/feature_toggles/api/global/route.js.map +2 -2
- package/dist/modules/feature_toggles/api/openapi.js +2 -2
- package/dist/modules/feature_toggles/api/openapi.js.map +2 -2
- package/dist/modules/feature_toggles/commands/global.js +14 -0
- package/dist/modules/feature_toggles/commands/global.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js +6 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
- package/dist/modules/messages/api/[id]/conversation/archive/route.js +25 -7
- package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +2 -2
- package/dist/modules/messages/api/[id]/conversation/read/route.js +24 -6
- package/dist/modules/messages/api/[id]/conversation/read/route.js.map +2 -2
- package/dist/modules/messages/api/[id]/route.js +13 -1
- package/dist/modules/messages/api/[id]/route.js.map +2 -2
- package/dist/modules/messages/api/openapi.js +3 -1
- package/dist/modules/messages/api/openapi.js.map +2 -2
- package/dist/modules/messages/commands/conversation.js +77 -0
- package/dist/modules/messages/commands/conversation.js.map +2 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js +16 -4
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js +3 -1
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +29 -4
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js +10 -1
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +13 -11
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +2 -2
- package/dist/modules/payment_gateways/api/cancel/route.js +5 -0
- package/dist/modules/payment_gateways/api/cancel/route.js.map +2 -2
- package/dist/modules/payment_gateways/api/capture/route.js +5 -0
- package/dist/modules/payment_gateways/api/capture/route.js.map +2 -2
- package/dist/modules/payment_gateways/api/refund/route.js +5 -0
- package/dist/modules/payment_gateways/api/refund/route.js.map +2 -2
- package/dist/modules/payment_gateways/lib/gateway-service.js +52 -25
- package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
- package/dist/modules/payment_gateways/lib/status-machine.js +13 -0
- package/dist/modules/payment_gateways/lib/status-machine.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/route.js +8 -2
- package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
- package/dist/modules/perspectives/data/entities.js +33 -3
- package/dist/modules/perspectives/data/entities.js.map +2 -2
- package/dist/modules/perspectives/migrations/Migration20260619120000_perspectives_live_row_uniqueness.js +63 -0
- package/dist/modules/perspectives/migrations/Migration20260619120000_perspectives_live_row_uniqueness.js.map +7 -0
- package/dist/modules/perspectives/services/perspectiveService.js +17 -0
- package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
- package/dist/modules/planner/commands/availability-weekly.js +33 -1
- package/dist/modules/planner/commands/availability-weekly.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +14 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/progress/api/active/route.js +1 -1
- package/dist/modules/progress/api/active/route.js.map +2 -2
- package/dist/modules/progress/lib/progressService.js.map +1 -1
- package/dist/modules/progress/lib/progressServiceImpl.js +33 -8
- package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
- package/dist/modules/query_index/api/status.js +19 -24
- package/dist/modules/query_index/api/status.js.map +3 -3
- package/dist/modules/query_index/lib/coverage.js +35 -0
- package/dist/modules/query_index/lib/coverage.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +11 -6
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/resources/api/resource-types.js +5 -37
- package/dist/modules/resources/api/resource-types.js.map +2 -2
- package/dist/modules/resources/api/resourceTypeCounts.js +35 -0
- package/dist/modules/resources/api/resourceTypeCounts.js.map +7 -0
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +1 -1
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +1 -1
- package/dist/modules/resources/backend/resources/resource-types/page.js +2 -1
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnDialog.js +4 -1
- package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +17 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/di.js +4 -0
- package/dist/modules/sales/di.js.map +2 -2
- package/dist/modules/sales/services/salesOrderService.js +26 -0
- package/dist/modules/sales/services/salesOrderService.js.map +7 -0
- package/dist/modules/shipping_carriers/api/shipments/route.js +8 -0
- package/dist/modules/shipping_carriers/api/shipments/route.js.map +2 -2
- package/dist/modules/shipping_carriers/data/entities.js +38 -0
- package/dist/modules/shipping_carriers/data/entities.js.map +2 -2
- package/dist/modules/shipping_carriers/data/validators.js +2 -1
- package/dist/modules/shipping_carriers/data/validators.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipment-idempotency.js +76 -0
- package/dist/modules/shipping_carriers/lib/shipment-idempotency.js.map +7 -0
- package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/shipmentApi.js +2 -1
- package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/shipmentApi.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/useShipmentWizard.js +20 -2
- package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/useShipmentWizard.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipping-service.js +82 -43
- package/dist/modules/shipping_carriers/lib/shipping-service.js.map +2 -2
- package/dist/modules/shipping_carriers/migrations/Migration20260618173616_shipping_carriers.js +14 -0
- package/dist/modules/shipping_carriers/migrations/Migration20260618173616_shipping_carriers.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/ListView.js +15 -6
- package/dist/modules/staff/lib/timesheets-ui/ListView.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +9 -18
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/generated/entities/carrier_shipment_idempotency_key/index.ts +8 -0
- package/generated/entities.ids.generated.ts +2 -1
- package/generated/entity-fields-registry.ts +10 -0
- package/package.json +9 -8
- package/src/modules/catalog/lib/productResolution.ts +75 -0
- package/src/modules/communication_channels/workers/channel-import-history.ts +1 -1
- package/src/modules/currencies/api/fetch-configs/route.ts +36 -0
- package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +20 -17
- package/src/modules/currencies/i18n/de.json +2 -1
- package/src/modules/currencies/i18n/en.json +2 -1
- package/src/modules/currencies/i18n/es.json +2 -1
- package/src/modules/currencies/i18n/pl.json +2 -1
- package/src/modules/customers/api/companies/[id]/route.ts +214 -189
- package/src/modules/customers/api/people/[id]/route.ts +106 -80
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +19 -12
- package/src/modules/customers/components/detail/ActivitiesAddNewMenu.tsx +8 -6
- package/src/modules/customers/components/detail/AiActionChips.tsx +6 -3
- package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +16 -18
- package/src/modules/data_sync/api/runs/[id]/cancel.ts +1 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +11 -58
- package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +13 -20
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +10 -8
- package/src/modules/data_sync/lib/id-mapping.ts +58 -1
- package/src/modules/data_sync/lib/sync-engine.ts +2 -2
- package/src/modules/data_sync/lib/syncRunStatus.ts +39 -0
- package/src/modules/entities/api/records.ts +14 -0
- package/src/modules/feature_toggles/api/global/route.ts +16 -14
- package/src/modules/feature_toggles/api/openapi.ts +2 -2
- package/src/modules/feature_toggles/commands/global.ts +15 -0
- package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +7 -0
- package/src/modules/messages/api/[id]/conversation/archive/route.ts +29 -6
- package/src/modules/messages/api/[id]/conversation/read/route.ts +29 -6
- package/src/modules/messages/api/[id]/route.ts +15 -0
- package/src/modules/messages/api/openapi.ts +2 -0
- package/src/modules/messages/commands/conversation.ts +87 -0
- package/src/modules/messages/components/MessageDetailPageClient.tsx +16 -4
- package/src/modules/messages/components/message-detail/hooks/useMessageDetails.ts +2 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +39 -4
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.ts +15 -1
- package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +29 -14
- package/src/modules/messages/components/message-detail/types.ts +2 -0
- package/src/modules/messages/i18n/de.json +4 -0
- package/src/modules/messages/i18n/en.json +4 -0
- package/src/modules/messages/i18n/es.json +4 -0
- package/src/modules/messages/i18n/pl.json +4 -0
- package/src/modules/payment_gateways/api/cancel/route.ts +5 -0
- package/src/modules/payment_gateways/api/capture/route.ts +5 -0
- package/src/modules/payment_gateways/api/refund/route.ts +5 -0
- package/src/modules/payment_gateways/lib/gateway-service.ts +58 -25
- package/src/modules/payment_gateways/lib/status-machine.ts +16 -0
- package/src/modules/perspectives/api/[tableId]/route.ts +8 -2
- package/src/modules/perspectives/data/entities.ts +43 -3
- package/src/modules/perspectives/migrations/.snapshot-open-mercato.json +69 -25
- package/src/modules/perspectives/migrations/Migration20260619120000_perspectives_live_row_uniqueness.ts +65 -0
- package/src/modules/perspectives/services/perspectiveService.ts +17 -0
- package/src/modules/planner/commands/availability-weekly.ts +48 -1
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +31 -10
- package/src/modules/progress/api/active/route.ts +1 -1
- package/src/modules/progress/lib/progressService.ts +2 -2
- package/src/modules/progress/lib/progressServiceImpl.ts +33 -8
- package/src/modules/query_index/api/status.ts +28 -32
- package/src/modules/query_index/lib/coverage.ts +63 -0
- package/src/modules/query_index/lib/engine.ts +37 -24
- package/src/modules/resources/api/resource-types.ts +4 -44
- package/src/modules/resources/api/resourceTypeCounts.ts +74 -0
- package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +1 -1
- package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -0
- package/src/modules/sales/components/documents/ReturnDialog.tsx +4 -1
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +20 -2
- package/src/modules/sales/di.ts +6 -0
- package/src/modules/sales/services/salesOrderService.ts +38 -0
- package/src/modules/shipping_carriers/api/shipments/route.ts +8 -0
- package/src/modules/shipping_carriers/data/entities.ts +33 -0
- package/src/modules/shipping_carriers/data/validators.ts +1 -0
- package/src/modules/shipping_carriers/i18n/de.json +1 -0
- package/src/modules/shipping_carriers/i18n/en.json +1 -0
- package/src/modules/shipping_carriers/i18n/es.json +1 -0
- package/src/modules/shipping_carriers/i18n/pl.json +1 -0
- package/src/modules/shipping_carriers/lib/shipment-idempotency.ts +119 -0
- package/src/modules/shipping_carriers/lib/shipment-wizard/hooks/shipmentApi.ts +3 -1
- package/src/modules/shipping_carriers/lib/shipment-wizard/hooks/useShipmentWizard.ts +24 -2
- package/src/modules/shipping_carriers/lib/shipping-service.ts +87 -43
- package/src/modules/shipping_carriers/migrations/.snapshot-open-mercato.json +197 -0
- package/src/modules/shipping_carriers/migrations/Migration20260618173616_shipping_carriers.ts +14 -0
- package/src/modules/staff/i18n/de.json +1 -0
- package/src/modules/staff/i18n/en.json +1 -0
- package/src/modules/staff/i18n/es.json +1 -0
- package/src/modules/staff/i18n/pl.json +1 -0
- package/src/modules/staff/lib/timesheets-ui/ListView.tsx +15 -7
- package/src/modules/translations/components/TranslationManager.tsx +17 -24
- package/src/modules/translations/i18n/de.json +1 -0
- package/src/modules/translations/i18n/en.json +1 -0
- package/src/modules/translations/i18n/es.json +1 -0
- package/src/modules/translations/i18n/pl.json +1 -0
|
@@ -228,6 +228,91 @@ const markConversationUnreadForActorCommand: CommandHandler<unknown, { ok: true;
|
|
|
228
228
|
},
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
const unarchiveConversationForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {
|
|
232
|
+
id: 'messages.conversation.unarchive_for_actor',
|
|
233
|
+
async execute(rawInput, ctx) {
|
|
234
|
+
const input = conversationCommandSchema.parse(rawInput)
|
|
235
|
+
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
236
|
+
const scope = await resolveConversationScope(em, input)
|
|
237
|
+
const messageIdsToUnarchive = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))
|
|
238
|
+
|
|
239
|
+
if (messageIdsToUnarchive.length === 0) {
|
|
240
|
+
return { ok: true, affectedCount: 0 }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const unarchivedIds: string[] = []
|
|
244
|
+
await em.transactional(async (trx) => {
|
|
245
|
+
const recipients = await trx.find(MessageRecipient, {
|
|
246
|
+
messageId: { $in: messageIdsToUnarchive },
|
|
247
|
+
recipientUserId: input.userId,
|
|
248
|
+
deletedAt: null,
|
|
249
|
+
})
|
|
250
|
+
for (const recipient of recipients) {
|
|
251
|
+
if (recipient.status === 'archived' || recipient.archivedAt !== null) {
|
|
252
|
+
recipient.archivedAt = null
|
|
253
|
+
recipient.status = recipient.readAt ? 'read' : 'unread'
|
|
254
|
+
unarchivedIds.push(recipient.messageId)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
for (const messageId of unarchivedIds) {
|
|
260
|
+
await emitMessagesEvent('messages.message.unarchived', {
|
|
261
|
+
messageId,
|
|
262
|
+
recipientUserId: input.userId,
|
|
263
|
+
userId: input.userId,
|
|
264
|
+
tenantId: input.tenantId,
|
|
265
|
+
organizationId: input.organizationId,
|
|
266
|
+
}, { persistent: true })
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return { ok: true, affectedCount: unarchivedIds.length }
|
|
270
|
+
},
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const markConversationReadForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {
|
|
274
|
+
id: 'messages.conversation.mark_read_for_actor',
|
|
275
|
+
async execute(rawInput, ctx) {
|
|
276
|
+
const input = conversationCommandSchema.parse(rawInput)
|
|
277
|
+
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
278
|
+
const scope = await resolveConversationScope(em, input)
|
|
279
|
+
const messageIdsToMarkRead = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))
|
|
280
|
+
|
|
281
|
+
if (messageIdsToMarkRead.length === 0) {
|
|
282
|
+
return { ok: true, affectedCount: 0 }
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const readAt = new Date()
|
|
286
|
+
const markedIds: string[] = []
|
|
287
|
+
await em.transactional(async (trx) => {
|
|
288
|
+
const recipients = await trx.find(MessageRecipient, {
|
|
289
|
+
messageId: { $in: messageIdsToMarkRead },
|
|
290
|
+
recipientUserId: input.userId,
|
|
291
|
+
deletedAt: null,
|
|
292
|
+
})
|
|
293
|
+
for (const recipient of recipients) {
|
|
294
|
+
if (recipient.status === 'unread') {
|
|
295
|
+
recipient.status = 'read'
|
|
296
|
+
recipient.readAt = readAt
|
|
297
|
+
markedIds.push(recipient.messageId)
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
for (const messageId of markedIds) {
|
|
303
|
+
await emitMessagesEvent('messages.message.read', {
|
|
304
|
+
messageId,
|
|
305
|
+
recipientUserId: input.userId,
|
|
306
|
+
userId: input.userId,
|
|
307
|
+
tenantId: input.tenantId,
|
|
308
|
+
organizationId: input.organizationId,
|
|
309
|
+
}, { persistent: true })
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return { ok: true, affectedCount: markedIds.length }
|
|
313
|
+
},
|
|
314
|
+
}
|
|
315
|
+
|
|
231
316
|
type DeletedTarget = { messageId: string; target: 'sender' | 'recipient' }
|
|
232
317
|
|
|
233
318
|
const deleteConversationForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {
|
|
@@ -289,5 +374,7 @@ const deleteConversationForActorCommand: CommandHandler<unknown, { ok: true; aff
|
|
|
289
374
|
}
|
|
290
375
|
|
|
291
376
|
registerCommand(archiveConversationForActorCommand)
|
|
377
|
+
registerCommand(unarchiveConversationForActorCommand)
|
|
292
378
|
registerCommand(markConversationUnreadForActorCommand)
|
|
379
|
+
registerCommand(markConversationReadForActorCommand)
|
|
293
380
|
registerCommand(deleteConversationForActorCommand)
|
|
@@ -220,6 +220,8 @@ export function MessageDetailPageClient({ id }: { id: string }) {
|
|
|
220
220
|
const firstConversationMessageId = state.conversationItems[0]?.id ?? null
|
|
221
221
|
const latestConversationMessageId = state.conversationItems[state.conversationItems.length - 1]?.id ?? null
|
|
222
222
|
const canRunConversationActions = Boolean(firstConversationMessageId)
|
|
223
|
+
const conversationArchived = Boolean(detail.conversationArchived)
|
|
224
|
+
const conversationAllUnread = Boolean(detail.conversationAllUnread)
|
|
223
225
|
|
|
224
226
|
return (
|
|
225
227
|
<div className="space-y-3">
|
|
@@ -228,6 +230,8 @@ export function MessageDetailPageClient({ id }: { id: string }) {
|
|
|
228
230
|
priority={(detail.priority as 'low' | 'normal' | 'high' | 'urgent') ?? 'normal'}
|
|
229
231
|
canReply={!detail.isDraft && detail.typeDefinition.allowReply && Boolean(firstConversationMessageId)}
|
|
230
232
|
canForwardAll={!detail.isDraft && detail.typeDefinition.allowForward && Boolean(latestConversationMessageId)}
|
|
233
|
+
conversationArchived={conversationArchived}
|
|
234
|
+
conversationAllUnread={conversationAllUnread}
|
|
231
235
|
actionsDisabled={Boolean(state.activeConversationAction)}
|
|
232
236
|
activeActionId={state.activeConversationAction}
|
|
233
237
|
onReply={() => {
|
|
@@ -244,13 +248,21 @@ export function MessageDetailPageClient({ id }: { id: string }) {
|
|
|
244
248
|
messageId: latestConversationMessageId,
|
|
245
249
|
})
|
|
246
250
|
}}
|
|
247
|
-
|
|
251
|
+
onToggleArchiveConversation={() => {
|
|
248
252
|
if (!canRunConversationActions) return
|
|
249
|
-
|
|
253
|
+
if (conversationArchived) {
|
|
254
|
+
void state.unarchiveConversation(firstConversationMessageId ?? undefined)
|
|
255
|
+
} else {
|
|
256
|
+
void state.archiveConversation(firstConversationMessageId ?? undefined)
|
|
257
|
+
}
|
|
250
258
|
}}
|
|
251
|
-
|
|
259
|
+
onToggleReadConversation={() => {
|
|
252
260
|
if (!canRunConversationActions) return
|
|
253
|
-
|
|
261
|
+
if (conversationAllUnread) {
|
|
262
|
+
void state.markConversationRead(firstConversationMessageId ?? undefined)
|
|
263
|
+
} else {
|
|
264
|
+
void state.markConversationUnread(firstConversationMessageId ?? undefined)
|
|
265
|
+
}
|
|
254
266
|
}}
|
|
255
267
|
onDeleteConversation={() => {
|
|
256
268
|
if (!canRunConversationActions || state.activeConversationAction) return
|
|
@@ -61,7 +61,9 @@ export function useMessageDetails(id: string) {
|
|
|
61
61
|
attachments: queryState.attachments,
|
|
62
62
|
isArchived,
|
|
63
63
|
onDeleted: () => router.push('/backend/messages'),
|
|
64
|
+
onMarkedUnread: () => router.push('/backend/messages'),
|
|
64
65
|
refreshDetailWithoutAutoMarkRead: queryState.refreshDetailWithoutAutoMarkRead,
|
|
66
|
+
suppressAutoMarkRead: queryState.suppressAutoMarkRead,
|
|
65
67
|
})
|
|
66
68
|
|
|
67
69
|
const conversationState = useMessageDetailsConversation({
|
|
@@ -18,9 +18,15 @@ import { isSafeNavigationHref, parseObjectActionId, toErrorMessage } from '../ut
|
|
|
18
18
|
|
|
19
19
|
type RequestAndRefreshOptions = {
|
|
20
20
|
skipDetailAutoMarkRead?: boolean
|
|
21
|
+
onSuccess?: () => void
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
type ConversationActionKind =
|
|
24
|
+
type ConversationActionKind =
|
|
25
|
+
| 'archiveConversation'
|
|
26
|
+
| 'unarchiveConversation'
|
|
27
|
+
| 'deleteConversation'
|
|
28
|
+
| 'markAllUnread'
|
|
29
|
+
| 'markAllRead'
|
|
24
30
|
|
|
25
31
|
type MessageDetailMutationContext = {
|
|
26
32
|
resourceKind: 'message' | 'conversation'
|
|
@@ -37,7 +43,9 @@ type UseMessageDetailsActionsInput = {
|
|
|
37
43
|
attachments: MessageAttachment[] | undefined
|
|
38
44
|
isArchived: boolean
|
|
39
45
|
onDeleted: () => void
|
|
46
|
+
onMarkedUnread: () => void
|
|
40
47
|
refreshDetailWithoutAutoMarkRead: () => Promise<MessageDetail | null>
|
|
48
|
+
suppressAutoMarkRead: () => void
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
export function useMessageDetailsActions({
|
|
@@ -48,7 +56,9 @@ export function useMessageDetailsActions({
|
|
|
48
56
|
attachments,
|
|
49
57
|
isArchived,
|
|
50
58
|
onDeleted,
|
|
59
|
+
onMarkedUnread,
|
|
51
60
|
refreshDetailWithoutAutoMarkRead,
|
|
61
|
+
suppressAutoMarkRead,
|
|
52
62
|
}: UseMessageDetailsActionsInput) {
|
|
53
63
|
const [replyOpen, setReplyOpen] = React.useState(false)
|
|
54
64
|
const [forwardOpen, setForwardOpen] = React.useState(false)
|
|
@@ -88,6 +98,7 @@ export function useMessageDetailsActions({
|
|
|
88
98
|
context: { resourceKind: 'message', messageId: id, action: 'state-change', retryLastMutation },
|
|
89
99
|
mutationPayload: { messageId: id, action: 'state-change', url, method },
|
|
90
100
|
})
|
|
101
|
+
options?.onSuccess?.()
|
|
91
102
|
} catch (err) {
|
|
92
103
|
flash(
|
|
93
104
|
err instanceof Error
|
|
@@ -188,13 +199,32 @@ export function useMessageDetailsActions({
|
|
|
188
199
|
})
|
|
189
200
|
}, [id, runConversationAction, t])
|
|
190
201
|
|
|
202
|
+
const unarchiveConversation = React.useCallback(async (messageId?: string) => {
|
|
203
|
+
const targetMessageId = messageId ?? id
|
|
204
|
+
await runConversationAction('unarchiveConversation', {
|
|
205
|
+
url: `/api/messages/${encodeURIComponent(targetMessageId)}/conversation/archive`,
|
|
206
|
+
method: 'DELETE',
|
|
207
|
+
successMessage: t('messages.flash.conversationUnarchived', 'Conversation restored from archive.'),
|
|
208
|
+
})
|
|
209
|
+
}, [id, runConversationAction, t])
|
|
210
|
+
|
|
191
211
|
const markConversationUnread = React.useCallback(async (messageId?: string) => {
|
|
212
|
+
suppressAutoMarkRead()
|
|
192
213
|
const targetMessageId = messageId ?? id
|
|
193
214
|
await runConversationAction('markAllUnread', {
|
|
194
215
|
url: `/api/messages/${encodeURIComponent(targetMessageId)}/conversation/read`,
|
|
195
216
|
method: 'DELETE',
|
|
196
217
|
successMessage: t('messages.flash.conversationMarkedUnread', 'Conversation marked unread.'),
|
|
197
|
-
|
|
218
|
+
onSuccess: onMarkedUnread,
|
|
219
|
+
})
|
|
220
|
+
}, [id, onMarkedUnread, runConversationAction, suppressAutoMarkRead, t])
|
|
221
|
+
|
|
222
|
+
const markConversationRead = React.useCallback(async (messageId?: string) => {
|
|
223
|
+
const targetMessageId = messageId ?? id
|
|
224
|
+
await runConversationAction('markAllRead', {
|
|
225
|
+
url: `/api/messages/${encodeURIComponent(targetMessageId)}/conversation/read`,
|
|
226
|
+
method: 'PUT',
|
|
227
|
+
successMessage: t('messages.flash.conversationMarkedRead', 'Conversation marked read.'),
|
|
198
228
|
})
|
|
199
229
|
}, [id, runConversationAction, t])
|
|
200
230
|
|
|
@@ -362,12 +392,15 @@ export function useMessageDetailsActions({
|
|
|
362
392
|
}, [detail?.actionData?.actions])
|
|
363
393
|
|
|
364
394
|
const toggleRead = React.useCallback(async () => {
|
|
395
|
+
if (detail?.isRead) {
|
|
396
|
+
suppressAutoMarkRead()
|
|
397
|
+
}
|
|
365
398
|
await requestAndRefresh(
|
|
366
399
|
`/api/messages/${encodeURIComponent(id)}/read`,
|
|
367
400
|
detail?.isRead ? 'DELETE' : 'PUT',
|
|
368
|
-
detail?.isRead ? { skipDetailAutoMarkRead: true } : undefined,
|
|
401
|
+
detail?.isRead ? { skipDetailAutoMarkRead: true, onSuccess: onMarkedUnread } : undefined,
|
|
369
402
|
)
|
|
370
|
-
}, [detail?.isRead, id, requestAndRefresh])
|
|
403
|
+
}, [detail?.isRead, id, onMarkedUnread, requestAndRefresh, suppressAutoMarkRead])
|
|
371
404
|
|
|
372
405
|
const toggleArchive = React.useCallback(async () => {
|
|
373
406
|
await requestAndRefresh(
|
|
@@ -393,8 +426,10 @@ export function useMessageDetailsActions({
|
|
|
393
426
|
toggleRead,
|
|
394
427
|
toggleArchive,
|
|
395
428
|
archiveConversation,
|
|
429
|
+
unarchiveConversation,
|
|
396
430
|
deleteConversation,
|
|
397
431
|
markConversationUnread,
|
|
432
|
+
markConversationRead,
|
|
398
433
|
requestAndRefresh,
|
|
399
434
|
handleDelete,
|
|
400
435
|
handleDeleteDialogKeyDown,
|
|
@@ -26,10 +26,19 @@ export function useMessageDetailsQueries({
|
|
|
26
26
|
[id, scopeVersion],
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
+
const suppressAutoMarkReadRef = React.useRef(false)
|
|
30
|
+
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
suppressAutoMarkReadRef.current = false
|
|
33
|
+
}, [id])
|
|
34
|
+
|
|
29
35
|
const detailQuery = useQuery<MessageDetail | null>({
|
|
30
36
|
queryKey: detailQueryKey,
|
|
31
37
|
queryFn: async () => {
|
|
32
|
-
const
|
|
38
|
+
const detailUrl = suppressAutoMarkReadRef.current
|
|
39
|
+
? `/api/messages/${encodeURIComponent(id)}?skipMarkRead=1`
|
|
40
|
+
: `/api/messages/${encodeURIComponent(id)}`
|
|
41
|
+
const call = await apiCall<MessageDetail>(detailUrl)
|
|
33
42
|
if (call.status === 404) {
|
|
34
43
|
return null
|
|
35
44
|
}
|
|
@@ -97,6 +106,10 @@ export function useMessageDetailsQueries({
|
|
|
97
106
|
return call.result
|
|
98
107
|
}, [detailQueryKey, id, queryClient, t])
|
|
99
108
|
|
|
109
|
+
const suppressAutoMarkRead = React.useCallback(() => {
|
|
110
|
+
suppressAutoMarkReadRef.current = true
|
|
111
|
+
}, [])
|
|
112
|
+
|
|
100
113
|
const listItemComponentKey = detail?.typeDefinition.ui?.listItemComponent ?? null
|
|
101
114
|
const contentComponentKey = detail?.typeDefinition.ui?.contentComponent ?? null
|
|
102
115
|
const actionsComponentKey = detail?.typeDefinition.ui?.actionsComponent ?? null
|
|
@@ -111,6 +124,7 @@ export function useMessageDetailsQueries({
|
|
|
111
124
|
attachmentsQuery,
|
|
112
125
|
attachments,
|
|
113
126
|
refreshDetailWithoutAutoMarkRead,
|
|
127
|
+
suppressAutoMarkRead,
|
|
114
128
|
listItemComponentKey,
|
|
115
129
|
contentComponentKey,
|
|
116
130
|
actionsComponentKey,
|
|
@@ -4,7 +4,7 @@ import * as React from 'react'
|
|
|
4
4
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
5
5
|
import { FormHeader, type ActionItem } from '@open-mercato/ui/backend/forms'
|
|
6
6
|
import { IconButton } from '@open-mercato/ui/primitives/icon-button'
|
|
7
|
-
import { Archive, Forward, MailMinus, Reply, Trash2 } from 'lucide-react'
|
|
7
|
+
import { Archive, ArchiveRestore, Forward, MailMinus, MailOpen, Reply, Trash2 } from 'lucide-react'
|
|
8
8
|
import { PriorityBadge } from '../../utils/PriorityBadge'
|
|
9
9
|
|
|
10
10
|
type MainMessageHeaderProps = {
|
|
@@ -12,12 +12,21 @@ type MainMessageHeaderProps = {
|
|
|
12
12
|
priority: 'low' | 'normal' | 'high' | 'urgent'
|
|
13
13
|
canReply: boolean
|
|
14
14
|
canForwardAll: boolean
|
|
15
|
+
conversationArchived: boolean
|
|
16
|
+
conversationAllUnread: boolean
|
|
15
17
|
actionsDisabled?: boolean
|
|
16
|
-
activeActionId?:
|
|
18
|
+
activeActionId?:
|
|
19
|
+
| 'forwardAll'
|
|
20
|
+
| 'archiveConversation'
|
|
21
|
+
| 'unarchiveConversation'
|
|
22
|
+
| 'markAllUnread'
|
|
23
|
+
| 'markAllRead'
|
|
24
|
+
| 'deleteConversation'
|
|
25
|
+
| null
|
|
17
26
|
onReply: () => void
|
|
18
27
|
onForwardAll: () => void
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
onToggleArchiveConversation: () => void
|
|
29
|
+
onToggleReadConversation: () => void
|
|
21
30
|
onDeleteConversation: () => void
|
|
22
31
|
}
|
|
23
32
|
|
|
@@ -42,19 +51,23 @@ export function MainMessageHeader(props: MainMessageHeaderProps) {
|
|
|
42
51
|
},
|
|
43
52
|
{
|
|
44
53
|
id: 'archive-conversation',
|
|
45
|
-
label:
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
label: props.conversationArchived
|
|
55
|
+
? t('messages.actions.unarchiveConversation', 'Unarchive conversation')
|
|
56
|
+
: t('messages.actions.archiveConversation', 'Archive conversation'),
|
|
57
|
+
icon: props.conversationArchived ? ArchiveRestore : Archive,
|
|
58
|
+
onSelect: props.onToggleArchiveConversation,
|
|
48
59
|
disabled: props.actionsDisabled,
|
|
49
|
-
loading: props.activeActionId === 'archiveConversation',
|
|
60
|
+
loading: props.activeActionId === 'archiveConversation' || props.activeActionId === 'unarchiveConversation',
|
|
50
61
|
},
|
|
51
62
|
{
|
|
52
63
|
id: 'mark-all-unread',
|
|
53
|
-
label:
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
label: props.conversationAllUnread
|
|
65
|
+
? t('messages.actions.markAllRead', 'Mark all read')
|
|
66
|
+
: t('messages.actions.markAllUnread', 'Mark all unread'),
|
|
67
|
+
icon: props.conversationAllUnread ? MailOpen : MailMinus,
|
|
68
|
+
onSelect: props.onToggleReadConversation,
|
|
56
69
|
disabled: props.actionsDisabled,
|
|
57
|
-
loading: props.activeActionId === 'markAllUnread',
|
|
70
|
+
loading: props.activeActionId === 'markAllUnread' || props.activeActionId === 'markAllRead',
|
|
58
71
|
},
|
|
59
72
|
{
|
|
60
73
|
id: 'delete-conversation',
|
|
@@ -68,10 +81,12 @@ export function MainMessageHeader(props: MainMessageHeaderProps) {
|
|
|
68
81
|
props.actionsDisabled,
|
|
69
82
|
props.canForwardAll,
|
|
70
83
|
props.canReply,
|
|
71
|
-
props.
|
|
84
|
+
props.conversationArchived,
|
|
85
|
+
props.conversationAllUnread,
|
|
86
|
+
props.onToggleArchiveConversation,
|
|
72
87
|
props.onDeleteConversation,
|
|
73
88
|
props.onForwardAll,
|
|
74
|
-
props.
|
|
89
|
+
props.onToggleReadConversation,
|
|
75
90
|
props.onReply,
|
|
76
91
|
props.activeActionId,
|
|
77
92
|
t,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"messages.actions.edit": "Bearbeiten",
|
|
10
10
|
"messages.actions.executing": "Wird ausgeführt...",
|
|
11
11
|
"messages.actions.forwardAll": "Alle weiterleiten",
|
|
12
|
+
"messages.actions.markAllRead": "Alle als gelesen markieren",
|
|
12
13
|
"messages.actions.markAllUnread": "Alle als ungelesen markieren",
|
|
13
14
|
"messages.actions.markRead": "Als gelesen markieren",
|
|
14
15
|
"messages.actions.markUnread": "Als ungelesen markieren",
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"messages.actions.taken": "Aktion ausgeführt",
|
|
17
18
|
"messages.actions.title": "Aktionen",
|
|
18
19
|
"messages.actions.unarchive": "Wiederherstellen",
|
|
20
|
+
"messages.actions.unarchiveConversation": "Konversation wiederherstellen",
|
|
19
21
|
"messages.attachFiles": "Dateien anhängen",
|
|
20
22
|
"messages.attachObject": "Objekt anhängen",
|
|
21
23
|
"messages.attachedFiles": "Anhänge",
|
|
@@ -146,7 +148,9 @@
|
|
|
146
148
|
"messages.flash.actionSuccess": "Aktion abgeschlossen.",
|
|
147
149
|
"messages.flash.conversationArchived": "Konversation archiviert.",
|
|
148
150
|
"messages.flash.conversationDeleted": "Konversation gelöscht.",
|
|
151
|
+
"messages.flash.conversationMarkedRead": "Konversation als gelesen markiert.",
|
|
149
152
|
"messages.flash.conversationMarkedUnread": "Konversation als ungelesen markiert.",
|
|
153
|
+
"messages.flash.conversationUnarchived": "Konversation wiederhergestellt.",
|
|
150
154
|
"messages.flash.deleted": "Nachricht gelöscht.",
|
|
151
155
|
"messages.flash.draftSaved": "Entwurf gespeichert.",
|
|
152
156
|
"messages.flash.forwardSuccess": "Nachricht weitergeleitet.",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"messages.actions.edit": "Edit",
|
|
10
10
|
"messages.actions.executing": "Executing...",
|
|
11
11
|
"messages.actions.forwardAll": "Forward all",
|
|
12
|
+
"messages.actions.markAllRead": "Mark all read",
|
|
12
13
|
"messages.actions.markAllUnread": "Mark all unread",
|
|
13
14
|
"messages.actions.markRead": "Mark read",
|
|
14
15
|
"messages.actions.markUnread": "Mark unread",
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"messages.actions.taken": "Action taken",
|
|
17
18
|
"messages.actions.title": "Actions",
|
|
18
19
|
"messages.actions.unarchive": "Unarchive",
|
|
20
|
+
"messages.actions.unarchiveConversation": "Unarchive conversation",
|
|
19
21
|
"messages.attachFiles": "Attach files",
|
|
20
22
|
"messages.attachObject": "Attach object",
|
|
21
23
|
"messages.attachedFiles": "Attachments",
|
|
@@ -146,7 +148,9 @@
|
|
|
146
148
|
"messages.flash.actionSuccess": "Action completed.",
|
|
147
149
|
"messages.flash.conversationArchived": "Conversation archived.",
|
|
148
150
|
"messages.flash.conversationDeleted": "Conversation deleted.",
|
|
151
|
+
"messages.flash.conversationMarkedRead": "Conversation marked read.",
|
|
149
152
|
"messages.flash.conversationMarkedUnread": "Conversation marked unread.",
|
|
153
|
+
"messages.flash.conversationUnarchived": "Conversation restored from archive.",
|
|
150
154
|
"messages.flash.deleted": "Message deleted.",
|
|
151
155
|
"messages.flash.draftSaved": "Draft saved.",
|
|
152
156
|
"messages.flash.forwardSuccess": "Message forwarded.",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"messages.actions.edit": "Editar",
|
|
10
10
|
"messages.actions.executing": "Ejecutando...",
|
|
11
11
|
"messages.actions.forwardAll": "Reenviar todo",
|
|
12
|
+
"messages.actions.markAllRead": "Marcar todo como leído",
|
|
12
13
|
"messages.actions.markAllUnread": "Marcar todo como no leído",
|
|
13
14
|
"messages.actions.markRead": "Marcar como leído",
|
|
14
15
|
"messages.actions.markUnread": "Marcar como no leído",
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"messages.actions.taken": "Acción realizada",
|
|
17
18
|
"messages.actions.title": "Acciones",
|
|
18
19
|
"messages.actions.unarchive": "Desarchivar",
|
|
20
|
+
"messages.actions.unarchiveConversation": "Desarchivar conversación",
|
|
19
21
|
"messages.attachFiles": "Adjuntar archivos",
|
|
20
22
|
"messages.attachObject": "Adjuntar objeto",
|
|
21
23
|
"messages.attachedFiles": "Adjuntos",
|
|
@@ -146,7 +148,9 @@
|
|
|
146
148
|
"messages.flash.actionSuccess": "Acción completada.",
|
|
147
149
|
"messages.flash.conversationArchived": "Conversación archivada.",
|
|
148
150
|
"messages.flash.conversationDeleted": "Conversación eliminada.",
|
|
151
|
+
"messages.flash.conversationMarkedRead": "Conversación marcada como leída.",
|
|
149
152
|
"messages.flash.conversationMarkedUnread": "Conversación marcada como no leída.",
|
|
153
|
+
"messages.flash.conversationUnarchived": "Conversación desarchivada.",
|
|
150
154
|
"messages.flash.deleted": "Mensaje eliminado.",
|
|
151
155
|
"messages.flash.draftSaved": "Borrador guardado.",
|
|
152
156
|
"messages.flash.forwardSuccess": "Mensaje reenviado.",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"messages.actions.edit": "Edytuj",
|
|
10
10
|
"messages.actions.executing": "Wykonywanie...",
|
|
11
11
|
"messages.actions.forwardAll": "Przekaż cały wątek",
|
|
12
|
+
"messages.actions.markAllRead": "Oznacz wszystko jako przeczytane",
|
|
12
13
|
"messages.actions.markAllUnread": "Oznacz wszystko jako nieprzeczytane",
|
|
13
14
|
"messages.actions.markRead": "Oznacz jako przeczytane",
|
|
14
15
|
"messages.actions.markUnread": "Oznacz jako nieprzeczytane",
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"messages.actions.taken": "Wykonana akcja",
|
|
17
18
|
"messages.actions.title": "Akcje",
|
|
18
19
|
"messages.actions.unarchive": "Przywróć z archiwum",
|
|
20
|
+
"messages.actions.unarchiveConversation": "Przywróć konwersację z archiwum",
|
|
19
21
|
"messages.attachFiles": "Dołącz pliki",
|
|
20
22
|
"messages.attachObject": "Dołącz obiekt",
|
|
21
23
|
"messages.attachedFiles": "Załączniki",
|
|
@@ -146,7 +148,9 @@
|
|
|
146
148
|
"messages.flash.actionSuccess": "Akcja wykonana.",
|
|
147
149
|
"messages.flash.conversationArchived": "Konwersacja zarchiwizowana.",
|
|
148
150
|
"messages.flash.conversationDeleted": "Konwersacja usunięta.",
|
|
151
|
+
"messages.flash.conversationMarkedRead": "Konwersacja oznaczona jako przeczytana.",
|
|
149
152
|
"messages.flash.conversationMarkedUnread": "Konwersacja oznaczona jako nieprzeczytana.",
|
|
153
|
+
"messages.flash.conversationUnarchived": "Konwersacja przywrócona z archiwum.",
|
|
150
154
|
"messages.flash.deleted": "Wiadomość usunięta.",
|
|
151
155
|
"messages.flash.draftSaved": "Szkic zapisany.",
|
|
152
156
|
"messages.flash.forwardSuccess": "Wiadomość przekazana.",
|
|
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server'
|
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
3
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
4
|
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
5
|
+
import { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
5
6
|
import { cancelSchema } from '../../data/validators'
|
|
6
7
|
import type { PaymentGatewayService } from '../../lib/gateway-service'
|
|
7
8
|
import { paymentGatewaysTag } from '../openapi'
|
|
@@ -73,6 +74,9 @@ export async function POST(req: Request) {
|
|
|
73
74
|
})
|
|
74
75
|
return NextResponse.json(result)
|
|
75
76
|
} catch (err: unknown) {
|
|
77
|
+
if (isCrudHttpError(err)) {
|
|
78
|
+
return NextResponse.json(err.body, { status: err.status })
|
|
79
|
+
}
|
|
76
80
|
const message = err instanceof Error ? err.message : 'Cancel failed'
|
|
77
81
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
78
82
|
}
|
|
@@ -87,6 +91,7 @@ export const openApi = {
|
|
|
87
91
|
tags: [paymentGatewaysTag],
|
|
88
92
|
responses: [
|
|
89
93
|
{ status: 200, description: 'Payment cancelled' },
|
|
94
|
+
{ status: 409, description: 'Invalid payment status transition' },
|
|
90
95
|
{ status: 422, description: 'Invalid payload' },
|
|
91
96
|
{ status: 502, description: 'Gateway provider error' },
|
|
92
97
|
],
|
|
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server'
|
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
3
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
4
|
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
5
|
+
import { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
5
6
|
import { captureSchema } from '../../data/validators'
|
|
6
7
|
import type { PaymentGatewayService } from '../../lib/gateway-service'
|
|
7
8
|
import { paymentGatewaysTag } from '../openapi'
|
|
@@ -73,6 +74,9 @@ export async function POST(req: Request) {
|
|
|
73
74
|
})
|
|
74
75
|
return NextResponse.json(result)
|
|
75
76
|
} catch (err: unknown) {
|
|
77
|
+
if (isCrudHttpError(err)) {
|
|
78
|
+
return NextResponse.json(err.body, { status: err.status })
|
|
79
|
+
}
|
|
76
80
|
const message = err instanceof Error ? err.message : 'Capture failed'
|
|
77
81
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
78
82
|
}
|
|
@@ -87,6 +91,7 @@ export const openApi = {
|
|
|
87
91
|
tags: [paymentGatewaysTag],
|
|
88
92
|
responses: [
|
|
89
93
|
{ status: 200, description: 'Payment captured' },
|
|
94
|
+
{ status: 409, description: 'Invalid payment status transition' },
|
|
90
95
|
{ status: 422, description: 'Invalid payload' },
|
|
91
96
|
{ status: 502, description: 'Gateway provider error' },
|
|
92
97
|
],
|
|
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server'
|
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
3
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
4
|
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
5
|
+
import { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
5
6
|
import { refundSchema } from '../../data/validators'
|
|
6
7
|
import type { PaymentGatewayService } from '../../lib/gateway-service'
|
|
7
8
|
import { paymentGatewaysTag } from '../openapi'
|
|
@@ -74,6 +75,9 @@ export async function POST(req: Request) {
|
|
|
74
75
|
})
|
|
75
76
|
return NextResponse.json(result)
|
|
76
77
|
} catch (err: unknown) {
|
|
78
|
+
if (isCrudHttpError(err)) {
|
|
79
|
+
return NextResponse.json(err.body, { status: err.status })
|
|
80
|
+
}
|
|
77
81
|
const message = err instanceof Error ? err.message : 'Refund failed'
|
|
78
82
|
return NextResponse.json({ error: message }, { status: 502 })
|
|
79
83
|
}
|
|
@@ -88,6 +92,7 @@ export const openApi = {
|
|
|
88
92
|
tags: [paymentGatewaysTag],
|
|
89
93
|
responses: [
|
|
90
94
|
{ status: 200, description: 'Payment refunded' },
|
|
95
|
+
{ status: 409, description: 'Invalid payment status transition' },
|
|
91
96
|
{ status: 422, description: 'Invalid payload' },
|
|
92
97
|
{ status: 502, description: 'Gateway provider error' },
|
|
93
98
|
],
|