@vendure/dashboard 3.2.3 → 3.3.0

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.
Files changed (123) hide show
  1. package/dist/plugin/utils/ast-utils.d.ts +10 -0
  2. package/dist/plugin/utils/ast-utils.js +96 -0
  3. package/dist/plugin/utils/ast-utils.spec.d.ts +1 -0
  4. package/dist/plugin/utils/ast-utils.spec.js +120 -0
  5. package/dist/plugin/{config-loader.d.ts → utils/config-loader.d.ts} +22 -8
  6. package/dist/plugin/utils/config-loader.js +325 -0
  7. package/dist/plugin/{schema-generator.d.ts → utils/schema-generator.d.ts} +5 -0
  8. package/dist/plugin/{schema-generator.js → utils/schema-generator.js} +7 -1
  9. package/dist/plugin/{ui-config.js → utils/ui-config.js} +2 -3
  10. package/dist/plugin/vite-plugin-admin-api-schema.js +2 -2
  11. package/dist/plugin/vite-plugin-config-loader.d.ts +2 -3
  12. package/dist/plugin/vite-plugin-config-loader.js +18 -9
  13. package/dist/plugin/vite-plugin-config.js +4 -6
  14. package/dist/plugin/vite-plugin-dashboard-metadata.js +12 -14
  15. package/dist/plugin/vite-plugin-gql-tada.js +2 -2
  16. package/dist/plugin/vite-plugin-ui-config.js +3 -2
  17. package/package.json +16 -11
  18. package/src/app/app-providers.tsx +9 -9
  19. package/src/app/main.tsx +1 -1
  20. package/src/app/routes/_authenticated/_assets/assets.graphql.ts +26 -0
  21. package/src/app/routes/_authenticated/_assets/assets.tsx +2 -2
  22. package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +156 -0
  23. package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +104 -0
  24. package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +228 -0
  25. package/src/app/routes/_authenticated/_orders/components/money-gross-net.tsx +18 -0
  26. package/src/app/routes/_authenticated/_orders/components/order-address.tsx +2 -1
  27. package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +38 -0
  28. package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +53 -0
  29. package/src/app/routes/_authenticated/_orders/components/order-table.tsx +8 -49
  30. package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +65 -0
  31. package/src/app/routes/_authenticated/_orders/orders.graphql.ts +187 -2
  32. package/src/app/routes/_authenticated/_orders/orders.tsx +39 -18
  33. package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +31 -9
  34. package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +418 -0
  35. package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +8 -2
  36. package/src/app/routes/_authenticated/_products/products.tsx +1 -1
  37. package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +6 -0
  38. package/src/app/routes/_authenticated/_system/job-queue.tsx +7 -8
  39. package/src/app/routes/_authenticated/_system/scheduled-tasks.tsx +241 -0
  40. package/src/app/routes/_authenticated.tsx +12 -1
  41. package/src/app/styles.css +15 -0
  42. package/src/lib/components/data-table/add-filter-menu.tsx +61 -0
  43. package/src/lib/components/data-table/data-table-column-header.tsx +0 -13
  44. package/src/lib/components/data-table/data-table-filter-badge.tsx +75 -0
  45. package/src/lib/components/data-table/data-table-filter-dialog.tsx +27 -28
  46. package/src/lib/components/data-table/data-table-types.ts +1 -0
  47. package/src/lib/components/data-table/data-table-view-options.tsx +73 -24
  48. package/src/lib/components/data-table/data-table.tsx +49 -44
  49. package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +57 -0
  50. package/src/lib/components/data-table/filters/data-table-datetime-filter.tsx +93 -0
  51. package/src/lib/components/data-table/filters/data-table-id-filter.tsx +58 -0
  52. package/src/lib/components/data-table/filters/data-table-number-filter.tsx +119 -0
  53. package/src/lib/components/data-table/filters/data-table-string-filter.tsx +62 -0
  54. package/src/lib/components/data-table/human-readable-operator.tsx +65 -0
  55. package/src/lib/components/data-table/refresh-button.tsx +25 -0
  56. package/src/lib/components/layout/nav-user.tsx +20 -15
  57. package/src/lib/components/layout/prerelease-popup.tsx +1 -5
  58. package/src/lib/components/shared/alerts.tsx +19 -1
  59. package/src/lib/components/shared/asset/asset-focal-point-editor.tsx +93 -0
  60. package/src/lib/components/shared/{asset-gallery.tsx → asset/asset-gallery.tsx} +51 -20
  61. package/src/lib/components/shared/{asset-picker-dialog.tsx → asset/asset-picker-dialog.tsx} +1 -1
  62. package/src/lib/components/shared/{asset-preview-dialog.tsx → asset/asset-preview-dialog.tsx} +1 -7
  63. package/src/lib/components/shared/asset/asset-preview-selector.tsx +34 -0
  64. package/src/lib/components/shared/asset/asset-preview.tsx +128 -0
  65. package/src/lib/components/shared/asset/asset-properties.tsx +46 -0
  66. package/src/lib/components/shared/{focal-point-control.tsx → asset/focal-point-control.tsx} +1 -1
  67. package/src/lib/components/shared/custom-fields-form.tsx +4 -3
  68. package/src/lib/components/shared/customer-selector.tsx +13 -14
  69. package/src/lib/components/shared/detail-page-button.tsx +2 -2
  70. package/src/lib/components/shared/entity-assets.tsx +3 -3
  71. package/src/lib/components/shared/error-page.tsx +2 -2
  72. package/src/lib/components/shared/navigation-confirmation.tsx +49 -0
  73. package/src/lib/components/shared/paginated-list-data-table.tsx +10 -1
  74. package/src/lib/components/shared/product-variant-selector.tsx +111 -0
  75. package/src/lib/components/shared/vendure-image.tsx +1 -1
  76. package/src/lib/components/ui/calendar.tsx +508 -63
  77. package/src/lib/framework/alert/alert-extensions.tsx +31 -0
  78. package/src/lib/framework/alert/alert-item.tsx +47 -0
  79. package/src/lib/framework/alert/alerts-indicator.tsx +23 -0
  80. package/src/lib/framework/alert/types.ts +13 -0
  81. package/src/lib/framework/dashboard-widget/base-widget.tsx +1 -0
  82. package/src/lib/framework/defaults.ts +34 -0
  83. package/src/lib/framework/document-introspection/get-document-structure.spec.ts +113 -3
  84. package/src/lib/framework/document-introspection/get-document-structure.ts +71 -13
  85. package/src/lib/framework/extension-api/define-dashboard-extension.ts +15 -5
  86. package/src/lib/framework/extension-api/extension-api-types.ts +81 -12
  87. package/src/lib/framework/form-engine/use-generated-form.tsx +8 -7
  88. package/src/lib/framework/layout-engine/layout-extensions.ts +3 -3
  89. package/src/lib/framework/layout-engine/page-layout.tsx +196 -35
  90. package/src/lib/framework/layout-engine/page-provider.tsx +10 -0
  91. package/src/lib/framework/page/detail-page.tsx +62 -9
  92. package/src/lib/framework/page/list-page.tsx +42 -4
  93. package/src/lib/framework/page/page-api.ts +1 -1
  94. package/src/lib/framework/page/use-detail-page.ts +82 -0
  95. package/src/lib/framework/registry/registry-types.ts +6 -2
  96. package/src/lib/graphql/fragments.tsx +8 -0
  97. package/src/lib/graphql/graphql-env.d.ts +25 -9
  98. package/src/lib/hooks/use-auth.tsx +13 -1
  99. package/src/lib/hooks/use-channel.ts +13 -0
  100. package/src/lib/hooks/use-local-format.ts +28 -1
  101. package/src/lib/hooks/use-page.tsx +2 -3
  102. package/src/lib/hooks/use-permissions.ts +13 -0
  103. package/src/lib/index.ts +7 -8
  104. package/src/lib/providers/auth.tsx +22 -9
  105. package/src/lib/providers/channel-provider.tsx +9 -1
  106. package/src/lib/providers/server-config.tsx +7 -1
  107. package/src/lib/providers/user-settings.tsx +24 -0
  108. package/vite/utils/ast-utils.spec.ts +128 -0
  109. package/vite/utils/ast-utils.ts +119 -0
  110. package/vite/utils/config-loader.ts +410 -0
  111. package/vite/{schema-generator.ts → utils/schema-generator.ts} +11 -6
  112. package/vite/{ui-config.ts → utils/ui-config.ts} +7 -3
  113. package/vite/vite-plugin-admin-api-schema.ts +2 -12
  114. package/vite/vite-plugin-config-loader.ts +25 -13
  115. package/vite/vite-plugin-config.ts +1 -0
  116. package/vite/vite-plugin-dashboard-metadata.ts +19 -15
  117. package/vite/vite-plugin-gql-tada.ts +2 -2
  118. package/vite/vite-plugin-ui-config.ts +3 -2
  119. package/dist/plugin/config-loader.js +0 -141
  120. package/src/lib/components/shared/asset-preview.tsx +0 -345
  121. package/src/lib/components/ui/avatar.tsx +0 -38
  122. package/vite/config-loader.ts +0 -181
  123. /package/dist/plugin/{ui-config.d.ts → utils/ui-config.d.ts} +0 -0
