@vendure/dashboard 3.4.3-master-202509260228 → 3.5.0-minor-202510012036

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/README.md +4 -0
  2. package/dist/plugin/api/api-extensions.js +11 -14
  3. package/dist/plugin/api/metrics.resolver.d.ts +2 -2
  4. package/dist/plugin/api/metrics.resolver.js +2 -2
  5. package/dist/plugin/config/metrics-strategies.d.ts +9 -9
  6. package/dist/plugin/config/metrics-strategies.js +6 -6
  7. package/dist/plugin/constants.d.ts +2 -0
  8. package/dist/plugin/constants.js +3 -1
  9. package/dist/plugin/dashboard.plugin.js +13 -0
  10. package/dist/plugin/service/metrics.service.d.ts +3 -3
  11. package/dist/plugin/service/metrics.service.js +37 -53
  12. package/dist/plugin/types.d.ts +9 -12
  13. package/dist/plugin/types.js +7 -11
  14. package/dist/vite/vite-plugin-config.js +13 -9
  15. package/dist/vite/vite-plugin-translations.d.ts +22 -0
  16. package/dist/vite/vite-plugin-translations.js +66 -0
  17. package/dist/vite/vite-plugin-vendure-dashboard.js +10 -8
  18. package/lingui.config.js +25 -2
  19. package/package.json +159 -156
  20. package/src/app/app-providers.tsx +0 -4
  21. package/src/app/common/delete-bulk-action.tsx +6 -5
  22. package/src/app/common/duplicate-bulk-action.tsx +4 -5
  23. package/src/app/common/duplicate-entity-dialog.tsx +1 -1
  24. package/src/app/common/set-document-direction.ts +7 -0
  25. package/src/app/main.tsx +50 -17
  26. package/src/app/routes/_authenticated/_administrators/administrators.tsx +8 -6
  27. package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +17 -6
  28. package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +2 -2
  29. package/src/app/routes/_authenticated/_assets/assets.tsx +1 -1
  30. package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +4 -4
  31. package/src/app/routes/_authenticated/_assets/components/asset-bulk-actions.tsx +8 -6
  32. package/src/app/routes/_authenticated/_assets/components/asset-tag-filter.tsx +1 -1
  33. package/src/app/routes/_authenticated/_assets/components/asset-tags-editor.tsx +1 -1
  34. package/src/app/routes/_authenticated/_assets/components/manage-tags-dialog.tsx +3 -8
  35. package/src/app/routes/_authenticated/_channels/channels.tsx +3 -6
  36. package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +5 -5
  37. package/src/app/routes/_authenticated/_collections/collections.tsx +10 -6
  38. package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +16 -5
  39. package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +1 -1
  40. package/src/app/routes/_authenticated/_collections/components/collection-contents-sheet.tsx +1 -1
  41. package/src/app/routes/_authenticated/_collections/components/move-collections-dialog.tsx +6 -6
  42. package/src/app/routes/_authenticated/_countries/countries.graphql.ts +2 -0
  43. package/src/app/routes/_authenticated/_countries/countries.tsx +2 -3
  44. package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +4 -4
  45. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-sheet.tsx +1 -1
  46. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-table.tsx +4 -4
  47. package/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx +2 -4
  48. package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +13 -6
  49. package/src/app/routes/_authenticated/_customers/components/customer-address-card.tsx +8 -8
  50. package/src/app/routes/_authenticated/_customers/components/customer-address-form.tsx +3 -3
  51. package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-container.tsx +1 -1
  52. package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-utils.tsx +1 -1
  53. package/src/app/routes/_authenticated/_customers/components/customer-history/default-customer-history-components.tsx +1 -1
  54. package/src/app/routes/_authenticated/_customers/components/customer-history/use-customer-history.ts +1 -1
  55. package/src/app/routes/_authenticated/_customers/components/customer-status-badge.tsx +1 -1
  56. package/src/app/routes/_authenticated/_customers/customers.graphql.ts +4 -0
  57. package/src/app/routes/_authenticated/_customers/customers.tsx +23 -11
  58. package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +10 -8
  59. package/src/app/routes/_authenticated/_facets/components/edit-facet-value.tsx +1 -1
  60. package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +6 -5
  61. package/src/app/routes/_authenticated/_facets/components/facet-values-sheet.tsx +1 -1
  62. package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +1 -1
  63. package/src/app/routes/_authenticated/_facets/facets.tsx +5 -5
  64. package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +7 -5
  65. package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +18 -6
  66. package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +5 -5
  67. package/src/app/routes/_authenticated/_orders/components/add-manual-payment-dialog.tsx +19 -21
  68. package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +1 -1
  69. package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +22 -22
  70. package/src/app/routes/_authenticated/_orders/components/fulfill-order-dialog.tsx +6 -6
  71. package/src/app/routes/_authenticated/_orders/components/fulfillment-details.tsx +15 -9
  72. package/src/app/routes/_authenticated/_orders/components/order-address.tsx +1 -1
  73. package/src/app/routes/_authenticated/_orders/components/order-detail-shared.tsx +11 -9
  74. package/src/app/routes/_authenticated/_orders/components/order-history/default-order-history-components.tsx +1 -1
  75. package/src/app/routes/_authenticated/_orders/components/order-history/order-history-container.tsx +1 -1
  76. package/src/app/routes/_authenticated/_orders/components/order-history/order-history-utils.tsx +1 -1
  77. package/src/app/routes/_authenticated/_orders/components/order-history/use-order-history.ts +1 -1
  78. package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +1 -1
  79. package/src/app/routes/_authenticated/_orders/components/order-modification-preview-dialog.tsx +4 -4
  80. package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +1 -1
  81. package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +27 -27
  82. package/src/app/routes/_authenticated/_orders/components/order-table.tsx +2 -2
  83. package/src/app/routes/_authenticated/_orders/components/order-tax-summary.tsx +1 -1
  84. package/src/app/routes/_authenticated/_orders/components/payment-details.tsx +26 -20
  85. package/src/app/routes/_authenticated/_orders/components/seller-orders-card.tsx +3 -1
  86. package/src/app/routes/_authenticated/_orders/components/settle-refund-dialog.tsx +6 -6
  87. package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +1 -1
  88. package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +1 -1
  89. package/src/app/routes/_authenticated/_orders/components/use-transition-order-to-state.tsx +3 -2
  90. package/src/app/routes/_authenticated/_orders/orders.tsx +5 -9
  91. package/src/app/routes/_authenticated/_orders/orders_.$aggregateOrderId_.seller-orders.$sellerOrderId.tsx +1 -1
  92. package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +1 -1
  93. package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +4 -4
  94. package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +17 -17
  95. package/src/app/routes/_authenticated/_orders/utils/order-detail-loaders.tsx +1 -1
  96. package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +5 -6
  97. package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +13 -6
  98. package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +1 -1
  99. package/src/app/routes/_authenticated/_product-variants/components/variant-price-detail.tsx +1 -1
  100. package/src/app/routes/_authenticated/_product-variants/product-variants.graphql.ts +10 -0
  101. package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +9 -2
  102. package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +13 -6
  103. package/src/app/routes/_authenticated/_products/components/add-option-group-dialog.tsx +5 -5
  104. package/src/app/routes/_authenticated/_products/components/add-product-variant-dialog.tsx +5 -5
  105. package/src/app/routes/_authenticated/_products/components/assign-facet-values-dialog.tsx +5 -4
  106. package/src/app/routes/_authenticated/_products/components/create-product-options-dialog.tsx +9 -12
  107. package/src/app/routes/_authenticated/_products/components/create-product-variants-dialog.tsx +1 -1
  108. package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +4 -4
  109. package/src/app/routes/_authenticated/_products/components/option-groups-editor.tsx +1 -1
  110. package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +1 -1
  111. package/src/app/routes/_authenticated/_products/components/product-option-group-badge.tsx +19 -0
  112. package/src/app/routes/_authenticated/_products/components/product-option-select.tsx +3 -3
  113. package/src/app/routes/_authenticated/_products/components/product-options-table.tsx +114 -0
  114. package/src/app/routes/_authenticated/_products/product-option-groups.graphql.ts +103 -0
  115. package/src/app/routes/_authenticated/_products/products.graphql.ts +44 -32
  116. package/src/app/routes/_authenticated/_products/products.tsx +34 -5
  117. package/src/app/routes/_authenticated/_products/products_.$id.tsx +29 -12
  118. package/src/app/routes/_authenticated/_products/products_.$id_.variants.tsx +11 -11
  119. package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$id.tsx +177 -0
  120. package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$productOptionGroupId.options_.$id.tsx +208 -0
  121. package/src/app/routes/_authenticated/_profile/profile.tsx +4 -4
  122. package/src/app/routes/_authenticated/_promotions/promotions.tsx +2 -4
  123. package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +16 -9
  124. package/src/app/routes/_authenticated/_roles/components/permissions-table-grid.tsx +1 -1
  125. package/src/app/routes/_authenticated/_roles/roles.tsx +3 -6
  126. package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +4 -6
  127. package/src/app/routes/_authenticated/_sellers/sellers.tsx +3 -4
  128. package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +4 -4
  129. package/src/app/routes/_authenticated/_shipping-methods/components/price-display.tsx +5 -5
  130. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-test-result-wrapper.tsx +1 -1
  131. package/src/app/routes/_authenticated/_shipping-methods/components/test-address-form.tsx +11 -11
  132. package/src/app/routes/_authenticated/_shipping-methods/components/test-order-builder.tsx +1 -1
  133. package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-result.tsx +8 -8
  134. package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-sheet.tsx +1 -1
  135. package/src/app/routes/_authenticated/_shipping-methods/components/test-single-method-result.tsx +8 -8
  136. package/src/app/routes/_authenticated/_shipping-methods/components/test-single-shipping-method-sheet.tsx +4 -4
  137. package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +2 -3
  138. package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +2 -2
  139. package/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx +3 -4
  140. package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +13 -6
  141. package/src/app/routes/_authenticated/_system/healthchecks.tsx +10 -4
  142. package/src/app/routes/_authenticated/_system/job-queue.tsx +10 -13
  143. package/src/app/routes/_authenticated/_system/scheduled-tasks.tsx +18 -16
  144. package/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx +2 -4
  145. package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +13 -6
  146. package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +8 -12
  147. package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +6 -4
  148. package/src/app/routes/_authenticated/_zones/components/zone-countries-sheet.tsx +4 -1
  149. package/src/app/routes/_authenticated/_zones/zones.tsx +4 -4
  150. package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +8 -5
  151. package/src/app/routes/_authenticated/index.tsx +46 -25
  152. package/src/app/styles.css +4 -0
  153. package/src/i18n/common-strings.ts +111 -0
  154. package/src/i18n/locales/ar.po +4777 -0
  155. package/src/i18n/locales/cs.po +4777 -0
  156. package/src/i18n/locales/de.po +4299 -1101
  157. package/src/i18n/locales/en.po +3857 -659
  158. package/src/i18n/locales/es.po +4777 -0
  159. package/src/i18n/locales/fa.po +4777 -0
  160. package/src/i18n/locales/fr.po +4777 -0
  161. package/src/i18n/locales/he.po +4777 -0
  162. package/src/i18n/locales/hr.po +4777 -0
  163. package/src/i18n/locales/it.po +4777 -0
  164. package/src/i18n/locales/ja.po +4777 -0
  165. package/src/i18n/locales/ko.po +4628 -0
  166. package/src/i18n/locales/nb.po +4777 -0
  167. package/src/i18n/locales/ne.po +4777 -0
  168. package/src/i18n/locales/nl.po +4628 -0
  169. package/src/i18n/locales/pl.po +4777 -0
  170. package/src/i18n/locales/pt_BR.po +4777 -0
  171. package/src/i18n/locales/pt_PT.po +4777 -0
  172. package/src/i18n/locales/ru.po +4777 -0
  173. package/src/i18n/locales/sv.po +4777 -0
  174. package/src/i18n/locales/tr.po +4777 -0
  175. package/src/i18n/locales/uk.po +4777 -0
  176. package/src/i18n/locales/zh_Hans.po +4777 -0
  177. package/src/i18n/locales/zh_Hant.po +4777 -0
  178. package/src/lib/components/data-display/json.tsx +16 -1
  179. package/src/lib/components/data-input/combination-mode-input.tsx +1 -1
  180. package/src/lib/components/data-input/custom-field-list-input.tsx +11 -7
  181. package/src/lib/components/data-input/customer-group-input.tsx +27 -33
  182. package/src/lib/components/data-input/datetime-input.tsx +40 -1
  183. package/src/lib/components/data-input/default-relation-input.tsx +5 -4
  184. package/src/lib/components/data-input/index.ts +3 -0
  185. package/src/lib/components/data-input/product-multi-selector-input.tsx +14 -14
  186. package/src/lib/components/data-input/relation-selector.tsx +1 -1
  187. package/src/lib/components/data-input/select-with-options.tsx +1 -1
  188. package/src/lib/components/data-input/slug-input.tsx +290 -0
  189. package/src/lib/components/data-table/add-filter-menu.tsx +17 -10
  190. package/src/lib/components/data-table/data-table-bulk-action-item.tsx +45 -8
  191. package/src/lib/components/data-table/data-table-bulk-actions.tsx +4 -4
  192. package/src/lib/components/data-table/data-table-column-header.tsx +13 -8
  193. package/src/lib/components/data-table/data-table-context.tsx +91 -0
  194. package/src/lib/components/data-table/data-table-faceted-filter.tsx +2 -1
  195. package/src/lib/components/data-table/data-table-filter-badge.tsx +9 -5
  196. package/src/lib/components/data-table/data-table-filter-dialog.tsx +1 -1
  197. package/src/lib/components/data-table/data-table-utils.ts +21 -4
  198. package/src/lib/components/data-table/data-table-view-options.tsx +21 -10
  199. package/src/lib/components/data-table/data-table.tsx +146 -94
  200. package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +4 -4
  201. package/src/lib/components/data-table/global-views-bar.tsx +97 -0
  202. package/src/lib/components/data-table/global-views-sheet.tsx +11 -0
  203. package/src/lib/components/data-table/human-readable-operator.tsx +1 -1
  204. package/src/lib/components/data-table/manage-global-views-button.tsx +26 -0
  205. package/src/lib/components/data-table/my-views-button.tsx +47 -0
  206. package/src/lib/components/data-table/refresh-button.tsx +12 -3
  207. package/src/lib/components/data-table/save-view-button.tsx +41 -0
  208. package/src/lib/components/data-table/save-view-dialog.tsx +113 -0
  209. package/src/lib/components/data-table/use-generated-columns.tsx +13 -8
  210. package/src/lib/components/data-table/user-views-sheet.tsx +11 -0
  211. package/src/lib/components/data-table/views-sheet.tsx +305 -0
  212. package/src/lib/components/date-range-picker.tsx +186 -0
  213. package/src/lib/components/layout/app-sidebar.tsx +3 -1
  214. package/src/lib/components/layout/channel-switcher.tsx +8 -10
  215. package/src/lib/components/layout/dev-mode-indicator.tsx +1 -1
  216. package/src/lib/components/layout/generated-breadcrumbs.tsx +10 -8
  217. package/src/lib/components/layout/language-dialog.tsx +34 -13
  218. package/src/lib/components/layout/manage-languages-dialog.tsx +1 -1
  219. package/src/lib/components/layout/nav-main.tsx +23 -13
  220. package/src/lib/components/layout/nav-user.tsx +19 -23
  221. package/src/lib/components/login/login-form.tsx +1 -1
  222. package/src/lib/components/shared/asset/asset-bulk-actions.tsx +4 -4
  223. package/src/lib/components/shared/asset/asset-focal-point-editor.tsx +1 -1
  224. package/src/lib/components/shared/asset/asset-gallery.tsx +15 -14
  225. package/src/lib/components/shared/assign-to-channel-bulk-action.tsx +11 -11
  226. package/src/lib/components/shared/assign-to-channel-dialog.tsx +6 -5
  227. package/src/lib/components/shared/channel-code-label.tsx +1 -1
  228. package/src/lib/components/shared/channel-selector.tsx +4 -4
  229. package/src/lib/components/shared/configurable-operation-multi-selector.tsx +16 -14
  230. package/src/lib/components/shared/configurable-operation-selector.tsx +1 -1
  231. package/src/lib/components/shared/confirmation-dialog.tsx +8 -8
  232. package/src/lib/components/shared/country-selector.tsx +1 -1
  233. package/src/lib/components/shared/currency-selector.tsx +4 -4
  234. package/src/lib/components/shared/custom-fields-form.tsx +8 -24
  235. package/src/lib/components/shared/customer-address-form.tsx +3 -3
  236. package/src/lib/components/shared/customer-group-selector.tsx +1 -1
  237. package/src/lib/components/shared/customer-selector.tsx +1 -1
  238. package/src/lib/components/shared/error-page.tsx +1 -1
  239. package/src/lib/components/shared/facet-value-selector.tsx +10 -10
  240. package/src/lib/components/shared/history-timeline/history-note-checkbox.tsx +1 -1
  241. package/src/lib/components/shared/history-timeline/history-note-editor.tsx +1 -1
  242. package/src/lib/components/shared/history-timeline/history-note-entry.tsx +1 -1
  243. package/src/lib/components/shared/language-selector.tsx +4 -4
  244. package/src/lib/components/shared/navigation-confirmation.tsx +1 -1
  245. package/src/lib/components/shared/paginated-list-data-table.tsx +64 -34
  246. package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +6 -5
  247. package/src/lib/components/shared/rich-text-editor/image-dialog.tsx +1 -1
  248. package/src/lib/components/shared/rich-text-editor/link-dialog.tsx +1 -1
  249. package/src/lib/components/shared/rich-text-editor/responsive-toolbar.tsx +1 -1
  250. package/src/lib/components/shared/rich-text-editor/table-edit-icons.tsx +1 -1
  251. package/src/lib/components/shared/role-code-label.tsx +1 -1
  252. package/src/lib/components/shared/role-selector.tsx +4 -4
  253. package/src/lib/components/shared/seller-selector.tsx +1 -1
  254. package/src/lib/components/shared/stock-level-label.tsx +3 -5
  255. package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +3 -1
  256. package/src/lib/components/shared/tax-category-selector.tsx +1 -1
  257. package/src/lib/components/shared/translatable-form-field.tsx +15 -15
  258. package/src/lib/components/shared/zone-selector.tsx +1 -1
  259. package/src/lib/components/ui/button.tsx +1 -1
  260. package/src/lib/framework/dashboard-widget/base-widget.tsx +11 -9
  261. package/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx +35 -6
  262. package/src/lib/framework/dashboard-widget/metrics-widget/index.tsx +18 -12
  263. package/src/lib/framework/dashboard-widget/metrics-widget/metrics-widget.graphql.ts +9 -3
  264. package/src/lib/framework/dashboard-widget/orders-summary/index.tsx +26 -79
  265. package/src/lib/framework/dashboard-widget/widget-filters-context.tsx +35 -0
  266. package/src/lib/framework/defaults.ts +34 -63
  267. package/src/lib/framework/document-introspection/add-custom-fields.spec.ts +319 -9
  268. package/src/lib/framework/document-introspection/add-custom-fields.ts +60 -31
  269. package/src/lib/framework/document-introspection/get-document-structure.spec.ts +1 -159
  270. package/src/lib/framework/document-introspection/include-only-selected-list-fields.spec.ts +1840 -0
  271. package/src/lib/framework/document-introspection/include-only-selected-list-fields.ts +940 -0
  272. package/src/lib/framework/document-introspection/testing-utils.ts +161 -0
  273. package/src/lib/framework/extension-api/display-component-extensions.tsx +2 -0
  274. package/src/lib/framework/extension-api/types/data-table.ts +62 -4
  275. package/src/lib/framework/extension-api/types/navigation.ts +16 -0
  276. package/src/lib/framework/form-engine/utils.ts +34 -0
  277. package/src/lib/framework/layout-engine/page-layout.tsx +36 -36
  278. package/src/lib/framework/page/detail-page.tsx +10 -10
  279. package/src/lib/framework/page/list-page.tsx +289 -4
  280. package/src/lib/framework/page/use-extended-router.tsx +101 -34
  281. package/src/lib/graphql/api.ts +6 -2
  282. package/src/lib/graphql/graphql-env.d.ts +38 -26
  283. package/src/lib/hooks/use-display-locale.ts +40 -0
  284. package/src/lib/hooks/use-dynamic-translations.ts +46 -0
  285. package/src/lib/hooks/use-extended-detail-query.ts +1 -1
  286. package/src/lib/hooks/use-extended-list-query.ts +6 -1
  287. package/src/lib/hooks/use-local-format.ts +15 -1
  288. package/src/lib/hooks/use-saved-views.ts +230 -0
  289. package/src/lib/hooks/use-ui-language-loader.ts +30 -0
  290. package/src/lib/index.ts +15 -0
  291. package/src/lib/lib/load-i18n-messages.ts +17 -0
  292. package/src/lib/lib/trans.tsx +15 -11
  293. package/src/lib/providers/i18n-provider.tsx +7 -14
  294. package/src/lib/types/saved-views.ts +39 -0
  295. package/src/lib/utils/saved-views-utils.ts +40 -0
