@vendure/dashboard 3.4.2-master-202509090229 → 3.4.2
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/package.json +4 -4
- package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_facets/facets.tsx +5 -8
- package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_products/products_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +4 -4
- package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +3 -3
- package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +4 -3
- package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +3 -3
- package/src/lib/components/data-input/affixed-input.tsx +18 -0
- package/src/lib/components/data-input/boolean-input.tsx +7 -0
- package/src/lib/components/data-input/checkbox-input.tsx +7 -0
- package/src/lib/components/data-input/datetime-input.tsx +7 -0
- package/src/lib/components/data-input/money-input.tsx +8 -0
- package/src/lib/components/data-input/number-input.tsx +7 -0
- package/src/lib/components/data-input/password-input.tsx +7 -0
- package/src/lib/components/data-input/rich-text-input.tsx +7 -0
- package/src/lib/components/data-input/text-input.tsx +7 -0
- package/src/lib/components/data-input/textarea-input.tsx +7 -0
- package/src/lib/components/data-table/data-table-view-options.tsx +29 -26
- package/src/lib/components/data-table/data-table.tsx +20 -0
- package/src/lib/components/data-table/types.ts +39 -0
- package/src/lib/components/layout/channel-switcher.tsx +1 -3
- package/src/lib/components/shared/asset/asset-gallery.tsx +58 -0
- package/src/lib/components/shared/asset/asset-picker-dialog.tsx +39 -0
- package/src/lib/components/shared/detail-page-button.tsx +8 -22
- package/src/lib/components/shared/facet-value-chip.tsx +7 -0
- package/src/lib/components/shared/facet-value-selector.tsx +55 -0
- package/src/lib/components/shared/form-field-wrapper.tsx +51 -0
- package/src/lib/components/shared/paginated-list-data-table.tsx +128 -16
- package/src/lib/components/shared/permission-guard.tsx +30 -0
- package/src/lib/components/shared/table-cell/order-table-cell-components.tsx +1 -1
- package/src/lib/components/shared/translatable-form-field.tsx +52 -0
- package/src/lib/components/shared/vendure-image.tsx +114 -2
- package/src/lib/framework/extension-api/define-dashboard-extension.ts +25 -3
- package/src/lib/framework/extension-api/extension-api-types.ts +12 -3
- package/src/lib/framework/extension-api/types/alerts.ts +2 -3
- package/src/lib/framework/extension-api/types/data-table.ts +2 -2
- package/src/lib/framework/extension-api/types/detail-forms.ts +2 -2
- package/src/lib/framework/extension-api/types/form-components.ts +2 -2
- package/src/lib/framework/extension-api/types/layout.ts +24 -13
- package/src/lib/framework/extension-api/types/login.ts +6 -5
- package/src/lib/framework/extension-api/types/navigation.ts +3 -3
- package/src/lib/framework/extension-api/types/widgets.ts +7 -3
- package/src/lib/framework/form-engine/form-engine-types.ts +13 -7
- package/src/lib/framework/form-engine/use-generated-form.tsx +44 -0
- package/src/lib/framework/layout-engine/page-layout.tsx +94 -31
- package/src/lib/framework/page/detail-page.tsx +3 -5
- package/src/lib/framework/page/list-page.tsx +87 -5
- package/src/lib/framework/page/use-detail-page.ts +4 -5
- package/src/lib/graphql/api.ts +2 -2
- package/src/lib/graphql/graphql-env.d.ts +7 -16
- package/src/lib/hooks/use-auth.tsx +1 -3
- package/src/lib/hooks/use-channel.ts +4 -2
- package/src/lib/hooks/use-page-block.tsx +9 -0
- package/src/lib/hooks/use-permissions.ts +6 -2
- package/src/lib/index.ts +2 -0
- package/src/lib/providers/auth.tsx +34 -2
- package/src/lib/providers/channel-provider.tsx +22 -1
- package/src/lib/components/shared/table-cell/table-cell-types.ts +0 -33
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
import { DataTable, FacetedFilter } from '
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from '
|
|
5
|
-
import { useListQueryFields } from '@/vdb/framework/document-introspection/hooks.js';
|
|
6
|
-
import { api } from '@/vdb/graphql/api.js';
|
|
1
|
+
import { DataTable, FacetedFilter } from '\@/vdb/components/data-table/data-table.js';
|
|
2
|
+
import { getObjectPathToPaginatedList } from '\@/vdb/framework/document-introspection/get-document-structure.js';
|
|
3
|
+
import { useListQueryFields } from '\@/vdb/framework/document-introspection/hooks.js';
|
|
4
|
+
import { api } from '\@/vdb/graphql/api.js';
|
|
7
5
|
import { keepPreviousData, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
8
6
|
import { useDebounce } from '@uidotdev/usehooks';
|
|
9
7
|
|
|
10
|
-
import { BulkAction } from '
|
|
11
|
-
import { ResultOf } from '
|
|
12
|
-
import { useExtendedListQuery } from '
|
|
8
|
+
import { BulkAction } from '\@/vdb/framework/extension-api/types/index.js';
|
|
9
|
+
import { ResultOf } from '\@/vdb/graphql/graphql.js';
|
|
10
|
+
import { useExtendedListQuery } from '\@/vdb/hooks/use-extended-list-query.js';
|
|
13
11
|
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
14
|
-
import {
|
|
15
|
-
ColumnFiltersState,
|
|
16
|
-
ColumnSort,
|
|
17
|
-
SortingState,
|
|
18
|
-
Table
|
|
19
|
-
} from '@tanstack/react-table';
|
|
12
|
+
import { ColumnFiltersState, ColumnSort, SortingState, Table } from '@tanstack/react-table';
|
|
20
13
|
import { ColumnDef, Row, TableOptions, VisibilityState } from '@tanstack/table-core';
|
|
21
14
|
import React from 'react';
|
|
22
15
|
import { getColumnVisibility } from '../data-table/data-table-utils.js';
|
|
@@ -163,6 +156,8 @@ export const PaginatedListContext = React.createContext<PaginatedListContext | u
|
|
|
163
156
|
* },
|
|
164
157
|
* });
|
|
165
158
|
* ```
|
|
159
|
+
* @docsCategory hooks
|
|
160
|
+
* @since 3.4.0
|
|
166
161
|
*/
|
|
167
162
|
export function usePaginatedList() {
|
|
168
163
|
const context = React.useContext(PaginatedListContext);
|
|
@@ -179,6 +174,14 @@ export interface RowAction<T> {
|
|
|
179
174
|
|
|
180
175
|
export type PaginatedListRefresherRegisterFn = (refreshFn: () => void) => void;
|
|
181
176
|
|
|
177
|
+
/**
|
|
178
|
+
* @description
|
|
179
|
+
* Props to configure the {@link PaginatedListDataTable} component.
|
|
180
|
+
*
|
|
181
|
+
* @docsCategory list-views
|
|
182
|
+
* @docsPage PaginatedListDataTable
|
|
183
|
+
* @since 3.4.0
|
|
184
|
+
*/
|
|
182
185
|
export interface PaginatedListDataTableProps<
|
|
183
186
|
T extends TypedDocumentNode<U, V>,
|
|
184
187
|
U extends ListQueryShape,
|
|
@@ -218,6 +221,116 @@ export interface PaginatedListDataTableProps<
|
|
|
218
221
|
|
|
219
222
|
export const PaginatedListDataTableKey = 'PaginatedListDataTable';
|
|
220
223
|
|
|
224
|
+
/**
|
|
225
|
+
* @description
|
|
226
|
+
* A wrapper around the {@link DataTable} component, which automatically configures functionality common to
|
|
227
|
+
* list queries that implement the `PaginatedList` interface, which is the common way of representing lists
|
|
228
|
+
* of data in Vendure.
|
|
229
|
+
*
|
|
230
|
+
* Given a GraphQL query document node, the component will automatically configure the required columns
|
|
231
|
+
* with sorting & filtering functionality.
|
|
232
|
+
*
|
|
233
|
+
* The automatic features can be further customized and enhanced using the many options available in the props.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```tsx
|
|
237
|
+
* import { Money } from '\@/vdb/components/data-display/money.js';
|
|
238
|
+
* import { PaginatedListDataTable } from '\@/vdb/components/shared/paginated-list-data-table.js';
|
|
239
|
+
* import { Badge } from '\@/vdb/components/ui/badge.js';
|
|
240
|
+
* import { Button } from '\@/vdb/components/ui/button.js';
|
|
241
|
+
* import { Link } from '\@tanstack/react-router';
|
|
242
|
+
* import { ColumnFiltersState, SortingState } from '\@tanstack/react-table';
|
|
243
|
+
* import { useState } from 'react';
|
|
244
|
+
* import { customerOrderListDocument } from '../customers.graphql.js';
|
|
245
|
+
*
|
|
246
|
+
* interface CustomerOrderTableProps {
|
|
247
|
+
* customerId: string;
|
|
248
|
+
* }
|
|
249
|
+
*
|
|
250
|
+
* export function CustomerOrderTable({ customerId }: Readonly<CustomerOrderTableProps>) {
|
|
251
|
+
* const [page, setPage] = useState(1);
|
|
252
|
+
* const [pageSize, setPageSize] = useState(10);
|
|
253
|
+
* const [sorting, setSorting] = useState<SortingState>([{ id: 'orderPlacedAt', desc: true }]);
|
|
254
|
+
* const [filters, setFilters] = useState<ColumnFiltersState>([]);
|
|
255
|
+
*
|
|
256
|
+
* return (
|
|
257
|
+
* <PaginatedListDataTable
|
|
258
|
+
* listQuery={customerOrderListDocument}
|
|
259
|
+
* transformVariables={variables => {
|
|
260
|
+
* return {
|
|
261
|
+
* ...variables,
|
|
262
|
+
* customerId,
|
|
263
|
+
* };
|
|
264
|
+
* }}
|
|
265
|
+
* defaultVisibility={{
|
|
266
|
+
* id: false,
|
|
267
|
+
* createdAt: false,
|
|
268
|
+
* updatedAt: false,
|
|
269
|
+
* type: false,
|
|
270
|
+
* currencyCode: false,
|
|
271
|
+
* total: false,
|
|
272
|
+
* }}
|
|
273
|
+
* customizeColumns={{
|
|
274
|
+
* total: {
|
|
275
|
+
* header: 'Total',
|
|
276
|
+
* cell: ({ cell, row }) => {
|
|
277
|
+
* const value = cell.getValue();
|
|
278
|
+
* const currencyCode = row.original.currencyCode;
|
|
279
|
+
* return <Money value={value} currency={currencyCode} />;
|
|
280
|
+
* },
|
|
281
|
+
* },
|
|
282
|
+
* totalWithTax: {
|
|
283
|
+
* header: 'Total with Tax',
|
|
284
|
+
* cell: ({ cell, row }) => {
|
|
285
|
+
* const value = cell.getValue();
|
|
286
|
+
* const currencyCode = row.original.currencyCode;
|
|
287
|
+
* return <Money value={value} currency={currencyCode} />;
|
|
288
|
+
* },
|
|
289
|
+
* },
|
|
290
|
+
* state: {
|
|
291
|
+
* header: 'State',
|
|
292
|
+
* cell: ({ cell }) => {
|
|
293
|
+
* const value = cell.getValue() as string;
|
|
294
|
+
* return <Badge variant="outline">{value}</Badge>;
|
|
295
|
+
* },
|
|
296
|
+
* },
|
|
297
|
+
* code: {
|
|
298
|
+
* header: 'Code',
|
|
299
|
+
* cell: ({ cell, row }) => {
|
|
300
|
+
* const value = cell.getValue() as string;
|
|
301
|
+
* const id = row.original.id;
|
|
302
|
+
* return (
|
|
303
|
+
* <Button asChild variant="ghost">
|
|
304
|
+
* <Link to={`/orders/${id}`}>{value}</Link>
|
|
305
|
+
* </Button>
|
|
306
|
+
* );
|
|
307
|
+
* },
|
|
308
|
+
* },
|
|
309
|
+
* }}
|
|
310
|
+
* page={page}
|
|
311
|
+
* itemsPerPage={pageSize}
|
|
312
|
+
* sorting={sorting}
|
|
313
|
+
* columnFilters={filters}
|
|
314
|
+
* onPageChange={(_, page, perPage) => {
|
|
315
|
+
* setPage(page);
|
|
316
|
+
* setPageSize(perPage);
|
|
317
|
+
* }}
|
|
318
|
+
* onSortChange={(_, sorting) => {
|
|
319
|
+
* setSorting(sorting);
|
|
320
|
+
* }}
|
|
321
|
+
* onFilterChange={(_, filters) => {
|
|
322
|
+
* setFilters(filters);
|
|
323
|
+
* }}
|
|
324
|
+
* />
|
|
325
|
+
* );
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* @docsCategory list-views
|
|
330
|
+
* @docsPage PaginatedListDataTable
|
|
331
|
+
* @since 3.4.0
|
|
332
|
+
* @docsWeight 0
|
|
333
|
+
*/
|
|
221
334
|
export function PaginatedListDataTable<
|
|
222
335
|
T extends TypedDocumentNode<U, V>,
|
|
223
336
|
U extends Record<string, any> = any,
|
|
@@ -358,4 +471,3 @@ export function PaginatedListDataTable<
|
|
|
358
471
|
</PaginatedListContext.Provider>
|
|
359
472
|
);
|
|
360
473
|
}
|
|
361
|
-
|
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import { usePermissions } from '@/vdb/hooks/use-permissions.js';
|
|
2
2
|
import { Permission } from '@vendure/common/lib/generated-types';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* The props for the PermissionGuard component.
|
|
7
|
+
*
|
|
8
|
+
* @docsCategory components
|
|
9
|
+
* @docsPage PermissionGuard
|
|
10
|
+
* @since 3.4.0
|
|
11
|
+
*/
|
|
4
12
|
export interface PermissionGuardProps {
|
|
13
|
+
/**
|
|
14
|
+
* @description
|
|
15
|
+
* The permission(s) required to access the children.
|
|
16
|
+
*/
|
|
5
17
|
requires: Permission | string | string[] | Permission[];
|
|
18
|
+
/**
|
|
19
|
+
* @description
|
|
20
|
+
* The children to render if the user has the required permissions.
|
|
21
|
+
*/
|
|
6
22
|
children: React.ReactNode;
|
|
7
23
|
}
|
|
8
24
|
|
|
@@ -10,6 +26,20 @@ export interface PermissionGuardProps {
|
|
|
10
26
|
* @description
|
|
11
27
|
* This component is used to protect a route from unauthorized access.
|
|
12
28
|
* It will render the children if the user has the required permissions.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <PermissionGuard requires={['UpdateTaxCategory']}>
|
|
33
|
+
* <Button type="submit">
|
|
34
|
+
* <Trans>Update</Trans>
|
|
35
|
+
* </Button>
|
|
36
|
+
* </PermissionGuard>
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @docsCategory components
|
|
40
|
+
* @docsPage PermissionGuard
|
|
41
|
+
* @docsWeight 0
|
|
42
|
+
* @since 3.4.0
|
|
13
43
|
*/
|
|
14
44
|
export function PermissionGuard({ requires, children }: Readonly<PermissionGuardProps>) {
|
|
15
45
|
const { hasPermissions } = usePermissions();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Money } from '@/vdb/components/data-display/money.js';
|
|
2
|
-
import { DataTableCellComponent } from '@/vdb/components/
|
|
2
|
+
import { DataTableCellComponent } from '@/vdb/components/data-table/types.js';
|
|
3
3
|
import { Badge } from '@/vdb/components/ui/badge.js';
|
|
4
4
|
import { Button } from '@/vdb/components/ui/button.js';
|
|
5
5
|
import { Link } from '@tanstack/react-router';
|
|
@@ -11,11 +11,27 @@ export type TranslatableEntity = FieldValues & {
|
|
|
11
11
|
translations?: Array<{ languageCode: string }> | null;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @description
|
|
16
|
+
* The props for the TranslatableFormField component.
|
|
17
|
+
*
|
|
18
|
+
* @docsCategory form-components
|
|
19
|
+
* @docsPage TranslatableFormFieldWrapper
|
|
20
|
+
* @since 3.4.0
|
|
21
|
+
*/
|
|
14
22
|
export type TranslatableFormFieldProps<TFieldValues extends TranslatableEntity | TranslatableEntity[]> = Omit<
|
|
15
23
|
ControllerProps<TFieldValues>,
|
|
16
24
|
'name'
|
|
17
25
|
> & {
|
|
26
|
+
/**
|
|
27
|
+
* @description
|
|
28
|
+
* The label for the form field.
|
|
29
|
+
*/
|
|
18
30
|
label?: React.ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* @description
|
|
33
|
+
* The name of the form field.
|
|
34
|
+
*/
|
|
19
35
|
name: TFieldValues extends TranslatableEntity
|
|
20
36
|
? keyof Omit<NonNullable<TFieldValues['translations']>[number], 'languageCode'>
|
|
21
37
|
: TFieldValues extends TranslatableEntity[]
|
|
@@ -57,6 +73,42 @@ export type TranslatableFormFieldWrapperProps<
|
|
|
57
73
|
> = TranslatableFormFieldProps<TFieldValues> &
|
|
58
74
|
Omit<React.ComponentProps<typeof FormFieldWrapper<TFieldValues>>, 'name'>;
|
|
59
75
|
|
|
76
|
+
/**
|
|
77
|
+
* @description
|
|
78
|
+
* This is the equivalent of the {@link FormFieldWrapper} component, but for translatable fields.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <PageBlock column="main" blockId="main-form">
|
|
83
|
+
* <DetailFormGrid>
|
|
84
|
+
* <TranslatableFormFieldWrapper
|
|
85
|
+
* control={form.control}
|
|
86
|
+
* name="name"
|
|
87
|
+
* label={<Trans>Product name</Trans>}
|
|
88
|
+
* render={({ field }) => <Input {...field} />}
|
|
89
|
+
* />
|
|
90
|
+
* <TranslatableFormFieldWrapper
|
|
91
|
+
* control={form.control}
|
|
92
|
+
* name="slug"
|
|
93
|
+
* label={<Trans>Slug</Trans>}
|
|
94
|
+
* render={({ field }) => <Input {...field} />}
|
|
95
|
+
* />
|
|
96
|
+
* </DetailFormGrid>
|
|
97
|
+
|
|
98
|
+
* <TranslatableFormFieldWrapper
|
|
99
|
+
* control={form.control}
|
|
100
|
+
* name="description"
|
|
101
|
+
* label={<Trans>Description</Trans>}
|
|
102
|
+
* render={({ field }) => <RichTextInput {...field} />}
|
|
103
|
+
* />
|
|
104
|
+
* </PageBlock>
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @docsCategory form-components
|
|
108
|
+
* @docsPage TranslatableFormFieldWrapper
|
|
109
|
+
* @docsWeight 0
|
|
110
|
+
* @since 3.4.0
|
|
111
|
+
*/
|
|
60
112
|
export const TranslatableFormFieldWrapper = <
|
|
61
113
|
TFieldValues extends TranslatableEntity | TranslatableEntity[] = TranslatableEntity,
|
|
62
114
|
>({
|
|
@@ -2,6 +2,14 @@ import { cn } from '@/vdb/lib/utils.js';
|
|
|
2
2
|
import { Image } from 'lucide-react';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* The type of object that can be used as an asset in the {@link VendureImage} component.
|
|
8
|
+
*
|
|
9
|
+
* @docsCategory components
|
|
10
|
+
* @docsPage VendureImage
|
|
11
|
+
* @since 3.4.0
|
|
12
|
+
*/
|
|
5
13
|
export interface AssetLike {
|
|
6
14
|
id: string;
|
|
7
15
|
preview: string; // Base URL of the asset
|
|
@@ -9,23 +17,127 @@ export interface AssetLike {
|
|
|
9
17
|
focalPoint?: { x: number; y: number } | null;
|
|
10
18
|
}
|
|
11
19
|
|
|
20
|
+
/**
|
|
21
|
+
* @description
|
|
22
|
+
* The presets that can be used for the {@link VendureImage} component.
|
|
23
|
+
*
|
|
24
|
+
* @docsCategory components
|
|
25
|
+
* @docsPage VendureImage
|
|
26
|
+
* @since 3.4.0
|
|
27
|
+
*/
|
|
12
28
|
export type ImagePreset = 'tiny' | 'thumb' | 'small' | 'medium' | 'large' | null;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @description
|
|
32
|
+
* The formats that can be used for the {@link VendureImage} component.
|
|
33
|
+
*
|
|
34
|
+
* @docsCategory components
|
|
35
|
+
* @docsPage VendureImage
|
|
36
|
+
* @since 3.4.0
|
|
37
|
+
*/
|
|
13
38
|
export type ImageFormat = 'jpg' | 'jpeg' | 'png' | 'webp' | 'avif' | null;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @description
|
|
42
|
+
* The modes that can be used for the {@link VendureImage} component.
|
|
43
|
+
*
|
|
44
|
+
* @docsCategory components
|
|
45
|
+
* @docsPage VendureImage
|
|
46
|
+
* @since 3.4.0
|
|
47
|
+
*/
|
|
14
48
|
export type ImageMode = 'crop' | 'resize' | null;
|
|
15
49
|
|
|
50
|
+
/**
|
|
51
|
+
* @description
|
|
52
|
+
* The props for the {@link VendureImage} component.
|
|
53
|
+
*
|
|
54
|
+
* @docsCategory components
|
|
55
|
+
* @docsPage VendureImage
|
|
56
|
+
* @docsWeight 1
|
|
57
|
+
* @since 3.4.0
|
|
58
|
+
*/
|
|
16
59
|
export interface VendureImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
|
|
60
|
+
/**
|
|
61
|
+
* @description
|
|
62
|
+
* The asset to display.
|
|
63
|
+
*/
|
|
17
64
|
asset: AssetLike | null | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* @description
|
|
67
|
+
* The preset to use for the image.
|
|
68
|
+
*/
|
|
18
69
|
preset?: ImagePreset;
|
|
70
|
+
/**
|
|
71
|
+
* @description
|
|
72
|
+
* The crop/resize mode to use for the image.
|
|
73
|
+
*/
|
|
19
74
|
mode?: ImageMode;
|
|
75
|
+
/**
|
|
76
|
+
* @description
|
|
77
|
+
* The width of the image.
|
|
78
|
+
*/
|
|
20
79
|
width?: number;
|
|
80
|
+
/**
|
|
81
|
+
* @description
|
|
82
|
+
* The height of the image.
|
|
83
|
+
*/
|
|
21
84
|
height?: number;
|
|
85
|
+
/**
|
|
86
|
+
* @description
|
|
87
|
+
* The format of the image.
|
|
88
|
+
*/
|
|
22
89
|
format?: ImageFormat;
|
|
90
|
+
/**
|
|
91
|
+
* @description
|
|
92
|
+
* The quality of the image.
|
|
93
|
+
*/
|
|
23
94
|
quality?: number;
|
|
24
|
-
|
|
25
|
-
|
|
95
|
+
/**
|
|
96
|
+
* @description
|
|
97
|
+
* Whether to use the asset's focal point in crop mode.
|
|
98
|
+
*/
|
|
99
|
+
useFocalPoint?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* @description
|
|
102
|
+
* The fallback to show if no asset is provided. If no fallback is provided,
|
|
103
|
+
* a default placeholder will be shown.
|
|
104
|
+
*/
|
|
105
|
+
fallback?: React.ReactNode;
|
|
106
|
+
/**
|
|
107
|
+
* @description
|
|
108
|
+
* The ref to the image element.
|
|
109
|
+
*/
|
|
26
110
|
ref?: React.Ref<HTMLImageElement>;
|
|
27
111
|
}
|
|
28
112
|
|
|
113
|
+
/**
|
|
114
|
+
* @description
|
|
115
|
+
* A component for displaying an image from a Vendure asset.
|
|
116
|
+
*
|
|
117
|
+
* Supports the following features:
|
|
118
|
+
*
|
|
119
|
+
* * Presets
|
|
120
|
+
* * Cropping
|
|
121
|
+
* * Resizing
|
|
122
|
+
* * Formatting
|
|
123
|
+
* * Quality
|
|
124
|
+
* * Focal point
|
|
125
|
+
* * Fallback
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```tsx
|
|
129
|
+
* <VendureImage
|
|
130
|
+
* asset={asset}
|
|
131
|
+
* preset="thumb"
|
|
132
|
+
* className="w-full h-full object-contain"
|
|
133
|
+
* />
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @docsCategory components
|
|
137
|
+
* @docsPage VendureImage
|
|
138
|
+
* @docsWeight 0
|
|
139
|
+
* @since 3.4.0
|
|
140
|
+
*/
|
|
29
141
|
export function VendureImage({
|
|
30
142
|
asset,
|
|
31
143
|
preset = null,
|
|
@@ -27,12 +27,34 @@ export function executeDashboardExtensionCallbacks() {
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* @description
|
|
30
|
-
*
|
|
30
|
+
* The main entry point for extensions to the React-based dashboard. Every dashboard extension
|
|
31
|
+
* must contain a call to this function, usually in the entry point file that is referenced by
|
|
32
|
+
* the `dashboard` property of the plugin decorator.
|
|
31
33
|
*
|
|
32
|
-
*
|
|
34
|
+
* Every type of customisation of the dashboard can be defined here, including:
|
|
33
35
|
*
|
|
36
|
+
* - Navigation (nav sections and routes)
|
|
37
|
+
* - Layout (action bar items and page blocks)
|
|
38
|
+
* - Widgets
|
|
39
|
+
* - Form components (custom form components, input components, and display components)
|
|
40
|
+
* - Data tables
|
|
41
|
+
* - Detail forms
|
|
42
|
+
* - Login
|
|
34
43
|
*
|
|
35
|
-
* @
|
|
44
|
+
* @example
|
|
45
|
+
* ```tsx
|
|
46
|
+
* defineDashboardExtension({
|
|
47
|
+
* navSections: [],
|
|
48
|
+
* routes: [],
|
|
49
|
+
* pageBlocks: [],
|
|
50
|
+
* actionBarItems: [],
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
*
|
|
55
|
+
* @docsCategory extensions-api
|
|
56
|
+
* @docsPage defineDashboardExtension
|
|
57
|
+
* @docsWeight 0
|
|
36
58
|
* @since 3.3.0
|
|
37
59
|
*/
|
|
38
60
|
export function defineDashboardExtension(extension: DashboardExtension) {
|
|
@@ -14,11 +14,20 @@ import {
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @description
|
|
17
|
-
*
|
|
17
|
+
* This is the main interface for defining _all_ extensions to the dashboard.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
19
|
+
* Every type of customisation of the dashboard can be defined here, including:
|
|
20
20
|
*
|
|
21
|
-
*
|
|
21
|
+
* - Navigation (nav sections and routes)
|
|
22
|
+
* - Layout (action bar items and page blocks)
|
|
23
|
+
* - Widgets for the Insights page
|
|
24
|
+
* - Form components
|
|
25
|
+
* - Data tables
|
|
26
|
+
* - Detail forms
|
|
27
|
+
* - Login page customisation
|
|
28
|
+
*
|
|
29
|
+
* @docsCategory extensions-api
|
|
30
|
+
* @docsPage defineDashboardExtension
|
|
22
31
|
* @since 3.3.0
|
|
23
32
|
*/
|
|
24
33
|
export interface DashboardExtension {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @description
|
|
3
|
-
* **Status: Developer Preview**
|
|
4
|
-
*
|
|
5
3
|
* Allows you to define custom alerts that can be displayed in the dashboard.
|
|
6
4
|
*
|
|
7
|
-
* @docsCategory extensions
|
|
5
|
+
* @docsCategory extensions-api
|
|
6
|
+
* @docsPage Alerts
|
|
8
7
|
* @since 3.3.0
|
|
9
8
|
*/
|
|
10
9
|
export interface DashboardAlertDefinition<TResponse = any> {
|
|
@@ -6,7 +6,7 @@ import { DocumentNode } from 'graphql';
|
|
|
6
6
|
* Allows you to define custom display components for specific columns in data tables.
|
|
7
7
|
* The pageId is already defined in the data table extension, so only the column name is needed.
|
|
8
8
|
*
|
|
9
|
-
* @docsCategory extensions
|
|
9
|
+
* @docsCategory extensions-api
|
|
10
10
|
* @docsPage DataTable
|
|
11
11
|
* @since 3.4.0
|
|
12
12
|
*/
|
|
@@ -61,7 +61,7 @@ export type BulkAction = {
|
|
|
61
61
|
* @description
|
|
62
62
|
* This allows you to customize aspects of existing data tables in the dashboard.
|
|
63
63
|
*
|
|
64
|
-
* @docsCategory extensions
|
|
64
|
+
* @docsCategory extensions-api
|
|
65
65
|
* @docsPage DataTable
|
|
66
66
|
* @since 3.4.0
|
|
67
67
|
*/
|
|
@@ -6,7 +6,7 @@ import { DocumentNode } from 'graphql';
|
|
|
6
6
|
* Allows you to define custom input components for specific fields in detail forms.
|
|
7
7
|
* The pageId is already defined in the detail form extension, so only the blockId and field are needed.
|
|
8
8
|
*
|
|
9
|
-
* @docsCategory extensions
|
|
9
|
+
* @docsCategory extensions-api
|
|
10
10
|
* @docsPage DetailForms
|
|
11
11
|
* @since 3.4.0
|
|
12
12
|
*/
|
|
@@ -36,7 +36,7 @@ export interface DashboardDetailFormInputComponent {
|
|
|
36
36
|
*
|
|
37
37
|
* @since 3.4.0
|
|
38
38
|
* @docsPage DetailForms
|
|
39
|
-
* @docsCategory extensions
|
|
39
|
+
* @docsCategory extensions-api
|
|
40
40
|
*/
|
|
41
41
|
export interface DashboardDetailFormExtensionDefinition {
|
|
42
42
|
/**
|
|
@@ -4,7 +4,7 @@ import { DashboardFormComponent } from '@/vdb/framework/form-engine/form-engine-
|
|
|
4
4
|
* @description
|
|
5
5
|
* Allows you to define custom form components for custom fields in the dashboard.
|
|
6
6
|
*
|
|
7
|
-
* @docsCategory extensions
|
|
7
|
+
* @docsCategory extensions-api
|
|
8
8
|
* @docsPage FormComponents
|
|
9
9
|
* @since 3.4.0
|
|
10
10
|
*/
|
|
@@ -27,7 +27,7 @@ export interface DashboardCustomFormComponent {
|
|
|
27
27
|
* Interface for registering custom field components in the dashboard.
|
|
28
28
|
* For input and display components, use the co-located approach with detailForms.
|
|
29
29
|
*
|
|
30
|
-
* @docsCategory extensions
|
|
30
|
+
* @docsCategory extensions-api
|
|
31
31
|
* @docsPage FormComponents
|
|
32
32
|
* @since 3.4.0
|
|
33
33
|
*/
|
|
@@ -2,17 +2,16 @@ import type React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { PageContextValue } from '../../layout-engine/page-provider.js';
|
|
4
4
|
|
|
5
|
-
export interface ActionBarButtonState {
|
|
6
|
-
disabled: boolean;
|
|
7
|
-
visible: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
5
|
/**
|
|
11
6
|
* @description
|
|
12
|
-
* Allows you to define custom action bar items for any page in the dashboard
|
|
7
|
+
* Allows you to define custom action bar items for any page in the dashboard, which is the
|
|
8
|
+
* top bar that normally contains the main call-to-action buttons such as "update" or "create".
|
|
13
9
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
10
|
+
* This API also allows you to specify dropdown menu items, which when defined, will appear in
|
|
11
|
+
* a context menu to the very right of the ActionBar.
|
|
12
|
+
*
|
|
13
|
+
* @docsCategory extensions-api
|
|
14
|
+
* @docsPage ActionBar
|
|
16
15
|
* @since 3.3.0
|
|
17
16
|
*/
|
|
18
17
|
export interface DashboardActionBarItem {
|
|
@@ -23,7 +22,8 @@ export interface DashboardActionBarItem {
|
|
|
23
22
|
pageId: string;
|
|
24
23
|
/**
|
|
25
24
|
* @description
|
|
26
|
-
* A React component that will be rendered in the action bar.
|
|
25
|
+
* A React component that will be rendered in the action bar. Typically, you would use
|
|
26
|
+
* the default Shadcn `<Button>` component.
|
|
27
27
|
*/
|
|
28
28
|
component: React.FunctionComponent<{ context: PageContextValue }>;
|
|
29
29
|
/**
|
|
@@ -54,6 +54,16 @@ export interface DashboardActionBarItem {
|
|
|
54
54
|
requiresPermission?: string | string[];
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @description
|
|
59
|
+
* The relative position of a PageBlock. This is determined by finding an existing
|
|
60
|
+
* block, and then specifying whether your custom block should come before, after,
|
|
61
|
+
* or completely replace that block.
|
|
62
|
+
*
|
|
63
|
+
* @docsCategory extensions-api
|
|
64
|
+
* @docsPage page-blocks
|
|
65
|
+
* @since 3.3.0
|
|
66
|
+
*/
|
|
57
67
|
export type PageBlockPosition = { blockId: string; order: 'before' | 'after' | 'replace' };
|
|
58
68
|
|
|
59
69
|
/**
|
|
@@ -62,8 +72,8 @@ export type PageBlockPosition = { blockId: string; order: 'before' | 'after' | '
|
|
|
62
72
|
* "developer mode" in the dashboard user menu (bottom left corner) and then
|
|
63
73
|
* clicking the `< />` icon when hovering over a page block.
|
|
64
74
|
*
|
|
65
|
-
* @docsCategory extensions
|
|
66
|
-
* @docsPage
|
|
75
|
+
* @docsCategory extensions-api
|
|
76
|
+
* @docsPage page-blocks
|
|
67
77
|
* @since 3.3.0
|
|
68
78
|
*/
|
|
69
79
|
export type PageBlockLocation = {
|
|
@@ -77,8 +87,9 @@ export type PageBlockLocation = {
|
|
|
77
87
|
* This allows you to insert a custom component into a specific location
|
|
78
88
|
* on any page in the dashboard.
|
|
79
89
|
*
|
|
80
|
-
* @docsCategory extensions
|
|
81
|
-
* @docsPage
|
|
90
|
+
* @docsCategory extensions-api
|
|
91
|
+
* @docsPage page-blocks
|
|
92
|
+
* @docsWeight 0
|
|
82
93
|
* @since 3.3.0
|
|
83
94
|
*/
|
|
84
95
|
export interface DashboardPageBlockDefinition {
|