@vendure/dashboard 3.5.0-minor-202509261210 → 3.5.0-minor-202510031341

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 (263) hide show
  1. package/README.md +4 -0
  2. package/dist/plugin/dashboard.plugin.d.ts +25 -6
  3. package/dist/plugin/dashboard.plugin.js +184 -27
  4. package/dist/plugin/default-page.html +188 -0
  5. package/dist/vite/vite-plugin-config.js +13 -9
  6. package/dist/vite/vite-plugin-translations.d.ts +22 -0
  7. package/dist/vite/vite-plugin-translations.js +66 -0
  8. package/dist/vite/vite-plugin-vendure-dashboard.js +8 -6
  9. package/lingui.config.js +25 -2
  10. package/package.json +159 -156
  11. package/src/app/app-providers.tsx +0 -4
  12. package/src/app/common/delete-bulk-action.tsx +6 -5
  13. package/src/app/common/duplicate-bulk-action.tsx +4 -5
  14. package/src/app/common/duplicate-entity-dialog.tsx +1 -1
  15. package/src/app/common/set-document-direction.ts +7 -0
  16. package/src/app/main.tsx +50 -17
  17. package/src/app/routes/_authenticated/_administrators/administrators.tsx +8 -6
  18. package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +17 -6
  19. package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +2 -2
  20. package/src/app/routes/_authenticated/_assets/assets.tsx +1 -1
  21. package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +4 -4
  22. package/src/app/routes/_authenticated/_assets/components/asset-bulk-actions.tsx +8 -6
  23. package/src/app/routes/_authenticated/_assets/components/asset-tag-filter.tsx +1 -1
  24. package/src/app/routes/_authenticated/_assets/components/asset-tags-editor.tsx +1 -1
  25. package/src/app/routes/_authenticated/_assets/components/manage-tags-dialog.tsx +3 -8
  26. package/src/app/routes/_authenticated/_channels/channels.tsx +3 -6
  27. package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +5 -5
  28. package/src/app/routes/_authenticated/_collections/collections.tsx +3 -4
  29. package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +4 -6
  30. package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +1 -1
  31. package/src/app/routes/_authenticated/_collections/components/collection-contents-sheet.tsx +1 -1
  32. package/src/app/routes/_authenticated/_collections/components/move-collections-dialog.tsx +6 -6
  33. package/src/app/routes/_authenticated/_countries/countries.graphql.ts +2 -0
  34. package/src/app/routes/_authenticated/_countries/countries.tsx +2 -3
  35. package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +4 -4
  36. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-sheet.tsx +1 -1
  37. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-table.tsx +4 -4
  38. package/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx +2 -4
  39. package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +13 -6
  40. package/src/app/routes/_authenticated/_customers/components/customer-address-card.tsx +8 -8
  41. package/src/app/routes/_authenticated/_customers/components/customer-address-form.tsx +3 -3
  42. package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-container.tsx +1 -1
  43. package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-utils.tsx +1 -1
  44. package/src/app/routes/_authenticated/_customers/components/customer-history/default-customer-history-components.tsx +1 -1
  45. package/src/app/routes/_authenticated/_customers/components/customer-history/use-customer-history.ts +1 -1
  46. package/src/app/routes/_authenticated/_customers/components/customer-status-badge.tsx +1 -1
  47. package/src/app/routes/_authenticated/_customers/customers.graphql.ts +4 -0
  48. package/src/app/routes/_authenticated/_customers/customers.tsx +23 -11
  49. package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +10 -8
  50. package/src/app/routes/_authenticated/_facets/components/edit-facet-value.tsx +1 -1
  51. package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +6 -5
  52. package/src/app/routes/_authenticated/_facets/components/facet-values-sheet.tsx +1 -1
  53. package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +1 -1
  54. package/src/app/routes/_authenticated/_facets/facets.tsx +5 -5
  55. package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +7 -5
  56. package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +4 -4
  57. package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +5 -5
  58. package/src/app/routes/_authenticated/_orders/components/add-manual-payment-dialog.tsx +19 -21
  59. package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +1 -1
  60. package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +22 -22
  61. package/src/app/routes/_authenticated/_orders/components/fulfill-order-dialog.tsx +6 -6
  62. package/src/app/routes/_authenticated/_orders/components/fulfillment-details.tsx +15 -9
  63. package/src/app/routes/_authenticated/_orders/components/order-address.tsx +1 -1
  64. package/src/app/routes/_authenticated/_orders/components/order-detail-shared.tsx +11 -9
  65. package/src/app/routes/_authenticated/_orders/components/order-history/default-order-history-components.tsx +1 -1
  66. package/src/app/routes/_authenticated/_orders/components/order-history/order-history-container.tsx +1 -1
  67. package/src/app/routes/_authenticated/_orders/components/order-history/order-history-utils.tsx +1 -1
  68. package/src/app/routes/_authenticated/_orders/components/order-history/use-order-history.ts +1 -1
  69. package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +1 -1
  70. package/src/app/routes/_authenticated/_orders/components/order-modification-preview-dialog.tsx +4 -4
  71. package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +1 -1
  72. package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +27 -27
  73. package/src/app/routes/_authenticated/_orders/components/order-table.tsx +2 -2
  74. package/src/app/routes/_authenticated/_orders/components/order-tax-summary.tsx +1 -1
  75. package/src/app/routes/_authenticated/_orders/components/payment-details.tsx +26 -20
  76. package/src/app/routes/_authenticated/_orders/components/seller-orders-card.tsx +3 -1
  77. package/src/app/routes/_authenticated/_orders/components/settle-refund-dialog.tsx +6 -6
  78. package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +1 -1
  79. package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +1 -1
  80. package/src/app/routes/_authenticated/_orders/components/use-transition-order-to-state.tsx +3 -2
  81. package/src/app/routes/_authenticated/_orders/orders.tsx +5 -9
  82. package/src/app/routes/_authenticated/_orders/orders_.$aggregateOrderId_.seller-orders.$sellerOrderId.tsx +1 -1
  83. package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +1 -1
  84. package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +4 -4
  85. package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +17 -17
  86. package/src/app/routes/_authenticated/_orders/utils/order-detail-loaders.tsx +1 -1
  87. package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +5 -6
  88. package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +13 -6
  89. package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +1 -1
  90. package/src/app/routes/_authenticated/_product-variants/components/variant-price-detail.tsx +1 -1
  91. package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +9 -2
  92. package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +13 -6
  93. package/src/app/routes/_authenticated/_products/components/add-option-group-dialog.tsx +5 -5
  94. package/src/app/routes/_authenticated/_products/components/add-product-variant-dialog.tsx +5 -5
  95. package/src/app/routes/_authenticated/_products/components/assign-facet-values-dialog.tsx +5 -4
  96. package/src/app/routes/_authenticated/_products/components/create-product-options-dialog.tsx +9 -12
  97. package/src/app/routes/_authenticated/_products/components/create-product-variants-dialog.tsx +1 -1
  98. package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +4 -4
  99. package/src/app/routes/_authenticated/_products/components/option-groups-editor.tsx +1 -1
  100. package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +1 -1
  101. package/src/app/routes/_authenticated/_products/components/product-option-select.tsx +3 -3
  102. package/src/app/routes/_authenticated/_products/components/product-options-table.tsx +9 -6
  103. package/src/app/routes/_authenticated/_products/products.graphql.ts +31 -31
  104. package/src/app/routes/_authenticated/_products/products.tsx +11 -6
  105. package/src/app/routes/_authenticated/_products/products_.$id.tsx +4 -4
  106. package/src/app/routes/_authenticated/_products/products_.$id_.variants.tsx +11 -11
  107. package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$id.tsx +8 -12
  108. package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$productOptionGroupId.options_.$id.tsx +2 -2
  109. package/src/app/routes/_authenticated/_profile/profile.tsx +4 -4
  110. package/src/app/routes/_authenticated/_promotions/promotions.tsx +2 -4
  111. package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +16 -9
  112. package/src/app/routes/_authenticated/_roles/components/permissions-table-grid.tsx +1 -1
  113. package/src/app/routes/_authenticated/_roles/roles.tsx +3 -6
  114. package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +4 -6
  115. package/src/app/routes/_authenticated/_sellers/sellers.tsx +3 -4
  116. package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +4 -4
  117. package/src/app/routes/_authenticated/_shipping-methods/components/price-display.tsx +5 -5
  118. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-test-result-wrapper.tsx +1 -1
  119. package/src/app/routes/_authenticated/_shipping-methods/components/test-address-form.tsx +4 -3
  120. package/src/app/routes/_authenticated/_shipping-methods/components/test-order-builder.tsx +4 -3
  121. package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-result.tsx +8 -8
  122. package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-sheet.tsx +1 -1
  123. package/src/app/routes/_authenticated/_shipping-methods/components/test-single-method-result.tsx +8 -8
  124. package/src/app/routes/_authenticated/_shipping-methods/components/test-single-shipping-method-sheet.tsx +4 -4
  125. package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +2 -3
  126. package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +2 -2
  127. package/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx +3 -4
  128. package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +13 -6
  129. package/src/app/routes/_authenticated/_system/healthchecks.tsx +10 -4
  130. package/src/app/routes/_authenticated/_system/job-queue.tsx +10 -13
  131. package/src/app/routes/_authenticated/_system/scheduled-tasks.tsx +18 -16
  132. package/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx +2 -4
  133. package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +13 -6
  134. package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +8 -12
  135. package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +6 -4
  136. package/src/app/routes/_authenticated/_zones/zones.tsx +4 -4
  137. package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +8 -5
  138. package/src/app/routes/_authenticated/index.tsx +6 -2
  139. package/src/app/styles.css +4 -0
  140. package/src/i18n/common-strings.ts +111 -0
  141. package/src/i18n/locales/ar.po +4777 -0
  142. package/src/i18n/locales/cs.po +4777 -0
  143. package/src/i18n/locales/de.po +4299 -1101
  144. package/src/i18n/locales/en.po +3857 -659
  145. package/src/i18n/locales/es.po +4777 -0
  146. package/src/i18n/locales/fa.po +4777 -0
  147. package/src/i18n/locales/fr.po +4777 -0
  148. package/src/i18n/locales/he.po +4777 -0
  149. package/src/i18n/locales/hr.po +4777 -0
  150. package/src/i18n/locales/it.po +4777 -0
  151. package/src/i18n/locales/ja.po +4777 -0
  152. package/src/i18n/locales/ko.po +4628 -0
  153. package/src/i18n/locales/nb.po +4777 -0
  154. package/src/i18n/locales/ne.po +4777 -0
  155. package/src/i18n/locales/nl.po +4628 -0
  156. package/src/i18n/locales/pl.po +4777 -0
  157. package/src/i18n/locales/pt_BR.po +4777 -0
  158. package/src/i18n/locales/pt_PT.po +4777 -0
  159. package/src/i18n/locales/ru.po +4777 -0
  160. package/src/i18n/locales/sv.po +4777 -0
  161. package/src/i18n/locales/tr.po +4777 -0
  162. package/src/i18n/locales/uk.po +4777 -0
  163. package/src/i18n/locales/zh_Hans.po +4777 -0
  164. package/src/i18n/locales/zh_Hant.po +4777 -0
  165. package/src/lib/components/data-input/combination-mode-input.tsx +1 -1
  166. package/src/lib/components/data-input/custom-field-list-input.tsx +11 -7
  167. package/src/lib/components/data-input/customer-group-input.tsx +27 -33
  168. package/src/lib/components/data-input/datetime-input.tsx +40 -1
  169. package/src/lib/components/data-input/default-relation-input.tsx +5 -4
  170. package/src/lib/components/data-input/product-multi-selector-input.tsx +14 -14
  171. package/src/lib/components/data-input/relation-selector.tsx +1 -1
  172. package/src/lib/components/data-input/select-with-options.tsx +1 -1
  173. package/src/lib/components/data-input/slug-input.tsx +9 -15
  174. package/src/lib/components/data-table/add-filter-menu.tsx +4 -4
  175. package/src/lib/components/data-table/data-table-bulk-action-item.tsx +8 -8
  176. package/src/lib/components/data-table/data-table-bulk-actions.tsx +4 -4
  177. package/src/lib/components/data-table/data-table-column-header.tsx +13 -8
  178. package/src/lib/components/data-table/data-table-faceted-filter.tsx +2 -1
  179. package/src/lib/components/data-table/data-table-filter-dialog.tsx +1 -1
  180. package/src/lib/components/data-table/data-table-utils.ts +21 -4
  181. package/src/lib/components/data-table/data-table-view-options.tsx +4 -2
  182. package/src/lib/components/data-table/data-table.tsx +3 -3
  183. package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +4 -4
  184. package/src/lib/components/data-table/global-views-bar.tsx +1 -1
  185. package/src/lib/components/data-table/human-readable-operator.tsx +1 -1
  186. package/src/lib/components/data-table/manage-global-views-button.tsx +1 -1
  187. package/src/lib/components/data-table/my-views-button.tsx +13 -13
  188. package/src/lib/components/data-table/refresh-button.tsx +1 -1
  189. package/src/lib/components/data-table/save-view-button.tsx +11 -11
  190. package/src/lib/components/data-table/use-generated-columns.tsx +10 -7
  191. package/src/lib/components/data-table/views-sheet.tsx +79 -71
  192. package/src/lib/components/date-range-picker.tsx +36 -34
  193. package/src/lib/components/layout/app-sidebar.tsx +3 -1
  194. package/src/lib/components/layout/channel-switcher.tsx +8 -10
  195. package/src/lib/components/layout/dev-mode-indicator.tsx +1 -1
  196. package/src/lib/components/layout/generated-breadcrumbs.tsx +10 -8
  197. package/src/lib/components/layout/language-dialog.tsx +34 -13
  198. package/src/lib/components/layout/manage-languages-dialog.tsx +1 -1
  199. package/src/lib/components/layout/nav-main.tsx +23 -13
  200. package/src/lib/components/layout/nav-user.tsx +19 -23
  201. package/src/lib/components/login/login-form.tsx +1 -1
  202. package/src/lib/components/shared/asset/asset-bulk-actions.tsx +4 -4
  203. package/src/lib/components/shared/asset/asset-focal-point-editor.tsx +1 -1
  204. package/src/lib/components/shared/asset/asset-gallery.tsx +15 -14
  205. package/src/lib/components/shared/assign-to-channel-bulk-action.tsx +11 -11
  206. package/src/lib/components/shared/assign-to-channel-dialog.tsx +6 -5
  207. package/src/lib/components/shared/channel-code-label.tsx +1 -1
  208. package/src/lib/components/shared/channel-selector.tsx +4 -4
  209. package/src/lib/components/shared/configurable-operation-multi-selector.tsx +16 -14
  210. package/src/lib/components/shared/configurable-operation-selector.tsx +1 -1
  211. package/src/lib/components/shared/confirmation-dialog.tsx +8 -8
  212. package/src/lib/components/shared/country-selector.tsx +1 -1
  213. package/src/lib/components/shared/currency-selector.tsx +4 -4
  214. package/src/lib/components/shared/custom-fields-form.tsx +8 -24
  215. package/src/lib/components/shared/customer-address-form.tsx +3 -3
  216. package/src/lib/components/shared/customer-group-selector.tsx +1 -1
  217. package/src/lib/components/shared/customer-selector.tsx +1 -1
  218. package/src/lib/components/shared/error-page.tsx +1 -1
  219. package/src/lib/components/shared/facet-value-selector.tsx +10 -10
  220. package/src/lib/components/shared/history-timeline/history-note-checkbox.tsx +1 -1
  221. package/src/lib/components/shared/history-timeline/history-note-editor.tsx +1 -1
  222. package/src/lib/components/shared/history-timeline/history-note-entry.tsx +1 -1
  223. package/src/lib/components/shared/language-selector.tsx +4 -4
  224. package/src/lib/components/shared/navigation-confirmation.tsx +1 -1
  225. package/src/lib/components/shared/paginated-list-data-table.tsx +21 -18
  226. package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +6 -5
  227. package/src/lib/components/shared/rich-text-editor/image-dialog.tsx +1 -1
  228. package/src/lib/components/shared/rich-text-editor/link-dialog.tsx +1 -1
  229. package/src/lib/components/shared/rich-text-editor/responsive-toolbar.tsx +1 -1
  230. package/src/lib/components/shared/rich-text-editor/table-edit-icons.tsx +1 -1
  231. package/src/lib/components/shared/role-code-label.tsx +1 -1
  232. package/src/lib/components/shared/role-selector.tsx +4 -4
  233. package/src/lib/components/shared/seller-selector.tsx +1 -1
  234. package/src/lib/components/shared/stock-level-label.tsx +3 -5
  235. package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +3 -1
  236. package/src/lib/components/shared/tax-category-selector.tsx +1 -1
  237. package/src/lib/components/shared/translatable-form-field.tsx +15 -15
  238. package/src/lib/components/shared/zone-selector.tsx +1 -1
  239. package/src/lib/constants.ts +10 -0
  240. package/src/lib/framework/dashboard-widget/base-widget.tsx +11 -9
  241. package/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx +6 -4
  242. package/src/lib/framework/dashboard-widget/metrics-widget/index.tsx +8 -5
  243. package/src/lib/framework/dashboard-widget/orders-summary/index.tsx +7 -4
  244. package/src/lib/framework/dashboard-widget/widget-filters-context.tsx +3 -1
  245. package/src/lib/framework/defaults.ts +34 -63
  246. package/src/lib/framework/layout-engine/page-layout.tsx +36 -36
  247. package/src/lib/framework/page/detail-page.tsx +10 -10
  248. package/src/lib/framework/page/use-extended-router.tsx +48 -23
  249. package/src/lib/graphql/api.ts +22 -7
  250. package/src/lib/graphql/graphql-env.d.ts +13 -25
  251. package/src/lib/hooks/use-display-locale.ts +40 -0
  252. package/src/lib/hooks/use-dynamic-translations.ts +46 -0
  253. package/src/lib/hooks/use-extended-detail-query.ts +1 -1
  254. package/src/lib/hooks/use-extended-list-query.ts +1 -1
  255. package/src/lib/hooks/use-local-format.ts +15 -1
  256. package/src/lib/hooks/use-saved-views.ts +7 -0
  257. package/src/lib/hooks/use-ui-language-loader.ts +30 -0
  258. package/src/lib/lib/load-i18n-messages.ts +17 -0
  259. package/src/lib/lib/trans.tsx +15 -11
  260. package/src/lib/providers/auth.tsx +2 -2
  261. package/src/lib/providers/channel-provider.tsx +3 -2
  262. package/src/lib/providers/i18n-provider.tsx +7 -14
  263. package/src/lib/providers/user-settings.tsx +46 -5
