@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
@@ -7,7 +7,7 @@ import {
7
7
  SheetTitle,
8
8
  SheetTrigger,
9
9
  } from '@/vdb/components/ui/sheet.js';
10
- import { Trans } from '@/vdb/lib/trans.js';
10
+ import { Trans } from '@lingui/react/macro';
11
11
  import { VariablesOf } from 'gql.tada';
12
12
  import { FlaskConical } from 'lucide-react';
13
13
  import { useState } from 'react';
@@ -20,9 +20,9 @@ interface TestSingleShippingMethodDialogProps {
20
20
  }
21
21
 
22
22
  export function TestSingleShippingMethodSheet({
23
- checker,
24
- calculator,
25
- }: Readonly<TestSingleShippingMethodDialogProps>) {
23
+ checker,
24
+ calculator,
25
+ }: Readonly<TestSingleShippingMethodDialogProps>) {
26
26
  const [open, setOpen] = useState(false);
27
27
 
28
28
  return (
@@ -3,7 +3,7 @@ import { PermissionGuard } from '@/vdb/components/shared/permission-guard.js';
3
3
  import { Button } from '@/vdb/components/ui/button.js';
4
4
  import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
5
5
  import { ListPage } from '@/vdb/framework/page/list-page.js';
6
- import { Trans } from '@/vdb/lib/trans.js';
6
+ import { Trans } from '@lingui/react/macro';
7
7
  import { createFileRoute, Link } from '@tanstack/react-router';
8
8
  import { PlusIcon } from 'lucide-react';
9
9
  import {
@@ -25,7 +25,7 @@ function ShippingMethodListPage() {
25
25
  pageId="shipping-method-list"
26
26
  listQuery={shippingMethodListQuery}
27
27
  route={Route}
28
- title="Shipping Methods"
28
+ title={<Trans>Shipping Methods</Trans>}
29
29
  defaultVisibility={{
30
30
  name: true,
31
31
  code: true,
@@ -33,7 +33,6 @@ function ShippingMethodListPage() {
33
33
  }}
34
34
  customizeColumns={{
35
35
  name: {
36
- header: 'Name',
37
36
  cell: ({ row }) => <DetailPageButton id={row.original.id} label={row.original.name} />,
38
37
  },
39
38
  }}
@@ -18,7 +18,7 @@ import {
18
18
  } from '@/vdb/framework/layout-engine/page-layout.js';
19
19
  import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
20
20
  import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
21
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
21
+ import { Trans, useLingui } from '@lingui/react/macro';
22
22
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
23
23
  import { toast } from 'sonner';
24
24
  import { FulfillmentHandlerSelector } from './components/fulfillment-handler-selector.js';
@@ -52,7 +52,7 @@ function ShippingMethodDetailPage() {
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,
@@ -3,7 +3,7 @@ import { PermissionGuard } from '@/vdb/components/shared/permission-guard.js';
3
3
  import { Button } from '@/vdb/components/ui/button.js';
4
4
  import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
5
5
  import { ListPage } from '@/vdb/framework/page/list-page.js';
6
- import { Trans } from '@/vdb/lib/trans.js';
6
+ import { Trans } from '@lingui/react/macro';
7
7
  import { createFileRoute, Link } from '@tanstack/react-router';
8
8
  import { PlusIcon } from 'lucide-react';
9
9
  import {
@@ -22,12 +22,11 @@ function StockLocationListPage() {
22
22
  return (
23
23
  <ListPage
24
24
  pageId="stock-location-list"
25
- title="Stock Locations"
25
+ title={<Trans>Stock Locations</Trans>}
26
26
  listQuery={stockLocationListQuery}
27
27
  route={Route}
28
28
  customizeColumns={{
29
29
  name: {
30
- header: 'Name',
31
30
  cell: ({ row }) => <DetailPageButton id={row.original.id} label={row.original.name} />,
32
31
  },
33
32
  }}
@@ -56,7 +55,7 @@ function StockLocationListPage() {
56
55
  <Button asChild>
57
56
  <Link to="./new">
58
57
  <PlusIcon className="mr-2 h-4 w-4" />
59
- New Stock Location
58
+ <Trans>New Stock Location</Trans>
60
59
  </Link>
61
60
  </Button>
62
61
  </PermissionGuard>
@@ -17,7 +17,7 @@ import {
17
17
  } from '@/vdb/framework/layout-engine/page-layout.js';
18
18
  import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
19
19
  import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
20
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
20
+ import { Trans, useLingui } from '@lingui/react/macro';
21
21
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
22
22
  import { toast } from 'sonner';
23
23
  import {
@@ -47,7 +47,7 @@ function StockLocationDetailPage() {
47
47
  const params = Route.useParams();
48
48
  const navigate = useNavigate();
49
49
  const creatingNewEntity = params.id === NEW_ENTITY_PATH;
50
- const { i18n } = useLingui();
50
+ const { t } = useLingui();
51
51
 
52
52
  const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
53
53
  pageId,
@@ -64,16 +64,23 @@ function StockLocationDetailPage() {
64
64
  },
65
65
  params: { id: params.id },
66
66
  onSuccess: async data => {
67
- toast.success(i18n.t(creatingNewEntity ? 'Successfully created stock location' : 'Successfully updated stock location'));
67
+ toast.success(
68
+ creatingNewEntity
69
+ ? t`Successfully created stock location`
70
+ : t`Successfully updated stock location`,
71
+ );
68
72
  resetForm();
69
73
  if (creatingNewEntity) {
70
74
  await navigate({ to: `../$id`, params: { id: data.id } });
71
75
  }
72
76
  },
73
77
  onError: err => {
74
- toast.error(i18n.t(creatingNewEntity ? 'Failed to create stock location' : 'Failed to update stock location'), {
75
- description: err instanceof Error ? err.message : 'Unknown error',
76
- });
78
+ toast.error(
79
+ creatingNewEntity ? t`Failed to create stock location` : t`Failed to update stock location`,
80
+ {
81
+ description: err instanceof Error ? err.message : 'Unknown error',
82
+ },
83
+ );
77
84
  },
78
85
  });
79
86
 
@@ -1,7 +1,7 @@
1
1
  import { Button } from '@/vdb/components/ui/button.js';
2
2
  import { Card, CardContent, CardHeader, CardTitle } from '@/vdb/components/ui/card.js';
3
3
  import { Page, PageActionBar, PageTitle } from '@/vdb/framework/layout-engine/page-layout.js';
4
- import { Trans } from '@/vdb/lib/trans.js';
4
+ import { Trans } from '@lingui/react/macro';
5
5
  import { useQuery } from '@tanstack/react-query';
6
6
  import { createFileRoute } from '@tanstack/react-router';
7
7
  import { formatRelative } from 'date-fns';
@@ -39,15 +39,21 @@ function HealthchecksPage() {
39
39
 
40
40
  return (
41
41
  <Page>
42
- <PageTitle>Healthchecks</PageTitle>
42
+ <PageTitle>
43
+ <Trans>Health checks</Trans>
44
+ </PageTitle>
43
45
  <PageActionBar>
44
- <Button onClick={() => refetch()}>Refresh</Button>
46
+ <Button onClick={() => refetch()}>
47
+ <Trans>Refresh</Trans>
48
+ </Button>
45
49
  </PageActionBar>
46
50
  <div className="grid grid-cols-1 lg:grid-cols-2 gap-8 mt-6">
47
51
  <Card>
48
52
  <CardHeader>
49
53
  <CardTitle className="flex items-center gap-2">
50
- <span> Current status</span>
54
+ <span>
55
+ <Trans>Current status</Trans>
56
+ </span>
51
57
  <span className="text-sm font-normal text-muted-foreground">
52
58
  <Trans>Last updated {formatRelative(dataUpdatedAt, new Date())}</Trans>
53
59
  </span>
@@ -9,7 +9,7 @@ import {
9
9
  import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
10
10
  import { ListPage } from '@/vdb/framework/page/list-page.js';
11
11
  import { api } from '@/vdb/graphql/api.js';
12
- import { Trans } from '@/vdb/lib/trans.js';
12
+ import { Trans, useLingui } from '@lingui/react/macro';
13
13
  import { useMutation } from '@tanstack/react-query';
14
14
  import { createFileRoute } from '@tanstack/react-router';
15
15
  import { formatRelative } from 'date-fns';
@@ -76,6 +76,7 @@ const REFRESH_INTERVALS = [
76
76
 
77
77
  function JobQueuePage() {
78
78
  const refreshRef = useRef<() => void>(() => {});
79
+ const { t } = useLingui();
79
80
  const [refreshInterval, setRefreshInterval] = useState(10000);
80
81
 
81
82
  useEffect(() => {
@@ -93,13 +94,12 @@ function JobQueuePage() {
93
94
  return (
94
95
  <ListPage
95
96
  pageId="job-queue-list"
96
- title="Job Queue"
97
+ title={<Trans>Job Queue</Trans>}
97
98
  defaultSort={[{ id: 'createdAt', desc: true }]}
98
99
  listQuery={jobListDocument}
99
100
  route={Route}
100
101
  customizeColumns={{
101
102
  createdAt: {
102
- header: 'Created At',
103
103
  cell: ({ row }) => (
104
104
  <div title={row.original.createdAt}>
105
105
  {formatRelative(new Date(row.original.createdAt), new Date())}
@@ -107,7 +107,6 @@ function JobQueuePage() {
107
107
  ),
108
108
  },
109
109
  data: {
110
- header: 'Data',
111
110
  cell: ({ row }) => (
112
111
  <PayloadDialog
113
112
  payload={row.original.data}
@@ -115,18 +114,16 @@ function JobQueuePage() {
115
114
  description={<Trans>The data that has been passed to the job</Trans>}
116
115
  trigger={
117
116
  <Button size="sm" variant="secondary">
118
- View data
117
+ <Trans>View data</Trans>
119
118
  </Button>
120
119
  }
121
120
  />
122
121
  ),
123
122
  },
124
123
  queueName: {
125
- header: 'Queue',
126
124
  cell: ({ row }) => <span className="font-mono">{row.original.queueName}</span>,
127
125
  },
128
126
  result: {
129
- header: 'Result',
130
127
  cell: ({ row }) => {
131
128
  return row.original.result ? (
132
129
  <PayloadDialog
@@ -135,7 +132,7 @@ function JobQueuePage() {
135
132
  description={<Trans>The result of the job</Trans>}
136
133
  trigger={
137
134
  <Button size="sm" variant="secondary">
138
- View result
135
+ <Trans>View result</Trans>
139
136
  </Button>
140
137
  }
141
138
  />
@@ -147,7 +144,6 @@ function JobQueuePage() {
147
144
  },
148
145
  },
149
146
  state: {
150
- header: 'State',
151
147
  cell: ({ row, table }) => {
152
148
  const cancelJobMutation = useMutation({
153
149
  mutationFn: (jobId: string) => api.mutate(cancelJobDocument, { jobId }),
@@ -196,7 +192,6 @@ function JobQueuePage() {
196
192
  },
197
193
  },
198
194
  duration: {
199
- header: 'Duration',
200
195
  cell: ({ row }) => {
201
196
  return row.original.duration ? `${row.original.duration}ms` : null;
202
197
  },
@@ -213,7 +208,7 @@ function JobQueuePage() {
213
208
  }}
214
209
  facetedFilters={{
215
210
  queueName: {
216
- title: 'Queue',
211
+ title: t`Queue`,
217
212
  optionsFn: async () => {
218
213
  return api.query(jobQueueListDocument).then(r => {
219
214
  return r.jobQueues.map(queue => ({
@@ -224,7 +219,7 @@ function JobQueuePage() {
224
219
  },
225
220
  },
226
221
  state: {
227
- title: 'State',
222
+ title: t`State`,
228
223
  options: STATES,
229
224
  },
230
225
  }}
@@ -237,7 +232,9 @@ function JobQueuePage() {
237
232
  <DropdownMenuTrigger asChild>
238
233
  <Button variant="outline" size="sm" className="gap-2">
239
234
  <RefreshCw className="h-4 w-4" />
240
- <span>Auto refresh: {currentInterval?.label}</span>
235
+ <span>
236
+ <Trans>Auto refresh: {currentInterval?.label}</Trans>
237
+ </span>
241
238
  <ChevronDown className="h-4 w-4" />
242
239
  </Button>
243
240
  </DropdownMenuTrigger>
@@ -16,7 +16,7 @@ import {
16
16
  import { api } from '@/vdb/graphql/api.js';
17
17
  import { graphql, ResultOf } from '@/vdb/graphql/graphql.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, useQuery, useQueryClient } from '@tanstack/react-query';
21
21
  import { createFileRoute } from '@tanstack/react-router';
22
22
  import { createColumnHelper } from '@tanstack/react-table';
@@ -65,7 +65,7 @@ const runScheduledTaskDocument = graphql(`
65
65
  type ScheduledTask = ResultOf<typeof getScheduledTasksDocument>['scheduledTasks'][number];
66
66
 
67
67
  function ScheduledTasksPage() {
68
- const { i18n } = useLingui();
68
+ const { t } = useLingui();
69
69
  const { data } = useQuery({
70
70
  queryKey: ['scheduledTasks'],
71
71
  queryFn: () => api.query(getScheduledTasksDocument),
@@ -84,10 +84,10 @@ function ScheduledTasksPage() {
84
84
  mutationFn: api.mutate(runScheduledTaskDocument),
85
85
  onSuccess: result => {
86
86
  if ((result as ResultOf<typeof runScheduledTaskDocument>).runScheduledTask.success) {
87
- toast.success(i18n.t(`Scheduled task will be executed`));
87
+ toast.success(t`Scheduled task will be executed`);
88
88
  queryClient.invalidateQueries({ queryKey: ['scheduledTasks'] });
89
89
  } else {
90
- toast.error(i18n.t(`Scheduled task could not be executed`));
90
+ toast.error(t`Scheduled task could not be executed`);
91
91
  }
92
92
  },
93
93
  });
@@ -104,13 +104,13 @@ function ScheduledTasksPage() {
104
104
  const columnHelper = createColumnHelper<ScheduledTask>();
105
105
  const columns = [
106
106
  columnHelper.accessor('id', {
107
- header: 'ID',
107
+ header: t`ID`,
108
108
  }),
109
109
  columnHelper.accessor('description', {
110
- header: 'Description',
110
+ header: t`Description`,
111
111
  }),
112
112
  columnHelper.accessor('enabled', {
113
- header: 'Enabled',
113
+ header: t`Enabled`,
114
114
  cell: ({ row }) => {
115
115
  return row.original.enabled ? (
116
116
  <Badge variant="success">
@@ -124,13 +124,13 @@ function ScheduledTasksPage() {
124
124
  },
125
125
  }),
126
126
  columnHelper.accessor('schedule', {
127
- header: 'Schedule Pattern',
127
+ header: t`Schedule Pattern`,
128
128
  }),
129
129
  columnHelper.accessor('scheduleDescription', {
130
- header: 'Schedule',
130
+ header: t`Schedule`,
131
131
  }),
132
132
  columnHelper.accessor('lastExecutedAt', {
133
- header: 'Last Executed',
133
+ header: t`Last Executed`,
134
134
  cell: ({ row }) => {
135
135
  return row.original.lastExecutedAt ? (
136
136
  <div title={row.original.lastExecutedAt}>
@@ -142,7 +142,7 @@ function ScheduledTasksPage() {
142
142
  },
143
143
  }),
144
144
  columnHelper.accessor('nextExecutionAt', {
145
- header: 'Next Execution',
145
+ header: t`Next Execution`,
146
146
  cell: ({ row }) => {
147
147
  return row.original.nextExecutionAt ? (
148
148
  formatDate(row.original.nextExecutionAt, intlDateOptions)
@@ -152,7 +152,7 @@ function ScheduledTasksPage() {
152
152
  },
153
153
  }),
154
154
  columnHelper.accessor('isRunning', {
155
- header: 'Running',
155
+ header: t`Running`,
156
156
  cell: ({ row }) => {
157
157
  return row.original.isRunning ? (
158
158
  <Badge variant="success">
@@ -166,7 +166,7 @@ function ScheduledTasksPage() {
166
166
  },
167
167
  }),
168
168
  columnHelper.accessor('lastResult', {
169
- header: 'Last Result',
169
+ header: t`Last Result`,
170
170
  cell: ({ row }) => {
171
171
  return row.original.lastResult ? (
172
172
  <PayloadDialog
@@ -175,7 +175,7 @@ function ScheduledTasksPage() {
175
175
  description={<Trans>The result of the job</Trans>}
176
176
  trigger={
177
177
  <Button size="sm" variant="secondary">
178
- View result
178
+ <Trans>View result</Trans>
179
179
  </Button>
180
180
  }
181
181
  />
@@ -188,7 +188,7 @@ function ScheduledTasksPage() {
188
188
  }),
189
189
  columnHelper.display({
190
190
  id: 'actions',
191
- header: 'Actions',
191
+ header: t`Actions`,
192
192
  cell: ({ row }) => {
193
193
  return (
194
194
  <DropdownMenu>
@@ -228,7 +228,9 @@ function ScheduledTasksPage() {
228
228
 
229
229
  return (
230
230
  <Page pageId="scheduled-tasks-list">
231
- <PageTitle>Scheduled Tasks</PageTitle>
231
+ <PageTitle>
232
+ <Trans>Scheduled Tasks</Trans>
233
+ </PageTitle>
232
234
  <PageLayout>
233
235
  <FullWidthPageBlock blockId="list-table">
234
236
  <DataTable
@@ -4,7 +4,7 @@ import { Badge } from '@/vdb/components/ui/badge.js';
4
4
  import { Button } from '@/vdb/components/ui/button.js';
5
5
  import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
6
6
  import { ListPage } from '@/vdb/framework/page/list-page.js';
7
- import { Trans } from '@/vdb/lib/trans.js';
7
+ import { Trans } from '@lingui/react/macro';
8
8
  import { createFileRoute, Link } from '@tanstack/react-router';
9
9
  import { PlusIcon } from 'lucide-react';
10
10
  import { DeleteTaxCategoriesBulkAction } from './components/tax-category-bulk-actions.js';
@@ -21,7 +21,7 @@ function TaxCategoryListPage() {
21
21
  pageId="tax-category-list"
22
22
  listQuery={taxCategoryListQuery}
23
23
  route={Route}
24
- title="Tax Categories"
24
+ title={<Trans>Tax Categories</Trans>}
25
25
  defaultVisibility={{
26
26
  name: true,
27
27
  isDefault: true,
@@ -37,11 +37,9 @@ function TaxCategoryListPage() {
37
37
  }}
38
38
  customizeColumns={{
39
39
  name: {
40
- header: 'Name',
41
40
  cell: ({ row }) => <DetailPageButton id={row.original.id} label={row.original.name} />,
42
41
  },
43
42
  isDefault: {
44
- header: 'Default',
45
43
  cell: ({ row }) => (
46
44
  <Badge variant={row.original.isDefault ? 'success' : 'destructive'}>
47
45
  <Trans>{row.original.isDefault ? 'Yes' : 'No'}</Trans>
@@ -17,7 +17,7 @@ import {
17
17
  } from '@/vdb/framework/layout-engine/page-layout.js';
18
18
  import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
19
19
  import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
20
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
20
+ import { Trans, useLingui } from '@lingui/react/macro';
21
21
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
22
22
  import { toast } from 'sonner';
23
23
  import {
@@ -47,7 +47,7 @@ function TaxCategoryDetailPage() {
47
47
  const params = Route.useParams();
48
48
  const navigate = useNavigate();
49
49
  const creatingNewEntity = params.id === NEW_ENTITY_PATH;
50
- const { i18n } = useLingui();
50
+ const { t } = useLingui();
51
51
 
52
52
  const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
53
53
  pageId,
@@ -63,16 +63,23 @@ function TaxCategoryDetailPage() {
63
63
  },
64
64
  params: { id: params.id },
65
65
  onSuccess: async data => {
66
- toast.success(i18n.t(creatingNewEntity ? 'Successfully created tax category' : 'Successfully updated tax category'));
66
+ toast.success(
67
+ creatingNewEntity
68
+ ? t`Successfully created tax category`
69
+ : t`Successfully updated tax category`,
70
+ );
67
71
  form.reset(form.getValues());
68
72
  if (creatingNewEntity) {
69
73
  await navigate({ to: `../$id`, params: { id: data.id } });
70
74
  }
71
75
  },
72
76
  onError: err => {
73
- toast.error(i18n.t(creatingNewEntity ? 'Failed to create tax category' : 'Failed to update tax category'), {
74
- description: err instanceof Error ? err.message : 'Unknown error',
75
- });
77
+ toast.error(
78
+ creatingNewEntity ? t`Failed to create tax category` : t`Failed to update tax category`,
79
+ {
80
+ description: err instanceof Error ? err.message : 'Unknown error',
81
+ },
82
+ );
76
83
  },
77
84
  });
78
85
 
@@ -5,7 +5,7 @@ import { Button } from '@/vdb/components/ui/button.js';
5
5
  import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
6
6
  import { ListPage } from '@/vdb/framework/page/list-page.js';
7
7
  import { api } from '@/vdb/graphql/api.js';
8
- import { Trans } from '@/vdb/lib/trans.js';
8
+ import { Trans, useLingui } from '@lingui/react/macro';
9
9
  import { createFileRoute, Link } from '@tanstack/react-router';
10
10
  import { PlusIcon } from 'lucide-react';
11
11
  import { taxCategoryListQuery } from '../_tax-categories/tax-categories.graphql.js';
@@ -19,12 +19,13 @@ export const Route = createFileRoute('/_authenticated/_tax-rates/tax-rates')({
19
19
  });
20
20
 
21
21
  function TaxRateListPage() {
22
+ const { t } = useLingui();
22
23
  return (
23
24
  <ListPage
24
25
  pageId="tax-rate-list"
25
26
  listQuery={taxRateListQuery}
26
27
  route={Route}
27
- title="Tax Rates"
28
+ title={<Trans>Tax Rates</Trans>}
28
29
  defaultVisibility={{
29
30
  name: true,
30
31
  enabled: true,
@@ -43,14 +44,14 @@ function TaxRateListPage() {
43
44
  }}
44
45
  facetedFilters={{
45
46
  enabled: {
46
- title: 'Enabled',
47
+ title: t`Enabled`,
47
48
  options: [
48
- { label: 'Enabled', value: true },
49
- { label: 'Disabled', value: false },
49
+ { label: t`Enabled`, value: true },
50
+ { label: t`Disabled`, value: false },
50
51
  ],
51
52
  },
52
53
  category: {
53
- title: 'Category',
54
+ title: t`Category`,
54
55
  optionsFn: async () => {
55
56
  const { taxCategories } = await api.query(taxCategoryListQuery);
56
57
  return taxCategories.items.map(category => ({
@@ -60,7 +61,7 @@ function TaxRateListPage() {
60
61
  },
61
62
  },
62
63
  zone: {
63
- title: 'Zone',
64
+ title: t`Zone`,
64
65
  optionsFn: async () => {
65
66
  const { zones } = await api.query(zoneListQuery);
66
67
  return zones.items.map(zone => ({
@@ -72,23 +73,18 @@ function TaxRateListPage() {
72
73
  }}
73
74
  customizeColumns={{
74
75
  name: {
75
- header: 'Name',
76
76
  cell: ({ row }) => <DetailPageButton id={row.original.id} label={row.original.name} />,
77
77
  },
78
78
  enabled: {
79
- header: 'Enabled',
80
79
  cell: ({ row }) => <BooleanDisplayBadge value={row.original.enabled} />,
81
80
  },
82
81
  category: {
83
- header: 'Category',
84
82
  cell: ({ row }) => row.original.category?.name,
85
83
  },
86
84
  zone: {
87
- header: 'Zone',
88
85
  cell: ({ row }) => row.original.zone?.name,
89
86
  },
90
87
  value: {
91
- header: 'Value',
92
88
  cell: ({ row }) => `${row.original.value}%`,
93
89
  },
94
90
  }}
@@ -20,7 +20,7 @@ import {
20
20
  } from '@/vdb/framework/layout-engine/page-layout.js';
21
21
  import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
22
22
  import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
23
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
23
+ import { Trans, useLingui } from '@lingui/react/macro';
24
24
  import { createFileRoute, useNavigate } from '@tanstack/react-router';
25
25
  import { toast } from 'sonner';
26
26
  import { createTaxRateDocument, taxRateDetailDocument, updateTaxRateDocument } from './tax-rates.graphql.js';
@@ -46,7 +46,7 @@ function TaxRateDetailPage() {
46
46
  const params = Route.useParams();
47
47
  const navigate = useNavigate();
48
48
  const creatingNewEntity = params.id === NEW_ENTITY_PATH;
49
- const { i18n } = useLingui();
49
+ const { t } = useLingui();
50
50
 
51
51
  const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
52
52
  pageId,
@@ -67,14 +67,16 @@ function TaxRateDetailPage() {
67
67
  },
68
68
  params: { id: params.id },
69
69
  onSuccess: async data => {
70
- toast.success(i18n.t(creatingNewEntity ? 'Successfully created tax rate' : 'Successfully updated tax rate'));
70
+ toast.success(
71
+ creatingNewEntity ? t`Successfully created tax rate` : t`Successfully updated tax rate`,
72
+ );
71
73
  resetForm();
72
74
  if (creatingNewEntity) {
73
75
  await navigate({ to: `../$id`, params: { id: data.id } });
74
76
  }
75
77
  },
76
78
  onError: err => {
77
- toast.error(i18n.t(creatingNewEntity ? 'Failed to create tax rate' : 'Failed to update tax rate'), {
79
+ toast.error(creatingNewEntity ? t`Failed to create tax rate` : t`Failed to update tax rate`, {
78
80
  description: err instanceof Error ? err.message : 'Unknown error',
79
81
  });
80
82
  },
@@ -1,6 +1,7 @@
1
1
  import { Button } from '@/vdb/components/ui/button.js';
2
2
  import { ScrollArea } from '@/vdb/components/ui/scroll-area.js';
3
3
  import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/vdb/components/ui/sheet.js';
4
+ import { FullWidthPageBlock } from '@/vdb/framework/layout-engine/page-layout.js';
4
5
  import { ZoneCountriesTable } from './zone-countries-table.js';
5
6
 
6
7
  interface ZoneCountriesSheetProps {
@@ -23,7 +24,9 @@ export function ZoneCountriesSheet({ zoneId, zoneName, children }: Readonly<Zone
23
24
  </SheetHeader>
24
25
  <div className="flex items-center gap-2"></div>
25
26
  <ScrollArea className="px-6 max-h-[600px]">
26
- <ZoneCountriesTable zoneId={zoneId} />
27
+ <FullWidthPageBlock blockId="zone-countries">
28
+ <ZoneCountriesTable zoneId={zoneId} />
29
+ </FullWidthPageBlock>
27
30
  </ScrollArea>
28
31
  </SheetContent>
29
32
  </Sheet>
@@ -3,7 +3,7 @@ import { PermissionGuard } from '@/vdb/components/shared/permission-guard.js';
3
3
  import { Button } from '@/vdb/components/ui/button.js';
4
4
  import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
5
5
  import { ListPage } from '@/vdb/framework/page/list-page.js';
6
- import { Trans } from '@/vdb/lib/trans.js';
6
+ import { Trans, useLingui } from '@lingui/react/macro';
7
7
  import { createFileRoute, Link } from '@tanstack/react-router';
8
8
  import { PlusIcon } from 'lucide-react';
9
9
  import { DeleteZonesBulkAction } from './components/zone-bulk-actions.js';
@@ -16,24 +16,24 @@ export const Route = createFileRoute('/_authenticated/_zones/zones')({
16
16
  });
17
17
 
18
18
  function ZoneListPage() {
19
+ const { t } = useLingui();
19
20
  return (
20
21
  <ListPage
21
22
  pageId="zone-list"
22
23
  listQuery={zoneListQuery}
23
24
  route={Route}
24
- title="Zones"
25
+ title={<Trans>Zones</Trans>}
25
26
  defaultVisibility={{
26
27
  name: true,
27
28
  }}
28
29
  customizeColumns={{
29
30
  name: {
30
- header: 'Name',
31
31
  cell: ({ row }) => <DetailPageButton id={row.original.id} label={row.original.name} />,
32
32
  },
33
33
  }}
34
34
  additionalColumns={{
35
35
  regions: {
36
- header: 'Regions',
36
+ header: t`Regions`,
37
37
  cell: ({ row }) => (
38
38
  <ZoneCountriesSheet zoneId={row.original.id} zoneName={row.original.name}>
39
39
  <Trans>Edit members</Trans>