@open-mercato/core 0.5.1-develop.2860.07af3a6a9d → 0.5.1-develop.2874.77704bccbd
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/dist/modules/api_docs/frontend/docs/api/Explorer.js +18 -18
- package/dist/modules/api_docs/frontend/docs/api/Explorer.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/create/page.js +1 -1
- package/dist/modules/api_keys/backend/api-keys/create/page.js.map +1 -1
- package/dist/modules/attachments/components/AttachmentLibrary.js +2 -2
- package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +1 -1
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +1 -1
- package/dist/modules/attachments/fields/attachment.js +1 -1
- package/dist/modules/attachments/fields/attachment.js.map +1 -1
- package/dist/modules/audit_logs/components/ActionLogDetailsDialog.js +1 -1
- package/dist/modules/audit_logs/components/ActionLogDetailsDialog.js.map +2 -2
- package/dist/modules/audit_logs/lib/display-helpers.js +1 -1
- package/dist/modules/audit_logs/lib/display-helpers.js.map +1 -1
- package/dist/modules/auth/backend/users/create/page.js +1 -1
- package/dist/modules/auth/backend/users/create/page.js.map +1 -1
- package/dist/modules/business_rules/backend/rules/page.js +6 -6
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +2 -2
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/business_rules/components/ActionBuilder.js +5 -5
- package/dist/modules/business_rules/components/ActionBuilder.js.map +2 -2
- package/dist/modules/business_rules/components/ActionRow.js +8 -8
- package/dist/modules/business_rules/components/ActionRow.js.map +1 -1
- package/dist/modules/business_rules/components/ConditionBuilder.js +5 -5
- package/dist/modules/business_rules/components/ConditionBuilder.js.map +2 -2
- package/dist/modules/business_rules/components/ConditionGroup.js +2 -2
- package/dist/modules/business_rules/components/ConditionGroup.js.map +1 -1
- package/dist/modules/business_rules/components/ConditionRow.js +3 -3
- package/dist/modules/business_rules/components/ConditionRow.js.map +2 -2
- package/dist/modules/business_rules/components/RuleSetMembers.js +8 -8
- package/dist/modules/business_rules/components/RuleSetMembers.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +1 -1
- package/dist/modules/catalog/backend/catalog/products/create/page.js +5 -5
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +1 -1
- package/dist/modules/catalog/components/products/MetadataEditor.js +1 -1
- package/dist/modules/catalog/components/products/MetadataEditor.js.map +1 -1
- package/dist/modules/catalog/components/products/ProductImageCell.js +1 -1
- package/dist/modules/catalog/components/products/ProductImageCell.js.map +1 -1
- package/dist/modules/catalog/components/products/VariantBuilder.js +1 -1
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +1 -1
- package/dist/modules/catalog/widgets/injection/product-seo/widget.client.js +1 -1
- package/dist/modules/catalog/widgets/injection/product-seo/widget.client.js.map +2 -2
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js +1 -1
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +1 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +9 -9
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +7 -7
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +2 -2
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +1 -1
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +3 -3
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +1 -1
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +1 -1
- package/dist/modules/customers/components/AddressTiles.js +1 -1
- package/dist/modules/customers/components/AddressTiles.js.map +1 -1
- package/dist/modules/customers/components/detail/ActivityForm.js +3 -3
- package/dist/modules/customers/components/detail/ActivityForm.js.map +1 -1
- package/dist/modules/customers/components/detail/AnnualRevenueField.js +2 -2
- package/dist/modules/customers/components/detail/AnnualRevenueField.js.map +1 -1
- package/dist/modules/customers/components/detail/CustomFieldValuesList.js +1 -1
- package/dist/modules/customers/components/detail/CustomFieldValuesList.js.map +1 -1
- package/dist/modules/customers/components/detail/DealForm.js +1 -1
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +1 -1
- package/dist/modules/customers/components/detail/DealsSection.js.map +1 -1
- package/dist/modules/customers/components/detail/DetailFieldsSection.js +1 -1
- package/dist/modules/customers/components/detail/DetailFieldsSection.js.map +1 -1
- package/dist/modules/customers/components/detail/InlineEditors.js +5 -5
- package/dist/modules/customers/components/detail/InlineEditors.js.map +2 -2
- package/dist/modules/customers/components/detail/TasksSection.js +1 -1
- package/dist/modules/customers/components/detail/TasksSection.js.map +1 -1
- package/dist/modules/customers/components/detail/TimelineItemHeader.js +1 -1
- package/dist/modules/customers/components/detail/TimelineItemHeader.js.map +1 -1
- package/dist/modules/customers/components/formConfig.js +2 -2
- package/dist/modules/customers/components/formConfig.js.map +1 -1
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +1 -1
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +1 -1
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js +2 -2
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js.map +1 -1
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js +1 -1
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js.map +1 -1
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js +1 -1
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js.map +1 -1
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +1 -1
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js +1 -1
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.js +1 -1
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js +1 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.js +1 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js +1 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +1 -1
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +1 -1
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +1 -1
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +1 -1
- package/dist/modules/data_sync/backend/data-sync/page.js +4 -4
- 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 +2 -2
- package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +1 -1
- package/dist/modules/dictionaries/components/AppearanceSelector.js +3 -3
- package/dist/modules/dictionaries/components/AppearanceSelector.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +4 -4
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +3 -3
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +1 -1
- package/dist/modules/dictionaries/fields/dictionary.js +4 -4
- package/dist/modules/dictionaries/fields/dictionary.js.map +1 -1
- package/dist/modules/entities/components/EncryptionManager.js +3 -3
- package/dist/modules/entities/components/EncryptionManager.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +1 -1
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/formConfig.js +1 -1
- package/dist/modules/feature_toggles/components/formConfig.js.map +1 -1
- package/dist/modules/feature_toggles/components/overrideFormConfig.js +2 -2
- package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +1 -1
- package/dist/modules/inbox_ops/backend/inbox-ops/proposals/[id]/page.js +12 -12
- package/dist/modules/inbox_ops/backend/inbox-ops/proposals/[id]/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/messages/InboxEmailPreview.js +1 -1
- package/dist/modules/inbox_ops/components/messages/InboxEmailPreview.js.map +1 -1
- package/dist/modules/inbox_ops/components/proposals/ActionCard.js +12 -12
- package/dist/modules/inbox_ops/components/proposals/ActionCard.js.map +2 -2
- package/dist/modules/inbox_ops/widgets/notifications/ProposalCreatedRenderer.js +3 -3
- package/dist/modules/inbox_ops/widgets/notifications/ProposalCreatedRenderer.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +6 -6
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +1 -1
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +1 -1
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js +1 -1
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js.map +1 -1
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js +1 -1
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js.map +1 -1
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js +1 -1
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js.map +1 -1
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js +1 -1
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js.map +1 -1
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js +1 -1
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js.map +1 -1
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +11 -11
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +3 -3
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js +4 -4
- package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +4 -4
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +1 -1
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +1 -1
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +4 -4
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +1 -1
- package/dist/modules/sales/components/DocumentNumberSettings.js +1 -1
- package/dist/modules/sales/components/DocumentNumberSettings.js.map +1 -1
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +1 -1
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +1 -1
- package/dist/modules/sales/components/documents/AdjustmentDialog.js +1 -1
- package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +1 -1
- package/dist/modules/sales/components/documents/DocumentTotals.js +3 -3
- package/dist/modules/sales/components/documents/DocumentTotals.js.map +1 -1
- package/dist/modules/sales/components/documents/PaymentDialog.js +1 -1
- package/dist/modules/sales/components/documents/PaymentDialog.js.map +1 -1
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js +4 -4
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js.map +1 -1
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js +4 -4
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js.map +1 -1
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js +2 -2
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +1 -1
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js +1 -1
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js.map +1 -1
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js +1 -1
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js.map +1 -1
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.js +1 -1
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.js.map +1 -1
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +1 -1
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +1 -1
- package/dist/modules/translations/components/TranslationDrawerAction.js +2 -2
- package/dist/modules/translations/components/TranslationDrawerAction.js.map +1 -1
- package/dist/modules/translations/components/TranslationManager.js +3 -3
- package/dist/modules/translations/components/TranslationManager.js.map +1 -1
- package/dist/modules/translations/widgets/injection/translation-manager/widget.client.js +2 -2
- package/dist/modules/translations/widgets/injection/translation-manager/widget.client.js.map +1 -1
- package/dist/modules/workflows/backend/definitions/[id]/page.js +5 -5
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.js +4 -4
- package/dist/modules/workflows/backend/events/[id]/page.js.map +1 -1
- package/dist/modules/workflows/backend/instances/[id]/page.js +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.js.map +1 -1
- package/dist/modules/workflows/backend/tasks/[id]/page.js +20 -20
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +1 -1
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +1 -1
- package/dist/modules/workflows/components/EdgeEditDialog.js +12 -12
- package/dist/modules/workflows/components/EdgeEditDialog.js.map +1 -1
- package/dist/modules/workflows/components/NodeEditDialog.js +26 -26
- package/dist/modules/workflows/components/NodeEditDialog.js.map +1 -1
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +1 -1
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +1 -1
- package/dist/modules/workflows/components/mobile/MobileDefinitionDetail.js +2 -2
- package/dist/modules/workflows/components/mobile/MobileDefinitionDetail.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileInstanceOverview.js +7 -7
- package/dist/modules/workflows/components/mobile/MobileInstanceOverview.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js +11 -11
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileVisualEditor.js +1 -1
- package/dist/modules/workflows/components/mobile/MobileVisualEditor.js.map +1 -1
- package/dist/modules/workflows/components/mobile/MobileWorkflowTimeline.js +23 -23
- package/dist/modules/workflows/components/mobile/MobileWorkflowTimeline.js.map +2 -2
- package/dist/modules/workflows/frontend/checkout-demo/page.js +6 -6
- package/dist/modules/workflows/frontend/checkout-demo/page.js.map +1 -1
- package/package.json +3 -3
- package/src/modules/api_docs/frontend/docs/api/Explorer.tsx +18 -18
- package/src/modules/api_keys/backend/api-keys/create/page.tsx +1 -1
- package/src/modules/attachments/components/AttachmentLibrary.tsx +3 -3
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +1 -1
- package/src/modules/attachments/fields/attachment.tsx +1 -1
- package/src/modules/audit_logs/components/ActionLogDetailsDialog.tsx +1 -1
- package/src/modules/audit_logs/lib/display-helpers.tsx +1 -1
- package/src/modules/auth/backend/users/create/page.tsx +1 -1
- package/src/modules/business_rules/backend/rules/page.tsx +7 -7
- package/src/modules/business_rules/backend/sets/page.tsx +3 -3
- package/src/modules/business_rules/components/ActionBuilder.tsx +6 -6
- package/src/modules/business_rules/components/ActionRow.tsx +8 -8
- package/src/modules/business_rules/components/ConditionBuilder.tsx +6 -6
- package/src/modules/business_rules/components/ConditionGroup.tsx +2 -2
- package/src/modules/business_rules/components/ConditionRow.tsx +3 -3
- package/src/modules/business_rules/components/RuleSetMembers.tsx +9 -9
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +2 -2
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +5 -5
- package/src/modules/catalog/components/products/MetadataEditor.tsx +1 -1
- package/src/modules/catalog/components/products/ProductImageCell.tsx +1 -1
- package/src/modules/catalog/components/products/VariantBuilder.tsx +1 -1
- package/src/modules/catalog/widgets/injection/product-seo/widget.client.tsx +1 -1
- package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +1 -1
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +2 -2
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +10 -10
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +9 -9
- package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +2 -2
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +3 -3
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +2 -2
- package/src/modules/customers/components/AddressTiles.tsx +1 -1
- package/src/modules/customers/components/detail/ActivityForm.tsx +3 -3
- package/src/modules/customers/components/detail/AnnualRevenueField.tsx +2 -2
- package/src/modules/customers/components/detail/CustomFieldValuesList.tsx +1 -1
- package/src/modules/customers/components/detail/DealForm.tsx +1 -1
- package/src/modules/customers/components/detail/DealsSection.tsx +1 -1
- package/src/modules/customers/components/detail/DetailFieldsSection.tsx +1 -1
- package/src/modules/customers/components/detail/InlineEditors.tsx +5 -5
- package/src/modules/customers/components/detail/TasksSection.tsx +1 -1
- package/src/modules/customers/components/detail/TimelineItemHeader.tsx +1 -1
- package/src/modules/customers/components/formConfig.tsx +2 -2
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +1 -1
- package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +2 -2
- package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +1 -1
- package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +1 -1
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.client.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/orders-kpi/widget.client.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +2 -2
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +1 -1
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +2 -2
- package/src/modules/data_sync/backend/data-sync/page.tsx +4 -4
- package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +2 -2
- package/src/modules/dictionaries/components/AppearanceSelector.tsx +3 -3
- package/src/modules/dictionaries/components/DictionariesManager.tsx +4 -4
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +2 -2
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +3 -3
- package/src/modules/dictionaries/fields/dictionary.tsx +4 -4
- package/src/modules/entities/components/EncryptionManager.tsx +3 -3
- package/src/modules/entities/components/UserEntitiesTable.tsx +1 -1
- package/src/modules/feature_toggles/components/formConfig.tsx +1 -1
- package/src/modules/feature_toggles/components/overrideFormConfig.tsx +2 -2
- package/src/modules/inbox_ops/backend/inbox-ops/proposals/[id]/page.tsx +12 -12
- package/src/modules/inbox_ops/components/messages/InboxEmailPreview.tsx +1 -1
- package/src/modules/inbox_ops/components/proposals/ActionCard.tsx +12 -12
- package/src/modules/inbox_ops/widgets/notifications/ProposalCreatedRenderer.tsx +4 -4
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +6 -6
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +1 -1
- package/src/modules/messages/components/defaults/DefaultMessageListItem.tsx +1 -1
- package/src/modules/messages/components/defaults/MessageRecordObjectDetail.tsx +1 -1
- package/src/modules/messages/components/defaults/MessageRecordObjectPreview.tsx +1 -1
- package/src/modules/messages/components/message-detail/panels/MessageListComponent.tsx +1 -1
- package/src/modules/messages/components/message-detail/panels/attachments-panel.tsx +1 -1
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +11 -11
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +2 -2
- package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +2 -2
- package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +3 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/profile/page.tsx +4 -4
- package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +4 -4
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +1 -1
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +4 -4
- package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -1
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +1 -1
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +1 -1
- package/src/modules/sales/components/documents/DocumentTotals.tsx +3 -3
- package/src/modules/sales/components/documents/PaymentDialog.tsx +1 -1
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +2 -2
- package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +4 -4
- package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +4 -4
- package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +2 -2
- package/src/modules/sales/widgets/messages/SalesDocumentMessageDetail.tsx +1 -1
- package/src/modules/sales/widgets/messages/SalesDocumentMessagePreview.tsx +1 -1
- package/src/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.tsx +1 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +1 -1
- package/src/modules/translations/components/TranslationDrawerAction.tsx +2 -2
- package/src/modules/translations/components/TranslationManager.tsx +3 -3
- package/src/modules/translations/widgets/injection/translation-manager/widget.client.tsx +2 -2
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +5 -5
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +2 -2
- package/src/modules/workflows/backend/events/[id]/page.tsx +4 -4
- package/src/modules/workflows/backend/instances/[id]/page.tsx +2 -2
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +23 -23
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +1 -1
- package/src/modules/workflows/components/EdgeEditDialog.tsx +12 -12
- package/src/modules/workflows/components/NodeEditDialog.tsx +26 -26
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +1 -1
- package/src/modules/workflows/components/mobile/MobileDefinitionDetail.tsx +2 -2
- package/src/modules/workflows/components/mobile/MobileInstanceOverview.tsx +7 -7
- package/src/modules/workflows/components/mobile/MobileTaskForm.tsx +14 -14
- package/src/modules/workflows/components/mobile/MobileVisualEditor.tsx +1 -1
- package/src/modules/workflows/components/mobile/MobileWorkflowTimeline.tsx +23 -23
- package/src/modules/workflows/frontend/checkout-demo/page.tsx +6 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/messages/components/MessagesInboxPageClient.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport { Archive, ChevronDown, FilePenLine, Inbox, Layers, Send } from 'lucide-react'\nimport { getMessageUiComponentRegistry } from './utils/typeUiRegistry'\nimport { DefaultMessageListItem } from './defaults/DefaultMessageListItem'\nimport { toErrorMessage } from './message-detail/utils'\nimport { useMessagesInboxBulkActions, type MessageFolder } from './useMessagesInboxBulkActions'\n\ntype MessageListItem = {\n id: string\n type: string\n subject: string\n bodyPreview: string\n senderUserId: string\n senderName?: string | null\n senderEmail?: string | null\n priority: string\n status: string\n hasObjects: boolean\n objectCount: number\n hasAttachments: boolean\n attachmentCount: number\n hasActions: boolean\n actionTaken?: string | null\n sentAt?: string | null\n readAt?: string | null\n threadId?: string | null\n}\n\ntype MessageListResponse = {\n items?: MessageListItem[]\n total?: number\n page?: number\n pageSize?: number\n totalPages?: number\n}\n\ntype MessageTypeItem = {\n type: string\n module: string\n labelKey: string\n ui?: {\n listItemComponent?: string | null\n } | null\n}\n\ntype UserListItem = {\n id: string\n email?: string | null\n name?: string | null\n}\n\nexport function MessagesInboxPageClient() {\n const router = useRouter()\n const t = useT()\n const queryClient = useQueryClient()\n const scopeVersion = useOrganizationScopeVersion()\n\n const invalidateMessageListQueries = React.useCallback(() => {\n void queryClient.invalidateQueries({ queryKey: ['messages', 'list'] })\n }, [queryClient])\n\n useAppEvent('messages.message.*', invalidateMessageListQueries, [invalidateMessageListQueries])\n\n useAppEvent('om:bridge:reconnected', invalidateMessageListQueries, [invalidateMessageListQueries])\n\n const [folder, setFolder] = React.useState<MessageFolder>('inbox')\n const [folderMenuOpen, setFolderMenuOpen] = React.useState(false)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [page, setPage] = React.useState(1)\n const pageSize = 20\n const folderMenuRef = React.useRef<HTMLDivElement | null>(null)\n const messageUiRegistry = React.useMemo(() => getMessageUiComponentRegistry(), [])\n const { bulkActions, selectionScopeKey, injectionContext, ConfirmDialogElement } = useMessagesInboxBulkActions<MessageListItem>({\n folder,\n page,\n search,\n filterValues,\n })\n\n const listQuery = useQuery({\n queryKey: [\n 'messages',\n 'list',\n folder,\n search,\n page,\n pageSize,\n JSON.stringify(filterValues),\n scopeVersion,\n ],\n queryFn: async () => {\n const params = new URLSearchParams()\n params.set('folder', folder)\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n\n if (search.trim()) {\n params.set('search', search.trim())\n }\n\n const status = typeof filterValues.status === 'string' ? filterValues.status.trim() : ''\n const type = typeof filterValues.type === 'string' ? filterValues.type.trim() : ''\n const hasObjects = typeof filterValues.hasObjects === 'string' ? filterValues.hasObjects.trim() : ''\n const hasAttachments = typeof filterValues.hasAttachments === 'string' ? filterValues.hasAttachments.trim() : ''\n const hasActions = typeof filterValues.hasActions === 'string' ? filterValues.hasActions.trim() : ''\n const senderId = typeof filterValues.senderId === 'string' ? filterValues.senderId.trim() : ''\n const since = typeof filterValues.since === 'string' ? filterValues.since.trim() : ''\n\n if (status) params.set('status', status)\n if (type) params.set('type', type)\n if (hasObjects) params.set('hasObjects', hasObjects)\n if (hasAttachments) params.set('hasAttachments', hasAttachments)\n if (hasActions) params.set('hasActions', hasActions)\n if (senderId) params.set('senderId', senderId)\n if (since) params.set('since', since)\n\n const call = await apiCall<MessageListResponse>(`/api/messages?${params.toString()}`)\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadListFailed', 'Failed to load messages.'),\n )\n }\n\n return {\n items: Array.isArray(call.result?.items) ? call.result?.items ?? [] : [],\n total: Number(call.result?.total ?? 0),\n page: Number(call.result?.page ?? page),\n pageSize: Number(call.result?.pageSize ?? pageSize),\n totalPages: Number(call.result?.totalPages ?? 0),\n }\n },\n })\n\n const messageTypesQuery = useQuery({\n queryKey: ['messages', 'types', scopeVersion],\n queryFn: async () => {\n const call = await apiCall<{ items?: MessageTypeItem[] }>('/api/messages/types')\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadTypesFailed', 'Failed to load message types.'),\n )\n }\n return Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n },\n })\n\n React.useEffect(() => {\n if (!listQuery.error) return\n flash(\n listQuery.error instanceof Error\n ? listQuery.error.message\n : t('messages.errors.loadListFailed', 'Failed to load messages.'),\n 'error',\n )\n }, [listQuery.error, t])\n\n React.useEffect(() => {\n if (!messageTypesQuery.error) return\n flash(\n messageTypesQuery.error instanceof Error\n ? messageTypesQuery.error.message\n : t('messages.errors.loadTypesFailed', 'Failed to load message types.'),\n 'error',\n )\n }, [messageTypesQuery.error, t])\n\n const messageTypeLabelMap = React.useMemo(() => {\n const map: Record<string, string> = {}\n for (const item of messageTypesQuery.data ?? []) {\n map[item.type] = t(item.labelKey, item.type)\n }\n return map\n }, [messageTypesQuery.data, t])\n\n const loadSenderOptions = React.useCallback(async (query?: string) => {\n const params = new URLSearchParams()\n params.set('page', '1')\n params.set('pageSize', '20')\n if (query && query.trim().length > 0) {\n params.set('search', query.trim())\n }\n\n const call = await apiCall<{ items?: UserListItem[] }>(`/api/auth/users?${params.toString()}`)\n if (!call.ok) return []\n\n const items = Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n return items.flatMap((item) => {\n if (!item || typeof item.id !== 'string' || item.id.trim().length === 0) return []\n const name = typeof item.name === 'string' && item.name.trim().length > 0 ? item.name.trim() : null\n const email = typeof item.email === 'string' && item.email.trim().length > 0 ? item.email.trim() : null\n const label = name ?? email ?? item.id\n return [{\n value: item.id,\n label,\n description: email && email !== label ? email : null,\n }]\n })\n }, [])\n\n const listItemComponentKeyByType = React.useMemo(() => {\n const map: Record<string, string | null> = {}\n for (const item of messageTypesQuery.data ?? []) {\n map[item.type] = item.ui?.listItemComponent ?? null\n }\n return map\n }, [messageTypesQuery.data])\n\n const filters = React.useMemo<FilterDef[]>(() => {\n const typeOptions = (messageTypesQuery.data ?? []).map((item) => ({\n value: item.type,\n label: t(item.labelKey, item.type),\n }))\n\n return [\n {\n id: 'status',\n label: t('messages.filters.status', 'Status'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'unread', label: t('messages.status.unread', 'Unread') },\n { value: 'read', label: t('messages.status.read', 'Read') },\n { value: 'archived', label: t('messages.status.archived', 'Archived') },\n ],\n },\n {\n id: 'type',\n label: t('messages.filters.type', 'Type'),\n type: 'select',\n options: [{ value: '', label: t('messages.filters.all', 'All') }, ...typeOptions],\n },\n {\n id: 'hasObjects',\n label: t('messages.filters.hasObjects', 'Objects'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'true', label: t('common.yes', 'Yes') },\n { value: 'false', label: t('common.no', 'No') },\n ],\n },\n {\n id: 'hasAttachments',\n label: t('messages.filters.hasAttachments', 'Attachments'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'true', label: t('common.yes', 'Yes') },\n { value: 'false', label: t('common.no', 'No') },\n ],\n },\n {\n id: 'hasActions',\n label: t('messages.filters.hasActions', 'Actions'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'true', label: t('common.yes', 'Yes') },\n { value: 'false', label: t('common.no', 'No') },\n ],\n },\n {\n id: 'senderId',\n label: t('messages.filters.sender', 'Sender'),\n type: 'select',\n options: [{ value: '', label: t('messages.filters.all', 'All') }],\n loadOptions: loadSenderOptions,\n },\n {\n id: 'since',\n label: t('messages.filters.since', 'Sent after'),\n type: 'text',\n placeholder: t('messages.filters.sincePlaceholder', 'YYYY-MM-DDTHH:mm:ssZ'),\n },\n ]\n }, [loadSenderOptions, messageTypesQuery.data, t])\n\n const columns = React.useMemo<ColumnDef<MessageListItem>[]>(() => [\n {\n accessorKey: 'message',\n header: t('messages.title', 'Messages'),\n meta: {\n truncate: false,\n maxWidth: '100%',\n },\n cell: ({ row }) => {\n const item = row.original\n const listItemComponentKey = listItemComponentKeyByType[item.type]\n const ListItemComponent = listItemComponentKey\n ? messageUiRegistry.listItemComponents[listItemComponentKey] ?? null\n : null\n const ComponentToUse = ListItemComponent || DefaultMessageListItem\n\n return (\n <ComponentToUse\n message={{\n id: item.id,\n type: item.type,\n typeLabel: messageTypeLabelMap[item.type] ?? item.type,\n subject: item.subject,\n body: item.bodyPreview,\n bodyFormat: 'text' as const,\n priority: (item.priority as 'low' | 'normal' | 'high' | 'urgent') ?? 'normal',\n sentAt: item.sentAt ? new Date(item.sentAt) : null,\n senderName: item.senderName || item.senderEmail || item.senderUserId,\n hasObjects: item.hasObjects,\n objectCount: item.objectCount,\n hasAttachments: item.hasAttachments,\n attachmentCount: item.attachmentCount,\n hasActions: item.hasActions,\n actionTaken: item.actionTaken ?? null,\n unread: item.status === 'unread',\n }}\n onClick={() => router.push(`/backend/messages/${item.id}`)}\n />\n )\n },\n },\n ], [listItemComponentKeyByType, messageTypeLabelMap, messageUiRegistry, router, t])\n\n const folderOptions = React.useMemo(() => [\n { id: 'inbox' as const, label: t('messages.folder.inbox', 'Inbox'), icon: Inbox },\n { id: 'sent' as const, label: t('messages.folder.sent', 'Sent'), icon: Send },\n { id: 'drafts' as const, label: t('messages.folder.drafts', 'Drafts'), icon: FilePenLine },\n { id: 'archived' as const, label: t('messages.folder.archived', 'Archived'), icon: Archive },\n { id: 'all' as const, label: t('messages.folder.all', 'All'), icon: Layers },\n ], [t])\n\n const activeFolderOption = folderOptions.find((option) => option.id === folder) ?? folderOptions[0]\n const ActiveFolderIcon = activeFolderOption.icon\n\n React.useEffect(() => {\n if (!folderMenuOpen) return\n const handleClickOutside = (event: MouseEvent) => {\n if (!folderMenuRef.current) return\n const target = event.target\n if (target instanceof Node && !folderMenuRef.current.contains(target)) {\n setFolderMenuOpen(false)\n }\n }\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setFolderMenuOpen(false)\n }\n document.addEventListener('mousedown', handleClickOutside)\n document.addEventListener('keydown', handleEscape)\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n document.removeEventListener('keydown', handleEscape)\n }\n }, [folderMenuOpen])\n\n const rows = listQuery.data?.items ?? []\n const total = listQuery.data?.total ?? 0\n const totalPages = listQuery.data?.totalPages ?? 0\n\n return (\n <div className=\"space-y-4\">\n <DataTable\n title={t('messages.title', 'Messages')}\n columns={columns}\n data={rows}\n bulkActions={bulkActions}\n selectionScopeKey={selectionScopeKey}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('messages.searchPlaceholder', 'Search messages')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(value) => {\n setFilterValues(value)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n injectionContext={injectionContext}\n isLoading={listQuery.isLoading || listQuery.isFetching}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"relative\" ref={folderMenuRef}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-2\"\n aria-expanded={folderMenuOpen}\n aria-haspopup=\"menu\"\n onClick={() => setFolderMenuOpen((value) => !value)}\n >\n <ActiveFolderIcon className=\"h-4 w-4\" aria-hidden />\n <span>{t('messages.folder.selector', 'Folder')}:</span>\n <span>{activeFolderOption.label}</span>\n <ChevronDown className=\"h-4 w-4 opacity-70\" aria-hidden />\n </Button>\n {folderMenuOpen ? (\n <div\n className=\"absolute right-0 z-20 mt-1 min-w-52 rounded-md border bg-background p-1 shadow\"\n role=\"menu\"\n >\n {folderOptions.map((option) => {\n const Icon = option.icon\n const isActive = option.id === folder\n return (\n <Button\n key={option.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n role=\"menuitemradio\"\n aria-checked={isActive}\n className={`w-full justify-start h-auto px-2 py-1.5 text-sm font-normal ${isActive ? 'bg-accent/60' : ''}`}\n onClick={() => {\n setFolder(option.id)\n setPage(1)\n setFolderMenuOpen(false)\n }}\n >\n <Icon className=\"h-4 w-4\" aria-hidden />\n <span>{option.label}</span>\n </Button>\n )\n })}\n </div>\n ) : null}\n </div>\n <Button asChild>\n <Link href=\"/backend/messages/compose\">{t('messages.compose', 'Compose message')}</Link>\n </Button>\n </div>\n }\n onRowClick={(row) => {\n router.push(`/backend/messages/${row.id}`)\n }}\n embedded\n />\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport { Archive, ChevronDown, FilePenLine, Inbox, Layers, Send } from 'lucide-react'\nimport { getMessageUiComponentRegistry } from './utils/typeUiRegistry'\nimport { DefaultMessageListItem } from './defaults/DefaultMessageListItem'\nimport { toErrorMessage } from './message-detail/utils'\nimport { useMessagesInboxBulkActions, type MessageFolder } from './useMessagesInboxBulkActions'\n\ntype MessageListItem = {\n id: string\n type: string\n subject: string\n bodyPreview: string\n senderUserId: string\n senderName?: string | null\n senderEmail?: string | null\n priority: string\n status: string\n hasObjects: boolean\n objectCount: number\n hasAttachments: boolean\n attachmentCount: number\n hasActions: boolean\n actionTaken?: string | null\n sentAt?: string | null\n readAt?: string | null\n threadId?: string | null\n}\n\ntype MessageListResponse = {\n items?: MessageListItem[]\n total?: number\n page?: number\n pageSize?: number\n totalPages?: number\n}\n\ntype MessageTypeItem = {\n type: string\n module: string\n labelKey: string\n ui?: {\n listItemComponent?: string | null\n } | null\n}\n\ntype UserListItem = {\n id: string\n email?: string | null\n name?: string | null\n}\n\nexport function MessagesInboxPageClient() {\n const router = useRouter()\n const t = useT()\n const queryClient = useQueryClient()\n const scopeVersion = useOrganizationScopeVersion()\n\n const invalidateMessageListQueries = React.useCallback(() => {\n void queryClient.invalidateQueries({ queryKey: ['messages', 'list'] })\n }, [queryClient])\n\n useAppEvent('messages.message.*', invalidateMessageListQueries, [invalidateMessageListQueries])\n\n useAppEvent('om:bridge:reconnected', invalidateMessageListQueries, [invalidateMessageListQueries])\n\n const [folder, setFolder] = React.useState<MessageFolder>('inbox')\n const [folderMenuOpen, setFolderMenuOpen] = React.useState(false)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [page, setPage] = React.useState(1)\n const pageSize = 20\n const folderMenuRef = React.useRef<HTMLDivElement | null>(null)\n const messageUiRegistry = React.useMemo(() => getMessageUiComponentRegistry(), [])\n const { bulkActions, selectionScopeKey, injectionContext, ConfirmDialogElement } = useMessagesInboxBulkActions<MessageListItem>({\n folder,\n page,\n search,\n filterValues,\n })\n\n const listQuery = useQuery({\n queryKey: [\n 'messages',\n 'list',\n folder,\n search,\n page,\n pageSize,\n JSON.stringify(filterValues),\n scopeVersion,\n ],\n queryFn: async () => {\n const params = new URLSearchParams()\n params.set('folder', folder)\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n\n if (search.trim()) {\n params.set('search', search.trim())\n }\n\n const status = typeof filterValues.status === 'string' ? filterValues.status.trim() : ''\n const type = typeof filterValues.type === 'string' ? filterValues.type.trim() : ''\n const hasObjects = typeof filterValues.hasObjects === 'string' ? filterValues.hasObjects.trim() : ''\n const hasAttachments = typeof filterValues.hasAttachments === 'string' ? filterValues.hasAttachments.trim() : ''\n const hasActions = typeof filterValues.hasActions === 'string' ? filterValues.hasActions.trim() : ''\n const senderId = typeof filterValues.senderId === 'string' ? filterValues.senderId.trim() : ''\n const since = typeof filterValues.since === 'string' ? filterValues.since.trim() : ''\n\n if (status) params.set('status', status)\n if (type) params.set('type', type)\n if (hasObjects) params.set('hasObjects', hasObjects)\n if (hasAttachments) params.set('hasAttachments', hasAttachments)\n if (hasActions) params.set('hasActions', hasActions)\n if (senderId) params.set('senderId', senderId)\n if (since) params.set('since', since)\n\n const call = await apiCall<MessageListResponse>(`/api/messages?${params.toString()}`)\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadListFailed', 'Failed to load messages.'),\n )\n }\n\n return {\n items: Array.isArray(call.result?.items) ? call.result?.items ?? [] : [],\n total: Number(call.result?.total ?? 0),\n page: Number(call.result?.page ?? page),\n pageSize: Number(call.result?.pageSize ?? pageSize),\n totalPages: Number(call.result?.totalPages ?? 0),\n }\n },\n })\n\n const messageTypesQuery = useQuery({\n queryKey: ['messages', 'types', scopeVersion],\n queryFn: async () => {\n const call = await apiCall<{ items?: MessageTypeItem[] }>('/api/messages/types')\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadTypesFailed', 'Failed to load message types.'),\n )\n }\n return Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n },\n })\n\n React.useEffect(() => {\n if (!listQuery.error) return\n flash(\n listQuery.error instanceof Error\n ? listQuery.error.message\n : t('messages.errors.loadListFailed', 'Failed to load messages.'),\n 'error',\n )\n }, [listQuery.error, t])\n\n React.useEffect(() => {\n if (!messageTypesQuery.error) return\n flash(\n messageTypesQuery.error instanceof Error\n ? messageTypesQuery.error.message\n : t('messages.errors.loadTypesFailed', 'Failed to load message types.'),\n 'error',\n )\n }, [messageTypesQuery.error, t])\n\n const messageTypeLabelMap = React.useMemo(() => {\n const map: Record<string, string> = {}\n for (const item of messageTypesQuery.data ?? []) {\n map[item.type] = t(item.labelKey, item.type)\n }\n return map\n }, [messageTypesQuery.data, t])\n\n const loadSenderOptions = React.useCallback(async (query?: string) => {\n const params = new URLSearchParams()\n params.set('page', '1')\n params.set('pageSize', '20')\n if (query && query.trim().length > 0) {\n params.set('search', query.trim())\n }\n\n const call = await apiCall<{ items?: UserListItem[] }>(`/api/auth/users?${params.toString()}`)\n if (!call.ok) return []\n\n const items = Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n return items.flatMap((item) => {\n if (!item || typeof item.id !== 'string' || item.id.trim().length === 0) return []\n const name = typeof item.name === 'string' && item.name.trim().length > 0 ? item.name.trim() : null\n const email = typeof item.email === 'string' && item.email.trim().length > 0 ? item.email.trim() : null\n const label = name ?? email ?? item.id\n return [{\n value: item.id,\n label,\n description: email && email !== label ? email : null,\n }]\n })\n }, [])\n\n const listItemComponentKeyByType = React.useMemo(() => {\n const map: Record<string, string | null> = {}\n for (const item of messageTypesQuery.data ?? []) {\n map[item.type] = item.ui?.listItemComponent ?? null\n }\n return map\n }, [messageTypesQuery.data])\n\n const filters = React.useMemo<FilterDef[]>(() => {\n const typeOptions = (messageTypesQuery.data ?? []).map((item) => ({\n value: item.type,\n label: t(item.labelKey, item.type),\n }))\n\n return [\n {\n id: 'status',\n label: t('messages.filters.status', 'Status'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'unread', label: t('messages.status.unread', 'Unread') },\n { value: 'read', label: t('messages.status.read', 'Read') },\n { value: 'archived', label: t('messages.status.archived', 'Archived') },\n ],\n },\n {\n id: 'type',\n label: t('messages.filters.type', 'Type'),\n type: 'select',\n options: [{ value: '', label: t('messages.filters.all', 'All') }, ...typeOptions],\n },\n {\n id: 'hasObjects',\n label: t('messages.filters.hasObjects', 'Objects'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'true', label: t('common.yes', 'Yes') },\n { value: 'false', label: t('common.no', 'No') },\n ],\n },\n {\n id: 'hasAttachments',\n label: t('messages.filters.hasAttachments', 'Attachments'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'true', label: t('common.yes', 'Yes') },\n { value: 'false', label: t('common.no', 'No') },\n ],\n },\n {\n id: 'hasActions',\n label: t('messages.filters.hasActions', 'Actions'),\n type: 'select',\n options: [\n { value: '', label: t('messages.filters.all', 'All') },\n { value: 'true', label: t('common.yes', 'Yes') },\n { value: 'false', label: t('common.no', 'No') },\n ],\n },\n {\n id: 'senderId',\n label: t('messages.filters.sender', 'Sender'),\n type: 'select',\n options: [{ value: '', label: t('messages.filters.all', 'All') }],\n loadOptions: loadSenderOptions,\n },\n {\n id: 'since',\n label: t('messages.filters.since', 'Sent after'),\n type: 'text',\n placeholder: t('messages.filters.sincePlaceholder', 'YYYY-MM-DDTHH:mm:ssZ'),\n },\n ]\n }, [loadSenderOptions, messageTypesQuery.data, t])\n\n const columns = React.useMemo<ColumnDef<MessageListItem>[]>(() => [\n {\n accessorKey: 'message',\n header: t('messages.title', 'Messages'),\n meta: {\n truncate: false,\n maxWidth: '100%',\n },\n cell: ({ row }) => {\n const item = row.original\n const listItemComponentKey = listItemComponentKeyByType[item.type]\n const ListItemComponent = listItemComponentKey\n ? messageUiRegistry.listItemComponents[listItemComponentKey] ?? null\n : null\n const ComponentToUse = ListItemComponent || DefaultMessageListItem\n\n return (\n <ComponentToUse\n message={{\n id: item.id,\n type: item.type,\n typeLabel: messageTypeLabelMap[item.type] ?? item.type,\n subject: item.subject,\n body: item.bodyPreview,\n bodyFormat: 'text' as const,\n priority: (item.priority as 'low' | 'normal' | 'high' | 'urgent') ?? 'normal',\n sentAt: item.sentAt ? new Date(item.sentAt) : null,\n senderName: item.senderName || item.senderEmail || item.senderUserId,\n hasObjects: item.hasObjects,\n objectCount: item.objectCount,\n hasAttachments: item.hasAttachments,\n attachmentCount: item.attachmentCount,\n hasActions: item.hasActions,\n actionTaken: item.actionTaken ?? null,\n unread: item.status === 'unread',\n }}\n onClick={() => router.push(`/backend/messages/${item.id}`)}\n />\n )\n },\n },\n ], [listItemComponentKeyByType, messageTypeLabelMap, messageUiRegistry, router, t])\n\n const folderOptions = React.useMemo(() => [\n { id: 'inbox' as const, label: t('messages.folder.inbox', 'Inbox'), icon: Inbox },\n { id: 'sent' as const, label: t('messages.folder.sent', 'Sent'), icon: Send },\n { id: 'drafts' as const, label: t('messages.folder.drafts', 'Drafts'), icon: FilePenLine },\n { id: 'archived' as const, label: t('messages.folder.archived', 'Archived'), icon: Archive },\n { id: 'all' as const, label: t('messages.folder.all', 'All'), icon: Layers },\n ], [t])\n\n const activeFolderOption = folderOptions.find((option) => option.id === folder) ?? folderOptions[0]\n const ActiveFolderIcon = activeFolderOption.icon\n\n React.useEffect(() => {\n if (!folderMenuOpen) return\n const handleClickOutside = (event: MouseEvent) => {\n if (!folderMenuRef.current) return\n const target = event.target\n if (target instanceof Node && !folderMenuRef.current.contains(target)) {\n setFolderMenuOpen(false)\n }\n }\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setFolderMenuOpen(false)\n }\n document.addEventListener('mousedown', handleClickOutside)\n document.addEventListener('keydown', handleEscape)\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n document.removeEventListener('keydown', handleEscape)\n }\n }, [folderMenuOpen])\n\n const rows = listQuery.data?.items ?? []\n const total = listQuery.data?.total ?? 0\n const totalPages = listQuery.data?.totalPages ?? 0\n\n return (\n <div className=\"space-y-4\">\n <DataTable\n title={t('messages.title', 'Messages')}\n columns={columns}\n data={rows}\n bulkActions={bulkActions}\n selectionScopeKey={selectionScopeKey}\n searchValue={search}\n onSearchChange={(value) => {\n setSearch(value)\n setPage(1)\n }}\n searchPlaceholder={t('messages.searchPlaceholder', 'Search messages')}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(value) => {\n setFilterValues(value)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n injectionContext={injectionContext}\n isLoading={listQuery.isLoading || listQuery.isFetching}\n pagination={{\n page,\n pageSize,\n total,\n totalPages,\n onPageChange: setPage,\n }}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"relative\" ref={folderMenuRef}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-2\"\n aria-expanded={folderMenuOpen}\n aria-haspopup=\"menu\"\n onClick={() => setFolderMenuOpen((value) => !value)}\n >\n <ActiveFolderIcon className=\"h-4 w-4\" aria-hidden />\n <span>{t('messages.folder.selector', 'Folder')}:</span>\n <span>{activeFolderOption.label}</span>\n <ChevronDown className=\"h-4 w-4 opacity-70\" aria-hidden />\n </Button>\n {folderMenuOpen ? (\n <div\n className=\"absolute right-0 z-dropdown mt-1 min-w-52 rounded-md border bg-background p-1 shadow\"\n role=\"menu\"\n >\n {folderOptions.map((option) => {\n const Icon = option.icon\n const isActive = option.id === folder\n return (\n <Button\n key={option.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n role=\"menuitemradio\"\n aria-checked={isActive}\n className={`w-full justify-start h-auto px-2 py-1.5 text-sm font-normal ${isActive ? 'bg-accent/60' : ''}`}\n onClick={() => {\n setFolder(option.id)\n setPage(1)\n setFolderMenuOpen(false)\n }}\n >\n <Icon className=\"h-4 w-4\" aria-hidden />\n <span>{option.label}</span>\n </Button>\n )\n })}\n </div>\n ) : null}\n </div>\n <Button asChild>\n <Link href=\"/backend/messages/compose\">{t('messages.compose', 'Compose message')}</Link>\n </Button>\n </div>\n }\n onRowClick={(row) => {\n router.push(`/backend/messages/${row.id}`)\n }}\n embedded\n />\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -40,7 +40,7 @@ function DefaultMessageListItem({ message, onClick }) {
|
|
|
40
40
|
"div",
|
|
41
41
|
{
|
|
42
42
|
className: cn(
|
|
43
|
-
"group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/
|
|
43
|
+
"group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/50",
|
|
44
44
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
45
45
|
),
|
|
46
46
|
role: "button",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/messages/components/defaults/DefaultMessageListItem.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport type { MessageListItemProps } from '@open-mercato/shared/modules/messages/types'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { CheckCircle2, FileText, Paperclip, Zap } from 'lucide-react'\n\nfunction formatDateTime(value: Date | null): string {\n if (!value) return '\u2014'\n if (Number.isNaN(value.getTime())) return '\u2014'\n return value.toLocaleString()\n}\n\nfunction formatSentTime(value: Date | null): string {\n if (!value) return '\u2014'\n if (Number.isNaN(value.getTime())) return '\u2014'\n\n const now = new Date()\n const isSameDay = now.toDateString() === value.toDateString()\n if (isSameDay) {\n return value.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n }\n\n const isSameYear = now.getFullYear() === value.getFullYear()\n if (isSameYear) {\n return value.toLocaleDateString([], { month: 'short', day: 'numeric' })\n }\n\n return value.toLocaleDateString([], { year: 'numeric', month: 'short', day: 'numeric' })\n}\n\nfunction truncateWords(value: string, maxWords: number): string {\n const normalized = value.trim().replace(/\\s+/g, ' ')\n if (!normalized) return '\u2014'\n const words = normalized.split(' ')\n if (words.length <= maxWords) return normalized\n return `${words.slice(0, maxWords).join(' ')}...`\n}\n\nexport function DefaultMessageListItem({ message, onClick }: MessageListItemProps) {\n const t = useT()\n const senderLabel = message.senderName || '\u2014'\n const subject = message.subject || '\u2014'\n const absoluteSentAt = formatDateTime(message.sentAt)\n const sentAtLabel = formatSentTime(message.sentAt)\n const bodyPreview = truncateWords(message.body || '', 16)\n\n return (\n <div\n className={cn(\n 'group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport type { MessageListItemProps } from '@open-mercato/shared/modules/messages/types'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { CheckCircle2, FileText, Paperclip, Zap } from 'lucide-react'\n\nfunction formatDateTime(value: Date | null): string {\n if (!value) return '\u2014'\n if (Number.isNaN(value.getTime())) return '\u2014'\n return value.toLocaleString()\n}\n\nfunction formatSentTime(value: Date | null): string {\n if (!value) return '\u2014'\n if (Number.isNaN(value.getTime())) return '\u2014'\n\n const now = new Date()\n const isSameDay = now.toDateString() === value.toDateString()\n if (isSameDay) {\n return value.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n }\n\n const isSameYear = now.getFullYear() === value.getFullYear()\n if (isSameYear) {\n return value.toLocaleDateString([], { month: 'short', day: 'numeric' })\n }\n\n return value.toLocaleDateString([], { year: 'numeric', month: 'short', day: 'numeric' })\n}\n\nfunction truncateWords(value: string, maxWords: number): string {\n const normalized = value.trim().replace(/\\s+/g, ' ')\n if (!normalized) return '\u2014'\n const words = normalized.split(' ')\n if (words.length <= maxWords) return normalized\n return `${words.slice(0, maxWords).join(' ')}...`\n}\n\nexport function DefaultMessageListItem({ message, onClick }: MessageListItemProps) {\n const t = useT()\n const senderLabel = message.senderName || '\u2014'\n const subject = message.subject || '\u2014'\n const absoluteSentAt = formatDateTime(message.sentAt)\n const sentAtLabel = formatSentTime(message.sentAt)\n const bodyPreview = truncateWords(message.body || '', 16)\n\n return (\n <div\n className={cn(\n 'group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/50',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n )}\n role=\"button\"\n tabIndex={0}\n aria-label={t('messages.openMessageDetailedA11y', 'Open message {subject} from {sender}, sent {sentAt}', {\n subject,\n sender: senderLabel,\n sentAt: absoluteSentAt,\n })}\n onClick={onClick}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick()\n }\n }}\n >\n <div className=\"flex items-center gap-3\">\n <span className={cn('w-40 flex-shrink-0 truncate text-sm md:w-56', message.unread ? 'font-semibold' : 'font-normal')}>\n {senderLabel}\n </span>\n\n <div className=\"flex min-w-0 flex-1 items-center gap-1.5 text-sm\">\n <span className={cn('truncate text-foreground', message.unread ? 'font-semibold' : 'font-normal')}>\n {subject}\n </span>\n <span className=\"text-muted-foreground\">-</span>\n <span className=\"truncate text-muted-foreground\">{bodyPreview}</span>\n </div>\n\n <div className=\"flex flex-shrink-0 items-center gap-1.5 text-muted-foreground\">\n {message.hasObjects ? <FileText className=\"h-3.5 w-3.5\" aria-hidden /> : null}\n {message.hasAttachments ? <Paperclip className=\"h-3.5 w-3.5\" aria-hidden /> : null}\n {message.hasActions && !message.actionTaken ? (\n <Zap className=\"h-3.5 w-3.5 text-amber-600\" aria-hidden />\n ) : null}\n {message.actionTaken ? <CheckCircle2 className=\"h-3.5 w-3.5 text-green-600\" aria-hidden /> : null}\n </div>\n\n <span\n className={cn('flex-shrink-0 text-xs', message.unread ? 'font-semibold text-foreground' : 'font-normal text-muted-foreground')}\n title={absoluteSentAt}\n >\n {sentAtLabel}\n </span>\n </div>\n </div>\n )\n}\n\nexport default DefaultMessageListItem\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -47,7 +47,7 @@ function MessageRecordObjectDetail({
|
|
|
47
47
|
const title = previewData?.title || readSnapshotLabel(snapshot) || fallbackTitle;
|
|
48
48
|
const subtitle = previewData?.subtitle || readSnapshotSubtitle(snapshot) || t("messages.objectPreview.fallback.subtitle", "{type} \u2022 {id}", { type: typeLabel, id: entityId });
|
|
49
49
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3 rounded p-3 text-sm", children: [
|
|
50
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded bg-muted/
|
|
50
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded bg-muted/30 p-3", children: [
|
|
51
51
|
/* @__PURE__ */ jsx(Link2, { className: "mt-0.5 h-4 w-4 text-muted-foreground" }),
|
|
52
52
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
53
53
|
/* @__PURE__ */ jsx("p", { className: "font-medium", children: title }),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/messages/components/defaults/MessageRecordObjectDetail.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Link2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { ObjectDetailProps } from '@open-mercato/shared/modules/messages/types'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { getMessageObjectType } from '../../lib/message-objects-registry'\n\nfunction readSnapshotLabel(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n\n const candidates = ['subject', 'title', 'name', 'label', 'id']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n\n return null\n}\n\nfunction readSnapshotSubtitle(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n\n const candidates = ['type', 'status']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n\n return null\n}\n\nexport function MessageRecordObjectDetail({\n entityId,\n entityModule,\n entityType,\n snapshot,\n previewData,\n actionRequired,\n actionLabel,\n actions,\n onAction,\n}: ObjectDetailProps) {\n const t = useT()\n const [executingActionId, setExecutingActionId] = React.useState<string | null>(null)\n\n const registeredType = getMessageObjectType(entityModule, entityType)\n const fallbackTitle = t('messages.objectPreview.fallback.title', 'Linked object')\n const typeLabel = registeredType\n ? t(registeredType.labelKey, `${entityModule}:${entityType}`)\n : `${entityModule}:${entityType}`\n const title = previewData?.title || readSnapshotLabel(snapshot) || fallbackTitle\n const subtitle = previewData?.subtitle\n || readSnapshotSubtitle(snapshot)\n || t('messages.objectPreview.fallback.subtitle', '{type} \u2022 {id}', { type: typeLabel, id: entityId })\n\n return (\n <div className=\"space-y-3 rounded p-3 text-sm\">\n <div className=\"flex items-start gap-3 rounded bg-muted/
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Link2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { ObjectDetailProps } from '@open-mercato/shared/modules/messages/types'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { getMessageObjectType } from '../../lib/message-objects-registry'\n\nfunction readSnapshotLabel(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n\n const candidates = ['subject', 'title', 'name', 'label', 'id']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n\n return null\n}\n\nfunction readSnapshotSubtitle(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n\n const candidates = ['type', 'status']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n\n return null\n}\n\nexport function MessageRecordObjectDetail({\n entityId,\n entityModule,\n entityType,\n snapshot,\n previewData,\n actionRequired,\n actionLabel,\n actions,\n onAction,\n}: ObjectDetailProps) {\n const t = useT()\n const [executingActionId, setExecutingActionId] = React.useState<string | null>(null)\n\n const registeredType = getMessageObjectType(entityModule, entityType)\n const fallbackTitle = t('messages.objectPreview.fallback.title', 'Linked object')\n const typeLabel = registeredType\n ? t(registeredType.labelKey, `${entityModule}:${entityType}`)\n : `${entityModule}:${entityType}`\n const title = previewData?.title || readSnapshotLabel(snapshot) || fallbackTitle\n const subtitle = previewData?.subtitle\n || readSnapshotSubtitle(snapshot)\n || t('messages.objectPreview.fallback.subtitle', '{type} \u2022 {id}', { type: typeLabel, id: entityId })\n\n return (\n <div className=\"space-y-3 rounded p-3 text-sm\">\n <div className=\"flex items-start gap-3 rounded bg-muted/30 p-3\">\n <Link2 className=\"mt-0.5 h-4 w-4 text-muted-foreground\" />\n <div className=\"min-w-0 flex-1 space-y-1\">\n <p className=\"font-medium\">{title}</p>\n <p className=\"text-xs text-muted-foreground\" title={entityId}>{subtitle}</p>\n {previewData?.status ? (\n <Badge variant=\"outline\" className=\"text-xs\">{previewData.status}</Badge>\n ) : null}\n </div>\n </div>\n\n {actionRequired ? (\n <p className=\"text-xs text-amber-700\">\n {actionLabel\n ? t('messages.composer.objectAction', 'Action: {action}', { action: actionLabel })\n : t('messages.composer.objectActionRequired', 'Action required')}\n </p>\n ) : null}\n\n {actions.length ? (\n <div className=\"flex flex-wrap gap-2\">\n {actions.map((action) => (\n <Button\n key={action.id}\n type=\"button\"\n size=\"sm\"\n variant={action.variant ?? 'default'}\n onClick={async () => {\n if (executingActionId) return\n setExecutingActionId(action.id)\n try {\n await onAction(action.id)\n } finally {\n setExecutingActionId(null)\n }\n }}\n disabled={executingActionId !== null}\n >\n {executingActionId === action.id\n ? t('messages.actions.executing', 'Executing...')\n : t(action.labelKey ?? action.id, action.labelKey ?? action.id)}\n </Button>\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport default MessageRecordObjectDetail\n"],
|
|
5
5
|
"mappings": ";AAiEQ,cACA,YADA;AA/DR,YAAY,WAAW;AACvB,SAAS,aAAa;AACtB,SAAS,YAAY;AAErB,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,4BAA4B;AAErC,SAAS,kBAAkB,UAA8D;AACvF,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,aAAa,CAAC,WAAW,SAAS,QAAQ,SAAS,IAAI;AAC7D,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,SAAS,GAAG;AAC1B,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACxD,aAAO,MAAM,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,qBAAqB,UAA8D;AAC1F,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,aAAa,CAAC,QAAQ,QAAQ;AACpC,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,SAAS,GAAG;AAC1B,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACxD,aAAO,MAAM,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAAwB,IAAI;AAEpF,QAAM,iBAAiB,qBAAqB,cAAc,UAAU;AACpE,QAAM,gBAAgB,EAAE,yCAAyC,eAAe;AAChF,QAAM,YAAY,iBACd,EAAE,eAAe,UAAU,GAAG,YAAY,IAAI,UAAU,EAAE,IAC1D,GAAG,YAAY,IAAI,UAAU;AACjC,QAAM,QAAQ,aAAa,SAAS,kBAAkB,QAAQ,KAAK;AACnE,QAAM,WAAW,aAAa,YACzB,qBAAqB,QAAQ,KAC7B,EAAE,4CAA4C,sBAAiB,EAAE,MAAM,WAAW,IAAI,SAAS,CAAC;AAErG,SACE,qBAAC,SAAI,WAAU,iCACb;AAAA,yBAAC,SAAI,WAAU,kDACb;AAAA,0BAAC,SAAM,WAAU,wCAAuC;AAAA,MACxD,qBAAC,SAAI,WAAU,4BACb;AAAA,4BAAC,OAAE,WAAU,eAAe,iBAAM;AAAA,QAClC,oBAAC,OAAE,WAAU,iCAAgC,OAAO,UAAW,oBAAS;AAAA,QACvE,aAAa,SACZ,oBAAC,SAAM,SAAQ,WAAU,WAAU,WAAW,sBAAY,QAAO,IAC/D;AAAA,SACN;AAAA,OACF;AAAA,IAEC,iBACC,oBAAC,OAAE,WAAU,0BACV,wBACG,EAAE,kCAAkC,oBAAoB,EAAE,QAAQ,YAAY,CAAC,IAC/E,EAAE,0CAA0C,iBAAiB,GACnE,IACE;AAAA,IAEH,QAAQ,SACP,oBAAC,SAAI,WAAU,wBACZ,kBAAQ,IAAI,CAAC,WACZ;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,SAAS,OAAO,WAAW;AAAA,QAC3B,SAAS,YAAY;AACnB,cAAI,kBAAmB;AACvB,+BAAqB,OAAO,EAAE;AAC9B,cAAI;AACF,kBAAM,SAAS,OAAO,EAAE;AAAA,UAC1B,UAAE;AACA,iCAAqB,IAAI;AAAA,UAC3B;AAAA,QACF;AAAA,QACA,UAAU,sBAAsB;AAAA,QAE/B,gCAAsB,OAAO,KAC1B,EAAE,8BAA8B,cAAc,IAC9C,EAAE,OAAO,YAAY,OAAO,IAAI,OAAO,YAAY,OAAO,EAAE;AAAA;AAAA,MAjB3D,OAAO;AAAA,IAkBd,CACD,GACH,IACE;AAAA,KACN;AAEJ;AAEA,IAAO,oCAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -41,7 +41,7 @@ function MessageRecordObjectPreview({
|
|
|
41
41
|
const typeLabel = registeredType ? t(registeredType.labelKey, `${entityModule}:${entityType}`) : `${entityModule}:${entityType}`;
|
|
42
42
|
const title = previewData?.title || readSnapshotLabel(snapshot) || fallbackTitle;
|
|
43
43
|
const subtitle = previewData?.subtitle || readSnapshotSubtitle(snapshot) || t("messages.objectPreview.fallback.subtitle", "{type} \u2022 {id}", { type: typeLabel, id: entityId });
|
|
44
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded bg-muted/
|
|
44
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded bg-muted/30 p-3", children: [
|
|
45
45
|
/* @__PURE__ */ jsx(Link2, { className: "mt-0.5 h-4 w-4 text-muted-foreground" }),
|
|
46
46
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
47
47
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/messages/components/defaults/MessageRecordObjectPreview.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport { Link2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { ObjectPreviewProps } from '@open-mercato/shared/modules/messages/types'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { getMessageObjectType } from '../../lib/message-objects-registry'\n\nfunction readSnapshotLabel(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n const candidates = ['subject', 'title', 'name', 'label', 'id']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n return null\n}\n\nfunction readSnapshotSubtitle(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n const candidates = ['type', 'status']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n return null\n}\n\nexport function MessageRecordObjectPreview({\n entityId,\n entityModule,\n entityType,\n snapshot,\n previewData,\n actionRequired,\n actionLabel,\n}: ObjectPreviewProps) {\n const t = useT()\n const registeredType = getMessageObjectType(entityModule, entityType)\n const fallbackTitle = t('messages.objectPreview.fallback.title', 'Linked object')\n const typeLabel = registeredType\n ? t(registeredType.labelKey, `${entityModule}:${entityType}`)\n : `${entityModule}:${entityType}`\n const title = previewData?.title || readSnapshotLabel(snapshot) || fallbackTitle\n const subtitle = previewData?.subtitle\n || readSnapshotSubtitle(snapshot)\n || t('messages.objectPreview.fallback.subtitle', '{type} \u2022 {id}', { type: typeLabel, id: entityId })\n\n return (\n <div className=\"flex items-start gap-3 rounded bg-muted/
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport { Link2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { ObjectPreviewProps } from '@open-mercato/shared/modules/messages/types'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { getMessageObjectType } from '../../lib/message-objects-registry'\n\nfunction readSnapshotLabel(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n const candidates = ['subject', 'title', 'name', 'label', 'id']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n return null\n}\n\nfunction readSnapshotSubtitle(snapshot: Record<string, unknown> | undefined): string | null {\n if (!snapshot) return null\n const candidates = ['type', 'status']\n for (const key of candidates) {\n const value = snapshot[key]\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim()\n }\n }\n return null\n}\n\nexport function MessageRecordObjectPreview({\n entityId,\n entityModule,\n entityType,\n snapshot,\n previewData,\n actionRequired,\n actionLabel,\n}: ObjectPreviewProps) {\n const t = useT()\n const registeredType = getMessageObjectType(entityModule, entityType)\n const fallbackTitle = t('messages.objectPreview.fallback.title', 'Linked object')\n const typeLabel = registeredType\n ? t(registeredType.labelKey, `${entityModule}:${entityType}`)\n : `${entityModule}:${entityType}`\n const title = previewData?.title || readSnapshotLabel(snapshot) || fallbackTitle\n const subtitle = previewData?.subtitle\n || readSnapshotSubtitle(snapshot)\n || t('messages.objectPreview.fallback.subtitle', '{type} \u2022 {id}', { type: typeLabel, id: entityId })\n\n return (\n <div className=\"flex items-start gap-3 rounded bg-muted/30 p-3\">\n <Link2 className=\"mt-0.5 h-4 w-4 text-muted-foreground\" />\n <div className=\"min-w-0 flex-1 space-y-1\">\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium text-sm\">{title}</p>\n {actionRequired ? (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {actionLabel || t('messages.composer.objectActionRequired', 'Action required')}\n </Badge>\n ) : null}\n </div>\n <p className=\"text-xs text-muted-foreground\" title={entityId}>{subtitle}</p>\n {previewData?.status ? (\n <Badge variant=\"outline\" className=\"text-xs\">{previewData.status}</Badge>\n ) : null}\n </div>\n </div>\n )\n}\n\nexport default MessageRecordObjectPreview\n"],
|
|
5
5
|
"mappings": ";AAsDM,cAEE,YAFF;AApDN,SAAS,aAAa;AACtB,SAAS,YAAY;AAErB,SAAS,aAAa;AACtB,SAAS,4BAA4B;AAErC,SAAS,kBAAkB,UAA8D;AACvF,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,aAAa,CAAC,WAAW,SAAS,QAAQ,SAAS,IAAI;AAC7D,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,SAAS,GAAG;AAC1B,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACxD,aAAO,MAAM,KAAK;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,UAA8D;AAC1F,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,aAAa,CAAC,QAAQ,QAAQ;AACpC,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,SAAS,GAAG;AAC1B,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACxD,aAAO,MAAM,KAAK;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,IAAI,KAAK;AACf,QAAM,iBAAiB,qBAAqB,cAAc,UAAU;AACpE,QAAM,gBAAgB,EAAE,yCAAyC,eAAe;AAChF,QAAM,YAAY,iBACd,EAAE,eAAe,UAAU,GAAG,YAAY,IAAI,UAAU,EAAE,IAC1D,GAAG,YAAY,IAAI,UAAU;AACjC,QAAM,QAAQ,aAAa,SAAS,kBAAkB,QAAQ,KAAK;AACnE,QAAM,WAAW,aAAa,YACzB,qBAAqB,QAAQ,KAC7B,EAAE,4CAA4C,sBAAiB,EAAE,MAAM,WAAW,IAAI,SAAS,CAAC;AAErG,SACE,qBAAC,SAAI,WAAU,kDACb;AAAA,wBAAC,SAAM,WAAU,wCAAuC;AAAA,IACxD,qBAAC,SAAI,WAAU,4BACb;AAAA,2BAAC,SAAI,WAAU,2BACb;AAAA,4BAAC,OAAE,WAAU,uBAAuB,iBAAM;AAAA,QACzC,iBACC,oBAAC,SAAM,SAAQ,aAAY,WAAU,WAClC,yBAAe,EAAE,0CAA0C,iBAAiB,GAC/E,IACE;AAAA,SACN;AAAA,MACA,oBAAC,OAAE,WAAU,iCAAgC,OAAO,UAAW,oBAAS;AAAA,MACvE,aAAa,SACZ,oBAAC,SAAM,SAAQ,WAAU,WAAU,WAAW,sBAAY,QAAO,IAC/D;AAAA,OACN;AAAA,KACF;AAEJ;AAEA,IAAO,qCAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -23,7 +23,7 @@ function MessageListComponent({ message, onClick }) {
|
|
|
23
23
|
"div",
|
|
24
24
|
{
|
|
25
25
|
className: cn(
|
|
26
|
-
"group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/
|
|
26
|
+
"group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/50",
|
|
27
27
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
28
28
|
),
|
|
29
29
|
role: "button",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/messages/components/message-detail/panels/MessageListComponent.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport type { MessageListItemProps } from '@open-mercato/shared/modules/messages/types'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nfunction formatSentTime(value: Date | null): string {\n if (!value || Number.isNaN(value.getTime())) return '\u2014'\n\n const now = new Date()\n if (now.toDateString() === value.toDateString()) {\n return value.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n }\n\n return value.toLocaleDateString([], { month: 'short', day: 'numeric' })\n}\n\nfunction normalizeBody(value: string | null): string {\n const normalized = (value ?? '').trim().replace(/\\s+/g, ' ')\n return normalized || '\u2014'\n}\n\nexport function MessageListComponent({ message, onClick }: MessageListItemProps) {\n const t = useT()\n const senderLabel = message.senderName || '\u2014'\n const body = normalizeBody(message.body)\n const sentAtLabel = formatSentTime(message.sentAt)\n\n return (\n <div\n className={cn(\n 'group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport type { MessageListItemProps } from '@open-mercato/shared/modules/messages/types'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nfunction formatSentTime(value: Date | null): string {\n if (!value || Number.isNaN(value.getTime())) return '\u2014'\n\n const now = new Date()\n if (now.toDateString() === value.toDateString()) {\n return value.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n }\n\n return value.toLocaleDateString([], { month: 'short', day: 'numeric' })\n}\n\nfunction normalizeBody(value: string | null): string {\n const normalized = (value ?? '').trim().replace(/\\s+/g, ' ')\n return normalized || '\u2014'\n}\n\nexport function MessageListComponent({ message, onClick }: MessageListItemProps) {\n const t = useT()\n const senderLabel = message.senderName || '\u2014'\n const body = normalizeBody(message.body)\n const sentAtLabel = formatSentTime(message.sentAt)\n\n return (\n <div\n className={cn(\n 'group min-w-0 w-full cursor-pointer rounded-md px-2 py-2 transition-colors hover:bg-muted/50',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n )}\n role=\"button\"\n tabIndex={0}\n aria-label={t('messages.openMessageA11y', 'Open message from {sender}', { sender: senderLabel })}\n onClick={onClick}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick()\n }\n }}\n >\n <div className=\"flex items-center gap-3\">\n <span className={cn('w-40 flex-shrink-0 truncate text-sm md:w-56', message.unread ? 'font-semibold' : 'font-normal')}>\n {senderLabel}\n </span>\n\n <span className=\"min-w-0 flex-1 truncate text-sm text-muted-foreground\">{body}</span>\n\n <span\n className={cn('flex-shrink-0 text-xs', message.unread ? 'font-semibold text-foreground' : 'font-normal text-muted-foreground')}\n >\n {sentAtLabel}\n </span>\n </div>\n </div>\n )\n}\n\nexport default MessageListComponent\n"],
|
|
5
5
|
"mappings": ";AA6CM,SACE,KADF;AA1CN,SAAS,YAAY;AACrB,SAAS,UAAU;AAEnB,SAAS,eAAe,OAA4B;AAClD,MAAI,CAAC,SAAS,OAAO,MAAM,MAAM,QAAQ,CAAC,EAAG,QAAO;AAEpD,QAAM,MAAM,oBAAI,KAAK;AACrB,MAAI,IAAI,aAAa,MAAM,MAAM,aAAa,GAAG;AAC/C,WAAO,MAAM,mBAAmB,CAAC,GAAG,EAAE,MAAM,WAAW,QAAQ,UAAU,CAAC;AAAA,EAC5E;AAEA,SAAO,MAAM,mBAAmB,CAAC,GAAG,EAAE,OAAO,SAAS,KAAK,UAAU,CAAC;AACxE;AAEA,SAAS,cAAc,OAA8B;AACnD,QAAM,cAAc,SAAS,IAAI,KAAK,EAAE,QAAQ,QAAQ,GAAG;AAC3D,SAAO,cAAc;AACvB;AAEO,SAAS,qBAAqB,EAAE,SAAS,QAAQ,GAAyB;AAC/E,QAAM,IAAI,KAAK;AACf,QAAM,cAAc,QAAQ,cAAc;AAC1C,QAAM,OAAO,cAAc,QAAQ,IAAI;AACvC,QAAM,cAAc,eAAe,QAAQ,MAAM;AAEjD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACL,UAAU;AAAA,MACV,cAAY,EAAE,4BAA4B,8BAA8B,EAAE,QAAQ,YAAY,CAAC;AAAA,MAC/F;AAAA,MACA,WAAW,CAAC,UAAU;AACpB,YAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,gBAAM,eAAe;AACrB,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,MAEA,+BAAC,SAAI,WAAU,2BACb;AAAA,4BAAC,UAAK,WAAW,GAAG,+CAA+C,QAAQ,SAAS,kBAAkB,aAAa,GAChH,uBACH;AAAA,QAEA,oBAAC,UAAK,WAAU,yDAAyD,gBAAK;AAAA,QAE9E;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,GAAG,yBAAyB,QAAQ,SAAS,kCAAkC,mCAAmC;AAAA,YAE5H;AAAA;AAAA,QACH;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,+BAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -47,7 +47,7 @@ function MessageDetailAttachmentsSection(props) {
|
|
|
47
47
|
}) : null,
|
|
48
48
|
className: "h-11 w-11 shrink-0 overflow-hidden rounded",
|
|
49
49
|
iconClassName: "mb-0 h-4 w-4",
|
|
50
|
-
labelClassName: "text-
|
|
50
|
+
labelClassName: "text-overline"
|
|
51
51
|
}
|
|
52
52
|
),
|
|
53
53
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/messages/components/message-detail/panels/attachments-panel.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport {\n AttachmentVisualPreview,\n formatAttachmentFileSize,\n} from '@open-mercato/ui/backend/detail/AttachmentVisualPreview'\nimport {\n buildAttachmentImageUrl,\n slugifyAttachmentFileName,\n} from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport type { MessageAttachment } from '../types'\n\ntype AttachmentsPanelProps = {\n attachmentsQuery: { isLoading: boolean; error: unknown }\n attachments: MessageAttachment[] | undefined\n}\n\nexport function MessageDetailAttachmentsSection(props: AttachmentsPanelProps) {\n const t = useT()\n\n if (props.attachmentsQuery.isLoading) {\n return (\n <section className=\"space-y-3 pl-4 py-2\">\n <h2 className=\"text-base font-semibold\">{t('messages.attachedFiles', 'Attachments')}</h2>\n <p className=\"text-sm text-muted-foreground\">{t('messages.loading.attachments', 'Loading attachments...')}</p>\n </section>\n )\n }\n\n if (props.attachmentsQuery.error) {\n return (\n <section className=\"space-y-3 pl-4 py-2\">\n <h2 className=\"text-base font-semibold\">{t('messages.attachedFiles', 'Attachments')}</h2>\n <p className=\"text-sm text-destructive\">\n {props.attachmentsQuery.error instanceof Error\n ? props.attachmentsQuery.error.message\n : t('messages.errors.loadAttachmentsFailed', 'Failed to load attachments.')}\n </p>\n </section>\n )\n }\n\n if ((props.attachments ?? []).length === 0) return null\n\n return (\n <section className=\"space-y-3 pl-4 py-2\">\n <h2 className=\"text-base font-semibold\">{t('messages.attachedFiles', 'Attachments')}</h2>\n <div className=\"space-y-2\">\n {(props.attachments ?? []).map((attachment) => (\n <a\n key={attachment.id}\n href={attachment.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"flex items-center gap-3 rounded px-3 py-2 text-sm hover:bg-muted\"\n >\n <AttachmentVisualPreview\n fileName={attachment.fileName}\n mimeType={attachment.mimeType}\n thumbnailUrl={\n attachment.mimeType?.toLowerCase().startsWith('image/')\n ? buildAttachmentImageUrl(attachment.id, {\n width: 120,\n height: 120,\n slug: slugifyAttachmentFileName(attachment.fileName),\n cropType: 'cover',\n })\n : null\n }\n className=\"h-11 w-11 shrink-0 overflow-hidden rounded\"\n iconClassName=\"mb-0 h-4 w-4\"\n labelClassName=\"text-
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport {\n AttachmentVisualPreview,\n formatAttachmentFileSize,\n} from '@open-mercato/ui/backend/detail/AttachmentVisualPreview'\nimport {\n buildAttachmentImageUrl,\n slugifyAttachmentFileName,\n} from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport type { MessageAttachment } from '../types'\n\ntype AttachmentsPanelProps = {\n attachmentsQuery: { isLoading: boolean; error: unknown }\n attachments: MessageAttachment[] | undefined\n}\n\nexport function MessageDetailAttachmentsSection(props: AttachmentsPanelProps) {\n const t = useT()\n\n if (props.attachmentsQuery.isLoading) {\n return (\n <section className=\"space-y-3 pl-4 py-2\">\n <h2 className=\"text-base font-semibold\">{t('messages.attachedFiles', 'Attachments')}</h2>\n <p className=\"text-sm text-muted-foreground\">{t('messages.loading.attachments', 'Loading attachments...')}</p>\n </section>\n )\n }\n\n if (props.attachmentsQuery.error) {\n return (\n <section className=\"space-y-3 pl-4 py-2\">\n <h2 className=\"text-base font-semibold\">{t('messages.attachedFiles', 'Attachments')}</h2>\n <p className=\"text-sm text-destructive\">\n {props.attachmentsQuery.error instanceof Error\n ? props.attachmentsQuery.error.message\n : t('messages.errors.loadAttachmentsFailed', 'Failed to load attachments.')}\n </p>\n </section>\n )\n }\n\n if ((props.attachments ?? []).length === 0) return null\n\n return (\n <section className=\"space-y-3 pl-4 py-2\">\n <h2 className=\"text-base font-semibold\">{t('messages.attachedFiles', 'Attachments')}</h2>\n <div className=\"space-y-2\">\n {(props.attachments ?? []).map((attachment) => (\n <a\n key={attachment.id}\n href={attachment.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"flex items-center gap-3 rounded px-3 py-2 text-sm hover:bg-muted\"\n >\n <AttachmentVisualPreview\n fileName={attachment.fileName}\n mimeType={attachment.mimeType}\n thumbnailUrl={\n attachment.mimeType?.toLowerCase().startsWith('image/')\n ? buildAttachmentImageUrl(attachment.id, {\n width: 120,\n height: 120,\n slug: slugifyAttachmentFileName(attachment.fileName),\n cropType: 'cover',\n })\n : null\n }\n className=\"h-11 w-11 shrink-0 overflow-hidden rounded\"\n iconClassName=\"mb-0 h-4 w-4\"\n labelClassName=\"text-overline\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate\">{attachment.fileName}</p>\n <p className=\"text-xs text-muted-foreground\">\n {formatAttachmentFileSize(attachment.fileSize)}\n </p>\n </div>\n </a>\n ))}\n </div>\n </section>\n )\n}\n"],
|
|
5
5
|
"mappings": ";AAuBM,SACE,KADF;AArBN,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAQA,SAAS,gCAAgC,OAA8B;AAC5E,QAAM,IAAI,KAAK;AAEf,MAAI,MAAM,iBAAiB,WAAW;AACpC,WACE,qBAAC,aAAQ,WAAU,uBACjB;AAAA,0BAAC,QAAG,WAAU,2BAA2B,YAAE,0BAA0B,aAAa,GAAE;AAAA,MACpF,oBAAC,OAAE,WAAU,iCAAiC,YAAE,gCAAgC,wBAAwB,GAAE;AAAA,OAC5G;AAAA,EAEJ;AAEA,MAAI,MAAM,iBAAiB,OAAO;AAChC,WACE,qBAAC,aAAQ,WAAU,uBACjB;AAAA,0BAAC,QAAG,WAAU,2BAA2B,YAAE,0BAA0B,aAAa,GAAE;AAAA,MACpF,oBAAC,OAAE,WAAU,4BACV,gBAAM,iBAAiB,iBAAiB,QACrC,MAAM,iBAAiB,MAAM,UAC7B,EAAE,yCAAyC,6BAA6B,GAC9E;AAAA,OACF;AAAA,EAEJ;AAEA,OAAK,MAAM,eAAe,CAAC,GAAG,WAAW,EAAG,QAAO;AAEnD,SACE,qBAAC,aAAQ,WAAU,uBACjB;AAAA,wBAAC,QAAG,WAAU,2BAA2B,YAAE,0BAA0B,aAAa,GAAE;AAAA,IACpF,oBAAC,SAAI,WAAU,aACX,iBAAM,eAAe,CAAC,GAAG,IAAI,CAAC,eAC9B;AAAA,MAAC;AAAA;AAAA,QAEC,MAAM,WAAW;AAAA,QACjB,QAAO;AAAA,QACP,KAAI;AAAA,QACJ,WAAU;AAAA,QAEV;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,UAAU,WAAW;AAAA,cACrB,UAAU,WAAW;AAAA,cACrB,cACE,WAAW,UAAU,YAAY,EAAE,WAAW,QAAQ,IAClD,wBAAwB,WAAW,IAAI;AAAA,gBACvC,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,MAAM,0BAA0B,WAAW,QAAQ;AAAA,gBACnD,UAAU;AAAA,cACZ,CAAC,IACC;AAAA,cAEN,WAAU;AAAA,cACV,eAAc;AAAA,cACd,gBAAe;AAAA;AAAA,UACjB;AAAA,UACA,qBAAC,SAAI,WAAU,kBACb;AAAA,gCAAC,OAAE,WAAU,YAAY,qBAAW,UAAS;AAAA,YAC7C,oBAAC,OAAE,WAAU,iCACV,mCAAyB,WAAW,QAAQ,GAC/C;AAAA,aACF;AAAA;AAAA;AAAA,MA5BK,WAAW;AAAA,IA6BlB,CACD,GACH;AAAA,KACF;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -81,8 +81,8 @@ function splitLogPayload(payload) {
|
|
|
81
81
|
return { inlineEntries, nestedEntries };
|
|
82
82
|
}
|
|
83
83
|
function DetailStat({ label, value }) {
|
|
84
|
-
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-muted/
|
|
85
|
-
/* @__PURE__ */ jsx("div", { className: "text-
|
|
84
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-muted/30 px-4 py-3", children: [
|
|
85
|
+
/* @__PURE__ */ jsx("div", { className: "text-overline font-medium uppercase tracking-wide text-muted-foreground", children: label }),
|
|
86
86
|
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm font-medium", children: value })
|
|
87
87
|
] });
|
|
88
88
|
}
|
|
@@ -445,8 +445,8 @@ function PaymentTransactionsPage() {
|
|
|
445
445
|
[t("payment_gateways.transactions.columns.updatedAt", "Updated at"), formatDateTime(detail.transaction.updatedAt)],
|
|
446
446
|
[t("payment_gateways.transactions.columns.lastWebhookAt", "Last webhook"), formatDateTime(detail.transaction.lastWebhookAt)],
|
|
447
447
|
[t("payment_gateways.transactions.columns.lastPolledAt", "Last poll"), formatDateTime(detail.transaction.lastPolledAt)]
|
|
448
|
-
].map(([label, value]) => /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-muted/
|
|
449
|
-
/* @__PURE__ */ jsx("dt", { className: "text-
|
|
448
|
+
].map(([label, value]) => /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-muted/30 px-4 py-3", children: [
|
|
449
|
+
/* @__PURE__ */ jsx("dt", { className: "text-overline font-medium uppercase tracking-wide text-muted-foreground", children: label }),
|
|
450
450
|
/* @__PURE__ */ jsx("dd", { className: "mt-1 break-all text-sm", children: value })
|
|
451
451
|
] }, label)) })
|
|
452
452
|
] }),
|
|
@@ -456,7 +456,7 @@ function PaymentTransactionsPage() {
|
|
|
456
456
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: t("payment_gateways.transactions.detail.webhooks", "Webhook activity") })
|
|
457
457
|
] }),
|
|
458
458
|
detail.transaction.webhookLog && detail.transaction.webhookLog.length > 0 ? /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
|
|
459
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/
|
|
459
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/50", children: [
|
|
460
460
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-2 text-left font-medium", children: t("payment_gateways.transactions.columns.eventType", "Event") }),
|
|
461
461
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-2 text-left font-medium", children: t("payment_gateways.transactions.columns.status", "Status") }),
|
|
462
462
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-2 text-left font-medium", children: t("payment_gateways.transactions.columns.processed", "Processed") }),
|
|
@@ -473,7 +473,7 @@ function PaymentTransactionsPage() {
|
|
|
473
473
|
/* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
474
474
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: t("payment_gateways.transactions.detail.logs", "Gateway logs") }),
|
|
475
475
|
detail.logs.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("payment_gateways.transactions.detail.logsEmpty", "No transaction-scoped logs are available yet.") }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
|
|
476
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/
|
|
476
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/50", children: [
|
|
477
477
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-2 text-left font-medium", children: t("payment_gateways.transactions.columns.time", "Time") }),
|
|
478
478
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-2 text-left font-medium", children: t("payment_gateways.transactions.columns.level", "Level") }),
|
|
479
479
|
/* @__PURE__ */ jsx("th", { className: "px-4 py-2 text-left font-medium", children: t("payment_gateways.transactions.columns.message", "Message") })
|
|
@@ -508,13 +508,13 @@ function PaymentTransactionsPage() {
|
|
|
508
508
|
}
|
|
509
509
|
) })
|
|
510
510
|
] }),
|
|
511
|
-
isExpanded ? /* @__PURE__ */ jsx("tr", { className: "border-b bg-muted/
|
|
512
|
-
metadataEntries.length > 0 ? /* @__PURE__ */ jsx("dl", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3", children: metadataEntries.map(([label, value]) => /* @__PURE__ */ jsxs("div", { className: "rounded-md border bg-muted/
|
|
513
|
-
/* @__PURE__ */ jsx("dt", { className: "text-
|
|
511
|
+
isExpanded ? /* @__PURE__ */ jsx("tr", { className: "border-b bg-muted/30 last:border-0", children: /* @__PURE__ */ jsx("td", { colSpan: 3, className: "px-4 py-4", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4 rounded-lg border bg-card p-4", children: [
|
|
512
|
+
metadataEntries.length > 0 ? /* @__PURE__ */ jsx("dl", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3", children: metadataEntries.map(([label, value]) => /* @__PURE__ */ jsxs("div", { className: "rounded-md border bg-muted/30 px-3 py-2", children: [
|
|
513
|
+
/* @__PURE__ */ jsx("dt", { className: "text-overline font-medium uppercase tracking-wide text-muted-foreground", children: label }),
|
|
514
514
|
/* @__PURE__ */ jsx("dd", { className: "mt-1 break-all text-sm", children: value })
|
|
515
515
|
] }, label)) }) : null,
|
|
516
|
-
inlineEntries.length > 0 ? /* @__PURE__ */ jsx("dl", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3", children: inlineEntries.map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "rounded-md border bg-muted/
|
|
517
|
-
/* @__PURE__ */ jsx("dt", { className: "text-
|
|
516
|
+
inlineEntries.length > 0 ? /* @__PURE__ */ jsx("dl", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3", children: inlineEntries.map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "rounded-md border bg-muted/30 px-3 py-2", children: [
|
|
517
|
+
/* @__PURE__ */ jsx("dt", { className: "text-overline font-medium uppercase tracking-wide text-muted-foreground", children: formatLogDetailLabel(key) }),
|
|
518
518
|
/* @__PURE__ */ jsx("dd", { className: "mt-1 break-words text-sm", children: formatLogPrimitiveValue(value) })
|
|
519
519
|
] }, key)) }) : null,
|
|
520
520
|
nestedEntries.map(([key, value]) => /* @__PURE__ */ jsx(
|