@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.
- package/README.md +4 -0
- package/dist/plugin/dashboard.plugin.d.ts +25 -6
- package/dist/plugin/dashboard.plugin.js +184 -27
- package/dist/plugin/default-page.html +188 -0
- package/dist/vite/vite-plugin-config.js +13 -9
- package/dist/vite/vite-plugin-translations.d.ts +22 -0
- package/dist/vite/vite-plugin-translations.js +66 -0
- package/dist/vite/vite-plugin-vendure-dashboard.js +8 -6
- package/lingui.config.js +25 -2
- package/package.json +159 -156
- package/src/app/app-providers.tsx +0 -4
- package/src/app/common/delete-bulk-action.tsx +6 -5
- package/src/app/common/duplicate-bulk-action.tsx +4 -5
- package/src/app/common/duplicate-entity-dialog.tsx +1 -1
- package/src/app/common/set-document-direction.ts +7 -0
- package/src/app/main.tsx +50 -17
- package/src/app/routes/_authenticated/_administrators/administrators.tsx +8 -6
- package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +17 -6
- package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +2 -2
- package/src/app/routes/_authenticated/_assets/assets.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_assets/components/asset-bulk-actions.tsx +8 -6
- package/src/app/routes/_authenticated/_assets/components/asset-tag-filter.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/components/asset-tags-editor.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/components/manage-tags-dialog.tsx +3 -8
- package/src/app/routes/_authenticated/_channels/channels.tsx +3 -6
- package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +5 -5
- package/src/app/routes/_authenticated/_collections/collections.tsx +3 -4
- package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +4 -6
- package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +1 -1
- package/src/app/routes/_authenticated/_collections/components/collection-contents-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_collections/components/move-collections-dialog.tsx +6 -6
- package/src/app/routes/_authenticated/_countries/countries.graphql.ts +2 -0
- package/src/app/routes/_authenticated/_countries/countries.tsx +2 -3
- package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-table.tsx +4 -4
- package/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx +2 -4
- package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_customers/components/customer-address-card.tsx +8 -8
- package/src/app/routes/_authenticated/_customers/components/customer-address-form.tsx +3 -3
- package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-container.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-utils.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-history/default-customer-history-components.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-history/use-customer-history.ts +1 -1
- package/src/app/routes/_authenticated/_customers/components/customer-status-badge.tsx +1 -1
- package/src/app/routes/_authenticated/_customers/customers.graphql.ts +4 -0
- package/src/app/routes/_authenticated/_customers/customers.tsx +23 -11
- package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +10 -8
- package/src/app/routes/_authenticated/_facets/components/edit-facet-value.tsx +1 -1
- package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +6 -5
- package/src/app/routes/_authenticated/_facets/components/facet-values-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +1 -1
- package/src/app/routes/_authenticated/_facets/facets.tsx +5 -5
- package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +7 -5
- package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +5 -5
- package/src/app/routes/_authenticated/_orders/components/add-manual-payment-dialog.tsx +19 -21
- package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +22 -22
- package/src/app/routes/_authenticated/_orders/components/fulfill-order-dialog.tsx +6 -6
- package/src/app/routes/_authenticated/_orders/components/fulfillment-details.tsx +15 -9
- package/src/app/routes/_authenticated/_orders/components/order-address.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-detail-shared.tsx +11 -9
- package/src/app/routes/_authenticated/_orders/components/order-history/default-order-history-components.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-history/order-history-container.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-history/order-history-utils.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-history/use-order-history.ts +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-modification-preview-dialog.tsx +4 -4
- package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +27 -27
- package/src/app/routes/_authenticated/_orders/components/order-table.tsx +2 -2
- package/src/app/routes/_authenticated/_orders/components/order-tax-summary.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/payment-details.tsx +26 -20
- package/src/app/routes/_authenticated/_orders/components/seller-orders-card.tsx +3 -1
- package/src/app/routes/_authenticated/_orders/components/settle-refund-dialog.tsx +6 -6
- package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/use-transition-order-to-state.tsx +3 -2
- package/src/app/routes/_authenticated/_orders/orders.tsx +5 -9
- package/src/app/routes/_authenticated/_orders/orders_.$aggregateOrderId_.seller-orders.$sellerOrderId.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +4 -4
- package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +17 -17
- package/src/app/routes/_authenticated/_orders/utils/order-detail-loaders.tsx +1 -1
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +5 -6
- package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +1 -1
- package/src/app/routes/_authenticated/_product-variants/components/variant-price-detail.tsx +1 -1
- package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +9 -2
- package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_products/components/add-option-group-dialog.tsx +5 -5
- package/src/app/routes/_authenticated/_products/components/add-product-variant-dialog.tsx +5 -5
- package/src/app/routes/_authenticated/_products/components/assign-facet-values-dialog.tsx +5 -4
- package/src/app/routes/_authenticated/_products/components/create-product-options-dialog.tsx +9 -12
- package/src/app/routes/_authenticated/_products/components/create-product-variants-dialog.tsx +1 -1
- package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +4 -4
- package/src/app/routes/_authenticated/_products/components/option-groups-editor.tsx +1 -1
- package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +1 -1
- package/src/app/routes/_authenticated/_products/components/product-option-select.tsx +3 -3
- package/src/app/routes/_authenticated/_products/components/product-options-table.tsx +9 -6
- package/src/app/routes/_authenticated/_products/products.graphql.ts +31 -31
- package/src/app/routes/_authenticated/_products/products.tsx +11 -6
- package/src/app/routes/_authenticated/_products/products_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_products/products_.$id_.variants.tsx +11 -11
- package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$id.tsx +8 -12
- package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$productOptionGroupId.options_.$id.tsx +2 -2
- package/src/app/routes/_authenticated/_profile/profile.tsx +4 -4
- package/src/app/routes/_authenticated/_promotions/promotions.tsx +2 -4
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +16 -9
- package/src/app/routes/_authenticated/_roles/components/permissions-table-grid.tsx +1 -1
- package/src/app/routes/_authenticated/_roles/roles.tsx +3 -6
- package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +4 -6
- package/src/app/routes/_authenticated/_sellers/sellers.tsx +3 -4
- package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_shipping-methods/components/price-display.tsx +5 -5
- package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-test-result-wrapper.tsx +1 -1
- package/src/app/routes/_authenticated/_shipping-methods/components/test-address-form.tsx +4 -3
- package/src/app/routes/_authenticated/_shipping-methods/components/test-order-builder.tsx +4 -3
- package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-result.tsx +8 -8
- package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-methods-sheet.tsx +1 -1
- package/src/app/routes/_authenticated/_shipping-methods/components/test-single-method-result.tsx +8 -8
- package/src/app/routes/_authenticated/_shipping-methods/components/test-single-shipping-method-sheet.tsx +4 -4
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +2 -3
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +2 -2
- package/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx +3 -4
- package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_system/healthchecks.tsx +10 -4
- package/src/app/routes/_authenticated/_system/job-queue.tsx +10 -13
- package/src/app/routes/_authenticated/_system/scheduled-tasks.tsx +18 -16
- package/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx +2 -4
- package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +13 -6
- package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +8 -12
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +6 -4
- package/src/app/routes/_authenticated/_zones/zones.tsx +4 -4
- package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +8 -5
- package/src/app/routes/_authenticated/index.tsx +6 -2
- package/src/app/styles.css +4 -0
- package/src/i18n/common-strings.ts +111 -0
- package/src/i18n/locales/ar.po +4777 -0
- package/src/i18n/locales/cs.po +4777 -0
- package/src/i18n/locales/de.po +4299 -1101
- package/src/i18n/locales/en.po +3857 -659
- package/src/i18n/locales/es.po +4777 -0
- package/src/i18n/locales/fa.po +4777 -0
- package/src/i18n/locales/fr.po +4777 -0
- package/src/i18n/locales/he.po +4777 -0
- package/src/i18n/locales/hr.po +4777 -0
- package/src/i18n/locales/it.po +4777 -0
- package/src/i18n/locales/ja.po +4777 -0
- package/src/i18n/locales/ko.po +4628 -0
- package/src/i18n/locales/nb.po +4777 -0
- package/src/i18n/locales/ne.po +4777 -0
- package/src/i18n/locales/nl.po +4628 -0
- package/src/i18n/locales/pl.po +4777 -0
- package/src/i18n/locales/pt_BR.po +4777 -0
- package/src/i18n/locales/pt_PT.po +4777 -0
- package/src/i18n/locales/ru.po +4777 -0
- package/src/i18n/locales/sv.po +4777 -0
- package/src/i18n/locales/tr.po +4777 -0
- package/src/i18n/locales/uk.po +4777 -0
- package/src/i18n/locales/zh_Hans.po +4777 -0
- package/src/i18n/locales/zh_Hant.po +4777 -0
- package/src/lib/components/data-input/combination-mode-input.tsx +1 -1
- package/src/lib/components/data-input/custom-field-list-input.tsx +11 -7
- package/src/lib/components/data-input/customer-group-input.tsx +27 -33
- package/src/lib/components/data-input/datetime-input.tsx +40 -1
- package/src/lib/components/data-input/default-relation-input.tsx +5 -4
- package/src/lib/components/data-input/product-multi-selector-input.tsx +14 -14
- package/src/lib/components/data-input/relation-selector.tsx +1 -1
- package/src/lib/components/data-input/select-with-options.tsx +1 -1
- package/src/lib/components/data-input/slug-input.tsx +9 -15
- package/src/lib/components/data-table/add-filter-menu.tsx +4 -4
- package/src/lib/components/data-table/data-table-bulk-action-item.tsx +8 -8
- package/src/lib/components/data-table/data-table-bulk-actions.tsx +4 -4
- package/src/lib/components/data-table/data-table-column-header.tsx +13 -8
- package/src/lib/components/data-table/data-table-faceted-filter.tsx +2 -1
- package/src/lib/components/data-table/data-table-filter-dialog.tsx +1 -1
- package/src/lib/components/data-table/data-table-utils.ts +21 -4
- package/src/lib/components/data-table/data-table-view-options.tsx +4 -2
- package/src/lib/components/data-table/data-table.tsx +3 -3
- package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +4 -4
- package/src/lib/components/data-table/global-views-bar.tsx +1 -1
- package/src/lib/components/data-table/human-readable-operator.tsx +1 -1
- package/src/lib/components/data-table/manage-global-views-button.tsx +1 -1
- package/src/lib/components/data-table/my-views-button.tsx +13 -13
- package/src/lib/components/data-table/refresh-button.tsx +1 -1
- package/src/lib/components/data-table/save-view-button.tsx +11 -11
- package/src/lib/components/data-table/use-generated-columns.tsx +10 -7
- package/src/lib/components/data-table/views-sheet.tsx +79 -71
- package/src/lib/components/date-range-picker.tsx +36 -34
- package/src/lib/components/layout/app-sidebar.tsx +3 -1
- package/src/lib/components/layout/channel-switcher.tsx +8 -10
- package/src/lib/components/layout/dev-mode-indicator.tsx +1 -1
- package/src/lib/components/layout/generated-breadcrumbs.tsx +10 -8
- package/src/lib/components/layout/language-dialog.tsx +34 -13
- package/src/lib/components/layout/manage-languages-dialog.tsx +1 -1
- package/src/lib/components/layout/nav-main.tsx +23 -13
- package/src/lib/components/layout/nav-user.tsx +19 -23
- package/src/lib/components/login/login-form.tsx +1 -1
- package/src/lib/components/shared/asset/asset-bulk-actions.tsx +4 -4
- package/src/lib/components/shared/asset/asset-focal-point-editor.tsx +1 -1
- package/src/lib/components/shared/asset/asset-gallery.tsx +15 -14
- package/src/lib/components/shared/assign-to-channel-bulk-action.tsx +11 -11
- package/src/lib/components/shared/assign-to-channel-dialog.tsx +6 -5
- package/src/lib/components/shared/channel-code-label.tsx +1 -1
- package/src/lib/components/shared/channel-selector.tsx +4 -4
- package/src/lib/components/shared/configurable-operation-multi-selector.tsx +16 -14
- package/src/lib/components/shared/configurable-operation-selector.tsx +1 -1
- package/src/lib/components/shared/confirmation-dialog.tsx +8 -8
- package/src/lib/components/shared/country-selector.tsx +1 -1
- package/src/lib/components/shared/currency-selector.tsx +4 -4
- package/src/lib/components/shared/custom-fields-form.tsx +8 -24
- package/src/lib/components/shared/customer-address-form.tsx +3 -3
- package/src/lib/components/shared/customer-group-selector.tsx +1 -1
- package/src/lib/components/shared/customer-selector.tsx +1 -1
- package/src/lib/components/shared/error-page.tsx +1 -1
- package/src/lib/components/shared/facet-value-selector.tsx +10 -10
- package/src/lib/components/shared/history-timeline/history-note-checkbox.tsx +1 -1
- package/src/lib/components/shared/history-timeline/history-note-editor.tsx +1 -1
- package/src/lib/components/shared/history-timeline/history-note-entry.tsx +1 -1
- package/src/lib/components/shared/language-selector.tsx +4 -4
- package/src/lib/components/shared/navigation-confirmation.tsx +1 -1
- package/src/lib/components/shared/paginated-list-data-table.tsx +21 -18
- package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +6 -5
- package/src/lib/components/shared/rich-text-editor/image-dialog.tsx +1 -1
- package/src/lib/components/shared/rich-text-editor/link-dialog.tsx +1 -1
- package/src/lib/components/shared/rich-text-editor/responsive-toolbar.tsx +1 -1
- package/src/lib/components/shared/rich-text-editor/table-edit-icons.tsx +1 -1
- package/src/lib/components/shared/role-code-label.tsx +1 -1
- package/src/lib/components/shared/role-selector.tsx +4 -4
- package/src/lib/components/shared/seller-selector.tsx +1 -1
- package/src/lib/components/shared/stock-level-label.tsx +3 -5
- package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +3 -1
- package/src/lib/components/shared/tax-category-selector.tsx +1 -1
- package/src/lib/components/shared/translatable-form-field.tsx +15 -15
- package/src/lib/components/shared/zone-selector.tsx +1 -1
- package/src/lib/constants.ts +10 -0
- package/src/lib/framework/dashboard-widget/base-widget.tsx +11 -9
- package/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx +6 -4
- package/src/lib/framework/dashboard-widget/metrics-widget/index.tsx +8 -5
- package/src/lib/framework/dashboard-widget/orders-summary/index.tsx +7 -4
- package/src/lib/framework/dashboard-widget/widget-filters-context.tsx +3 -1
- package/src/lib/framework/defaults.ts +34 -63
- package/src/lib/framework/layout-engine/page-layout.tsx +36 -36
- package/src/lib/framework/page/detail-page.tsx +10 -10
- package/src/lib/framework/page/use-extended-router.tsx +48 -23
- package/src/lib/graphql/api.ts +22 -7
- package/src/lib/graphql/graphql-env.d.ts +13 -25
- package/src/lib/hooks/use-display-locale.ts +40 -0
- package/src/lib/hooks/use-dynamic-translations.ts +46 -0
- package/src/lib/hooks/use-extended-detail-query.ts +1 -1
- package/src/lib/hooks/use-extended-list-query.ts +1 -1
- package/src/lib/hooks/use-local-format.ts +15 -1
- package/src/lib/hooks/use-saved-views.ts +7 -0
- package/src/lib/hooks/use-ui-language-loader.ts +30 -0
- package/src/lib/lib/load-i18n-messages.ts +17 -0
- package/src/lib/lib/trans.tsx +15 -11
- package/src/lib/providers/auth.tsx +2 -2
- package/src/lib/providers/channel-provider.tsx +3 -2
- package/src/lib/providers/i18n-provider.tsx +7 -14
- 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 '
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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);
|
|
@@ -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 '
|
|
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 '
|
|
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 '
|
|
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 {
|
|
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={
|
|
45
|
-
searchPlaceholder={
|
|
44
|
+
placeholder={t`Select a language`}
|
|
45
|
+
searchPlaceholder={t`Search languages...`}
|
|
46
46
|
/>
|
|
47
47
|
);
|
|
48
48
|
}
|
|
@@ -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
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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]:
|
|
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 '
|
|
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 {
|
|
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 ${
|
|
62
|
+
`Failed to remove ${selectionLength} ${entityType} from channel: ${onErrorMessage}`;
|
|
62
63
|
toast.error(message);
|
|
63
64
|
},
|
|
64
65
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CUSTOMER_ROLE_CODE, SUPER_ADMIN_ROLE_CODE } from '@/vdb/constants.js';
|
|
2
|
-
import { Trans } from '
|
|
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 '
|
|
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 {
|
|
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={
|
|
53
|
-
searchPlaceholder={
|
|
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 '
|
|
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 '
|
|
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 {
|
|
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 '
|
|
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 '
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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 '
|
|
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
|
|
package/src/lib/constants.ts
CHANGED
|
@@ -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 '
|
|
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(
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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=
|
|
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:
|
|
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:
|
|
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:
|
|
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=
|
|
61
|
-
description=
|
|
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=
|
|
82
|
-
description=
|
|
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 }}
|