@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
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { useDayPickerLocale } from '@/vdb/components/data-input/index.js';
|
|
3
4
|
import { Button } from '@/vdb/components/ui/button.js';
|
|
4
5
|
import { Calendar } from '@/vdb/components/ui/calendar.js';
|
|
5
6
|
import { Popover, PopoverContent, PopoverTrigger } from '@/vdb/components/ui/popover.js';
|
|
6
7
|
import { DefinedDateRange } from '@/vdb/framework/dashboard-widget/widget-filters-context.js';
|
|
8
|
+
import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
|
|
7
9
|
import { cn } from '@/vdb/lib/utils.js';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
endOfDay,
|
|
11
|
-
endOfMonth,
|
|
12
|
-
endOfWeek,
|
|
13
|
-
format,
|
|
14
|
-
startOfDay,
|
|
15
|
-
startOfMonth,
|
|
16
|
-
startOfWeek,
|
|
17
|
-
subDays
|
|
18
|
-
} from 'date-fns';
|
|
10
|
+
import { Trans, useLingui } from '@lingui/react/macro';
|
|
11
|
+
import { endOfDay, endOfMonth, endOfWeek, startOfDay, startOfMonth, startOfWeek, subDays } from 'date-fns';
|
|
19
12
|
import { CalendarIcon } from 'lucide-react';
|
|
20
13
|
import * as React from 'react';
|
|
21
14
|
import { DateRange } from 'react-day-picker';
|
|
@@ -28,56 +21,64 @@ interface DateRangePickerProps {
|
|
|
28
21
|
|
|
29
22
|
const presets = [
|
|
30
23
|
{
|
|
31
|
-
|
|
24
|
+
id: 'today',
|
|
25
|
+
label: <Trans context="date-range">Today</Trans>,
|
|
32
26
|
getValue: () => ({
|
|
33
27
|
from: startOfDay(new Date()),
|
|
34
28
|
to: endOfDay(new Date()),
|
|
35
29
|
}),
|
|
36
30
|
},
|
|
37
31
|
{
|
|
38
|
-
|
|
32
|
+
id: 'yesterday',
|
|
33
|
+
label: <Trans context="date-range">Yesterday</Trans>,
|
|
39
34
|
getValue: () => ({
|
|
40
35
|
from: startOfDay(subDays(new Date(), 1)),
|
|
41
36
|
to: endOfDay(subDays(new Date(), 1)),
|
|
42
37
|
}),
|
|
43
38
|
},
|
|
44
39
|
{
|
|
45
|
-
|
|
40
|
+
id: 'last-7-days',
|
|
41
|
+
label: <Trans context="date-range">Last 7 days</Trans>,
|
|
46
42
|
getValue: () => ({
|
|
47
43
|
from: startOfDay(subDays(new Date(), 6)),
|
|
48
44
|
to: endOfDay(new Date()),
|
|
49
45
|
}),
|
|
50
46
|
},
|
|
51
47
|
{
|
|
52
|
-
|
|
48
|
+
id: 'this-week',
|
|
49
|
+
label: <Trans context="date-range">This week</Trans>,
|
|
53
50
|
getValue: () => ({
|
|
54
51
|
from: startOfWeek(new Date(), { weekStartsOn: 1 }),
|
|
55
52
|
to: endOfWeek(new Date(), { weekStartsOn: 1 }),
|
|
56
53
|
}),
|
|
57
54
|
},
|
|
58
55
|
{
|
|
59
|
-
|
|
56
|
+
id: 'last-30-days',
|
|
57
|
+
label: <Trans context="date-range">Last 30 days</Trans>,
|
|
60
58
|
getValue: () => ({
|
|
61
59
|
from: startOfDay(subDays(new Date(), 29)),
|
|
62
60
|
to: endOfDay(new Date()),
|
|
63
61
|
}),
|
|
64
62
|
},
|
|
65
63
|
{
|
|
66
|
-
|
|
64
|
+
id: 'month-to-date',
|
|
65
|
+
label: <Trans context="date-range">Month to date</Trans>,
|
|
67
66
|
getValue: () => ({
|
|
68
67
|
from: startOfMonth(new Date()),
|
|
69
68
|
to: endOfDay(new Date()),
|
|
70
69
|
}),
|
|
71
70
|
},
|
|
72
71
|
{
|
|
73
|
-
|
|
72
|
+
id: 'this-month',
|
|
73
|
+
label: <Trans context="date-range">This month</Trans>,
|
|
74
74
|
getValue: () => ({
|
|
75
75
|
from: startOfMonth(new Date()),
|
|
76
76
|
to: endOfMonth(new Date()),
|
|
77
77
|
}),
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
|
-
|
|
80
|
+
id: 'last-month',
|
|
81
|
+
label: <Trans context="date-range">Last month</Trans>,
|
|
81
82
|
getValue: () => ({
|
|
82
83
|
from: startOfMonth(subDays(new Date(), 30)),
|
|
83
84
|
to: endOfMonth(subDays(new Date(), 30)),
|
|
@@ -87,16 +88,19 @@ const presets = [
|
|
|
87
88
|
|
|
88
89
|
export function DateRangePicker({ className, dateRange, onDateRangeChange }: DateRangePickerProps) {
|
|
89
90
|
const [open, setOpen] = React.useState(false);
|
|
91
|
+
const { t } = useLingui();
|
|
92
|
+
const { formatDate } = useLocalFormat();
|
|
93
|
+
const locale = useDayPickerLocale();
|
|
90
94
|
// Internal state uses react-day-picker's DateRange type for Calendar compatibility
|
|
91
95
|
const [selectedRange, setSelectedRange] = React.useState<DateRange>({
|
|
92
96
|
from: dateRange.from,
|
|
93
|
-
to: dateRange.to
|
|
97
|
+
to: dateRange.to,
|
|
94
98
|
});
|
|
95
99
|
|
|
96
100
|
React.useEffect(() => {
|
|
97
101
|
setSelectedRange({
|
|
98
102
|
from: dateRange.from,
|
|
99
|
-
to: dateRange.to
|
|
103
|
+
to: dateRange.to,
|
|
100
104
|
});
|
|
101
105
|
}, [dateRange]);
|
|
102
106
|
|
|
@@ -106,14 +110,14 @@ export function DateRangePicker({ className, dateRange, onDateRangeChange }: Dat
|
|
|
106
110
|
const to = range.to || range.from;
|
|
107
111
|
const finalRange: DefinedDateRange = {
|
|
108
112
|
from: range.from,
|
|
109
|
-
to: to
|
|
113
|
+
to: to,
|
|
110
114
|
};
|
|
111
115
|
setSelectedRange({ from: range.from, to });
|
|
112
116
|
onDateRangeChange(finalRange);
|
|
113
117
|
}
|
|
114
118
|
};
|
|
115
119
|
|
|
116
|
-
const handlePresetClick = (preset: typeof presets[number]) => {
|
|
120
|
+
const handlePresetClick = (preset: (typeof presets)[number]) => {
|
|
117
121
|
const range = preset.getValue();
|
|
118
122
|
handleSelect(range);
|
|
119
123
|
setOpen(false);
|
|
@@ -121,15 +125,15 @@ export function DateRangePicker({ className, dateRange, onDateRangeChange }: Dat
|
|
|
121
125
|
|
|
122
126
|
const formatDateRange = () => {
|
|
123
127
|
if (!selectedRange.from) {
|
|
124
|
-
return
|
|
128
|
+
return t`Select date range`;
|
|
125
129
|
}
|
|
126
130
|
if (!selectedRange.to || selectedRange.from === selectedRange.to) {
|
|
127
|
-
return
|
|
131
|
+
return formatDate(selectedRange.from, { dateStyle: 'medium' });
|
|
128
132
|
}
|
|
129
|
-
return `${
|
|
133
|
+
return `${formatDate(selectedRange.from, { dateStyle: 'medium' })} - ${formatDate(selectedRange.to, { dateStyle: 'medium' })}`;
|
|
130
134
|
};
|
|
131
135
|
|
|
132
|
-
const isPresetActive = (preset: typeof presets[number]) => {
|
|
136
|
+
const isPresetActive = (preset: (typeof presets)[number]) => {
|
|
133
137
|
if (!selectedRange.from || !selectedRange.to) return false;
|
|
134
138
|
const presetRange = preset.getValue();
|
|
135
139
|
return (
|
|
@@ -143,10 +147,7 @@ export function DateRangePicker({ className, dateRange, onDateRangeChange }: Dat
|
|
|
143
147
|
<PopoverTrigger asChild>
|
|
144
148
|
<Button
|
|
145
149
|
variant="outline"
|
|
146
|
-
className={cn(
|
|
147
|
-
'w-[280px] justify-start text-left font-normal',
|
|
148
|
-
className
|
|
149
|
-
)}
|
|
150
|
+
className={cn('w-[280px] justify-start text-left font-normal', className)}
|
|
150
151
|
>
|
|
151
152
|
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
152
153
|
{formatDateRange()}
|
|
@@ -155,9 +156,9 @@ export function DateRangePicker({ className, dateRange, onDateRangeChange }: Dat
|
|
|
155
156
|
<PopoverContent className="w-auto p-0" align="start">
|
|
156
157
|
<div className="flex">
|
|
157
158
|
<div className="border-r p-2 space-y-0.5 min-w-0 w-32">
|
|
158
|
-
{presets.map(
|
|
159
|
+
{presets.map(preset => (
|
|
159
160
|
<Button
|
|
160
|
-
key={preset.
|
|
161
|
+
key={preset.id}
|
|
161
162
|
variant={isPresetActive(preset) ? 'default' : 'ghost'}
|
|
162
163
|
size="sm"
|
|
163
164
|
className="w-full justify-start font-normal text-xs h-7 px-2"
|
|
@@ -175,10 +176,11 @@ export function DateRangePicker({ className, dateRange, onDateRangeChange }: Dat
|
|
|
175
176
|
onSelect={handleSelect}
|
|
176
177
|
numberOfMonths={2}
|
|
177
178
|
showOutsideDays={false}
|
|
179
|
+
locale={locale}
|
|
178
180
|
/>
|
|
179
181
|
</div>
|
|
180
182
|
</div>
|
|
181
183
|
</PopoverContent>
|
|
182
184
|
</Popover>
|
|
183
185
|
);
|
|
184
|
-
}
|
|
186
|
+
}
|
|
@@ -9,16 +9,18 @@ import {
|
|
|
9
9
|
} from '@/vdb/components/ui/sidebar.js';
|
|
10
10
|
import { useDashboardExtensions } from '@/vdb/framework/extension-api/use-dashboard-extensions.js';
|
|
11
11
|
import { getNavMenuConfig } from '@/vdb/framework/nav-menu/nav-menu-extensions.js';
|
|
12
|
+
import { useDisplayLocale } from '@/vdb/hooks/use-display-locale.js';
|
|
12
13
|
import * as React from 'react';
|
|
13
14
|
import { ChannelSwitcher } from './channel-switcher.js';
|
|
14
15
|
|
|
15
16
|
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
|
16
17
|
const { extensionsLoaded } = useDashboardExtensions();
|
|
18
|
+
const { isRTL } = useDisplayLocale();
|
|
17
19
|
const { sections } = getNavMenuConfig();
|
|
18
20
|
|
|
19
21
|
return (
|
|
20
22
|
extensionsLoaded && (
|
|
21
|
-
<Sidebar collapsible="icon" {...props}>
|
|
23
|
+
<Sidebar collapsible="icon" {...props} side={isRTL ? 'right' : 'left'}>
|
|
22
24
|
<SidebarHeader>
|
|
23
25
|
<ChannelSwitcher />
|
|
24
26
|
</SidebarHeader>
|
|
@@ -18,8 +18,8 @@ import { useChannel } from '@/vdb/hooks/use-channel.js';
|
|
|
18
18
|
import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
|
|
19
19
|
import { useServerConfig } from '@/vdb/hooks/use-server-config.js';
|
|
20
20
|
import { useUserSettings } from '@/vdb/hooks/use-user-settings.js';
|
|
21
|
-
import { Trans } from '@/vdb/lib/trans.js';
|
|
22
21
|
import { cn } from '@/vdb/lib/utils.js';
|
|
22
|
+
import { Trans } from '@lingui/react/macro';
|
|
23
23
|
import { Link } from '@tanstack/react-router';
|
|
24
24
|
import { useEffect, useState } from 'react';
|
|
25
25
|
import { ManageLanguagesDialog } from './manage-languages-dialog.js';
|
|
@@ -99,13 +99,9 @@ export function ChannelSwitcher() {
|
|
|
99
99
|
<ChannelCodeLabel code={displayChannel?.code} />
|
|
100
100
|
</span>
|
|
101
101
|
<span className="truncate text-xs">
|
|
102
|
-
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
</span>
|
|
106
|
-
) : (
|
|
107
|
-
<span>Language: {formatLanguageName(contentLanguage)}</span>
|
|
108
|
-
)}
|
|
102
|
+
<span>
|
|
103
|
+
<Trans>Language: {formatLanguageName(contentLanguage)}</Trans>
|
|
104
|
+
</span>
|
|
109
105
|
</span>
|
|
110
106
|
</div>
|
|
111
107
|
<ChevronsUpDown className="ml-auto" />
|
|
@@ -139,7 +135,7 @@ export function ChannelSwitcher() {
|
|
|
139
135
|
<ChannelCodeLabel code={channel.code} />
|
|
140
136
|
{channel.id === displayChannel?.id && (
|
|
141
137
|
<span className="ml-auto text-xs text-muted-foreground">
|
|
142
|
-
Current
|
|
138
|
+
<Trans context="current channel">Current</Trans>
|
|
143
139
|
</span>
|
|
144
140
|
)}
|
|
145
141
|
</DropdownMenuItem>
|
|
@@ -168,7 +164,9 @@ export function ChannelSwitcher() {
|
|
|
168
164
|
<span>{formatLanguageName(languageCode)}</span>
|
|
169
165
|
{contentLanguage === languageCode && (
|
|
170
166
|
<span className="ml-auto text-xs text-muted-foreground">
|
|
171
|
-
|
|
167
|
+
<Trans context="active language">
|
|
168
|
+
Active
|
|
169
|
+
</Trans>
|
|
172
170
|
</span>
|
|
173
171
|
)}
|
|
174
172
|
</DropdownMenuItem>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Badge } from '@/vdb/components/ui/badge.js';
|
|
2
2
|
import { Button } from '@/vdb/components/ui/button.js';
|
|
3
3
|
import { useUserSettings } from '@/vdb/hooks/use-user-settings.js';
|
|
4
|
-
import { Trans } from '
|
|
4
|
+
import { Trans } from '@lingui/react/macro';
|
|
5
5
|
import { CodeXmlIcon, XIcon } from 'lucide-react';
|
|
6
6
|
|
|
7
7
|
export function DevModeIndicator() {
|
|
@@ -5,11 +5,13 @@ import {
|
|
|
5
5
|
BreadcrumbList,
|
|
6
6
|
BreadcrumbSeparator,
|
|
7
7
|
} from '@/vdb/components/ui/breadcrumb.js';
|
|
8
|
+
import type { NavMenuItem, NavMenuSection } from '@/vdb/framework/nav-menu/nav-menu-extensions.js';
|
|
9
|
+
import { getNavMenuConfig } from '@/vdb/framework/nav-menu/nav-menu-extensions.js';
|
|
10
|
+
import { useDisplayLocale } from '@/vdb/hooks/use-display-locale.js';
|
|
11
|
+
import { useLingui } from '@lingui/react';
|
|
8
12
|
import { Link, useRouter, useRouterState } from '@tanstack/react-router';
|
|
9
13
|
import * as React from 'react';
|
|
10
14
|
import { Fragment } from 'react';
|
|
11
|
-
import { getNavMenuConfig } from '@/vdb/framework/nav-menu/nav-menu-extensions.js';
|
|
12
|
-
import type { NavMenuItem, NavMenuSection } from '@/vdb/framework/nav-menu/nav-menu-extensions.js';
|
|
13
15
|
|
|
14
16
|
export interface BreadcrumbPair {
|
|
15
17
|
label: string | React.ReactElement;
|
|
@@ -24,7 +26,9 @@ export function GeneratedBreadcrumbs() {
|
|
|
24
26
|
const matches = useRouterState({ select: s => s.matches });
|
|
25
27
|
const currentPath = useRouterState({ select: s => s.location.pathname });
|
|
26
28
|
const router = useRouter();
|
|
29
|
+
const { i18n } = useLingui();
|
|
27
30
|
const navMenuConfig = getNavMenuConfig();
|
|
31
|
+
const { bcp47Tag } = useDisplayLocale();
|
|
28
32
|
const basePath = router.basepath || '';
|
|
29
33
|
|
|
30
34
|
const normalizeBreadcrumb = (breadcrumb: any, pathname: string): BreadcrumbPair[] => {
|
|
@@ -51,9 +55,7 @@ export function GeneratedBreadcrumbs() {
|
|
|
51
55
|
const rawCrumbs: BreadcrumbPair[] = React.useMemo(() => {
|
|
52
56
|
return matches
|
|
53
57
|
.filter(match => match.loaderData?.breadcrumb)
|
|
54
|
-
.flatMap(({ pathname, loaderData }) =>
|
|
55
|
-
normalizeBreadcrumb(loaderData.breadcrumb, pathname)
|
|
56
|
-
);
|
|
58
|
+
.flatMap(({ pathname, loaderData }) => normalizeBreadcrumb(loaderData.breadcrumb, pathname));
|
|
57
59
|
}, [matches]);
|
|
58
60
|
|
|
59
61
|
const isBaseRoute = (p: string) => p === basePath || p === `${basePath}/`;
|
|
@@ -119,8 +121,8 @@ export function GeneratedBreadcrumbs() {
|
|
|
119
121
|
);
|
|
120
122
|
const breadcrumbs: BreadcrumbPair[] = React.useMemo(() => {
|
|
121
123
|
const arr = sectionCrumb ? [sectionCrumb, ...pageCrumbs] : pageCrumbs;
|
|
122
|
-
return arr.filter(
|
|
123
|
-
self.findIndex(x => x.path === c.path && x.label === c.label) === i,
|
|
124
|
+
return arr.filter(
|
|
125
|
+
(c, i, self) => self.findIndex(x => x.path === c.path && x.label === c.label) === i,
|
|
124
126
|
);
|
|
125
127
|
}, [sectionCrumb, pageCrumbs]);
|
|
126
128
|
return (
|
|
@@ -130,7 +132,7 @@ export function GeneratedBreadcrumbs() {
|
|
|
130
132
|
<Fragment key={`${path}-${index}`}>
|
|
131
133
|
<BreadcrumbItem className="hidden md:block">
|
|
132
134
|
<BreadcrumbLink asChild>
|
|
133
|
-
<Link to={path}>{label}</Link>
|
|
135
|
+
<Link to={path}>{typeof label === 'string' ? i18n.t(label) : label}</Link>
|
|
134
136
|
</BreadcrumbLink>
|
|
135
137
|
</BreadcrumbItem>
|
|
136
138
|
{index < arr.length - 1 && <BreadcrumbSeparator className="hidden md:block" />}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { CurrencyCode } from '@/vdb/constants.js';
|
|
2
|
+
import { useDisplayLocale } from '@/vdb/hooks/use-display-locale.js';
|
|
2
3
|
import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
|
|
4
|
+
import { useUiLanguageLoader } from '@/vdb/hooks/use-ui-language-loader.js';
|
|
3
5
|
import { useUserSettings } from '@/vdb/hooks/use-user-settings.js';
|
|
4
|
-
import { Trans } from '
|
|
6
|
+
import { Trans } from '@lingui/react/macro';
|
|
5
7
|
import { useState } from 'react';
|
|
6
8
|
import { uiConfig } from 'virtual:vendure-ui-config';
|
|
7
9
|
import { Button } from '../ui/button.js';
|
|
@@ -11,12 +13,22 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '.
|
|
|
11
13
|
|
|
12
14
|
export function LanguageDialog() {
|
|
13
15
|
const { i18n } = uiConfig;
|
|
16
|
+
const { loadAndActivateLocale } = useUiLanguageLoader();
|
|
14
17
|
const { availableLocales, availableLanguages } = i18n;
|
|
15
18
|
const { settings, setDisplayLanguage, setDisplayLocale } = useUserSettings();
|
|
19
|
+
const { humanReadableLanguageAndLocale } = useDisplayLocale();
|
|
16
20
|
const availableCurrencyCodes = Object.values(CurrencyCode);
|
|
17
|
-
const { formatCurrency, formatLanguageName, formatCurrencyName, formatDate } =
|
|
21
|
+
const { formatCurrency, formatLanguageName, formatRegionName, formatCurrencyName, formatDate } =
|
|
22
|
+
useLocalFormat();
|
|
18
23
|
const [selectedCurrency, setSelectedCurrency] = useState<string>('USD');
|
|
19
24
|
|
|
25
|
+
const orderedAvailableLanguages = availableLanguages.slice().sort((a, b) => a.localeCompare(b));
|
|
26
|
+
const orderedAvailableLocales = availableLocales.slice().sort((a, b) => a.localeCompare(b));
|
|
27
|
+
const handleLanguageChange = async (value: string) => {
|
|
28
|
+
setDisplayLanguage(value);
|
|
29
|
+
void loadAndActivateLocale(value);
|
|
30
|
+
};
|
|
31
|
+
|
|
20
32
|
return (
|
|
21
33
|
<DialogContent>
|
|
22
34
|
<DialogHeader>
|
|
@@ -29,14 +41,15 @@ export function LanguageDialog() {
|
|
|
29
41
|
<Label>
|
|
30
42
|
<Trans>Display language</Trans>
|
|
31
43
|
</Label>
|
|
32
|
-
<Select defaultValue={settings.displayLanguage} onValueChange={
|
|
44
|
+
<Select defaultValue={settings.displayLanguage} onValueChange={handleLanguageChange}>
|
|
33
45
|
<SelectTrigger className="w-full">
|
|
34
46
|
<SelectValue placeholder="Select a language" />
|
|
35
47
|
</SelectTrigger>
|
|
36
48
|
<SelectContent>
|
|
37
|
-
{
|
|
38
|
-
<SelectItem key={language} value={language}>
|
|
39
|
-
{
|
|
49
|
+
{orderedAvailableLanguages.map(language => (
|
|
50
|
+
<SelectItem key={language} value={language} className="flex gap-1">
|
|
51
|
+
<span className="uppercase text-muted-foreground">{language}</span>
|
|
52
|
+
<span>{formatLanguageName(language)}</span>
|
|
40
53
|
</SelectItem>
|
|
41
54
|
))}
|
|
42
55
|
</SelectContent>
|
|
@@ -51,9 +64,10 @@ export function LanguageDialog() {
|
|
|
51
64
|
<SelectValue placeholder="Select a locale" />
|
|
52
65
|
</SelectTrigger>
|
|
53
66
|
<SelectContent>
|
|
54
|
-
{
|
|
55
|
-
<SelectItem key={locale} value={locale}>
|
|
56
|
-
{
|
|
67
|
+
{orderedAvailableLocales.map(locale => (
|
|
68
|
+
<SelectItem key={locale} value={locale} className="flex gap-1">
|
|
69
|
+
<span className="uppercase text-muted-foreground">{locale}</span>
|
|
70
|
+
<span>{formatRegionName(locale)}</span>
|
|
57
71
|
</SelectItem>
|
|
58
72
|
))}
|
|
59
73
|
</SelectContent>
|
|
@@ -62,7 +76,8 @@ export function LanguageDialog() {
|
|
|
62
76
|
</div>
|
|
63
77
|
<div className="bg-sidebar border border-border rounded-md px-6 py-4 space-y-4">
|
|
64
78
|
<span className="font-medium block text-accent-foreground">
|
|
65
|
-
<Trans>Sample Formatting</Trans>:
|
|
79
|
+
<Trans>Sample Formatting</Trans>:{' '}
|
|
80
|
+
<span className="text-muted-foreground">{humanReadableLanguageAndLocale}</span>
|
|
66
81
|
</span>
|
|
67
82
|
<Select defaultValue={selectedCurrency} onValueChange={setSelectedCurrency}>
|
|
68
83
|
<SelectTrigger>
|
|
@@ -77,15 +92,21 @@ export function LanguageDialog() {
|
|
|
77
92
|
</SelectContent>
|
|
78
93
|
</Select>
|
|
79
94
|
<div className="flex flex-col">
|
|
80
|
-
<span className="text-muted-foreground text-sm font-medium">
|
|
95
|
+
<span className="text-muted-foreground text-sm font-medium">
|
|
96
|
+
<Trans>Medium date</Trans>
|
|
97
|
+
</span>
|
|
81
98
|
<span>{formatDate(new Date('2025-03-14'), { dateStyle: 'medium' })}</span>
|
|
82
99
|
</div>
|
|
83
100
|
<div className="flex flex-col">
|
|
84
|
-
<span className="text-muted-foreground text-sm font-medium">
|
|
101
|
+
<span className="text-muted-foreground text-sm font-medium">
|
|
102
|
+
<Trans>Short date</Trans>
|
|
103
|
+
</span>
|
|
85
104
|
<span>{formatDate(new Date('2025-03-14'), { dateStyle: 'short' })}</span>
|
|
86
105
|
</div>
|
|
87
106
|
<div className="flex flex-col">
|
|
88
|
-
<span className="text-muted-foreground text-sm font-medium">
|
|
107
|
+
<span className="text-muted-foreground text-sm font-medium">
|
|
108
|
+
<Trans>Price</Trans>
|
|
109
|
+
</span>
|
|
89
110
|
<span>{formatCurrency(100.0, selectedCurrency)}</span>
|
|
90
111
|
</div>
|
|
91
112
|
</div>
|
|
@@ -17,7 +17,7 @@ import { graphql } from '@/vdb/graphql/graphql.js';
|
|
|
17
17
|
import { useChannel } from '@/vdb/hooks/use-channel.js';
|
|
18
18
|
import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
|
|
19
19
|
import { usePermissions } from '@/vdb/hooks/use-permissions.js';
|
|
20
|
-
import { Trans } from '
|
|
20
|
+
import { Trans } from '@lingui/react/macro';
|
|
21
21
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
22
22
|
import { AlertCircle, Lock } from 'lucide-react';
|
|
23
23
|
import { useEffect, useState } from 'react';
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
NavMenuSectionPlacement,
|
|
16
16
|
} from '@/vdb/framework/nav-menu/nav-menu-extensions.js';
|
|
17
17
|
import { usePermissions } from '@/vdb/hooks/use-permissions.js';
|
|
18
|
+
import { useLingui } from '@lingui/react';
|
|
18
19
|
import { Link, useRouter, useRouterState } from '@tanstack/react-router';
|
|
19
20
|
import { ChevronRight } from 'lucide-react';
|
|
20
21
|
import * as React from 'react';
|
|
@@ -41,6 +42,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
41
42
|
const router = useRouter();
|
|
42
43
|
const routerState = useRouterState();
|
|
43
44
|
const { hasPermissions } = usePermissions();
|
|
45
|
+
const { i18n } = useLingui();
|
|
44
46
|
const currentPath = routerState.location.pathname;
|
|
45
47
|
const basePath = router.basepath || '';
|
|
46
48
|
|
|
@@ -183,12 +185,16 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
183
185
|
const renderTopSection = (item: NavMenuSection | NavMenuItem) => {
|
|
184
186
|
if ('url' in item) {
|
|
185
187
|
return (
|
|
186
|
-
<NavItemWrapper key={item.
|
|
188
|
+
<NavItemWrapper key={item.id} locationId={item.id} order={item.order} offset={true}>
|
|
187
189
|
<SidebarMenuItem>
|
|
188
|
-
<SidebarMenuButton
|
|
190
|
+
<SidebarMenuButton
|
|
191
|
+
tooltip={i18n.t(item.title)}
|
|
192
|
+
asChild
|
|
193
|
+
isActive={isPathActive(item.url)}
|
|
194
|
+
>
|
|
189
195
|
<Link to={item.url}>
|
|
190
196
|
{item.icon && <item.icon />}
|
|
191
|
-
<span>{item.title}</span>
|
|
197
|
+
<span>{i18n.t(item.title)}</span>
|
|
192
198
|
</Link>
|
|
193
199
|
</SidebarMenuButton>
|
|
194
200
|
</SidebarMenuItem>
|
|
@@ -197,7 +203,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
197
203
|
}
|
|
198
204
|
|
|
199
205
|
return (
|
|
200
|
-
<NavItemWrapper key={item.
|
|
206
|
+
<NavItemWrapper key={item.id} locationId={item.id} order={item.order} offset={true}>
|
|
201
207
|
<Collapsible
|
|
202
208
|
asChild
|
|
203
209
|
open={openTopSectionIds.has(item.id)}
|
|
@@ -208,7 +214,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
208
214
|
<CollapsibleTrigger asChild>
|
|
209
215
|
<SidebarMenuButton tooltip={item.title}>
|
|
210
216
|
{item.icon && <item.icon />}
|
|
211
|
-
<span>{item.title}</span>
|
|
217
|
+
<span>{i18n.t(item.title)}</span>
|
|
212
218
|
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
|
|
213
219
|
</SidebarMenuButton>
|
|
214
220
|
</CollapsibleTrigger>
|
|
@@ -216,7 +222,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
216
222
|
<SidebarMenuSub>
|
|
217
223
|
{item.items?.map(subItem => (
|
|
218
224
|
<NavItemWrapper
|
|
219
|
-
key={subItem.
|
|
225
|
+
key={subItem.id}
|
|
220
226
|
locationId={subItem.id}
|
|
221
227
|
order={subItem.order}
|
|
222
228
|
parentLocationId={item.id}
|
|
@@ -227,7 +233,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
227
233
|
isActive={isPathActive(subItem.url)}
|
|
228
234
|
>
|
|
229
235
|
<Link to={subItem.url}>
|
|
230
|
-
<span>{subItem.title}</span>
|
|
236
|
+
<span>{i18n.t(subItem.title)}</span>
|
|
231
237
|
</Link>
|
|
232
238
|
</SidebarMenuSubButton>
|
|
233
239
|
</SidebarMenuSubItem>
|
|
@@ -247,10 +253,14 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
247
253
|
return (
|
|
248
254
|
<NavItemWrapper key={item.title} locationId={item.id} order={item.order} offset={true}>
|
|
249
255
|
<SidebarMenuItem>
|
|
250
|
-
<SidebarMenuButton
|
|
256
|
+
<SidebarMenuButton
|
|
257
|
+
tooltip={i18n.t(item.title)}
|
|
258
|
+
asChild
|
|
259
|
+
isActive={isPathActive(item.url)}
|
|
260
|
+
>
|
|
251
261
|
<Link to={item.url}>
|
|
252
262
|
{item.icon && <item.icon />}
|
|
253
|
-
<span>{item.title}</span>
|
|
263
|
+
<span>{i18n.t(item.title)}</span>
|
|
254
264
|
</Link>
|
|
255
265
|
</SidebarMenuButton>
|
|
256
266
|
</SidebarMenuItem>
|
|
@@ -267,9 +277,9 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
267
277
|
>
|
|
268
278
|
<SidebarMenuItem>
|
|
269
279
|
<CollapsibleTrigger asChild>
|
|
270
|
-
<SidebarMenuButton tooltip={item.title}>
|
|
280
|
+
<SidebarMenuButton tooltip={i18n.t(item.title)}>
|
|
271
281
|
{item.icon && <item.icon />}
|
|
272
|
-
<span>{item.title}</span>
|
|
282
|
+
<span>{i18n.t(item.title)}</span>
|
|
273
283
|
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
|
|
274
284
|
</SidebarMenuButton>
|
|
275
285
|
</CollapsibleTrigger>
|
|
@@ -277,7 +287,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
277
287
|
<SidebarMenuSub>
|
|
278
288
|
{item.items?.map(subItem => (
|
|
279
289
|
<NavItemWrapper
|
|
280
|
-
key={subItem.title}
|
|
290
|
+
key={i18n.t(subItem.title)}
|
|
281
291
|
locationId={subItem.id}
|
|
282
292
|
order={subItem.order}
|
|
283
293
|
parentLocationId={item.id}
|
|
@@ -288,7 +298,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
|
|
|
288
298
|
isActive={isPathActive(subItem.url)}
|
|
289
299
|
>
|
|
290
300
|
<Link to={subItem.url}>
|
|
291
|
-
<span>{subItem.title}</span>
|
|
301
|
+
<span>{i18n.t(subItem.title)}</span>
|
|
292
302
|
</Link>
|
|
293
303
|
</SidebarMenuSubButton>
|
|
294
304
|
</SidebarMenuSubItem>
|