@@ -1,3 +1,4 @@
1
+ import { PageBreadcrumb } from '@/vdb/components/layout/generated-breadcrumbs.js';
1
2
  import { ErrorPage } from '@/vdb/components/shared/error-page.js';
2
3
  import { FormFieldWrapper } from '@/vdb/components/shared/form-field-wrapper.js';
3
4
  import { PermissionGuard } from '@/vdb/components/shared/permission-guard.js';
@@ -17,7 +18,7 @@ import {
17
18
  } from '@/vdb/framework/layout-engine/page-layout.js';
18
19
  import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
19
20
  import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
20
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
21
+ import { Trans, useLingui } from '@lingui/react/macro';
21
22
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
22
23
  import { toast } from 'sonner';
23
24
  import {
@@ -25,7 +26,6 @@ import {
25
26
  facetValueDetailDocument,
26
27
  updateFacetValueDocument,
27
28
  } from './facets.graphql.js';
28
- import { PageBreadcrumb } from '@/vdb/components/layout/generated-breadcrumbs.js';
29
29
 
30
30
  const pageId = 'facet-value-detail';
31
31
 
@@ -52,7 +52,7 @@ function FacetValueDetailPage() {
52
52
  const params = Route.useParams();
53
53
  const navigate = useNavigate();
54
54
  const creatingNewEntity = params.id === NEW_ENTITY_PATH;
55
- const { i18n } = useLingui();
55
+ const { t } = useLingui();
56
56
 
57
57
  const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
58
58
  pageId,
@@ -81,7 +81,9 @@ function FacetValueDetailPage() {
81
81
  },
82
82
  params: { id: params.id },
83
83
  onSuccess: async data => {
84
- toast(i18n.t(creatingNewEntity ? 'Successfully created facet value' : 'Successfully updated facet value'));
84
+ toast(
85
+ creatingNewEntity ? t`Successfully created facet value` : t`Successfully updated facet value`,
86
+ );
85
87
  resetForm();
86
88
  const created = Array.isArray(data) ? data[0] : data;
87
89
  if (creatingNewEntity && created) {
@@ -89,7 +91,7 @@ function FacetValueDetailPage() {
89
91
  }
90
92
  },
91
93
  onError: err => {
92
- toast(i18n.t(creatingNewEntity ? 'Failed to create facet value' : 'Failed to update facet value'), {
94
+ toast(creatingNewEntity ? t`Failed to create facet value` : t`Failed to update facet value`, {
93
95
  description: err instanceof Error ? err.message : 'Unknown error',
94
96
  });
95
97
  },
@@ -1,3 +1,4 @@
1
+ import { SlugInput } from '@/vdb/components/data-input/index.js';
1
2
  import { ErrorPage } from '@/vdb/components/shared/error-page.js';
2
3
  import { FormFieldWrapper } from '@/vdb/components/shared/form-field-wrapper.js';
3
4
  import { PermissionGuard } from '@/vdb/components/shared/permission-guard.js';
@@ -18,7 +19,7 @@ import {
18
19
  } from '@/vdb/framework/layout-engine/page-layout.js';
19
20
  import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
20
21
  import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
21
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
22
+ import { Trans, useLingui } from '@lingui/react/macro';
22
23
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
23
24
  import { toast } from 'sonner';
24
25
  import { FacetValuesTable } from './components/facet-values-table.js';
@@ -32,7 +33,10 @@ export const Route = createFileRoute('/_authenticated/_facets/facets_/$id')({
32
33
  pageId,
33
34
  queryDocument: facetDetailDocument,
34
35
  breadcrumb(isNew, entity) {
35
- return [{ path: '/facets', label: <Trans>Facets</Trans> }, isNew ? <Trans>New facet</Trans> : entity?.name];
36
+ return [
37
+ { path: '/facets', label: <Trans>Facets</Trans> },
38
+ isNew ? <Trans>New facet</Trans> : entity?.name,
39
+ ];
36
40
  },
37
41
  }),
38
42
  errorComponent: ({ error }) => <ErrorPage message={error.message} />,
@@ -42,7 +46,7 @@ function FacetDetailPage() {
42
46
  const params = Route.useParams();
43
47
  const navigate = useNavigate();
44
48
  const creatingNewEntity = params.id === NEW_ENTITY_PATH;
45
- const { i18n } = useLingui();
49
+ const { t } = useLingui();
46
50
 
47
51
  const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
48
52
  pageId,
@@ -72,14 +76,14 @@ function FacetDetailPage() {
72
76
  },
73
77
  params: { id: params.id },
74
78
  onSuccess: async data => {
75
- toast(i18n.t(creatingNewEntity ? 'Successfully created facet' : 'Successfully updated facet'));
79
+ toast(creatingNewEntity ? t`Successfully created facet` : t`Successfully updated facet`);
76
80
  resetForm();
77
81
  if (creatingNewEntity) {
78
82
  await navigate({ to: `../$id`, params: { id: data.id } });
79
83
  }
80
84
  },
81
85
  onError: err => {
82
- toast(i18n.t(creatingNewEntity ? 'Failed to create facet' : 'Failed to update facet'), {
86
+ toast(creatingNewEntity ? t`Failed to create facet` : t`Failed to update facet`, {
83
87
  description: err instanceof Error ? err.message : 'Unknown error',
84
88
  });
85
89
  },
@@ -124,7 +128,15 @@ function FacetDetailPage() {
124
128
  control={form.control}
125
129
  name="code"
126
130
  label={<Trans>Code</Trans>}
127
- render={({ field }) => <Input {...field} />}
131
+ render={({ field }) => (
132
+ <SlugInput
133
+ fieldName="code"
134
+ watchFieldName="name"
135
+ entityName="Facet"
136
+ entityId={entity?.id}
137
+ {...field}
138
+ />
139
+ )}
128
140
  />
129
141
  </DetailFormGrid>
130
142
  </PageBlock>
@@ -19,7 +19,7 @@ import {
19
19
  PageTitle,
20
20
  } from '@/vdb/framework/layout-engine/page-layout.js';
21
21
  import { getDetailQueryOptions, useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
22
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
22
+ import { Trans, useLingui } from '@lingui/react/macro';
23
23
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
24
24
  import { toast } from 'sonner';
25
25
  import { globalSettingsDocument, updateGlobalSettingsDocument } from './global-settings.graphql.js';
@@ -48,7 +48,7 @@ function GlobalSettingsPage() {
48
48
  const params = Route.useParams();
49
49
  const navigate = useNavigate();
50
50
  const creatingNewEntity = params.id === NEW_ENTITY_PATH;
51
- const { i18n } = useLingui();
51
+ const { t } = useLingui();
52
52
 
53
53
  const { form, submitHandler, entity, isPending } = useDetailPage({
54
54
  queryDocument: globalSettingsDocument,
@@ -67,19 +67,19 @@ function GlobalSettingsPage() {
67
67
  params: { id: 'undefined' },
68
68
  onSuccess: async data => {
69
69
  if (data.__typename === 'GlobalSettings') {
70
- toast(i18n.t('Successfully updated global settings'));
70
+ toast(t`Successfully updated global settings`);
71
71
  form.reset(form.getValues());
72
72
  if (creatingNewEntity) {
73
73
  await navigate({ to: `../$id`, params: { id: data.id } });
74
74
  }
75
75
  } else {
76
- toast(i18n.t('Failed to update global settings'), {
76
+ toast(t`Failed to update global settings`, {
77
77
  description: data.message,
78
78
  });
79
79
  }
80
80
  },
81
81
  onError: err => {
82
- toast(i18n.t('Failed to update global settings'), {
82
+ toast(t`Failed to update global settings`, {
83
83
  description: err instanceof Error ? err.message : 'Unknown error',
84
84
  });
85
85
  },
@@ -16,15 +16,12 @@ import { Form } from '@/vdb/components/ui/form.js';
16
16
  import { Input } from '@/vdb/components/ui/input.js';
17
17
  import { api } from '@/vdb/graphql/api.js';
18
18
  import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
19
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
19
+ import { Trans, useLingui } from '@lingui/react/macro';
20
20
  import { useMutation } from '@tanstack/react-query';
21
21
  import { useState } from 'react';
22
22
  import { useForm } from 'react-hook-form';
23
23
  import { toast } from 'sonner';
24
- import {
25
- addManualPaymentToOrderDocument,
26
- paymentMethodsDocument
27
- } from '../orders.graphql.js';
24
+ import { addManualPaymentToOrderDocument, paymentMethodsDocument } from '../orders.graphql.js';
28
25
  import { Order } from '../utils/order-types.js';
29
26
  import { calculateOutstandingPaymentAmount } from '../utils/order-utils.js';
30
27
 
@@ -39,7 +36,7 @@ interface FormData {
39
36
  }
40
37
 
41
38
  export function AddManualPaymentDialog({ order, onSuccess }: Readonly<AddManualPaymentDialogProps>) {
42
- const { i18n } = useLingui();
39
+ const { t } = useLingui();
43
40
  const { formatCurrency } = useLocalFormat();
44
41
  const [isSubmitting, setIsSubmitting] = useState(false);
45
42
  const [open, setOpen] = useState(false);
@@ -49,16 +46,16 @@ export function AddManualPaymentDialog({ order, onSuccess }: Readonly<AddManualP
49
46
  onSuccess: (result: any) => {
50
47
  const { addManualPaymentToOrder } = result;
51
48
  if (addManualPaymentToOrder.__typename === 'Order') {
52
- toast(i18n.t('Successfully added payment to order'));
49
+ toast(t`Successfully added payment to order`);
53
50
  onSuccess?.();
54
51
  } else {
55
- toast(i18n.t('Failed to add payment'), {
52
+ toast(t`Failed to add payment`, {
56
53
  description: addManualPaymentToOrder.message,
57
54
  });
58
55
  }
59
56
  },
60
57
  onError: error => {
61
- toast(i18n.t('Failed to add payment'), {
58
+ toast(t`Failed to add payment`, {
62
59
  description: error instanceof Error ? error.message : 'Unknown error',
63
60
  });
64
61
  },
@@ -86,7 +83,7 @@ export function AddManualPaymentDialog({ order, onSuccess }: Readonly<AddManualP
86
83
  setOpen(false);
87
84
  form.reset();
88
85
  } catch (error) {
89
- toast(i18n.t('Failed to add payment'), {
86
+ toast(t`Failed to add payment`, {
90
87
  description: error instanceof Error ? error.message : 'Unknown error',
91
88
  });
92
89
  } finally {
@@ -107,7 +104,7 @@ export function AddManualPaymentDialog({ order, onSuccess }: Readonly<AddManualP
107
104
  listQuery: paymentMethodsDocument,
108
105
  idKey: 'code',
109
106
  labelKey: 'name',
110
- placeholder: i18n.t('Search payment methods...'),
107
+ placeholder: t`Search payment methods...`,
111
108
  multiple: false,
112
109
  label: (method: any) => `${method.name} (${method.code})`,
113
110
  });
@@ -136,15 +133,18 @@ export function AddManualPaymentDialog({ order, onSuccess }: Readonly<AddManualP
136
133
  </DialogDescription>
137
134
  </DialogHeader>
138
135
  <Form {...form}>
139
- <form onSubmit={e => {
140
- e.stopPropagation();
141
- form.handleSubmit(handleSubmit)(e);
142
- }} className="space-y-4">
136
+ <form
137
+ onSubmit={e => {
138
+ e.stopPropagation();
139
+ form.handleSubmit(handleSubmit)(e);
140
+ }}
141
+ className="space-y-4"
142
+ >
143
143
  <FormFieldWrapper
144
144
  control={form.control}
145
145
  name="method"
146
146
  label={<Trans>Payment method</Trans>}
147
- rules={{ required: i18n.t('Payment method is required') }}
147
+ rules={{ required: t`Payment method is required` }}
148
148
  render={({ field }) => (
149
149
  <RelationSelector
150
150
  config={paymentMethodSelectorConfig}
@@ -158,9 +158,9 @@ export function AddManualPaymentDialog({ order, onSuccess }: Readonly<AddManualP
158
158
  control={form.control}
159
159
  name="transactionId"
160
160
  label={<Trans>Transaction ID</Trans>}
161
- rules={{ required: i18n.t('Transaction ID is required') }}
161
+ rules={{ required: t`Transaction ID is required` }}
162
162
  render={({ field }) => (
163
- <Input {...field} placeholder={i18n.t('Enter transaction ID')} />
163
+ <Input {...field} placeholder={t`Enter transaction ID`} />
164
164
  )}
165
165
  />
166
166
  <DialogFooter>
@@ -169,9 +169,7 @@ export function AddManualPaymentDialog({ order, onSuccess }: Readonly<AddManualP
169
169
  </Button>
170
170
  <Button
171
171
  type="submit"
172
- disabled={
173
- !form.formState.isValid || isSubmitting || !method
174
- }
172
+ disabled={!form.formState.isValid || isSubmitting || !method}
175
173
  >
176
174
  {isSubmitting ? (
177
175
  <Trans>Adding...</Trans>
@@ -3,7 +3,7 @@ import { Card } from '@/vdb/components/ui/card.js';
3
3
  import { Popover, PopoverContent, PopoverTrigger } from '@/vdb/components/ui/popover.js';
4
4
  import { api } from '@/vdb/graphql/api.js';
5
5
  import { graphql, ResultOf } from '@/vdb/graphql/graphql.js';
6
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
6
+ import { Trans, useLingui } from '@lingui/react/macro';
7
7
  import { cn } from '@/vdb/lib/utils.js';
8
8
  import { useQuery } from '@tanstack/react-query';
9
9
  import { Plus } from 'lucide-react';
@@ -5,7 +5,7 @@ import { Button } from '@/vdb/components/ui/button.js';
5
5
  import { Input } from '@/vdb/components/ui/input.js';
6
6
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/vdb/components/ui/table.js';
7
7
  import { ResultOf } from '@/vdb/graphql/graphql.js';
8
- import { Trans } from '@/vdb/lib/trans.js';
8
+ import { Trans } from '@lingui/react/macro';
9
9
  import {
10
10
  ColumnDef,
11
11
  flexRender,
@@ -53,16 +53,16 @@ export interface OrderTableProps {
53
53
  }
54
54
 
55
55
  export function EditOrderTable({
56
- order,
57
- eligibleShippingMethods,
58
- onAddItem,
59
- onAdjustLine,
60
- onRemoveLine,
61
- onSetShippingMethod,
62
- onApplyCouponCode,
63
- onRemoveCouponCode,
64
- displayTotals = true,
65
- }: Readonly<OrderTableProps>) {
56
+ order,
57
+ eligibleShippingMethods,
58
+ onAddItem,
59
+ onAdjustLine,
60
+ onRemoveLine,
61
+ onSetShippingMethod,
62
+ onApplyCouponCode,
63
+ onRemoveCouponCode,
64
+ displayTotals = true,
65
+ }: Readonly<OrderTableProps>) {
66
66
  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
67
67
  const currencyCode = order.currencyCode;
68
68
  const columns: ColumnDef<OrderLineFragment & { customFields?: Record<string, any> }>[] = [
@@ -169,9 +169,9 @@ export function EditOrderTable({
169
169
  {header.isPlaceholder
170
170
  ? null
171
171
  : flexRender(
172
- header.column.columnDef.header,
173
- header.getContext(),
174
- )}
172
+ header.column.columnDef.header,
173
+ header.getContext(),
174
+ )}
175
175
  </TableHead>
176
176
  );
177
177
  })}
@@ -181,14 +181,14 @@ export function EditOrderTable({
181
181
  <TableBody>
182
182
  {table.getRowModel().rows?.length
183
183
  ? table.getRowModel().rows.map(row => (
184
- <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
185
- {row.getVisibleCells().map(cell => (
186
- <TableCell key={cell.id}>
187
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
188
- </TableCell>
189
- ))}
190
- </TableRow>
191
- ))
184
+ <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
185
+ {row.getVisibleCells().map(cell => (
186
+ <TableCell key={cell.id}>
187
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
188
+ </TableCell>
189
+ ))}
190
+ </TableRow>
191
+ ))
192
192
  : null}
193
193
  <TableRow>
194
194
  <TableCell colSpan={columns.length} className="h-12">
@@ -14,7 +14,7 @@ import { Input } from '@/vdb/components/ui/input.js';
14
14
  import { Label } from '@/vdb/components/ui/label.js';
15
15
  import { api } from '@/vdb/graphql/api.js';
16
16
  import { graphql } from '@/vdb/graphql/graphql.js';
17
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
17
+ import { Trans, useLingui } from '@lingui/react/macro';
18
18
  import { useMutation, useQuery } from '@tanstack/react-query';
19
19
  import { ConfigurableOperationInput as ConfigurableOperationInputType } from '@vendure/common/lib/generated-types';
20
20
  import { useState } from 'react';
@@ -38,7 +38,7 @@ interface FulfillmentQuantity {
38
38
  }
39
39
 
40
40
  export function FulfillOrderDialog({ order, onSuccess }: Readonly<FulfillOrderDialogProps>) {
41
- const { i18n } = useLingui();
41
+ const { t } = useLingui();
42
42
  const [isSubmitting, setIsSubmitting] = useState(false);
43
43
  const [open, setOpen] = useState(false);
44
44
  const [fulfillmentQuantities, setFulfillmentQuantities] = useState<{
@@ -73,16 +73,16 @@ export function FulfillOrderDialog({ order, onSuccess }: Readonly<FulfillOrderDi
73
73
  onSuccess: (result: any) => {
74
74
  const { addFulfillmentToOrder } = result;
75
75
  if (addFulfillmentToOrder.__typename === 'Fulfillment') {
76
- toast(i18n.t('Successfully fulfilled order'));
76
+ toast(t`Successfully fulfilled order`);
77
77
  onSuccess?.();
78
78
  } else {
79
- toast(i18n.t('Failed to fulfill order'), {
79
+ toast(t`Failed to fulfill order`, {
80
80
  description: addFulfillmentToOrder.message,
81
81
  });
82
82
  }
83
83
  },
84
84
  onError: error => {
85
- toast(i18n.t('Failed to fulfill order'), {
85
+ toast(t`Failed to fulfill order`, {
86
86
  description: error instanceof Error ? error.message : 'Unknown error',
87
87
  });
88
88
  },
@@ -184,7 +184,7 @@ export function FulfillOrderDialog({ order, onSuccess }: Readonly<FulfillOrderDi
184
184
  form.reset();
185
185
  setFulfillmentQuantities({});
186
186
  } catch (error) {
187
- toast(i18n.t('Failed to fulfill order'), {
187
+ toast(t`Failed to fulfill order`, {
188
188
  description: error instanceof Error ? error.message : 'Unknown error',
189
189
  });
190
190
  } finally {
@@ -2,8 +2,9 @@ import { LabeledData } from '@/vdb/components/labeled-data.js';
2
2
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/vdb/components/ui/collapsible.js';
3
3
  import { api } from '@/vdb/graphql/api.js';
4
4
  import { ResultOf } from '@/vdb/graphql/graphql.js';
5
+ import { useDynamicTranslations } from '@/vdb/hooks/use-dynamic-translations.js';
5
6
  import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
6
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
7
+ import { Trans, useLingui } from '@lingui/react/macro';
7
8
  import { useMutation } from '@tanstack/react-query';
8
9
  import { ChevronDown } from 'lucide-react';
9
10
  import { toast } from 'sonner';
@@ -24,7 +25,8 @@ type FulfillmentDetailsProps = {
24
25
 
25
26
  export function FulfillmentDetails({ order, fulfillment, onSuccess }: Readonly<FulfillmentDetailsProps>) {
26
27
  const { formatDate } = useLocalFormat();
27
- const { i18n } = useLingui();
28
+ const { t } = useLingui();
29
+ const { getTranslatedFulfillmentState } = useDynamicTranslations();
28
30
 
29
31
  // Create a map of order lines by ID for quick lookup
30
32
  const orderLinesMap = new Map(order.lines.map(line => [line.id, line]));
@@ -34,14 +36,14 @@ export function FulfillmentDetails({ order, fulfillment, onSuccess }: Readonly<F
34
36
  onSuccess: (result: ResultOf<typeof transitionFulfillmentToStateDocument>) => {
35
37
  const fulfillment = result.transitionFulfillmentToState;
36
38
  if (fulfillment.__typename === 'Fulfillment') {
37
- toast.success(i18n.t('Fulfillment state updated successfully'));
39
+ toast.success(t`Fulfillment state updated successfully`);
38
40
  onSuccess?.();
39
41
  } else {
40
- toast.error(fulfillment.message ?? i18n.t('Failed to update fulfillment state'));
42
+ toast.error(fulfillment.message ?? t`Failed to update fulfillment state`);
41
43
  }
42
44
  },
43
45
  onError: error => {
44
- toast.error(i18n.t('Failed to update fulfillment state'));
46
+ toast.error(t`Failed to update fulfillment state`);
45
47
  },
46
48
  });
47
49
 
@@ -77,8 +79,9 @@ export function FulfillmentDetails({ order, fulfillment, onSuccess }: Readonly<F
77
79
 
78
80
  const suggested = nextSuggestedState();
79
81
  if (suggested) {
82
+ const suggestedState = getTranslatedFulfillmentState(suggested);
80
83
  actions.push({
81
- label: `Transition to ${suggested}`,
84
+ label: t`Transition to ${suggestedState}`,
82
85
  onClick: () => handleStateTransition(suggested),
83
86
  disabled: transitionFulfillmentMutation.isPending,
84
87
  });
@@ -86,7 +89,7 @@ export function FulfillmentDetails({ order, fulfillment, onSuccess }: Readonly<F
86
89
 
87
90
  nextOtherStates().forEach(state => {
88
91
  actions.push({
89
- label: `Transition to ${state}`,
92
+ label: t`Transition to ${getTranslatedFulfillmentState(state)}`,
90
93
  type: getTypeForState(state),
91
94
  onClick: () => handleStateTransition(state),
92
95
  disabled: transitionFulfillmentMutation.isPending,
@@ -101,7 +104,10 @@ export function FulfillmentDetails({ order, fulfillment, onSuccess }: Readonly<F
101
104
  <div className="space-y-1">
102
105
  <LabeledData label={<Trans>Fulfillment ID</Trans>} value={fulfillment.id.slice(-8)} />
103
106
  <LabeledData label={<Trans>Method</Trans>} value={fulfillment.method} />
104
- <LabeledData label={<Trans>State</Trans>} value={fulfillment.state} />
107
+ <LabeledData
108
+ label={<Trans>State</Trans>}
109
+ value={getTranslatedFulfillmentState(fulfillment.state)}
110
+ />
105
111
  {fulfillment.trackingCode && (
106
112
  <LabeledData label={<Trans>Tracking code</Trans>} value={fulfillment.trackingCode} />
107
113
  )}
@@ -143,7 +149,7 @@ export function FulfillmentDetails({ order, fulfillment, onSuccess }: Readonly<F
143
149
 
144
150
  <div className="mt-3 pt-3 border-t">
145
151
  <StateTransitionControl
146
- currentState={fulfillment.state}
152
+ currentState={getTranslatedFulfillmentState(fulfillment.state)}
147
153
  actions={getFulfillmentActions()}
148
154
  isLoading={transitionFulfillmentMutation.isPending}
149
155
  />
@@ -2,7 +2,7 @@ import { Separator } from '@/vdb/components/ui/separator.js';
2
2
  import { ResultOf } from 'gql.tada';
3
3
  import { Globe, Phone } from 'lucide-react';
4
4
  import { orderAddressFragment } from '../orders.graphql.js';
5
- import { Trans } from '@/vdb/lib/trans.js';
5
+ import { Trans } from '@lingui/react/macro';
6
6
 
7
7
  type OrderAddress = Omit<ResultOf<typeof orderAddressFragment>, 'country'> & {
8
8
  country: string | { code: string; name: string } | null;
@@ -13,7 +13,8 @@ import {
13
13
  import { getDetailQueryOptions, useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
14
14
  import { api } from '@/vdb/graphql/api.js';
15
15
  import { useCustomFieldConfig } from '@/vdb/hooks/use-custom-field-config.js';
16
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
16
+ import { useDynamicTranslations } from '@/vdb/hooks/use-dynamic-translations.js';
17
+ import { Trans, useLingui } from '@lingui/react/macro';
17
18
  import { useMutation, useQueryClient } from '@tanstack/react-query';
18
19
  import { Link, useNavigate } from '@tanstack/react-router';
19
20
  import { ResultOf } from 'gql.tada';
@@ -64,9 +65,10 @@ export function OrderDetailShared({
64
65
  titleSlot,
65
66
  beforeOrderTable,
66
67
  }: Readonly<OrderDetailSharedProps>) {
67
- const { i18n } = useLingui();
68
+ const { t } = useLingui();
68
69
  const navigate = useNavigate();
69
70
  const queryClient = useQueryClient();
71
+ const { getTranslatedOrderState } = useDynamicTranslations();
70
72
 
71
73
  const { form, submitHandler, entity, refreshEntity } = useDetailPage({
72
74
  pageId,
@@ -80,11 +82,11 @@ export function OrderDetailShared({
80
82
  },
81
83
  params: { id: orderId },
82
84
  onSuccess: async () => {
83
- toast(i18n.t('Successfully updated order'));
85
+ toast(t`Successfully updated order`);
84
86
  form.reset(form.getValues());
85
87
  },
86
88
  onError: err => {
87
- toast(i18n.t('Failed to update order'), {
89
+ toast(t`Failed to update order`, {
88
90
  description: err instanceof Error ? err.message : 'Unknown error',
89
91
  });
90
92
  },
@@ -102,12 +104,12 @@ export function OrderDetailShared({
102
104
  return [];
103
105
  }
104
106
  return entity.nextStates.map((state: string) => ({
105
- label: `Transition to ${state}`,
107
+ label: t`Transition to ${getTranslatedOrderState(state)}`,
106
108
  type: getTypeForState(state),
107
109
  onClick: async () => {
108
110
  const transitionError = await transitionToState(state);
109
111
  if (transitionError) {
110
- toast(i18n.t('Failed to transition order to state'), {
112
+ toast(t`Failed to transition order to state`, {
111
113
  description: transitionError,
112
114
  });
113
115
  } else {
@@ -115,7 +117,7 @@ export function OrderDetailShared({
115
117
  }
116
118
  },
117
119
  }));
118
- }, [entity, transitionToState, i18n]);
120
+ }, [entity, transitionToState, t]);
119
121
 
120
122
  if (!entity) {
121
123
  return null;
@@ -131,7 +133,7 @@ export function OrderDetailShared({
131
133
  await queryClient.invalidateQueries({ queryKey });
132
134
  await navigate({ to: `/orders/$id/modify`, params: { id: entity.id } });
133
135
  } catch (error) {
134
- toast(i18n.t('Failed to modify order'), {
136
+ toast(t`Failed to modify order`, {
135
137
  description: error instanceof Error ? error.message : 'Unknown error',
136
138
  });
137
139
  }
@@ -232,7 +234,7 @@ export function OrderDetailShared({
232
234
  {/* Side Column Blocks */}
233
235
  <PageBlock column="side" blockId="state">
234
236
  <StateTransitionControl
235
- currentState={entity?.state}
237
+ currentState={getTranslatedOrderState(entity?.state)}
236
238
  actions={stateTransitionActions}
237
239
  isLoading={transitionOrderToStateMutation.isPending}
238
240
  />
@@ -1,5 +1,5 @@
1
1
  import { HistoryEntry, HistoryEntryProps } from '@/vdb/framework/history-entry/history-entry.js';
2
- import { Trans } from '@/vdb/lib/trans.js';
2
+ import { Trans } from '@lingui/react/macro';
3
3
 
4
4
  export function OrderStateTransitionComponent(props: Readonly<HistoryEntryProps>) {
5
5
  const { entry } = props;
@@ -1,7 +1,7 @@
1
1
  import { Alert, AlertDescription } from '@/vdb/components/ui/alert.js';
2
2
  import { Button } from '@/vdb/components/ui/button.js';
3
3
  import { Skeleton } from '@/vdb/components/ui/skeleton.js';
4
- import { Trans } from '@/vdb/lib/trans.js';
4
+ import { Trans } from '@lingui/react/macro';
5
5
  import { TriangleAlert } from 'lucide-react';
6
6
  import { OrderHistory } from './order-history.js';
7
7
  import { useOrderHistory } from './use-order-history.js';
@@ -1,5 +1,5 @@
1
1
  import { HistoryEntryItem } from '@/vdb/framework/extension-api/types/index.js';
2
- import { Trans } from '@/vdb/lib/trans.js';
2
+ import { Trans } from '@lingui/react/macro';
3
3
  import {
4
4
  ArrowRightToLine,
5
5
  Ban,
@@ -1,6 +1,6 @@
1
1
  import { api } from '@/vdb/graphql/api.js';
2
2
  import { graphql, ResultOf } from '@/vdb/graphql/graphql.js';
3
- import { useLingui } from '@/vdb/lib/trans.js';
3
+ import { useLingui } from '@lingui/react/macro';
4
4
  import { QueryKey, useInfiniteQuery, useMutation } from '@tanstack/react-query';
5
5
  import { useState } from 'react';
6
6
  import { toast } from 'sonner';
@@ -2,7 +2,7 @@ import { CustomFieldsForm } from '@/vdb/components/shared/custom-fields-form.js'
2
2
  import { Button } from '@/vdb/components/ui/button.js';
3
3
  import { Form } from '@/vdb/components/ui/form.js';
4
4
  import { Popover, PopoverContent, PopoverTrigger } from '@/vdb/components/ui/popover.js';
5
- import { Trans } from '@/vdb/lib/trans.js';
5
+ import { Trans } from '@lingui/react/macro';
6
6
  import { Settings2 } from 'lucide-react';
7
7
  import { useForm } from 'react-hook-form';
8
8