@@ -10,7 +10,7 @@ import {
10
10
  import { Popover, PopoverContent, PopoverTrigger } from '@/vdb/components/ui/popover.js';
11
11
  import { api } from '@/vdb/graphql/api.js';
12
12
  import { graphql } from '@/vdb/graphql/graphql.js';
13
- import { Trans } from '@/vdb/lib/trans.js';
13
+ import { Trans } from '@lingui/react/macro';
14
14
  import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
15
15
  import { useDebounce } from '@uidotdev/usehooks';
16
16
  import { ChevronRight, Loader2, Plus } from 'lucide-react';
@@ -41,9 +41,9 @@ interface FacetValueSelectorProps {
41
41
  /**
42
42
  * @description
43
43
  * The function to call when a facet value is selected.
44
- *
44
+ *
45
45
  * The `value` will have the following structure:
46
- *
46
+ *
47
47
  * ```ts
48
48
  * {
49
49
  * id: string;
@@ -71,7 +71,7 @@ interface FacetValueSelectorProps {
71
71
  /**
72
72
  * @description
73
73
  * The number of facet values to display per page.
74
- *
74
+ *
75
75
  * @default 4
76
76
  */
77
77
  pageSize?: number;
@@ -129,7 +129,7 @@ const getFacetValuesForFacetDocument = graphql(`
129
129
  /**
130
130
  * @description
131
131
  * A component for selecting facet values.
132
- *
132
+ *
133
133
  * @example
134
134
  * ```tsx
135
135
  * <FacetValueSelector onValueSelect={onValueSelectHandler} disabled={disabled} />
@@ -141,11 +141,11 @@ const getFacetValuesForFacetDocument = graphql(`
141
141
  * @since 3.4.0
142
142
  */
143
143
  export function FacetValueSelector({
144
- onValueSelect,
145
- disabled,
146
- placeholder = 'Search facet values...',
147
- pageSize = 4,
148
- }: FacetValueSelectorProps) {
144
+ onValueSelect,
145
+ disabled,
146
+ placeholder = 'Search facet values...',
147
+ pageSize = 4,
148
+ }: FacetValueSelectorProps) {
149
149
  const [open, setOpen] = useState(false);
150
150
  const [searchTerm, setSearchTerm] = useState('');
151
151
  const [expandedFacetId, setExpandedFacetId] = useState<string | null>(null);
@@ -1,5 +1,5 @@
1
1
  import { Checkbox } from '@/vdb/components/ui/checkbox.js';
2
- import { Trans } from '@/vdb/lib/trans.js';
2
+ import { Trans } from '@lingui/react/macro';
3
3
 
4
4
  interface HistoryNoteCheckboxProps {
5
5
  value: boolean;
@@ -8,7 +8,7 @@ import {
8
8
  DialogTitle,
9
9
  } from '@/vdb/components/ui/dialog.js';
10
10
  import { Textarea } from '@/vdb/components/ui/textarea.js';
11
- import { Trans } from '@/vdb/lib/trans.js';
11
+ import { Trans } from '@lingui/react/macro';
12
12
  import { useState } from 'react';
13
13
  import { HistoryNoteCheckbox } from './history-note-checkbox.js';
14
14
 
@@ -8,7 +8,7 @@ import {
8
8
  } from '@/vdb/components/ui/dropdown-menu.js';
9
9
  import { Separator } from '@/vdb/components/ui/separator.js';
10
10
  import { HistoryEntry, HistoryEntryProps } from '@/vdb/framework/history-entry/history-entry.js';
11
- import { Trans } from '@/vdb/lib/trans.js';
11
+ import { Trans } from '@lingui/react/macro';
12
12
  import { MoreVerticalIcon, PencilIcon, TrashIcon } from 'lucide-react';
13
13
 
14
14
  interface HistoryNoteEntryProps extends Readonly<HistoryEntryProps> {
@@ -1,7 +1,7 @@
1
1
  import { api } from '@/vdb/graphql/api.js';
2
2
  import { graphql } from '@/vdb/graphql/graphql.js';
3
3
  import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
4
- import { useLingui } from '@/vdb/lib/trans.js';
4
+ import { useLingui } from '@lingui/react/macro';
5
5
  import { useQuery } from '@tanstack/react-query';
6
6
  import { MultiSelect } from './multi-select.js';
7
7
 
@@ -28,7 +28,7 @@ export function LanguageSelector<T extends boolean>(props: LanguageSelectorProps
28
28
  });
29
29
  const { formatLanguageName } = useLocalFormat();
30
30
  const { value, onChange, multiple, availableLanguageCodes } = props;
31
- const { i18n } = useLingui();
31
+ const { t } = useLingui();
32
32
 
33
33
  const items = (availableLanguageCodes ?? data?.globalSettings.availableLanguages ?? []).map(language => ({
34
34
  value: language,
@@ -41,8 +41,8 @@ export function LanguageSelector<T extends boolean>(props: LanguageSelectorProps
41
41
  onChange={onChange}
42
42
  multiple={multiple}
43
43
  items={items}
44
- placeholder={i18n.t('Select a language')}
45
- searchPlaceholder={i18n.t('Search languages...')}
44
+ placeholder={t`Select a language`}
45
+ searchPlaceholder={t`Search languages...`}
46
46
  />
47
47
  );
48
48
  }
@@ -1,4 +1,4 @@
1
- import { Trans } from '@/vdb/lib/trans.js';
1
+ import { Trans } from '@lingui/react/macro';
2
2
  import { useBlocker } from '@tanstack/react-router';
3
3
  import { UseFormReturn } from 'react-hook-form';
4
4
 
@@ -14,7 +14,7 @@ import { TypedDocumentNode } from '@graphql-typed-document-node/core';
14
14
  import { ColumnFiltersState, ColumnSort, SortingState, Table } from '@tanstack/react-table';
15
15
  import { ColumnDef, Row, TableOptions, VisibilityState } from '@tanstack/table-core';
16
16
  import React from 'react';
17
- import { getColumnVisibility } from '../data-table/data-table-utils.js';
17
+ import { getColumnVisibility, getStandardizedDefaultColumnOrder } from '../data-table/data-table-utils.js';
18
18
  import { useGeneratedColumns } from '../data-table/use-generated-columns.js';
19
19
 
20
20
  // Type that identifies a paginated list structure (has items array and totalItems)
@@ -89,21 +89,25 @@ export type AllItemFieldKeys<T extends TypedDocumentNode<any, any>> =
89
89
  | keyof PaginatedListItemFields<T>
90
90
  | CustomFieldKeysOfItem<PaginatedListItemFields<T>>;
91
91
 
92
- export type CustomizeColumnConfig<T extends TypedDocumentNode<any, any>> = {
93
- [Key in AllItemFieldKeys<T>]?: Partial<ColumnDef<PaginatedListItemFields<T>, any>> & {
94
- meta?: {
95
- /**
96
- * @description
97
- * Columns that rely on _other_ columns in order to correctly render,
98
- * can declare those other columns as dependencies in order to ensure that
99
- * those columns are always fetched, even when those columns are not explicitly
100
- * included in the visible table columns.
101
- */
102
- dependencies?: Array<AllItemFieldKeys<T>>;
103
- };
92
+ export type ColumnDefWithMetaDependencies<T extends TypedDocumentNode<any, any>> = Partial<
93
+ ColumnDef<T, any>
94
+ > & {
95
+ meta?: {
96
+ /**
97
+ * @description
98
+ * Columns that rely on _other_ columns in order to correctly render,
99
+ * can declare those other columns as dependencies in order to ensure that
100
+ * those columns are always fetched, even when those columns are not explicitly
101
+ * included in the visible table columns.
102
+ */
103
+ dependencies?: Array<AllItemFieldKeys<T>>;
104
104
  };
105
105
  };
106
106
 
107
+ export type CustomizeColumnConfig<T extends TypedDocumentNode<any, any>> = {
108
+ [Key in AllItemFieldKeys<T>]?: ColumnDefWithMetaDependencies<PaginatedListItemFields<T>>;
109
+ };
110
+
107
111
  export type FacetedFilterConfig<T extends TypedDocumentNode<any, any>> = {
108
112
  [Key in AllItemFieldKeys<T>]?: FacetedFilter;
109
113
  };
@@ -145,7 +149,7 @@ export type ListQueryOptionsShape = {
145
149
  };
146
150
 
147
151
  export type AdditionalColumns<T extends TypedDocumentNode<any, any>> = {
148
- [key: string]: ColumnDef<PaginatedListItemFields<T>>;
152
+ [key: string]: ColumnDefWithMetaDependencies<PaginatedListItemFields<T>>;
149
153
  };
150
154
 
151
155
  export interface PaginatedListContext {
@@ -419,15 +423,14 @@ export function PaginatedListDataTable<
419
423
  bulkActions,
420
424
  deleteMutation,
421
425
  additionalColumns,
422
- defaultColumnOrder,
426
+ defaultColumnOrder: getStandardizedDefaultColumnOrder(defaultColumnOrder),
423
427
  });
424
-
425
- const columnVisibility = getColumnVisibility(fields, defaultVisibility, customFieldColumnNames);
428
+ const columnVisibility = getColumnVisibility(columns, defaultVisibility, customFieldColumnNames);
426
429
  // Get the actual visible columns and only fetch those
427
430
  const visibleColumns = columns
428
431
  // Filter out invisible columns, but _always_ select "id"
429
432
  // because it is usually needed.
430
- .filter(c => columnVisibility[c.id as string] || c.id === 'id')
433
+ .filter(c => columnVisibility[c.id as string] !== false || c.id === 'id')
431
434
  .map(c => ({
432
435
  name: c.id as string,
433
436
  isCustomField: (c.meta as any)?.isCustomField ?? false,
@@ -6,7 +6,7 @@ import { DataTableBulkActionItem } from '@/vdb/components/data-table/data-table-
6
6
  import { usePaginatedList } from '@/vdb/components/shared/paginated-list-data-table.js';
7
7
  import { ResultOf } from '@/vdb/graphql/graphql.js';
8
8
  import { useChannel } from '@/vdb/hooks/use-channel.js';
9
- import { Trans, useLingui } from '@/vdb/lib/trans.js';
9
+ import { Trans, useLingui } from '@lingui/react/macro';
10
10
 
11
11
  interface RemoveFromChannelBulkActionProps {
12
12
  selection: any[];
@@ -43,22 +43,23 @@ export function RemoveFromChannelBulkAction({
43
43
  }: Readonly<RemoveFromChannelBulkActionProps>) {
44
44
  const { refetchPaginatedList } = usePaginatedList();
45
45
  const { activeChannel } = useChannel();
46
- const { i18n } = useLingui();
46
+ const { t } = useLingui();
47
+ const selectionLength = selection.length;
47
48
  const { mutate } = useMutation({
48
49
  mutationFn,
49
50
  onSuccess: result => {
50
51
  const message =
51
- successMessage ||
52
- i18n.t(`Successfully removed ${selection.length} ${entityType} from channel`);
52
+ successMessage || t`Successfully removed ${selectionLength} ${entityType} from channel`;
53
53
  toast.success(message);
54
54
  refetchPaginatedList();
55
55
  table.resetRowSelection();
56
56
  onSuccess?.(result);
57
57
  },
58
58
  onError: error => {
59
+ const onErrorMessage = error.message;
59
60
  const message =
60
61
  errorMessage ||
61
- `Failed to remove ${selection.length} ${entityType} from channel: ${error.message}`;
62
+ `Failed to remove ${selectionLength} ${entityType} from channel: ${onErrorMessage}`;
62
63
  toast.error(message);
63
64
  },
64
65
  });
@@ -1,4 +1,4 @@
1
- import { Trans } from '@/vdb/lib/trans.js';
1
+ import { Trans } from '@lingui/react/macro';
2
2
  import { SetImageOptions } from '@tiptap/extension-image';
3
3
  import { Editor } from '@tiptap/react';
4
4
  import { ImageIcon, PaperclipIcon } from 'lucide-react';
@@ -1,4 +1,4 @@
1
- import { Trans } from '@/vdb/lib/trans.js';
1
+ import { Trans } from '@lingui/react/macro';
2
2
  import { Editor } from '@tiptap/react';
3
3
  import { useEffect, useState } from 'react';
4
4
  import { Button } from '../../ui/button.js';
@@ -1,4 +1,4 @@
1
- import { Trans } from '@/vdb/lib/trans.js';
1
+ import { Trans } from '@lingui/react/macro';
2
2
  import { Editor } from '@tiptap/react';
3
3
  import {
4
4
  BoldIcon,
@@ -1,4 +1,4 @@
1
- import { Trans } from '@/vdb/lib/trans.js';
1
+ import { Trans } from '@lingui/react/macro';
2
2
  import { Editor } from '@tiptap/react';
3
3
  import { MoreHorizontalIcon, MoreVerticalIcon } from 'lucide-react';
4
4
  import { useEffect, useState } from 'react';
@@ -1,5 +1,5 @@
1
1
  import { CUSTOMER_ROLE_CODE, SUPER_ADMIN_ROLE_CODE } from '@/vdb/constants.js';
2
- import { Trans } from '@/vdb/lib/trans.js';
2
+ import { Trans } from '@lingui/react/macro';
3
3
 
4
4
  export function RoleCodeLabel({ code }: Readonly<{ code: string }> | Readonly<{ code: undefined }>) {
5
5
  return code === SUPER_ADMIN_ROLE_CODE ? (
@@ -1,6 +1,6 @@
1
1
  import { api } from '@/vdb/graphql/api.js';
2
2
  import { graphql } from '@/vdb/graphql/graphql.js';
3
- import { useLingui } from '@/vdb/lib/trans.js';
3
+ import { useLingui } from '@lingui/react/macro';
4
4
  import { useQuery } from '@tanstack/react-query';
5
5
  import { MultiSelect } from './multi-select.js';
6
6
 
@@ -24,7 +24,7 @@ export interface RoleSelectorProps<T extends boolean> {
24
24
 
25
25
  export function RoleSelector<T extends boolean>(props: RoleSelectorProps<T>) {
26
26
  const { value, onChange, multiple } = props;
27
- const { i18n } = useLingui();
27
+ const { t } = useLingui();
28
28
 
29
29
  const { data } = useQuery({
30
30
  queryKey: ['roles'],
@@ -49,8 +49,8 @@ export function RoleSelector<T extends boolean>(props: RoleSelectorProps<T>) {
49
49
  onChange={onChange}
50
50
  multiple={multiple}
51
51
  items={items}
52
- placeholder={i18n.t('Select a role')}
53
- searchPlaceholder={i18n.t('Search roles...')}
52
+ placeholder={t`Select a role`}
53
+ searchPlaceholder={t`Search roles...`}
54
54
  />
55
55
  );
56
56
  }
@@ -9,7 +9,7 @@ import {
9
9
  import { Popover, PopoverContent, PopoverTrigger } from '@/vdb/components/ui/popover.js';
10
10
  import { api } from '@/vdb/graphql/api.js';
11
11
  import { graphql } from '@/vdb/graphql/graphql.js';
12
- import { Trans } from '@/vdb/lib/trans.js';
12
+ import { Trans } from '@lingui/react/macro';
13
13
  import { useQuery } from '@tanstack/react-query';
14
14
  import { Plus } from 'lucide-react';
15
15
  import { useState } from 'react';
@@ -1,4 +1,4 @@
1
- import { useLingui } from '../../lib/trans.js';
1
+ import { useLingui } from '@lingui/react/macro';
2
2
 
3
3
  export type StockLevel = {
4
4
  stockOnHand: number;
@@ -6,7 +6,7 @@ export type StockLevel = {
6
6
  };
7
7
 
8
8
  export function StockLevelLabel({ stockLevels }: Readonly<{ stockLevels: StockLevel[] }>) {
9
- const { i18n } = useLingui();
9
+ const { t } = useLingui();
10
10
 
11
11
  if (!Array.isArray(stockLevels)) {
12
12
  return null;
@@ -15,9 +15,7 @@ export function StockLevelLabel({ stockLevels }: Readonly<{ stockLevels: StockLe
15
15
  const totalAllocated = stockLevels.reduce((acc, curr) => acc + curr.stockAllocated, 0);
16
16
 
17
17
  return (
18
- <span
19
- title={`${i18n.t('Stock on hand')}: ${totalOnHand}, ${i18n.t('Stock allocated')}: ${totalAllocated}`}
20
- >
18
+ <span title={`${t`Stock on hand`}: ${totalOnHand}, ${t`Stock allocated`}: ${totalAllocated}`}>
21
19
  {totalOnHand} <span className="text-muted-foreground">/ {totalAllocated}</span>
22
20
  </span>
23
21
  );
@@ -2,6 +2,7 @@ import { Money } from '@/vdb/components/data-display/money.js';
2
2
  import { DataTableCellComponent } from '@/vdb/components/data-table/types.js';
3
3
  import { Badge } from '@/vdb/components/ui/badge.js';
4
4
  import { Button } from '@/vdb/components/ui/button.js';
5
+ import { useDynamicTranslations } from '@/vdb/hooks/use-dynamic-translations.js';
5
6
  import { Link } from '@tanstack/react-router';
6
7
 
7
8
  type CustomerCellData = {
@@ -27,8 +28,9 @@ export const CustomerCell: DataTableCellComponent<CustomerCellData> = ({ row })
27
28
  };
28
29
 
29
30
  export const OrderStateCell: DataTableCellComponent<{ state: string }> = ({ row }) => {
31
+ const { getTranslatedOrderState } = useDynamicTranslations();
30
32
  const value = row.original.state;
31
- return <Badge variant="outline">{value}</Badge>;
33
+ return <Badge variant="outline">{getTranslatedOrderState(value)}</Badge>;
32
34
  };
33
35
 
34
36
  export const OrderMoneyCell: DataTableCellComponent<{ currencyCode: string }> = ({ cell, row }) => {
@@ -8,7 +8,7 @@ import {
8
8
  } from '@/vdb/components/ui/select.js';
9
9
  import { api } from '@/vdb/graphql/api.js';
10
10
  import { graphql } from '@/vdb/graphql/graphql.js';
11
- import { Trans } from '@/vdb/lib/trans.js';
11
+ import { Trans } from '@lingui/react/macro';
12
12
  import { useQuery } from '@tanstack/react-query';
13
13
  import { Skeleton } from '../ui/skeleton.js';
14
14
 
@@ -2,7 +2,7 @@ import { OverriddenFormComponent } from '@/vdb/framework/form-engine/overridden-
2
2
  import { LocationWrapper } from '@/vdb/framework/layout-engine/location-wrapper.js';
3
3
  import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
4
4
  import { useUserSettings } from '@/vdb/hooks/use-user-settings.js';
5
- import { Trans } from '@/vdb/lib/trans.js';
5
+ import { Trans } from '@lingui/react/macro';
6
6
  import { Controller, ControllerProps, FieldPath, FieldValues } from 'react-hook-form';
7
7
  import { FormControl, FormDescription, FormItem, FormLabel, FormMessage } from '../ui/form.js';
8
8
  import { FormFieldWrapper } from './form-field-wrapper.js';
@@ -35,17 +35,17 @@ export type TranslatableFormFieldProps<TFieldValues extends TranslatableEntity |
35
35
  name: TFieldValues extends TranslatableEntity
36
36
  ? keyof Omit<NonNullable<TFieldValues['translations']>[number], 'languageCode'>
37
37
  : TFieldValues extends TranslatableEntity[]
38
- ? keyof Omit<NonNullable<TFieldValues[number]['translations']>[number], 'languageCode'>
39
- : never;
38
+ ? keyof Omit<NonNullable<TFieldValues[number]['translations']>[number], 'languageCode'>
39
+ : never;
40
40
  };
41
41
 
42
42
  export const TranslatableFormField = <
43
43
  TFieldValues extends TranslatableEntity | TranslatableEntity[] = TranslatableEntity,
44
44
  >({
45
- name,
46
- label,
47
- ...props
48
- }: TranslatableFormFieldProps<TFieldValues>) => {
45
+ name,
46
+ label,
47
+ ...props
48
+ }: TranslatableFormFieldProps<TFieldValues>) => {
49
49
  const { formatLanguageName } = useLocalFormat();
50
50
  const { contentLanguage } = useUserSettings().settings;
51
51
  const formValues = props.control?._formValues;
@@ -76,7 +76,7 @@ export type TranslatableFormFieldWrapperProps<
76
76
  /**
77
77
  * @description
78
78
  * This is the equivalent of the {@link FormFieldWrapper} component, but for translatable fields.
79
- *
79
+ *
80
80
  * @example
81
81
  * ```tsx
82
82
  * <PageBlock column="main" blockId="main-form">
@@ -112,13 +112,13 @@ export type TranslatableFormFieldWrapperProps<
112
112
  export const TranslatableFormFieldWrapper = <
113
113
  TFieldValues extends TranslatableEntity | TranslatableEntity[] = TranslatableEntity,
114
114
  >({
115
- name,
116
- label,
117
- description,
118
- render,
119
- renderFormControl,
120
- ...props
121
- }: TranslatableFormFieldWrapperProps<TFieldValues>) => {
115
+ name,
116
+ label,
117
+ description,
118
+ render,
119
+ renderFormControl,
120
+ ...props
121
+ }: TranslatableFormFieldWrapperProps<TFieldValues>) => {
122
122
  return (
123
123
  <LocationWrapper identifier={name as string}>
124
124
  <TranslatableFormField
@@ -8,7 +8,7 @@ import {
8
8
  } from '@/vdb/components/ui/select.js';
9
9
  import { api } from '@/vdb/graphql/api.js';
10
10
  import { graphql } from '@/vdb/graphql/graphql.js';
11
- import { Trans } from '@/vdb/lib/trans.js';
11
+ import { Trans } from '@lingui/react/macro';
12
12
  import { useQuery } from '@tanstack/react-query';
13
13
  import { Skeleton } from '../ui/skeleton.js';
14
14
 
@@ -3,6 +3,16 @@ export const AUTHENTICATED_ROUTE_PREFIX = '/_authenticated';
3
3
  export const DEFAULT_CHANNEL_CODE = '__default_channel__';
4
4
  export const SUPER_ADMIN_ROLE_CODE = '__super_admin_role__';
5
5
  export const CUSTOMER_ROLE_CODE = '__customer_role__';
6
+
7
+ /**
8
+ * Local storage keys
9
+ */
10
+ export const LS_KEY_SESSION_TOKEN = 'vendure-session-token';
11
+ export const LS_KEY_USER_SETTINGS = 'vendure-user-settings';
12
+ export const LS_KEY_SELECTED_CHANNEL_TOKEN = 'vendure-selected-channel-token';
13
+ export const LS_KEY_SHIPPING_TEST_ORDER = 'vendure-shipping-test-order';
14
+ export const LS_KEY_SHIPPING_TEST_ADDRESS = 'vendure-shipping-test-address';
15
+
6
16
  /**
7
17
  * This is copied from the generated types from @vendure/common/lib/generated-types.d.ts
8
18
  * It is used to provide a list of available currency codes for the user to select from.
@@ -1,6 +1,7 @@
1
1
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/vdb/components/ui/card.js';
2
2
  import { DashboardBaseWidgetProps } from '@/vdb/framework/extension-api/types/index.js';
3
- import { Trans } from '@/vdb/lib/trans.js';
3
+ import { Trans } from '@lingui/react/macro';
4
+ import { useLingui } from '@lingui/react/macro';
4
5
  import { cn } from '@/vdb/lib/utils.js';
5
6
  import { createContext, useContext, useEffect, useRef, useState } from 'react';
6
7
 
@@ -12,21 +13,22 @@ type WidgetDimensions = {
12
13
  export const WidgetContentContext = createContext<WidgetDimensions>({ width: 0, height: 0 });
13
14
 
14
15
  export const useWidgetDimensions = () => {
16
+ const { t } = useLingui();
15
17
  const context = useContext(WidgetContentContext);
16
18
  if (!context) {
17
- throw new Error('useWidgetDimensions must be used within a DashboardBaseWidget');
19
+ throw new Error(t`useWidgetDimensions must be used within a DashboardBaseWidget`);
18
20
  }
19
21
  return context;
20
22
  };
21
23
 
22
24
  export function DashboardBaseWidget({
23
- id,
24
- config,
25
- children,
26
- title,
27
- description,
28
- actions,
29
- }: DashboardBaseWidgetProps) {
25
+ id,
26
+ config,
27
+ children,
28
+ title,
29
+ description,
30
+ actions,
31
+ }: DashboardBaseWidgetProps) {
30
32
  const headerRef = useRef<HTMLDivElement>(null);
31
33
  const wrapperRef = useRef<HTMLDivElement>(null);
32
34
  const contentRef = useRef<HTMLDivElement>(null);
@@ -6,6 +6,7 @@ import {
6
6
  } from '@/vdb/components/shared/table-cell/order-table-cell-components.js';
7
7
  import { Button } from '@/vdb/components/ui/button.js';
8
8
  import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
9
+ import { useLingui } from '@lingui/react/macro';
9
10
  import { Link } from '@tanstack/react-router';
10
11
  import { ColumnFiltersState, SortingState } from '@tanstack/react-table';
11
12
  import { formatRelative } from 'date-fns';
@@ -17,6 +18,7 @@ import { latestOrdersQuery } from './latest-orders-widget.graphql.js';
17
18
  export const WIDGET_ID = 'latest-orders-widget';
18
19
 
19
20
  export function LatestOrdersWidget() {
21
+ const { t } = useLingui();
20
22
  const { dateRange } = useWidgetFilters();
21
23
  const [sorting, setSorting] = useState<SortingState>([
22
24
  {
@@ -55,7 +57,7 @@ export function LatestOrdersWidget() {
55
57
  }, [dateRange]);
56
58
 
57
59
  return (
58
- <DashboardBaseWidget id={WIDGET_ID} title="Latest Orders" description="Your latest orders">
60
+ <DashboardBaseWidget id={WIDGET_ID} title={t`Latest Orders`} description={t`Your latest orders`}>
59
61
  <PaginatedListDataTable
60
62
  page={page}
61
63
  transformVariables={variables => ({
@@ -75,7 +77,7 @@ export function LatestOrdersWidget() {
75
77
  })}
76
78
  customizeColumns={{
77
79
  code: {
78
- header: 'Code',
80
+ header: t`Code`,
79
81
  cell: ({ row }) => {
80
82
  return (
81
83
  <Button variant="ghost" asChild>
@@ -85,7 +87,7 @@ export function LatestOrdersWidget() {
85
87
  },
86
88
  },
87
89
  orderPlacedAt: {
88
- header: 'Placed At',
90
+ header: t`Placed At`,
89
91
  cell: ({ row }) => {
90
92
  return (
91
93
  <span className="capitalize">
@@ -95,7 +97,7 @@ export function LatestOrdersWidget() {
95
97
  },
96
98
  },
97
99
  total: {
98
- header: 'Total',
100
+ header: t`Total`,
99
101
  cell: OrderMoneyCell,
100
102
  },
101
103
  totalWithTax: { cell: OrderMoneyCell },
@@ -3,6 +3,8 @@ import { Tabs, TabsList, TabsTrigger } from '@/vdb/components/ui/tabs.js';
3
3
  import { api } from '@/vdb/graphql/api.js';
4
4
  import { useChannel } from '@/vdb/hooks/use-channel.js';
5
5
  import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
6
+ import { Trans } from '@lingui/react/macro';
7
+ import { useLingui } from '@lingui/react/macro';
6
8
  import { useQuery } from '@tanstack/react-query';
7
9
  import { RefreshCw } from 'lucide-react';
8
10
  import { useMemo, useState } from 'react';
@@ -18,6 +20,7 @@ enum DATA_TYPES {
18
20
  }
19
21
 
20
22
  export function MetricsWidget() {
23
+ const { t } = useLingui();
21
24
  const { formatDate, formatCurrency } = useLocalFormat();
22
25
  const { activeChannel } = useChannel();
23
26
  const { dateRange } = useWidgetFilters();
@@ -57,16 +60,16 @@ export function MetricsWidget() {
57
60
  return (
58
61
  <DashboardBaseWidget
59
62
  id="metrics-widget"
60
- title="Metrics"
61
- description="Order metrics"
63
+ title={t`Metrics`}
64
+ description={t`Order metrics`}
62
65
  actions={
63
66
  <div className="flex gap-1">
64
67
  <Tabs defaultValue={dataType} onValueChange={value => setDataType(value as DATA_TYPES)}>
65
68
  <TabsList>
66
- <TabsTrigger value={DATA_TYPES.OrderCount}>Order Count</TabsTrigger>
67
- <TabsTrigger value={DATA_TYPES.OrderTotal}>Order Total</TabsTrigger>
69
+ <TabsTrigger value={DATA_TYPES.OrderCount}><Trans>Order Count</Trans></TabsTrigger>
70
+ <TabsTrigger value={DATA_TYPES.OrderTotal}><Trans>Order Total</Trans></TabsTrigger>
68
71
  <TabsTrigger value={DATA_TYPES.AverageOrderValue}>
69
- Average Order Value
72
+ <Trans>Average Order Value</Trans>
70
73
  </TabsTrigger>
71
74
  </TabsList>
72
75
  </Tabs>
@@ -1,5 +1,7 @@
1
1
  import { AnimatedCurrency, AnimatedNumber } from '@/vdb/components/shared/animated-number.js';
2
2
  import { api } from '@/vdb/graphql/api.js';
3
+ import { Trans } from '@lingui/react/macro';
4
+ import { useLingui } from '@lingui/react/macro';
3
5
  import { useQuery } from '@tanstack/react-query';
4
6
  import { differenceInDays, subDays } from 'date-fns';
5
7
  import { useMemo } from 'react';
@@ -27,6 +29,7 @@ function PercentageChange({ value }: PercentageChangeProps) {
27
29
  }
28
30
 
29
31
  export function OrdersSummaryWidget() {
32
+ const { t } = useLingui();
30
33
  const { dateRange } = useWidgetFilters();
31
34
 
32
35
  const variables = useMemo(() => {
@@ -78,13 +81,13 @@ export function OrdersSummaryWidget() {
78
81
  return (
79
82
  <DashboardBaseWidget
80
83
  id={WIDGET_ID}
81
- title="Orders Summary"
82
- description="Your orders summary"
84
+ title={t`Orders Summary`}
85
+ description={t`Your orders summary`}
83
86
  >
84
87
  <div className="@container h-full">
85
88
  <div className="flex flex-col h-full @md:flex-row gap-8 items-center justify-center @md:justify-evenly text-center tabular-nums">
86
89
  <div className="flex flex-col lg:gap-2">
87
- <p className="lg:text-lg text-muted-foreground">Total Orders</p>
90
+ <p className="lg:text-lg text-muted-foreground"><Trans>Total Orders</Trans></p>
88
91
  <p className="text-xl @md:text-3xl font-semibold">
89
92
  <AnimatedNumber
90
93
  animationConfig={{ mass: 0.01, stiffness: 90, damping: 3 }}
@@ -94,7 +97,7 @@ export function OrdersSummaryWidget() {
94
97
  <PercentageChange value={orderChange} />
95
98
  </div>
96
99
  <div className="flex flex-col lg:gap-2">
97
- <p className="lg:text-lg text-muted-foreground">Total Revenue</p>
100
+ <p className="lg:text-lg text-muted-foreground"><Trans>Total Revenue</Trans></p>
98
101
  <p className="text-xl @md:text-3xl font-semibold">
99
102
  <AnimatedCurrency
100
103
  animationConfig={{ mass: 0.01, stiffness: 90, damping: 3 }}