@@ -1,6 +1,5 @@
1
- import { assetFragment } from '@/graphql/fragments.js';
1
+ import { assetFragment, errorResultFragment } from '@/graphql/fragments.js';
2
2
  import { graphql } from '@/graphql/graphql.js';
3
- import { gql } from 'awesome-graphql-client';
4
3
 
5
4
  export const orderListDocument = graphql(`
6
5
  query GetOrders($options: OrderListOptions) {
@@ -163,6 +162,7 @@ export const orderLineFragment = graphql(
163
162
  linePriceWithTax
164
163
  discountedLinePrice
165
164
  discountedLinePriceWithTax
165
+ customFields
166
166
  }
167
167
  `,
168
168
  [assetFragment],
@@ -214,6 +214,7 @@ export const orderDetailFragment = graphql(
214
214
  promotions {
215
215
  id
216
216
  couponCode
217
+ name
217
218
  }
218
219
  subTotal
219
220
  subTotalWithTax
@@ -323,3 +324,187 @@ export const orderHistoryDocument = graphql(`
323
324
  }
324
325
  }
325
326
  `);
327
+
328
+ export const createDraftOrderDocument = graphql(`
329
+ mutation CreateDraftOrder {
330
+ createDraftOrder {
331
+ id
332
+ }
333
+ }
334
+ `);
335
+
336
+ export const deleteDraftOrderDocument = graphql(`
337
+ mutation DeleteDraftOrder($orderId: ID!) {
338
+ deleteDraftOrder(orderId: $orderId) {
339
+ result
340
+ message
341
+ }
342
+ }
343
+ `);
344
+
345
+ export const addItemToDraftOrderDocument = graphql(
346
+ `
347
+ mutation AddItemToDraftOrder($orderId: ID!, $input: AddItemToDraftOrderInput!) {
348
+ addItemToDraftOrder(orderId: $orderId, input: $input) {
349
+ __typename
350
+ ... on Order {
351
+ id
352
+ }
353
+ ...ErrorResult
354
+ }
355
+ }
356
+ `,
357
+ [errorResultFragment],
358
+ );
359
+
360
+ export const adjustDraftOrderLineDocument = graphql(
361
+ `
362
+ mutation AdjustDraftOrderLine($orderId: ID!, $input: AdjustDraftOrderLineInput!) {
363
+ adjustDraftOrderLine(orderId: $orderId, input: $input) {
364
+ __typename
365
+ ... on Order {
366
+ id
367
+ }
368
+ ...ErrorResult
369
+ }
370
+ }
371
+ `,
372
+ [errorResultFragment],
373
+ );
374
+
375
+ export const removeDraftOrderLineDocument = graphql(
376
+ `
377
+ mutation RemoveDraftOrderLine($orderId: ID!, $orderLineId: ID!) {
378
+ removeDraftOrderLine(orderId: $orderId, orderLineId: $orderLineId) {
379
+ __typename
380
+ ... on Order {
381
+ id
382
+ }
383
+ ...ErrorResult
384
+ }
385
+ }
386
+ `,
387
+ [errorResultFragment],
388
+ );
389
+
390
+ export const setCustomerForDraftOrderDocument = graphql(
391
+ `
392
+ mutation SetCustomerForDraftOrder($orderId: ID!, $customerId: ID, $input: CreateCustomerInput) {
393
+ setCustomerForDraftOrder(orderId: $orderId, customerId: $customerId, input: $input) {
394
+ __typename
395
+ ... on Order {
396
+ id
397
+ }
398
+ ...ErrorResult
399
+ }
400
+ }
401
+ `,
402
+ [errorResultFragment],
403
+ );
404
+
405
+ export const setShippingAddressForDraftOrderDocument = graphql(`
406
+ mutation SetDraftOrderShippingAddress($orderId: ID!, $input: CreateAddressInput!) {
407
+ setDraftOrderShippingAddress(orderId: $orderId, input: $input) {
408
+ id
409
+ }
410
+ }
411
+ `);
412
+
413
+ export const setBillingAddressForDraftOrderDocument = graphql(`
414
+ mutation SetDraftOrderBillingAddress($orderId: ID!, $input: CreateAddressInput!) {
415
+ setDraftOrderBillingAddress(orderId: $orderId, input: $input) {
416
+ id
417
+ }
418
+ }
419
+ `);
420
+
421
+ export const unsetShippingAddressForDraftOrderDocument = graphql(`
422
+ mutation UnsetDraftOrderShippingAddress($orderId: ID!) {
423
+ unsetDraftOrderShippingAddress(orderId: $orderId) {
424
+ id
425
+ }
426
+ }
427
+ `);
428
+
429
+ export const unsetBillingAddressForDraftOrderDocument = graphql(`
430
+ mutation UnsetDraftOrderBillingAddress($orderId: ID!) {
431
+ unsetDraftOrderBillingAddress(orderId: $orderId) {
432
+ id
433
+ }
434
+ }
435
+ `);
436
+
437
+ export const applyCouponCodeToDraftOrderDocument = graphql(
438
+ `
439
+ mutation ApplyCouponCodeToDraftOrder($orderId: ID!, $couponCode: String!) {
440
+ applyCouponCodeToDraftOrder(orderId: $orderId, couponCode: $couponCode) {
441
+ __typename
442
+ ... on Order {
443
+ id
444
+ }
445
+ ...ErrorResult
446
+ }
447
+ }
448
+ `,
449
+ [errorResultFragment],
450
+ );
451
+
452
+ export const removeCouponCodeFromDraftOrderDocument = graphql(`
453
+ mutation RemoveCouponCodeFromDraftOrder($orderId: ID!, $couponCode: String!) {
454
+ removeCouponCodeFromDraftOrder(orderId: $orderId, couponCode: $couponCode) {
455
+ id
456
+ }
457
+ }
458
+ `);
459
+
460
+ export const draftOrderEligibleShippingMethodsDocument = graphql(`
461
+ query DraftOrderEligibleShippingMethods($orderId: ID!) {
462
+ eligibleShippingMethodsForDraftOrder(orderId: $orderId) {
463
+ id
464
+ name
465
+ code
466
+ description
467
+ price
468
+ priceWithTax
469
+ metadata
470
+ }
471
+ }
472
+ `);
473
+
474
+ export const setDraftOrderShippingMethodDocument = graphql(
475
+ `
476
+ mutation SetDraftOrderShippingMethod($orderId: ID!, $shippingMethodId: ID!) {
477
+ setDraftOrderShippingMethod(orderId: $orderId, shippingMethodId: $shippingMethodId) {
478
+ __typename
479
+ ... on Order {
480
+ id
481
+ }
482
+ ...ErrorResult
483
+ }
484
+ }
485
+ `,
486
+ [errorResultFragment],
487
+ );
488
+
489
+ export const setDraftOrderCustomFieldsDocument = graphql(`
490
+ mutation SetDraftOrderCustomFields($orderId: ID!, $input: UpdateOrderInput!) {
491
+ setDraftOrderCustomFields(orderId: $orderId, input: $input) {
492
+ id
493
+ }
494
+ }
495
+ `);
496
+
497
+ export const transitionOrderToStateDocument = graphql(
498
+ `
499
+ mutation TransitionOrderToState($id: ID!, $state: String!) {
500
+ transitionOrderToState(id: $id, state: $state) {
501
+ __typename
502
+ ... on Order {
503
+ id
504
+ }
505
+ ...ErrorResult
506
+ }
507
+ }
508
+ `,
509
+ [errorResultFragment],
510
+ );
@@ -4,9 +4,14 @@ import { Badge } from '@/components/ui/badge.js';
4
4
  import { Button } from '@/components/ui/button.js';
5
5
  import { ListPage } from '@/framework/page/list-page.js';
6
6
  import { Trans } from '@/lib/trans.js';
7
- import { createFileRoute, Link } from '@tanstack/react-router';
8
- import { orderListDocument } from './orders.graphql.js';
7
+ import { createFileRoute, Link, useNavigate } from '@tanstack/react-router';
8
+ import { createDraftOrderDocument, orderListDocument } from './orders.graphql.js';
9
9
  import { useServerConfig } from '@/hooks/use-server-config.js';
10
+ import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
11
+ import { PlusIcon } from 'lucide-react';
12
+ import { useMutation } from '@tanstack/react-query';
13
+ import { api } from '@/graphql/api.js';
14
+ import { ResultOf } from '@/graphql/graphql.js';
10
15
 
11
16
  export const Route = createFileRoute('/_authenticated/_orders/orders')({
12
17
  component: OrderListPage,
@@ -15,30 +20,39 @@ export const Route = createFileRoute('/_authenticated/_orders/orders')({
15
20
 
16
21
  function OrderListPage() {
17
22
  const serverConfig = useServerConfig();
23
+ const navigate = useNavigate();
24
+ const { mutate: createDraftOrder } = useMutation({
25
+ mutationFn: api.mutate(createDraftOrderDocument),
26
+ onSuccess: (result: ResultOf<typeof createDraftOrderDocument>) => {
27
+ navigate({ to: '/orders/draft/$id', params: { id: result.createDraftOrder.id } });
28
+ }
29
+ })
18
30
  return (
19
31
  <ListPage
20
32
  pageId="order-list"
21
33
  title="Orders"
22
34
  onSearchTermChange={searchTerm => {
23
35
  return {
24
- code: {
25
- contains: searchTerm,
26
- },
27
- customerLastName: {
28
- contains: searchTerm,
29
- },
30
- transactionId: {
31
- contains: searchTerm,
32
- },
36
+ _or: [
37
+ {
38
+ code: {
39
+ contains: searchTerm,
40
+ },
41
+ },
42
+ {
43
+ customerLastName: {
44
+ contains: searchTerm,
45
+ },
46
+ },
47
+ {
48
+ transactionId: {
49
+ contains: searchTerm,
50
+ },
51
+ },
52
+ ],
33
53
  };
34
54
  }}
35
55
  defaultSort={[{ id: 'orderPlacedAt', desc: true }]}
36
- transformVariables={variables => {
37
- return {
38
- ...variables,
39
- filterOperator: 'OR',
40
- };
41
- }}
42
56
  listQuery={orderListDocument}
43
57
  route={Route}
44
58
  customizeColumns={{
@@ -115,6 +129,13 @@ function OrderListPage() {
115
129
  }) ?? [],
116
130
  },
117
131
  }}
118
- />
132
+ >
133
+ <PageActionBarRight>
134
+ <Button onClick={() => createDraftOrder({})}>
135
+ <PlusIcon className="mr-2 h-4 w-4" />
136
+ <Trans>Draft order</Trans>
137
+ </Button>
138
+ </PageActionBarRight>
139
+ </ListPage>
119
140
  );
120
141
  }
@@ -2,6 +2,7 @@ import { ErrorPage } from '@/components/shared/error-page.js';
2
2
  import { PermissionGuard } from '@/components/shared/permission-guard.js';
3
3
  import { Badge } from '@/components/ui/badge.js';
4
4
  import { Button } from '@/components/ui/button.js';
5
+ import { addCustomFields } from '@/framework/document-introspection/add-custom-fields.js';
5
6
  import {
6
7
  CustomFieldsPageBlock,
7
8
  Page,
@@ -11,10 +12,10 @@ import {
11
12
  PageLayout,
12
13
  PageTitle,
13
14
  } from '@/framework/layout-engine/page-layout.js';
14
- import { detailPageRouteLoader } from '@/framework/page/detail-page-route-loader.js';
15
- import { useDetailPage } from '@/framework/page/use-detail-page.js';
15
+ import { getDetailQueryOptions, useDetailPage } from '@/framework/page/use-detail-page.js';
16
+ import { ResultOf } from '@/graphql/graphql.js';
16
17
  import { Trans, useLingui } from '@/lib/trans.js';
17
- import { Link, createFileRoute } from '@tanstack/react-router';
18
+ import { Link, createFileRoute, redirect } from '@tanstack/react-router';
18
19
  import { User } from 'lucide-react';
19
20
  import { toast } from 'sonner';
20
21
  import { OrderAddress } from './components/order-address.js';
@@ -26,12 +27,33 @@ import { orderDetailDocument } from './orders.graphql.js';
26
27
 
27
28
  export const Route = createFileRoute('/_authenticated/_orders/orders_/$id')({
28
29
  component: OrderDetailPage,
29
- loader: detailPageRouteLoader({
30
- queryDocument: orderDetailDocument,
31
- breadcrumb(_isNew, entity) {
32
- return [{ path: '/orders', label: 'Orders' }, entity?.code];
33
- },
34
- }),
30
+ loader: async ({
31
+ context,
32
+ params,
33
+ }) => {
34
+ if (!params.id) {
35
+ throw new Error('ID param is required');
36
+ }
37
+
38
+ const result: ResultOf<typeof orderDetailDocument> = await context.queryClient.ensureQueryData(
39
+ getDetailQueryOptions(addCustomFields(orderDetailDocument), { id: params.id }),
40
+ { id: params.id },
41
+ );
42
+
43
+ if (!result.order) {
44
+ throw new Error(`Order with the ID ${params.id} was not found`);
45
+ }
46
+
47
+ if (result.order.state === 'Draft') {
48
+ throw redirect({
49
+ to: `/orders/draft/${params.id}`,
50
+ });
51
+ }
52
+
53
+ return {
54
+ breadcrumb: [{ path: '/orders', label: 'Orders' }, result.order.code],
55
+ };
56
+ },
35
57
  errorComponent: ({ error }) => <ErrorPage message={error.message} />,
36
58
  });
37
59