@vendure/dashboard 3.3.5-master-202506201217 → 3.3.5-master-202506201437
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/vite-plugin-transform-index.d.ts +11 -0
- package/dist/plugin/vite-plugin-transform-index.js +35 -0
- package/dist/plugin/vite-plugin-vendure-dashboard.js +2 -0
- package/package.json +4 -4
- package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +6 -35
- package/src/app/routes/_authenticated/_products/components/product-variants-table.tsx +13 -36
- package/src/app/routes/_authenticated/_products/products.graphql.ts +5 -0
- package/src/lib/components/shared/detail-page-button.tsx +7 -2
- package/src/lib/components/shared/paginated-list-data-table.tsx +13 -5
- package/src/lib/components/shared/stock-level-label.tsx +24 -0
- package/src/lib/framework/page/list-page.tsx +1 -9
- package/src/lib/index.ts +1 -0
- package/vite/vite-plugin-transform-index.ts +40 -0
- package/vite/vite-plugin-vendure-dashboard.ts +2 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* @description
|
|
4
|
+
* This Vite plugin handles the scenario where the `base` path is set in the Vite config.
|
|
5
|
+
* The default Vite behavior is to prepend the `base` path to all `href` and `src` attributes in the HTML,
|
|
6
|
+
* but this causes the Vendure Dashboard not to load its assets correctly.
|
|
7
|
+
*
|
|
8
|
+
* This plugin removes the `base` path from all `href` and `src` attributes in the HTML,
|
|
9
|
+
* and adds a `<base>` tag to the `<head>` of the HTML document.
|
|
10
|
+
*/
|
|
11
|
+
export declare function transformIndexHtmlPlugin(): Plugin;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* This Vite plugin handles the scenario where the `base` path is set in the Vite config.
|
|
4
|
+
* The default Vite behavior is to prepend the `base` path to all `href` and `src` attributes in the HTML,
|
|
5
|
+
* but this causes the Vendure Dashboard not to load its assets correctly.
|
|
6
|
+
*
|
|
7
|
+
* This plugin removes the `base` path from all `href` and `src` attributes in the HTML,
|
|
8
|
+
* and adds a `<base>` tag to the `<head>` of the HTML document.
|
|
9
|
+
*/
|
|
10
|
+
export function transformIndexHtmlPlugin() {
|
|
11
|
+
let config;
|
|
12
|
+
return {
|
|
13
|
+
name: 'vendure:vite-config-transform-index-html',
|
|
14
|
+
configResolved(resolvedConfig) {
|
|
15
|
+
// store the resolved config
|
|
16
|
+
config = resolvedConfig;
|
|
17
|
+
},
|
|
18
|
+
// Only apply this plugin during the build phase
|
|
19
|
+
apply: 'build',
|
|
20
|
+
transformIndexHtml(html) {
|
|
21
|
+
if (config.base && config.base !== '/') {
|
|
22
|
+
// Remove the base path from hrefs and srcs
|
|
23
|
+
const basePath = config.base.replace(/\/$/, ''); // Remove trailing slash
|
|
24
|
+
// Single regex to handle both href and src attributes with any quote type
|
|
25
|
+
const attributeRegex = new RegExp(`(href|src)=(["'])${basePath}/?`, 'g');
|
|
26
|
+
let transformedHtml = html.replace(attributeRegex, '$1=$2');
|
|
27
|
+
// Add base tag to head
|
|
28
|
+
const baseTag = ` <base href="${config.base}">\n`;
|
|
29
|
+
transformedHtml = transformedHtml.replace(/<head>/, `<head>\n${baseTag}`);
|
|
30
|
+
return transformedHtml;
|
|
31
|
+
}
|
|
32
|
+
return html;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -8,6 +8,7 @@ import { viteConfigPlugin } from './vite-plugin-config.js';
|
|
|
8
8
|
import { dashboardMetadataPlugin } from './vite-plugin-dashboard-metadata.js';
|
|
9
9
|
import { gqlTadaPlugin } from './vite-plugin-gql-tada.js';
|
|
10
10
|
import { themeVariablesPlugin } from './vite-plugin-theme.js';
|
|
11
|
+
import { transformIndexHtmlPlugin } from './vite-plugin-transform-index.js';
|
|
11
12
|
import { uiConfigPlugin } from './vite-plugin-ui-config.js';
|
|
12
13
|
/**
|
|
13
14
|
* @description
|
|
@@ -54,6 +55,7 @@ export function vendureDashboardPlugin(options) {
|
|
|
54
55
|
...(options.gqlTadaOutputPath
|
|
55
56
|
? [gqlTadaPlugin({ gqlTadaOutputPath: options.gqlTadaOutputPath, tempDir, packageRoot })]
|
|
56
57
|
: []),
|
|
58
|
+
transformIndexHtmlPlugin(),
|
|
57
59
|
];
|
|
58
60
|
}
|
|
59
61
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vendure/dashboard",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "3.3.5-master-
|
|
4
|
+
"version": "3.3.5-master-202506201437",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"@types/react-dom": "^19.0.4",
|
|
87
87
|
"@types/react-grid-layout": "^1.3.5",
|
|
88
88
|
"@uidotdev/usehooks": "^2.4.1",
|
|
89
|
-
"@vendure/common": "^3.3.5-master-
|
|
90
|
-
"@vendure/core": "^3.3.5-master-
|
|
89
|
+
"@vendure/common": "^3.3.5-master-202506201437",
|
|
90
|
+
"@vendure/core": "^3.3.5-master-202506201437",
|
|
91
91
|
"@vitejs/plugin-react": "^4.3.4",
|
|
92
92
|
"awesome-graphql-client": "^2.1.0",
|
|
93
93
|
"class-variance-authority": "^0.7.1",
|
|
@@ -130,5 +130,5 @@
|
|
|
130
130
|
"lightningcss-linux-arm64-musl": "^1.29.3",
|
|
131
131
|
"lightningcss-linux-x64-musl": "^1.29.1"
|
|
132
132
|
},
|
|
133
|
-
"gitHead": "
|
|
133
|
+
"gitHead": "a3a70099c3e41947dd3626f530b01805d633ac5a"
|
|
134
134
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Money } from '@/components/data-display/money.js';
|
|
2
2
|
import { DetailPageButton } from '@/components/shared/detail-page-button.js';
|
|
3
|
-
import {
|
|
3
|
+
import { StockLevelLabel } from '@/components/shared/stock-level-label.js';
|
|
4
4
|
import { ListPage } from '@/framework/page/list-page.js';
|
|
5
5
|
import { useLocalFormat } from '@/hooks/use-local-format.js';
|
|
6
6
|
import { Trans } from '@/lib/trans.js';
|
|
@@ -23,48 +23,19 @@ function ProductListPage() {
|
|
|
23
23
|
customizeColumns={{
|
|
24
24
|
name: {
|
|
25
25
|
header: 'Product Name',
|
|
26
|
-
cell: ({ row }) => <DetailPageButton id={
|
|
26
|
+
cell: ({ row: { original } }) => <DetailPageButton id={original.id} label={original.name} />,
|
|
27
27
|
},
|
|
28
28
|
currencyCode: {
|
|
29
|
-
cell: ({
|
|
30
|
-
const value = cell.getValue();
|
|
31
|
-
return formatCurrencyName(value as string, 'full');
|
|
32
|
-
},
|
|
29
|
+
cell: ({ row: { original } }) => formatCurrencyName(original.currencyCode, 'full'),
|
|
33
30
|
},
|
|
34
31
|
price: {
|
|
35
|
-
cell: ({
|
|
36
|
-
const value = cell.getValue();
|
|
37
|
-
const currencyCode = row.original.currencyCode;
|
|
38
|
-
if (typeof value === 'number') {
|
|
39
|
-
return <Money value={value} currency={currencyCode} />;
|
|
40
|
-
}
|
|
41
|
-
return value;
|
|
42
|
-
},
|
|
32
|
+
cell: ({ row: { original } }) => <Money value={original.price} currency={original.currencyCode} />,
|
|
43
33
|
},
|
|
44
34
|
priceWithTax: {
|
|
45
|
-
cell: ({
|
|
46
|
-
const value = cell.getValue();
|
|
47
|
-
const currencyCode = row.original.currencyCode;
|
|
48
|
-
if (typeof value === 'number') {
|
|
49
|
-
return <Money value={value} currency={currencyCode} />;
|
|
50
|
-
}
|
|
51
|
-
return value;
|
|
52
|
-
},
|
|
35
|
+
cell: ({ row: { original } }) => <Money value={original.priceWithTax} currency={original.currencyCode} />,
|
|
53
36
|
},
|
|
54
37
|
stockLevels: {
|
|
55
|
-
cell: ({
|
|
56
|
-
const value = cell.getValue();
|
|
57
|
-
if (Array.isArray(value)) {
|
|
58
|
-
const totalOnHand = value.reduce((acc, curr) => acc + curr.stockOnHand, 0);
|
|
59
|
-
const totalAllocated = value.reduce((acc, curr) => acc + curr.stockAllocated, 0);
|
|
60
|
-
return (
|
|
61
|
-
<span>
|
|
62
|
-
{totalOnHand} / {totalAllocated}
|
|
63
|
-
</span>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
return value;
|
|
67
|
-
},
|
|
38
|
+
cell: ({ row: { original } }) => <StockLevelLabel stockLevels={original.stockLevels} />,
|
|
68
39
|
},
|
|
69
40
|
}}
|
|
70
41
|
onSearchTermChange={searchTerm => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { PaginatedListDataTable, PaginatedListRefresherRegisterFn } from "@/components/shared/paginated-list-data-table.js";
|
|
2
|
-
import { productVariantListDocument } from "../products.graphql.js";
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import { ColumnFiltersState, SortingState } from "@tanstack/react-table";
|
|
5
1
|
import { Money } from "@/components/data-display/money.js";
|
|
2
|
+
import { PaginatedListDataTable, PaginatedListRefresherRegisterFn } from "@/components/shared/paginated-list-data-table.js";
|
|
3
|
+
import { StockLevelLabel } from "@/components/shared/stock-level-label.js";
|
|
6
4
|
import { useLocalFormat } from "@/hooks/use-local-format.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import { DetailPageButton } from "@/index.js";
|
|
6
|
+
import { ColumnFiltersState, SortingState } from "@tanstack/react-table";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { productVariantListDocument } from "../products.graphql.js";
|
|
9
9
|
|
|
10
10
|
interface ProductVariantsTableProps {
|
|
11
11
|
productId: string;
|
|
@@ -33,42 +33,19 @@ export function ProductVariantsTable({ productId, registerRefresher }: ProductVa
|
|
|
33
33
|
customizeColumns={{
|
|
34
34
|
name: {
|
|
35
35
|
header: 'Variant name',
|
|
36
|
-
cell: ({ row }) => {
|
|
37
|
-
const variant = row.original as any;
|
|
38
|
-
return (
|
|
39
|
-
<Button asChild variant="ghost">
|
|
40
|
-
<Link to={`../../product-variants/${variant.id}`}>{variant.name} </Link>
|
|
41
|
-
</Button>
|
|
42
|
-
);
|
|
43
|
-
},
|
|
36
|
+
cell: ({ row: { original } }) => <DetailPageButton href={`../../product-variants/${original.id}`} label={original.name} />,
|
|
44
37
|
},
|
|
45
38
|
currencyCode: {
|
|
46
|
-
cell: ({
|
|
47
|
-
const value = cell.getValue();
|
|
48
|
-
return formatCurrencyName(value as string, 'full');
|
|
49
|
-
},
|
|
39
|
+
cell: ({ row: { original } }) => formatCurrencyName(original.currencyCode, 'full'),
|
|
50
40
|
},
|
|
51
41
|
price: {
|
|
52
|
-
cell: ({
|
|
53
|
-
const variant = row.original as any;
|
|
54
|
-
const value = cell.getValue();
|
|
55
|
-
const currencyCode = variant.currencyCode;
|
|
56
|
-
if (typeof value === 'number') {
|
|
57
|
-
return <Money value={value} currency={currencyCode} />;
|
|
58
|
-
}
|
|
59
|
-
return value;
|
|
60
|
-
},
|
|
42
|
+
cell: ({ row: { original } }) => <Money value={original.price} currency={original.currencyCode} />,
|
|
61
43
|
},
|
|
62
44
|
priceWithTax: {
|
|
63
|
-
cell: ({
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (typeof value === 'number') {
|
|
68
|
-
return <Money value={value} currency={currencyCode} />;
|
|
69
|
-
}
|
|
70
|
-
return value;
|
|
71
|
-
},
|
|
45
|
+
cell: ({ row: { original } }) => <Money value={original.priceWithTax} currency={original.currencyCode} />,
|
|
46
|
+
},
|
|
47
|
+
stockLevels: {
|
|
48
|
+
cell: ({ row: { original } }) => <StockLevelLabel stockLevels={original.stockLevels} />,
|
|
72
49
|
},
|
|
73
50
|
}}
|
|
74
51
|
page={page}
|
|
@@ -4,16 +4,21 @@ import { Button } from '../ui/button.js';
|
|
|
4
4
|
|
|
5
5
|
export function DetailPageButton({
|
|
6
6
|
id,
|
|
7
|
+
href,
|
|
7
8
|
label,
|
|
8
9
|
disabled,
|
|
9
10
|
}: {
|
|
10
|
-
id: string;
|
|
11
11
|
label: string | React.ReactNode;
|
|
12
|
+
id?: string;
|
|
13
|
+
href?: string;
|
|
12
14
|
disabled?: boolean;
|
|
13
15
|
}) {
|
|
16
|
+
if (!id && !href) {
|
|
17
|
+
return <span>{label}</span>;
|
|
18
|
+
}
|
|
14
19
|
return (
|
|
15
20
|
<Button asChild variant="ghost" disabled={disabled}>
|
|
16
|
-
<Link to={`./${id}`}>
|
|
21
|
+
<Link to={href ?? `./${id}`}>
|
|
17
22
|
{label}
|
|
18
23
|
{!disabled && <ChevronRight className="h-3 w-3 text-muted-foreground" />}
|
|
19
24
|
</Link>
|
|
@@ -114,6 +114,14 @@ export type FacetedFilterConfig<T extends TypedDocumentNode<any, any>> = {
|
|
|
114
114
|
[Key in AllItemFieldKeys<T>]?: FacetedFilter;
|
|
115
115
|
};
|
|
116
116
|
|
|
117
|
+
export type ListQueryFields<T extends TypedDocumentNode<any, any>> = {
|
|
118
|
+
[Key in keyof ResultOf<T>]: ResultOf<T>[Key] extends { items: infer U }
|
|
119
|
+
? U extends any[]
|
|
120
|
+
? U[number]
|
|
121
|
+
: never
|
|
122
|
+
: never;
|
|
123
|
+
}[keyof ResultOf<T>];
|
|
124
|
+
|
|
117
125
|
export type ListQueryShape =
|
|
118
126
|
| {
|
|
119
127
|
[key: string]: {
|
|
@@ -185,7 +193,7 @@ export type PaginatedListRefresherRegisterFn = (refreshFn: () => void) => void;
|
|
|
185
193
|
|
|
186
194
|
export interface PaginatedListDataTableProps<
|
|
187
195
|
T extends TypedDocumentNode<U, V>,
|
|
188
|
-
U extends
|
|
196
|
+
U extends ListQueryShape,
|
|
189
197
|
V extends ListQueryOptionsShape,
|
|
190
198
|
AC extends AdditionalColumns<T>,
|
|
191
199
|
> {
|
|
@@ -195,7 +203,7 @@ export interface PaginatedListDataTableProps<
|
|
|
195
203
|
transformVariables?: (variables: V) => V;
|
|
196
204
|
customizeColumns?: CustomizeColumnConfig<T>;
|
|
197
205
|
additionalColumns?: AC;
|
|
198
|
-
defaultColumnOrder?: (
|
|
206
|
+
defaultColumnOrder?: (keyof ListQueryFields<T> | keyof AC | CustomFieldKeysOfItem<ListQueryFields<T>>)[];
|
|
199
207
|
defaultVisibility?: Partial<Record<AllItemFieldKeys<T>, boolean>>;
|
|
200
208
|
onSearchTermChange?: (searchTerm: string) => NonNullable<V['options']>['filter'];
|
|
201
209
|
page: number;
|
|
@@ -407,10 +415,10 @@ export function PaginatedListDataTable<
|
|
|
407
415
|
// appear as the first columns in sequence, and leave the remainder in the
|
|
408
416
|
// existing order
|
|
409
417
|
const orderedColumns = finalColumns
|
|
410
|
-
.filter(column => column.id && defaultColumnOrder.includes(column.id))
|
|
411
|
-
.sort((a, b) => defaultColumnOrder.indexOf(a.id) - defaultColumnOrder.indexOf(b.id));
|
|
418
|
+
.filter(column => column.id && defaultColumnOrder.includes(column.id as any))
|
|
419
|
+
.sort((a, b) => defaultColumnOrder.indexOf(a.id as any) - defaultColumnOrder.indexOf(b.id as any));
|
|
412
420
|
const remainingColumns = finalColumns.filter(
|
|
413
|
-
column => !column.id || !defaultColumnOrder.includes(column.id),
|
|
421
|
+
column => !column.id || !defaultColumnOrder.includes(column.id as any),
|
|
414
422
|
);
|
|
415
423
|
finalColumns = [...orderedColumns, ...remainingColumns];
|
|
416
424
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useLingui } from '../../lib/trans.js';
|
|
2
|
+
|
|
3
|
+
export type StockLevel = {
|
|
4
|
+
stockOnHand: number;
|
|
5
|
+
stockAllocated: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function StockLevelLabel({ stockLevels }: { stockLevels: StockLevel[] }) {
|
|
9
|
+
const { i18n } = useLingui();
|
|
10
|
+
|
|
11
|
+
if (!Array.isArray(stockLevels)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const totalOnHand = stockLevels.reduce((acc, curr) => acc + curr.stockOnHand, 0);
|
|
15
|
+
const totalAllocated = stockLevels.reduce((acc, curr) => acc + curr.stockAllocated, 0);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<span
|
|
19
|
+
title={`${i18n.t('Stock on hand')}: ${totalOnHand}, ${i18n.t('Stock allocated')}: ${totalAllocated}`}
|
|
20
|
+
>
|
|
21
|
+
{totalOnHand} <span className="text-muted-foreground">/ {totalAllocated}</span>
|
|
22
|
+
</span>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
FacetedFilterConfig,
|
|
6
6
|
ListQueryOptionsShape,
|
|
7
7
|
ListQueryShape,
|
|
8
|
+
ListQueryFields,
|
|
8
9
|
PaginatedListDataTable,
|
|
9
10
|
RowAction,
|
|
10
11
|
} from '@/components/shared/paginated-list-data-table.js';
|
|
@@ -13,7 +14,6 @@ import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
|
13
14
|
import { AnyRoute, AnyRouter, useNavigate } from '@tanstack/react-router';
|
|
14
15
|
import { ColumnFiltersState, SortingState, Table } from '@tanstack/react-table';
|
|
15
16
|
import { TableOptions } from '@tanstack/table-core';
|
|
16
|
-
import { ResultOf } from 'gql.tada';
|
|
17
17
|
|
|
18
18
|
import { addCustomFields } from '../document-introspection/add-custom-fields.js';
|
|
19
19
|
import {
|
|
@@ -24,14 +24,6 @@ import {
|
|
|
24
24
|
PageTitle,
|
|
25
25
|
} from '../layout-engine/page-layout.js';
|
|
26
26
|
|
|
27
|
-
type ListQueryFields<T extends TypedDocumentNode<any, any>> = {
|
|
28
|
-
[Key in keyof ResultOf<T>]: ResultOf<T>[Key] extends { items: infer U }
|
|
29
|
-
? U extends any[]
|
|
30
|
-
? U[number]
|
|
31
|
-
: never
|
|
32
|
-
: never;
|
|
33
|
-
}[keyof ResultOf<T>];
|
|
34
|
-
|
|
35
27
|
/**
|
|
36
28
|
* @description
|
|
37
29
|
* **Status: Developer Preview**
|
package/src/lib/index.ts
CHANGED
|
@@ -67,6 +67,7 @@ export * from './components/shared/rich-text-editor.js';
|
|
|
67
67
|
export * from './components/shared/role-code-label.js';
|
|
68
68
|
export * from './components/shared/role-selector.js';
|
|
69
69
|
export * from './components/shared/seller-selector.js';
|
|
70
|
+
export * from './components/shared/stock-level-label.js';
|
|
70
71
|
export * from './components/shared/tax-category-selector.js';
|
|
71
72
|
export * from './components/shared/translatable-form-field.js';
|
|
72
73
|
export * from './components/shared/vendure-image.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Plugin, ResolvedConfig } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* This Vite plugin handles the scenario where the `base` path is set in the Vite config.
|
|
6
|
+
* The default Vite behavior is to prepend the `base` path to all `href` and `src` attributes in the HTML,
|
|
7
|
+
* but this causes the Vendure Dashboard not to load its assets correctly.
|
|
8
|
+
*
|
|
9
|
+
* This plugin removes the `base` path from all `href` and `src` attributes in the HTML,
|
|
10
|
+
* and adds a `<base>` tag to the `<head>` of the HTML document.
|
|
11
|
+
*/
|
|
12
|
+
export function transformIndexHtmlPlugin(): Plugin {
|
|
13
|
+
let config: ResolvedConfig;
|
|
14
|
+
return {
|
|
15
|
+
name: 'vendure:vite-config-transform-index-html',
|
|
16
|
+
configResolved(resolvedConfig) {
|
|
17
|
+
// store the resolved config
|
|
18
|
+
config = resolvedConfig;
|
|
19
|
+
},
|
|
20
|
+
// Only apply this plugin during the build phase
|
|
21
|
+
apply: 'build',
|
|
22
|
+
transformIndexHtml(html) {
|
|
23
|
+
if (config.base && config.base !== '/') {
|
|
24
|
+
// Remove the base path from hrefs and srcs
|
|
25
|
+
const basePath = config.base.replace(/\/$/, ''); // Remove trailing slash
|
|
26
|
+
|
|
27
|
+
// Single regex to handle both href and src attributes with any quote type
|
|
28
|
+
const attributeRegex = new RegExp(`(href|src)=(["'])${basePath}/?`, 'g');
|
|
29
|
+
let transformedHtml = html.replace(attributeRegex, '$1=$2');
|
|
30
|
+
|
|
31
|
+
// Add base tag to head
|
|
32
|
+
const baseTag = ` <base href="${config.base}">\n`;
|
|
33
|
+
transformedHtml = transformedHtml.replace(/<head>/, `<head>\n${baseTag}`);
|
|
34
|
+
|
|
35
|
+
return transformedHtml;
|
|
36
|
+
}
|
|
37
|
+
return html;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -10,6 +10,7 @@ import { viteConfigPlugin } from './vite-plugin-config.js';
|
|
|
10
10
|
import { dashboardMetadataPlugin } from './vite-plugin-dashboard-metadata.js';
|
|
11
11
|
import { gqlTadaPlugin } from './vite-plugin-gql-tada.js';
|
|
12
12
|
import { ThemeVariablesPluginOptions, themeVariablesPlugin } from './vite-plugin-theme.js';
|
|
13
|
+
import { transformIndexHtmlPlugin } from './vite-plugin-transform-index.js';
|
|
13
14
|
import { UiConfigPluginOptions, uiConfigPlugin } from './vite-plugin-ui-config.js';
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -92,6 +93,7 @@ export function vendureDashboardPlugin(options: VitePluginVendureDashboardOption
|
|
|
92
93
|
...(options.gqlTadaOutputPath
|
|
93
94
|
? [gqlTadaPlugin({ gqlTadaOutputPath: options.gqlTadaOutputPath, tempDir, packageRoot })]
|
|
94
95
|
: []),
|
|
96
|
+
transformIndexHtmlPlugin(),
|
|
95
97
|
];
|
|
96
98
|
}
|
|
97
99
|
|