@vendure/dashboard 3.5.0-minor-202510012036 → 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/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/package.json +9 -9
- package/src/app/routes/_authenticated/_shipping-methods/components/test-address-form.tsx +13 -12
- package/src/app/routes/_authenticated/_shipping-methods/components/test-order-builder.tsx +3 -2
- package/src/lib/components/data-table/my-views-button.tsx +12 -12
- package/src/lib/components/data-table/save-view-button.tsx +5 -1
- package/src/lib/constants.ts +10 -0
- package/src/lib/graphql/api.ts +17 -4
- package/src/lib/graphql/graphql-env.d.ts +29 -50
- package/src/lib/hooks/use-saved-views.ts +7 -0
- package/src/lib/providers/auth.tsx +2 -2
- package/src/lib/providers/channel-provider.tsx +3 -2
- package/src/lib/providers/user-settings.tsx +46 -5
|
@@ -7,6 +7,7 @@ import { AccordionContent, AccordionItem, AccordionTrigger } from '@/vdb/compone
|
|
|
7
7
|
import { Button } from '@/vdb/components/ui/button.js';
|
|
8
8
|
import { Input } from '@/vdb/components/ui/input.js';
|
|
9
9
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/vdb/components/ui/table.js';
|
|
10
|
+
import { LS_KEY_SHIPPING_TEST_ORDER } from '@/vdb/constants.js';
|
|
10
11
|
import { useChannel } from '@/vdb/hooks/use-channel.js';
|
|
11
12
|
import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
|
|
12
13
|
import { Trans } from '@lingui/react/macro';
|
|
@@ -38,7 +39,7 @@ export function TestOrderBuilder({ onOrderLinesChange }: Readonly<TestOrderBuild
|
|
|
38
39
|
const { activeChannel } = useChannel();
|
|
39
40
|
const [lines, setLines] = useState<TestOrderLine[]>(() => {
|
|
40
41
|
try {
|
|
41
|
-
const stored = localStorage.getItem(
|
|
42
|
+
const stored = localStorage.getItem(LS_KEY_SHIPPING_TEST_ORDER);
|
|
42
43
|
return stored ? JSON.parse(stored) : [];
|
|
43
44
|
} catch {
|
|
44
45
|
return [];
|
|
@@ -51,7 +52,7 @@ export function TestOrderBuilder({ onOrderLinesChange }: Readonly<TestOrderBuild
|
|
|
51
52
|
|
|
52
53
|
useEffect(() => {
|
|
53
54
|
try {
|
|
54
|
-
localStorage.setItem(
|
|
55
|
+
localStorage.setItem(LS_KEY_SHIPPING_TEST_ORDER, JSON.stringify(lines));
|
|
55
56
|
} catch {
|
|
56
57
|
// Ignore localStorage errors
|
|
57
58
|
}
|
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import { Bookmark } from 'lucide-react';
|
|
2
|
-
import React, { useState, useMemo } from 'react';
|
|
3
|
-
import { Button } from '../ui/button.js';
|
|
4
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip.js';
|
|
5
1
|
import { Trans } from '@lingui/react/macro';
|
|
6
|
-
import {
|
|
2
|
+
import { Bookmark } from 'lucide-react';
|
|
3
|
+
import React, { useMemo, useState } from 'react';
|
|
7
4
|
import { useSavedViews } from '../../hooks/use-saved-views.js';
|
|
8
5
|
import { findMatchingSavedView } from '../../utils/saved-views-utils.js';
|
|
6
|
+
import { Button } from '../ui/button.js';
|
|
7
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip.js';
|
|
9
8
|
import { useDataTableContext } from './data-table-context.js';
|
|
9
|
+
import { UserViewsSheet } from './user-views-sheet.js';
|
|
10
10
|
|
|
11
11
|
export const MyViewsButton: React.FC = () => {
|
|
12
12
|
const [sheetOpen, setSheetOpen] = useState(false);
|
|
13
|
-
const { userViews } = useSavedViews();
|
|
14
|
-
const { columnFilters, searchTerm
|
|
13
|
+
const { userViews, savedViewsAreAvailable } = useSavedViews();
|
|
14
|
+
const { columnFilters, searchTerm } = useDataTableContext();
|
|
15
15
|
|
|
16
16
|
// Find the active view using centralized utility
|
|
17
17
|
const activeView = useMemo(() => {
|
|
18
18
|
return findMatchingSavedView(columnFilters, searchTerm, userViews);
|
|
19
19
|
}, [userViews, columnFilters, searchTerm]);
|
|
20
20
|
|
|
21
|
+
if (!savedViewsAreAvailable) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
return (
|
|
22
26
|
<>
|
|
23
27
|
<div className="flex items-center gap-2">
|
|
@@ -35,11 +39,7 @@ export const MyViewsButton: React.FC = () => {
|
|
|
35
39
|
<Trans>My saved views</Trans>
|
|
36
40
|
</TooltipContent>
|
|
37
41
|
</Tooltip>
|
|
38
|
-
{activeView &&
|
|
39
|
-
<span className="text-sm text-muted-foreground">
|
|
40
|
-
{activeView.name}
|
|
41
|
-
</span>
|
|
42
|
-
)}
|
|
42
|
+
{activeView && <span className="text-sm text-muted-foreground">{activeView.name}</span>}
|
|
43
43
|
</div>
|
|
44
44
|
<UserViewsSheet open={sheetOpen} onOpenChange={setSheetOpen} />
|
|
45
45
|
</>
|
|
@@ -13,7 +13,7 @@ interface SaveViewButtonProps {
|
|
|
13
13
|
|
|
14
14
|
export const SaveViewButton: React.FC<SaveViewButtonProps> = ({ disabled }) => {
|
|
15
15
|
const [dialogOpen, setDialogOpen] = useState(false);
|
|
16
|
-
const { userViews, globalViews } = useSavedViews();
|
|
16
|
+
const { userViews, globalViews, savedViewsAreAvailable } = useSavedViews();
|
|
17
17
|
const { columnFilters, searchTerm } = useDataTableContext();
|
|
18
18
|
|
|
19
19
|
const hasFilters = columnFilters.length > 0 || (searchTerm && searchTerm.length > 0);
|
|
@@ -24,6 +24,10 @@ export const SaveViewButton: React.FC<SaveViewButtonProps> = ({ disabled }) => {
|
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
if (!savedViewsAreAvailable) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
return (
|
|
28
32
|
<>
|
|
29
33
|
<Button variant="outline" size="sm" onClick={() => setDialogOpen(true)} disabled={disabled}>
|
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.
|
package/src/lib/graphql/api.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LS_KEY_SELECTED_CHANNEL_TOKEN,
|
|
3
|
+
LS_KEY_SESSION_TOKEN,
|
|
4
|
+
LS_KEY_USER_SETTINGS,
|
|
5
|
+
} from '@/vdb/constants.js';
|
|
1
6
|
import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
2
7
|
import { AwesomeGraphQLClient } from 'awesome-graphql-client';
|
|
3
8
|
import { DocumentNode, print } from 'graphql';
|
|
@@ -12,8 +17,6 @@ const API_URL =
|
|
|
12
17
|
`:${uiConfig.api.port !== 'auto' ? uiConfig.api.port : window.location.port}` +
|
|
13
18
|
`/${uiConfig.api.adminApiPath}`;
|
|
14
19
|
|
|
15
|
-
export const SELECTED_CHANNEL_TOKEN_KEY = 'vendure-selected-channel-token';
|
|
16
|
-
|
|
17
20
|
export type Variables = object;
|
|
18
21
|
export type RequestDocument = string | DocumentNode;
|
|
19
22
|
|
|
@@ -21,9 +24,13 @@ const awesomeClient = new AwesomeGraphQLClient({
|
|
|
21
24
|
endpoint: API_URL,
|
|
22
25
|
fetch: async (url: string, options: RequestInit = {}) => {
|
|
23
26
|
// Get the active channel token from localStorage
|
|
24
|
-
const channelToken = localStorage.getItem(
|
|
27
|
+
const channelToken = localStorage.getItem(LS_KEY_SELECTED_CHANNEL_TOKEN);
|
|
28
|
+
const sessionToken = localStorage.getItem(LS_KEY_SESSION_TOKEN);
|
|
25
29
|
const headers = new Headers(options.headers);
|
|
26
30
|
|
|
31
|
+
if (sessionToken) {
|
|
32
|
+
headers.set('Authorization', `Bearer ${sessionToken}`);
|
|
33
|
+
}
|
|
27
34
|
if (channelToken) {
|
|
28
35
|
headers.set(uiConfig.api.channelTokenKey, channelToken);
|
|
29
36
|
}
|
|
@@ -31,7 +38,7 @@ const awesomeClient = new AwesomeGraphQLClient({
|
|
|
31
38
|
// Get the content language from user settings and add as query parameter
|
|
32
39
|
let finalUrl = url;
|
|
33
40
|
try {
|
|
34
|
-
const userSettings = localStorage.getItem(
|
|
41
|
+
const userSettings = localStorage.getItem(LS_KEY_USER_SETTINGS);
|
|
35
42
|
if (userSettings) {
|
|
36
43
|
const settings = JSON.parse(userSettings);
|
|
37
44
|
const contentLanguage = settings.contentLanguage;
|
|
@@ -52,6 +59,12 @@ const awesomeClient = new AwesomeGraphQLClient({
|
|
|
52
59
|
headers,
|
|
53
60
|
credentials: 'include',
|
|
54
61
|
mode: 'cors',
|
|
62
|
+
}).then(res => {
|
|
63
|
+
const authToken = res.headers.get('vendure-auth-token');
|
|
64
|
+
if (authToken) {
|
|
65
|
+
localStorage.setItem(LS_KEY_SESSION_TOKEN, authToken);
|
|
66
|
+
}
|
|
67
|
+
return res;
|
|
55
68
|
});
|
|
56
69
|
},
|
|
57
70
|
});
|