@vendure/dashboard 3.5.0-minor-202510071456 → 3.5.0-minor-202510201346
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/dist/plugin/dashboard.plugin.js +1 -1
- package/dist/vite/utils/ast-utils.spec.js +3 -3
- package/dist/vite/vite-plugin-hmr.d.ts +8 -0
- package/dist/vite/vite-plugin-hmr.js +34 -0
- package/dist/vite/vite-plugin-theme.js +6 -6
- package/dist/vite/vite-plugin-transform-index.js +6 -1
- package/dist/vite/vite-plugin-vendure-dashboard.d.ts +31 -4
- package/dist/vite/vite-plugin-vendure-dashboard.js +89 -34
- package/package.json +17 -5
- package/src/app/app-providers.tsx +4 -1
- package/src/app/common/map-faceted-filter-fields.ts +21 -0
- package/src/app/main.tsx +3 -1
- package/src/app/routes/_authenticated/_administrators/administrators.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_administrators/administrators.tsx +13 -3
- package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +6 -13
- package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +1 -1
- package/src/app/routes/_authenticated/_assets/assets.tsx +17 -1
- package/src/app/routes/_authenticated/_collections/collections.graphql.ts +1 -0
- package/src/app/routes/_authenticated/_collections/collections.tsx +5 -0
- package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +0 -1
- package/src/app/routes/_authenticated/_customers/customers.tsx +9 -5
- package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +0 -6
- package/src/app/routes/_authenticated/_facets/components/facet-value-bulk-actions.tsx +16 -0
- package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +43 -12
- package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +14 -5
- package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +117 -92
- package/src/app/routes/_authenticated/_orders/components/order-detail-shared.tsx +1 -1
- package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +2 -1
- package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +26 -27
- package/src/app/routes/_authenticated/_orders/components/order-table.tsx +5 -3
- package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +6 -9
- package/src/app/routes/_authenticated/_orders/orders.graphql.ts +17 -1
- package/src/app/routes/_authenticated/_orders/orders.tsx +2 -0
- package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +48 -281
- package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +59 -40
- package/src/app/routes/_authenticated/_orders/utils/order-utils.ts +73 -0
- package/src/app/routes/_authenticated/_orders/utils/use-modify-order.ts +312 -0
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +4 -0
- package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +2 -0
- package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +0 -6
- package/src/app/routes/_authenticated/_products/products.tsx +6 -2
- package/src/app/routes/_authenticated/_products/products_.$productId.option-groups.$productOptionGroupId.options_.$id.tsx +4 -8
- package/src/app/routes/_authenticated/_promotions/components/promotion-bulk-actions.tsx +0 -10
- package/src/app/routes/_authenticated/_promotions/promotions.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_promotions/promotions.tsx +12 -0
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +6 -2
- package/src/app/routes/_authenticated/_sellers/sellers.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +4 -0
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +4 -10
- package/src/app/routes/_authenticated/_stock-locations/stock-locations.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_tax-categories/tax-categories.graphql.ts +2 -2
- package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +9 -0
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +1 -0
- package/src/app/routes/_authenticated/_zones/zones.graphql.ts +2 -2
- package/src/app/routes/login.tsx +2 -2
- package/src/i18n/locales/ar.po +420 -289
- package/src/i18n/locales/cs.po +420 -289
- package/src/i18n/locales/de.po +420 -289
- package/src/i18n/locales/en.po +420 -289
- package/src/i18n/locales/es.po +420 -289
- package/src/i18n/locales/fa.po +420 -289
- package/src/i18n/locales/fr.po +468 -337
- package/src/i18n/locales/he.po +420 -289
- package/src/i18n/locales/hr.po +420 -289
- package/src/i18n/locales/it.po +420 -289
- package/src/i18n/locales/ja.po +420 -289
- package/src/i18n/locales/nb.po +420 -289
- package/src/i18n/locales/ne.po +420 -289
- package/src/i18n/locales/pl.po +420 -289
- package/src/i18n/locales/pt_BR.po +420 -289
- package/src/i18n/locales/pt_PT.po +420 -289
- package/src/i18n/locales/ru.po +420 -289
- package/src/i18n/locales/sv.po +420 -289
- package/src/i18n/locales/tr.po +420 -289
- package/src/i18n/locales/uk.po +420 -289
- package/src/i18n/locales/zh_Hans.po +420 -289
- package/src/i18n/locales/zh_Hant.po +420 -289
- package/src/lib/components/data-input/affixed-input.stories.tsx +93 -0
- package/src/lib/components/data-input/affixed-input.tsx +5 -2
- package/src/lib/components/data-input/boolean-input.stories.tsx +102 -0
- package/src/lib/components/data-input/checkbox-input.stories.tsx +61 -0
- package/src/lib/components/data-input/datetime-input.stories.tsx +62 -0
- package/src/lib/components/data-input/datetime-input.tsx +27 -13
- package/src/lib/components/data-input/default-relation-input.tsx +18 -12
- package/src/lib/components/data-input/money-input.stories.tsx +88 -0
- package/src/lib/components/data-input/number-input.stories.tsx +103 -0
- package/src/lib/components/data-input/number-input.tsx +10 -4
- package/src/lib/components/data-input/password-form-input.stories.tsx +65 -0
- package/src/lib/components/data-input/{password-input.tsx → password-form-input.tsx} +1 -1
- package/src/lib/components/data-input/rich-text-input.stories.tsx +92 -0
- package/src/lib/components/data-input/slug-input.stories.tsx +232 -0
- package/src/lib/components/data-input/slug-input.tsx +9 -10
- package/src/lib/components/data-input/text-input.stories.tsx +52 -0
- package/src/lib/components/data-input/textarea-input.stories.tsx +55 -0
- package/src/lib/components/data-table/add-filter-menu.tsx +6 -1
- package/src/lib/components/data-table/column-header-wrapper.tsx +106 -0
- package/src/lib/components/data-table/data-table-bulk-action-item.tsx +11 -9
- package/src/lib/components/data-table/data-table-bulk-actions.tsx +4 -4
- package/src/lib/components/data-table/data-table-column-header.tsx +17 -14
- package/src/lib/components/data-table/data-table-faceted-filter.tsx +33 -11
- package/src/lib/components/data-table/data-table-filter-badge-editable.tsx +35 -0
- package/src/lib/components/data-table/data-table-filter-badge.tsx +23 -16
- package/src/lib/components/data-table/data-table-filter-dialog.tsx +28 -8
- package/src/lib/components/data-table/data-table-pagination.tsx +23 -7
- package/src/lib/components/data-table/data-table.stories.tsx +249 -0
- package/src/lib/components/data-table/data-table.tsx +37 -9
- package/src/lib/components/data-table/filters/data-table-datetime-filter.tsx +79 -34
- package/src/lib/components/data-table/use-generated-columns.tsx +55 -27
- package/src/lib/components/layout/nav-user.tsx +19 -13
- package/src/lib/components/login/login-form.tsx +39 -123
- package/src/lib/components/shared/alerts.tsx +29 -17
- package/src/lib/components/shared/asset/asset-bulk-actions.tsx +3 -3
- package/src/lib/components/shared/asset/asset-gallery.stories.tsx +76 -0
- package/src/lib/components/shared/asset/asset-gallery.tsx +147 -113
- package/src/lib/components/shared/asset/asset-picker-dialog.stories.tsx +58 -0
- package/src/lib/components/shared/customer-group-selector.tsx +5 -2
- package/src/lib/components/shared/detail-page-button.stories.tsx +52 -0
- package/src/lib/components/shared/facet-value-selector.stories.tsx +48 -0
- package/src/lib/components/shared/facet-value-selector.tsx +130 -34
- package/src/lib/components/shared/paginated-list-data-table.stories.tsx +212 -0
- package/src/lib/components/shared/paginated-list-data-table.tsx +12 -12
- package/src/lib/components/shared/permission-guard.stories.tsx +46 -0
- package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +2 -0
- package/src/lib/components/shared/rich-text-editor/responsive-toolbar.tsx +8 -4
- package/src/lib/components/shared/rich-text-editor/rich-text-editor.tsx +1 -0
- package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +40 -0
- package/src/lib/components/shared/vendure-image.stories.tsx +167 -0
- package/src/lib/components/shared/vendure-image.tsx +6 -7
- package/src/lib/components/ui/accordion.stories.tsx +33 -0
- package/src/lib/components/ui/alert-dialog.stories.tsx +48 -0
- package/src/lib/components/ui/alert.stories.tsx +35 -0
- package/src/lib/components/ui/aspect-ratio.stories.tsx +28 -0
- package/src/lib/components/ui/badge.stories.tsx +28 -0
- package/src/lib/components/ui/breadcrumb.stories.tsx +41 -0
- package/src/lib/components/ui/button.stories.tsx +38 -0
- package/src/lib/components/ui/calendar.stories.tsx +22 -0
- package/src/lib/components/ui/card.stories.tsx +28 -0
- package/src/lib/components/ui/carousel.stories.tsx +34 -0
- package/src/lib/components/ui/checkbox.stories.tsx +31 -0
- package/src/lib/components/ui/collapsible.stories.tsx +39 -0
- package/src/lib/components/ui/command.stories.tsx +44 -0
- package/src/lib/components/ui/context-menu.stories.tsx +38 -0
- package/src/lib/components/ui/dialog.stories.tsx +52 -0
- package/src/lib/components/ui/drawer.stories.tsx +50 -0
- package/src/lib/components/ui/dropdown-menu.stories.tsx +41 -0
- package/src/lib/components/ui/hover-card.stories.tsx +38 -0
- package/src/lib/components/ui/input-group.tsx +148 -0
- package/src/lib/components/ui/input-otp.stories.tsx +30 -0
- package/src/lib/components/ui/input.stories.tsx +38 -0
- package/src/lib/components/ui/label.stories.tsx +24 -0
- package/src/lib/components/ui/menubar.stories.tsx +53 -0
- package/src/lib/components/ui/navigation-menu.stories.tsx +54 -0
- package/src/lib/components/ui/pagination.stories.tsx +51 -0
- package/src/lib/components/ui/password-input.stories.tsx +32 -0
- package/src/lib/components/ui/password-input.tsx +29 -0
- package/src/lib/components/ui/popover.stories.tsx +33 -0
- package/src/lib/components/ui/progress.stories.tsx +27 -0
- package/src/lib/components/ui/radio-group.stories.tsx +34 -0
- package/src/lib/components/ui/resizable.stories.tsx +32 -0
- package/src/lib/components/ui/scroll-area.stories.tsx +31 -0
- package/src/lib/components/ui/select.stories.tsx +36 -0
- package/src/lib/components/ui/separator.stories.tsx +35 -0
- package/src/lib/components/ui/sheet.stories.tsx +50 -0
- package/src/lib/components/ui/sidebar-context.ts +16 -0
- package/src/lib/components/ui/sidebar.tsx +2 -13
- package/src/lib/components/ui/skeleton.stories.tsx +26 -0
- package/src/lib/components/ui/slider.stories.tsx +37 -0
- package/src/lib/components/ui/switch.stories.tsx +31 -0
- package/src/lib/components/ui/table.stories.tsx +52 -0
- package/src/lib/components/ui/tabs.stories.tsx +29 -0
- package/src/lib/components/ui/textarea.stories.tsx +32 -0
- package/src/lib/components/ui/toggle-group.stories.tsx +31 -0
- package/src/lib/components/ui/toggle.stories.tsx +39 -0
- package/src/lib/components/ui/tooltip.stories.tsx +30 -0
- package/src/lib/components/ui/tooltip.tsx +2 -2
- package/src/lib/framework/alert/alert-extensions.tsx +0 -11
- package/src/lib/framework/alert/alert-item.tsx +14 -19
- package/src/lib/framework/alert/alerts-indicator.tsx +14 -15
- package/src/lib/framework/alert/search-index-buffer-alert/search-index-buffer-alert.ts +41 -0
- package/src/lib/framework/component-registry/component-registry.tsx +3 -14
- package/src/lib/framework/dashboard-widget/base-widget.tsx +18 -9
- package/src/lib/framework/dashboard-widget/widget-filters-context.tsx +12 -11
- package/src/lib/framework/defaults.ts +9 -13
- package/src/lib/framework/extension-api/input-component-extensions.tsx +8 -3
- package/src/lib/framework/extension-api/logic/alerts.ts +3 -2
- package/src/lib/framework/extension-api/types/alerts.ts +12 -6
- package/src/lib/framework/extension-api/types/data-table.ts +5 -2
- package/src/lib/framework/extension-api/types/login.ts +0 -21
- package/src/lib/framework/layout-engine/custom-form-page.stories.tsx +344 -0
- package/src/lib/framework/layout-engine/page-layout.tsx +11 -9
- package/src/lib/framework/layout-engine/page.stories.tsx +275 -0
- package/src/lib/framework/nav-menu/nav-menu-extensions.ts +32 -19
- package/src/lib/framework/page/detail-page.stories.tsx +151 -0
- package/src/lib/framework/page/list-page.stories.tsx +217 -0
- package/src/lib/framework/page/list-page.tsx +8 -1
- package/src/lib/graphql/api.ts +18 -1
- package/src/lib/graphql/graphql-env.d.ts +1 -1
- package/src/lib/hooks/use-alerts.ts +84 -0
- package/src/lib/hooks/use-floating-bulk-actions.ts +2 -3
- package/src/lib/index.ts +14 -1
- package/src/lib/providers/alerts-provider.tsx +60 -0
- package/src/lib/providers/theme-provider.tsx +6 -3
|
@@ -27,7 +27,7 @@ import { Dialog, DialogTrigger } from '../ui/dialog.js';
|
|
|
27
27
|
import { LanguageDialog } from './language-dialog.js';
|
|
28
28
|
|
|
29
29
|
export function NavUser() {
|
|
30
|
-
const { isMobile } = useSidebar();
|
|
30
|
+
const { isMobile, state } = useSidebar();
|
|
31
31
|
const router = useRouter();
|
|
32
32
|
const navigate = useNavigate();
|
|
33
33
|
const { humanReadableLanguage } = useDisplayLocale();
|
|
@@ -65,13 +65,15 @@ export function NavUser() {
|
|
|
65
65
|
<div className="relative flex rounded-lg border justify-center items-center w-8 h-8">
|
|
66
66
|
{avatarFallback}
|
|
67
67
|
</div>
|
|
68
|
-
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
{state === 'expanded' ? (
|
|
69
|
+
<div className="grid flex-1 text-left text-sm leading-tight">
|
|
70
|
+
<span className="truncate font-semibold">
|
|
71
|
+
{user.firstName} {user.lastName}
|
|
72
|
+
</span>
|
|
73
|
+
<span className="truncate text-xs">{user.emailAddress}</span>
|
|
74
|
+
</div>
|
|
75
|
+
) : null}
|
|
76
|
+
{state === 'expanded' ? <ChevronsUpDown className="ml-auto size-4" /> : null}
|
|
75
77
|
</SidebarMenuButton>
|
|
76
78
|
</DropdownMenuTrigger>
|
|
77
79
|
<DropdownMenuContent
|
|
@@ -115,7 +117,9 @@ export function NavUser() {
|
|
|
115
117
|
</DropdownMenuItem>
|
|
116
118
|
</DialogTrigger>
|
|
117
119
|
<DropdownMenuSub>
|
|
118
|
-
<DropdownMenuSubTrigger
|
|
120
|
+
<DropdownMenuSubTrigger>
|
|
121
|
+
<Trans>Theme</Trans>
|
|
122
|
+
</DropdownMenuSubTrigger>
|
|
119
123
|
<DropdownMenuPortal>
|
|
120
124
|
<DropdownMenuSubContent>
|
|
121
125
|
<DropdownMenuRadioGroup
|
|
@@ -124,15 +128,15 @@ export function NavUser() {
|
|
|
124
128
|
>
|
|
125
129
|
<DropdownMenuRadioItem value="light">
|
|
126
130
|
<Sun />
|
|
127
|
-
<Trans context=
|
|
131
|
+
<Trans context="theme">Light</Trans>
|
|
128
132
|
</DropdownMenuRadioItem>
|
|
129
133
|
<DropdownMenuRadioItem value="dark">
|
|
130
134
|
<Moon />
|
|
131
|
-
<Trans context=
|
|
135
|
+
<Trans context="theme">Dark</Trans>
|
|
132
136
|
</DropdownMenuRadioItem>
|
|
133
137
|
<DropdownMenuRadioItem value="system">
|
|
134
138
|
<Monitor />
|
|
135
|
-
<Trans context=
|
|
139
|
+
<Trans context="theme">System</Trans>
|
|
136
140
|
</DropdownMenuRadioItem>
|
|
137
141
|
</DropdownMenuRadioGroup>
|
|
138
142
|
</DropdownMenuSubContent>
|
|
@@ -141,7 +145,9 @@ export function NavUser() {
|
|
|
141
145
|
</DropdownMenuGroup>
|
|
142
146
|
{isDevMode && (
|
|
143
147
|
<DropdownMenuSub>
|
|
144
|
-
<DropdownMenuSubTrigger
|
|
148
|
+
<DropdownMenuSubTrigger>
|
|
149
|
+
<Trans>Dev Mode</Trans>
|
|
150
|
+
</DropdownMenuSubTrigger>
|
|
145
151
|
<DropdownMenuPortal>
|
|
146
152
|
<DropdownMenuSubContent>
|
|
147
153
|
<DropdownMenuRadioGroup
|
|
@@ -1,31 +1,27 @@
|
|
|
1
1
|
import { Button } from '@/vdb/components/ui/button.js';
|
|
2
2
|
import { Card, CardContent } from '@/vdb/components/ui/card.js';
|
|
3
3
|
import { Input } from '@/vdb/components/ui/input.js';
|
|
4
|
-
import {
|
|
4
|
+
import { PasswordInput } from '@/vdb/components/ui/password-input.js';
|
|
5
5
|
import { cn } from '@/vdb/lib/utils.js';
|
|
6
6
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
7
|
+
import { Trans, useLingui } from '@lingui/react/macro';
|
|
7
8
|
import { Loader2 } from 'lucide-react';
|
|
8
9
|
import * as React from 'react';
|
|
9
10
|
import { useForm } from 'react-hook-form';
|
|
10
11
|
import { toast } from 'sonner';
|
|
11
|
-
import { uiConfig } from 'virtual:vendure-ui-config';
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
import { useLoginExtensions } from '../../framework/extension-api/use-login-extensions.js';
|
|
14
14
|
import { LogoMark } from '../shared/logo-mark.js';
|
|
15
|
-
import { Form, FormControl, FormField, FormItem,
|
|
15
|
+
import { Form, FormControl, FormField, FormItem, FormMessage } from '../ui/form.js';
|
|
16
16
|
import { Separator } from '../ui/separator.js';
|
|
17
17
|
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
urls: { regular: string };
|
|
26
|
-
location: { name: string };
|
|
27
|
-
user: { name: string; links: { html: string } };
|
|
28
|
-
};
|
|
18
|
+
export type LoginFormProps = Readonly<
|
|
19
|
+
{
|
|
20
|
+
loginError?: string;
|
|
21
|
+
isVerifying?: boolean;
|
|
22
|
+
onFormSubmit?: (username: string, password: string) => void;
|
|
23
|
+
} & React.ComponentProps<'div'>
|
|
24
|
+
>;
|
|
29
25
|
|
|
30
26
|
const formSchema = z.object({
|
|
31
27
|
username: z.string().min(1),
|
|
@@ -33,16 +29,8 @@ const formSchema = z.object({
|
|
|
33
29
|
});
|
|
34
30
|
|
|
35
31
|
export function LoginForm({ className, onFormSubmit, isVerifying, loginError, ...props }: LoginFormProps) {
|
|
36
|
-
const [remoteLoginImage, setRemoteLoginImage] = React.useState<RemoteLoginImage | null>(null);
|
|
37
32
|
const loginExtensions = useLoginExtensions();
|
|
38
|
-
|
|
39
|
-
React.useEffect(() => {
|
|
40
|
-
if (!uiConfig.loginImageUrl) {
|
|
41
|
-
fetch('https://login-image.vendure.io')
|
|
42
|
-
.then(res => res.json())
|
|
43
|
-
.then(data => setRemoteLoginImage(data));
|
|
44
|
-
}
|
|
45
|
-
}, []);
|
|
33
|
+
const { t } = useLingui();
|
|
46
34
|
|
|
47
35
|
React.useEffect(() => {
|
|
48
36
|
if (loginError && !isVerifying) {
|
|
@@ -59,60 +47,41 @@ export function LoginForm({ className, onFormSubmit, isVerifying, loginError, ..
|
|
|
59
47
|
});
|
|
60
48
|
|
|
61
49
|
return (
|
|
62
|
-
<div className={cn('flex flex-col gap-6
|
|
63
|
-
|
|
64
|
-
<
|
|
50
|
+
<div className={cn('flex flex-col items-center gap-6', className)} {...props}>
|
|
51
|
+
{loginExtensions.logo ? (
|
|
52
|
+
<loginExtensions.logo.component />
|
|
53
|
+
) : (
|
|
54
|
+
<LogoMark className="text-primary h-8 w-auto" />
|
|
55
|
+
)}
|
|
56
|
+
<Card className="w-full">
|
|
57
|
+
<CardContent className="pt-6">
|
|
65
58
|
<Form {...form}>
|
|
66
59
|
<form
|
|
67
|
-
className="
|
|
60
|
+
className="flex flex-col items-center gap-6"
|
|
68
61
|
onSubmit={form.handleSubmit(data => onFormSubmit?.(data.username, data.password))}
|
|
69
62
|
>
|
|
70
|
-
|
|
71
|
-
<div className="
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
) : (
|
|
83
|
-
<>
|
|
84
|
-
{!uiConfig.hideVendureBranding && (
|
|
85
|
-
<LogoMark className="text-vendure-brand h-6 w-auto" />
|
|
86
|
-
)}
|
|
87
|
-
<div>
|
|
88
|
-
<h1 className="text-2xl font-medium">
|
|
89
|
-
<Trans>Welcome back!</Trans>
|
|
90
|
-
</h1>
|
|
91
|
-
<p className="text-muted-foreground text-balance">
|
|
92
|
-
Login to your Vendure store
|
|
93
|
-
</p>
|
|
94
|
-
</div>
|
|
95
|
-
{loginExtensions.beforeForm && (
|
|
96
|
-
<>
|
|
97
|
-
<Separator className="w-full" />
|
|
98
|
-
<div className="w-full">
|
|
99
|
-
<loginExtensions.beforeForm.component />
|
|
100
|
-
</div>
|
|
101
|
-
</>
|
|
102
|
-
)}
|
|
103
|
-
</>
|
|
104
|
-
)}
|
|
63
|
+
{loginExtensions.beforeForm ? (
|
|
64
|
+
<div className="w-full">
|
|
65
|
+
<loginExtensions.beforeForm.component />
|
|
66
|
+
</div>
|
|
67
|
+
) : (
|
|
68
|
+
<div className="flex flex-col items-center text-center gap-2">
|
|
69
|
+
<h1 className="text-2xl font-semibold tracking-tight">
|
|
70
|
+
<Trans>Welcome to Vendure</Trans>
|
|
71
|
+
</h1>
|
|
72
|
+
<p className="text-sm text-muted-foreground">
|
|
73
|
+
<Trans>Sign in to access the admin dashboard</Trans>
|
|
74
|
+
</p>
|
|
105
75
|
</div>
|
|
76
|
+
)}
|
|
77
|
+
<div className="grid gap-4 w-full">
|
|
106
78
|
<FormField
|
|
107
79
|
control={form.control}
|
|
108
80
|
name="username"
|
|
109
81
|
render={({ field }) => (
|
|
110
82
|
<FormItem>
|
|
111
|
-
<FormLabel htmlFor="email" asChild>
|
|
112
|
-
<Trans>Username</Trans>
|
|
113
|
-
</FormLabel>
|
|
114
83
|
<FormControl>
|
|
115
|
-
<Input {...field} placeholder=
|
|
84
|
+
<Input {...field} placeholder={t`Email`} />
|
|
116
85
|
</FormControl>
|
|
117
86
|
<FormMessage />
|
|
118
87
|
</FormItem>
|
|
@@ -123,84 +92,31 @@ export function LoginForm({ className, onFormSubmit, isVerifying, loginError, ..
|
|
|
123
92
|
name="password"
|
|
124
93
|
render={({ field }) => (
|
|
125
94
|
<FormItem>
|
|
126
|
-
<div className="flex items-center">
|
|
127
|
-
<FormLabel htmlFor="password" asChild>
|
|
128
|
-
<Trans>Password</Trans>
|
|
129
|
-
</FormLabel>
|
|
130
|
-
<a
|
|
131
|
-
tabIndex={-1}
|
|
132
|
-
href="#"
|
|
133
|
-
className="ml-auto text-sm underline-offset-2 hover:underline"
|
|
134
|
-
>
|
|
135
|
-
Forgot your password?
|
|
136
|
-
</a>
|
|
137
|
-
</div>
|
|
138
95
|
<FormControl>
|
|
139
|
-
<
|
|
96
|
+
<PasswordInput {...field} placeholder={t`Password`} />
|
|
140
97
|
</FormControl>
|
|
141
98
|
<FormMessage />
|
|
142
99
|
</FormItem>
|
|
143
100
|
)}
|
|
144
101
|
/>
|
|
145
|
-
<Button type="submit" disabled={isVerifying}>
|
|
102
|
+
<Button type="submit" className="w-full" disabled={isVerifying}>
|
|
146
103
|
{isVerifying && (
|
|
147
104
|
<>
|
|
148
105
|
<Loader2 className="animate-spin" />
|
|
149
106
|
Please wait
|
|
150
107
|
</>
|
|
151
108
|
)}
|
|
152
|
-
{!isVerifying && <
|
|
109
|
+
{!isVerifying && <Trans>Sign in</Trans>}
|
|
153
110
|
</Button>
|
|
154
111
|
</div>
|
|
155
112
|
{loginExtensions.afterForm && (
|
|
156
113
|
<>
|
|
157
|
-
<Separator className="w-full
|
|
158
|
-
|
|
114
|
+
<Separator className="w-full" />
|
|
159
115
|
<loginExtensions.afterForm.component />
|
|
160
116
|
</>
|
|
161
117
|
)}
|
|
162
118
|
</form>
|
|
163
119
|
</Form>
|
|
164
|
-
{loginExtensions.loginImage ? (
|
|
165
|
-
<loginExtensions.loginImage.component />
|
|
166
|
-
) : (
|
|
167
|
-
<div className="bg-muted relative hidden md:block lg:min-h-[500px]">
|
|
168
|
-
{remoteLoginImage && (
|
|
169
|
-
<>
|
|
170
|
-
<img
|
|
171
|
-
src={remoteLoginImage.urls.regular}
|
|
172
|
-
alt="Image"
|
|
173
|
-
className="absolute inset-0 h-full w-full object-cover"
|
|
174
|
-
/>
|
|
175
|
-
<div className="absolute h-full w-full top-0 left-0 flex items-end justify-start bg-gradient-to-b from-transparent to-black/80 p-4 ">
|
|
176
|
-
<div>
|
|
177
|
-
<p className="text-lg font-medium text-white">
|
|
178
|
-
{remoteLoginImage.location.name}
|
|
179
|
-
</p>
|
|
180
|
-
<p className="text-sm text-white/80">
|
|
181
|
-
By
|
|
182
|
-
<a
|
|
183
|
-
className="mx-1 underline"
|
|
184
|
-
href={remoteLoginImage.user.links.html}
|
|
185
|
-
target="_blank"
|
|
186
|
-
>
|
|
187
|
-
{remoteLoginImage.user.name}
|
|
188
|
-
</a>
|
|
189
|
-
on Unsplash
|
|
190
|
-
</p>
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
</>
|
|
194
|
-
)}
|
|
195
|
-
{uiConfig.loginImageUrl && (
|
|
196
|
-
<img
|
|
197
|
-
src={uiConfig.loginImageUrl}
|
|
198
|
-
alt="Login image"
|
|
199
|
-
className="absolute inset-0 h-full w-full object-cover"
|
|
200
|
-
/>
|
|
201
|
-
)}
|
|
202
|
-
</div>
|
|
203
|
-
)}
|
|
204
120
|
</CardContent>
|
|
205
121
|
</Card>
|
|
206
122
|
</div>
|
|
@@ -1,38 +1,50 @@
|
|
|
1
|
-
import { useAlerts } from '@/vdb/framework/alert/alert-extensions.js';
|
|
2
1
|
import { AlertItem } from '@/vdb/framework/alert/alert-item.js';
|
|
3
2
|
import { AlertsIndicator } from '@/vdb/framework/alert/alerts-indicator.js';
|
|
3
|
+
import { useAlerts } from '@/vdb/hooks/use-alerts.js';
|
|
4
|
+
import { Trans } from '@lingui/react/macro';
|
|
4
5
|
import { BellIcon } from 'lucide-react';
|
|
5
6
|
import { Button } from '../ui/button.js';
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
DropdownMenu,
|
|
9
|
+
DropdownMenuContent,
|
|
10
|
+
DropdownMenuLabel,
|
|
11
|
+
DropdownMenuSeparator,
|
|
12
|
+
DropdownMenuTrigger,
|
|
13
|
+
} from '../ui/dropdown-menu.js';
|
|
7
14
|
import { ScrollArea } from '../ui/scroll-area.js';
|
|
8
15
|
|
|
9
16
|
export function Alerts() {
|
|
10
|
-
const { alerts } = useAlerts();
|
|
17
|
+
const { alerts, activeCount } = useAlerts();
|
|
11
18
|
|
|
12
19
|
if (alerts.length === 0) {
|
|
13
20
|
return null;
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
return (
|
|
17
|
-
<
|
|
18
|
-
<
|
|
24
|
+
<DropdownMenu>
|
|
25
|
+
<DropdownMenuTrigger asChild>
|
|
19
26
|
<Button size="icon" variant="ghost" className="relative">
|
|
20
27
|
<BellIcon />
|
|
21
28
|
<AlertsIndicator />
|
|
22
29
|
</Button>
|
|
23
|
-
</
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
</DialogHeader>
|
|
30
|
+
</DropdownMenuTrigger>
|
|
31
|
+
<DropdownMenuContent align="end" className="max-w-[800px] min-w-96">
|
|
32
|
+
<DropdownMenuLabel>Alerts</DropdownMenuLabel>
|
|
33
|
+
<DropdownMenuSeparator />
|
|
28
34
|
<ScrollArea className="max-h-[500px]">
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
{activeCount > 0 ? (
|
|
36
|
+
<div className="flex flex-col divide-y divide-border px-2">
|
|
37
|
+
{alerts.map(alert => (
|
|
38
|
+
<AlertItem className="py-2" key={alert.definition.id} alert={alert} />
|
|
39
|
+
))}
|
|
40
|
+
</div>
|
|
41
|
+
) : (
|
|
42
|
+
<div className="flex items-center justify-center py-10 text-muted-foreground">
|
|
43
|
+
<Trans>No alerts</Trans>
|
|
44
|
+
</div>
|
|
45
|
+
)}
|
|
34
46
|
</ScrollArea>
|
|
35
|
-
</
|
|
36
|
-
</
|
|
47
|
+
</DropdownMenuContent>
|
|
48
|
+
</DropdownMenu>
|
|
37
49
|
);
|
|
38
50
|
}
|
|
@@ -40,7 +40,7 @@ export function AssetBulkActions({ selection, bulkActions, refetch }: Readonly<A
|
|
|
40
40
|
|
|
41
41
|
const { position, shouldShow } = useFloatingBulkActions({
|
|
42
42
|
selectionCount: selection.length,
|
|
43
|
-
containerSelector: '[data-asset-gallery]'
|
|
43
|
+
containerSelector: '[data-asset-gallery]',
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
if (!shouldShow) {
|
|
@@ -70,12 +70,12 @@ export function AssetBulkActions({ selection, bulkActions, refetch }: Readonly<A
|
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
72
|
<div
|
|
73
|
-
className="flex items-center gap-4 px-8 py-2 animate-in fade-in duration-200 fixed transform -translate-x-1/2 bg-
|
|
73
|
+
className="flex items-center gap-4 px-8 py-2 animate-in fade-in duration-200 fixed transform -translate-x-1/2 bg-background shadow-2xl rounded-md border z-50"
|
|
74
74
|
style={{
|
|
75
75
|
height: 'auto',
|
|
76
76
|
maxHeight: '60px',
|
|
77
77
|
bottom: position.bottom,
|
|
78
|
-
left: position.left
|
|
78
|
+
left: position.left,
|
|
79
79
|
}}
|
|
80
80
|
>
|
|
81
81
|
<span className="text-sm text-muted-foreground">
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { AssetGallery } from '@/vdb/components/shared/asset/asset-gallery.js';
|
|
2
|
+
import { FullWidthPageBlock, Page, PageLayout } from '@/vdb/framework/layout-engine/page-layout.js';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
import { RouterContextProvider } from '@tanstack/react-router';
|
|
5
|
+
import { createDemoRoute } from '../../../../../.storybook/providers.js';
|
|
6
|
+
import { withDescription } from '../../../../../.storybook/with-description.js';
|
|
7
|
+
|
|
8
|
+
const meta = {
|
|
9
|
+
title: 'Components/AssetGallery',
|
|
10
|
+
component: AssetGallery,
|
|
11
|
+
...withDescription(import.meta.url, './asset-gallery.js'),
|
|
12
|
+
parameters: {
|
|
13
|
+
layout: 'fullscreen',
|
|
14
|
+
},
|
|
15
|
+
tags: ['autodocs'],
|
|
16
|
+
argTypes: {
|
|
17
|
+
selectable: {
|
|
18
|
+
control: 'boolean',
|
|
19
|
+
description: 'Whether assets can be selected',
|
|
20
|
+
},
|
|
21
|
+
multiSelect: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
options: ['auto', 'manual'],
|
|
24
|
+
description: 'Multi-select mode',
|
|
25
|
+
},
|
|
26
|
+
pageSize: {
|
|
27
|
+
control: 'number',
|
|
28
|
+
description: 'Number of assets per page',
|
|
29
|
+
},
|
|
30
|
+
fixedHeight: {
|
|
31
|
+
control: 'boolean',
|
|
32
|
+
description: 'Whether the gallery has a fixed height',
|
|
33
|
+
},
|
|
34
|
+
showHeader: {
|
|
35
|
+
control: 'boolean',
|
|
36
|
+
description: 'Whether to show the header with search and filters',
|
|
37
|
+
},
|
|
38
|
+
displayBulkActions: {
|
|
39
|
+
control: 'boolean',
|
|
40
|
+
description: 'Whether to display bulk actions bar',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
} satisfies Meta<typeof AssetGallery>;
|
|
44
|
+
|
|
45
|
+
export default meta;
|
|
46
|
+
type Story = StoryObj<typeof meta>;
|
|
47
|
+
|
|
48
|
+
export const Playground: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
selectable: true,
|
|
51
|
+
multiSelect: 'manual',
|
|
52
|
+
pageSize: 12,
|
|
53
|
+
fixedHeight: false,
|
|
54
|
+
showHeader: true,
|
|
55
|
+
displayBulkActions: true,
|
|
56
|
+
},
|
|
57
|
+
render: args => {
|
|
58
|
+
const { route, router } = createDemoRoute();
|
|
59
|
+
return (
|
|
60
|
+
<div className="p-6 h-screen">
|
|
61
|
+
<RouterContextProvider router={router}>
|
|
62
|
+
<Page pageId="test-page">
|
|
63
|
+
<PageLayout>
|
|
64
|
+
<FullWidthPageBlock blockId="test-block">
|
|
65
|
+
<AssetGallery
|
|
66
|
+
{...args}
|
|
67
|
+
onSelect={assets => console.log('Selected:', assets)}
|
|
68
|
+
/>
|
|
69
|
+
</FullWidthPageBlock>
|
|
70
|
+
</PageLayout>
|
|
71
|
+
</Page>
|
|
72
|
+
</RouterContextProvider>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
};
|