@vendure/dashboard 3.4.0-minor-202506250934 → 3.4.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 (523) hide show
  1. package/README.md +102 -3
  2. package/dist/plugin/api/api-extensions.d.ts +1 -0
  3. package/dist/plugin/api/api-extensions.js +38 -0
  4. package/dist/plugin/api/metrics.resolver.d.ts +8 -0
  5. package/dist/plugin/api/metrics.resolver.js +40 -0
  6. package/dist/plugin/config/metrics-strategies.d.ts +39 -0
  7. package/dist/plugin/config/metrics-strategies.js +74 -0
  8. package/dist/plugin/constants.d.ts +4 -3
  9. package/dist/plugin/constants.js +10 -277
  10. package/dist/plugin/dashboard.plugin.d.ts +95 -0
  11. package/dist/plugin/dashboard.plugin.js +168 -0
  12. package/dist/plugin/index.d.ts +2 -1
  13. package/dist/plugin/index.js +18 -1
  14. package/dist/plugin/package.json +3 -0
  15. package/dist/plugin/service/metrics.service.d.ts +15 -0
  16. package/dist/plugin/service/metrics.service.js +145 -0
  17. package/dist/plugin/types.d.ts +23 -0
  18. package/dist/plugin/types.js +13 -0
  19. package/dist/vite/constants.d.ts +5 -0
  20. package/dist/vite/constants.js +277 -0
  21. package/dist/vite/index.d.ts +1 -0
  22. package/dist/vite/index.js +1 -0
  23. package/dist/vite/types.d.ts +40 -0
  24. package/dist/{plugin → vite}/utils/ast-utils.d.ts +0 -5
  25. package/dist/vite/utils/ast-utils.js +29 -0
  26. package/dist/vite/utils/ast-utils.spec.d.ts +1 -0
  27. package/dist/vite/utils/ast-utils.spec.js +45 -0
  28. package/dist/vite/utils/compiler.d.ts +22 -0
  29. package/dist/vite/utils/compiler.js +162 -0
  30. package/dist/vite/utils/config-loader.d.ts +1 -0
  31. package/dist/vite/utils/config-loader.js +1 -0
  32. package/dist/vite/utils/logger.d.ts +3 -0
  33. package/dist/vite/utils/logger.js +39 -0
  34. package/dist/vite/utils/plugin-discovery.d.ts +27 -0
  35. package/dist/vite/utils/plugin-discovery.js +387 -0
  36. package/dist/vite/utils/tsconfig-utils.d.ts +9 -0
  37. package/dist/vite/utils/tsconfig-utils.js +50 -0
  38. package/dist/vite/utils/ui-config.d.ts +3 -0
  39. package/dist/vite/utils/ui-config.js +30 -0
  40. package/dist/{plugin → vite}/vite-plugin-config-loader.d.ts +3 -3
  41. package/dist/{plugin → vite}/vite-plugin-config-loader.js +18 -13
  42. package/dist/{plugin → vite}/vite-plugin-config.js +6 -7
  43. package/dist/{plugin → vite}/vite-plugin-dashboard-metadata.d.ts +1 -3
  44. package/dist/{plugin → vite}/vite-plugin-dashboard-metadata.js +20 -10
  45. package/dist/vite/vite-plugin-tailwind-source.d.ts +7 -0
  46. package/dist/vite/vite-plugin-tailwind-source.js +61 -0
  47. package/dist/vite/vite-plugin-theme.js +130 -0
  48. package/dist/vite/vite-plugin-ui-config.d.ts +123 -0
  49. package/dist/{plugin → vite}/vite-plugin-ui-config.js +3 -11
  50. package/dist/vite/vite-plugin-vendure-dashboard.d.ts +85 -0
  51. package/dist/{plugin → vite}/vite-plugin-vendure-dashboard.js +10 -7
  52. package/index.html +1 -1
  53. package/package.json +56 -31
  54. package/src/app/app-providers.tsx +7 -7
  55. package/src/app/common/delete-bulk-action.tsx +148 -0
  56. package/src/app/common/duplicate-bulk-action.tsx +134 -0
  57. package/src/app/main.tsx +9 -9
  58. package/src/app/routes/__root.tsx +1 -2
  59. package/src/app/routes/_authenticated/_administrators/administrators.graphql.ts +10 -1
  60. package/src/app/routes/_authenticated/_administrators/administrators.tsx +15 -8
  61. package/src/app/routes/_authenticated/_administrators/administrators_.$id.tsx +16 -12
  62. package/src/app/routes/_authenticated/_administrators/components/administrator-bulk-actions.tsx +15 -0
  63. package/src/app/routes/_authenticated/_administrators/components/role-permissions-display.tsx +16 -16
  64. package/src/app/routes/_authenticated/_assets/assets.graphql.ts +13 -2
  65. package/src/app/routes/_authenticated/_assets/assets.tsx +16 -4
  66. package/src/app/routes/_authenticated/_assets/assets_.$id.tsx +52 -38
  67. package/src/app/routes/_authenticated/_assets/components/asset-bulk-actions.tsx +45 -0
  68. package/src/app/routes/_authenticated/_channels/channels.graphql.ts +10 -1
  69. package/src/app/routes/_authenticated/_channels/channels.tsx +17 -10
  70. package/src/app/routes/_authenticated/_channels/channels_.$id.tsx +21 -17
  71. package/src/app/routes/_authenticated/_channels/components/channel-bulk-actions.tsx +15 -0
  72. package/src/app/routes/_authenticated/_collections/collections.graphql.ts +60 -3
  73. package/src/app/routes/_authenticated/_collections/collections.tsx +168 -124
  74. package/src/app/routes/_authenticated/_collections/collections_.$id.tsx +21 -17
  75. package/src/app/routes/_authenticated/_collections/components/collection-bulk-actions.tsx +123 -0
  76. package/src/app/routes/_authenticated/_collections/components/collection-contents-preview-table.tsx +8 -9
  77. package/src/app/routes/_authenticated/_collections/components/collection-contents-sheet.tsx +9 -5
  78. package/src/app/routes/_authenticated/_collections/components/collection-contents-table.tsx +10 -9
  79. package/src/app/routes/_authenticated/_collections/components/collection-filters-selector.tsx +12 -79
  80. package/src/app/routes/_authenticated/_collections/components/move-collections-dialog.tsx +430 -0
  81. package/src/app/routes/_authenticated/_collections/components/move-single-collection.tsx +33 -0
  82. package/src/app/routes/_authenticated/_countries/components/country-bulk-actions.tsx +15 -0
  83. package/src/app/routes/_authenticated/_countries/countries.graphql.ts +11 -2
  84. package/src/app/routes/_authenticated/_countries/countries.tsx +13 -6
  85. package/src/app/routes/_authenticated/_countries/countries_.$id.tsx +21 -17
  86. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-bulk-actions.tsx +15 -0
  87. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-sheet.tsx +12 -5
  88. package/src/app/routes/_authenticated/_customer-groups/components/customer-group-members-table.tsx +22 -17
  89. package/src/app/routes/_authenticated/_customer-groups/customer-groups.graphql.ts +11 -2
  90. package/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx +13 -6
  91. package/src/app/routes/_authenticated/_customer-groups/customer-groups_.$id.tsx +18 -15
  92. package/src/app/routes/_authenticated/_customers/components/customer-address-card.tsx +19 -19
  93. package/src/app/routes/_authenticated/_customers/components/customer-address-form.tsx +10 -10
  94. package/src/app/routes/_authenticated/_customers/components/customer-bulk-actions.tsx +15 -0
  95. package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history-container.tsx +5 -5
  96. package/src/app/routes/_authenticated/_customers/components/customer-history/customer-history.tsx +11 -7
  97. package/src/app/routes/_authenticated/_customers/components/customer-history/use-customer-history.ts +4 -4
  98. package/src/app/routes/_authenticated/_customers/components/customer-order-table.tsx +75 -73
  99. package/src/app/routes/_authenticated/_customers/components/customer-status-badge.tsx +4 -4
  100. package/src/app/routes/_authenticated/_customers/customers.graphql.ts +10 -2
  101. package/src/app/routes/_authenticated/_customers/customers.tsx +13 -6
  102. package/src/app/routes/_authenticated/_customers/customers_.$id.tsx +19 -15
  103. package/src/app/routes/_authenticated/_facets/components/edit-facet-value.tsx +9 -9
  104. package/src/app/routes/_authenticated/_facets/components/facet-bulk-actions.tsx +104 -0
  105. package/src/app/routes/_authenticated/_facets/components/facet-values-sheet.tsx +4 -4
  106. package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +76 -65
  107. package/src/app/routes/_authenticated/_facets/facets.graphql.ts +80 -1
  108. package/src/app/routes/_authenticated/_facets/facets.tsx +31 -7
  109. package/src/app/routes/_authenticated/_facets/facets_.$facetId.values_.$id.tsx +147 -0
  110. package/src/app/routes/_authenticated/_facets/facets_.$id.tsx +17 -13
  111. package/src/app/routes/_authenticated/_global-settings/global-settings.graphql.ts +1 -1
  112. package/src/app/routes/_authenticated/_global-settings/global-settings.tsx +26 -18
  113. package/src/app/routes/_authenticated/_orders/components/add-manual-payment-dialog.tsx +191 -0
  114. package/src/app/routes/_authenticated/_orders/components/customer-address-selector.tsx +11 -15
  115. package/src/app/routes/_authenticated/_orders/components/edit-order-table.tsx +111 -80
  116. package/src/app/routes/_authenticated/_orders/components/fulfill-order-dialog.tsx +320 -0
  117. package/src/app/routes/_authenticated/_orders/components/fulfillment-details.tsx +153 -0
  118. package/src/app/routes/_authenticated/_orders/components/money-gross-net.tsx +11 -9
  119. package/src/app/routes/_authenticated/_orders/components/order-address.tsx +19 -13
  120. package/src/app/routes/_authenticated/_orders/components/order-history/order-history-container.tsx +67 -62
  121. package/src/app/routes/_authenticated/_orders/components/order-history/order-history.tsx +391 -39
  122. package/src/app/routes/_authenticated/_orders/components/order-history/use-order-history.ts +9 -5
  123. package/src/app/routes/_authenticated/_orders/components/order-line-custom-fields-form.tsx +28 -13
  124. package/src/app/routes/_authenticated/_orders/components/order-modification-preview-dialog.tsx +364 -0
  125. package/src/app/routes/_authenticated/_orders/components/order-modification-summary.tsx +222 -0
  126. package/src/app/routes/_authenticated/_orders/components/order-table-totals.tsx +39 -22
  127. package/src/app/routes/_authenticated/_orders/components/order-table.tsx +148 -87
  128. package/src/app/routes/_authenticated/_orders/components/order-tax-summary.tsx +37 -36
  129. package/src/app/routes/_authenticated/_orders/components/payment-details.tsx +274 -48
  130. package/src/app/routes/_authenticated/_orders/components/settle-refund-dialog.tsx +80 -0
  131. package/src/app/routes/_authenticated/_orders/components/shipping-method-selector.tsx +43 -44
  132. package/src/app/routes/_authenticated/_orders/components/state-transition-control.tsx +102 -0
  133. package/src/app/routes/_authenticated/_orders/components/use-transition-order-to-state.tsx +144 -0
  134. package/src/app/routes/_authenticated/_orders/orders.graphql.ts +219 -5
  135. package/src/app/routes/_authenticated/_orders/orders.tsx +23 -22
  136. package/src/app/routes/_authenticated/_orders/orders_.$id.tsx +190 -42
  137. package/src/app/routes/_authenticated/_orders/orders_.$id_.modify.tsx +550 -0
  138. package/src/app/routes/_authenticated/_orders/orders_.draft.$id.tsx +187 -107
  139. package/src/app/routes/_authenticated/_orders/utils/order-types.ts +10 -0
  140. package/src/app/routes/_authenticated/_orders/utils/order-utils.ts +78 -0
  141. package/src/app/routes/_authenticated/_payment-methods/components/payment-eligibility-checker-selector.tsx +12 -79
  142. package/src/app/routes/_authenticated/_payment-methods/components/payment-handler-selector.tsx +12 -79
  143. package/src/app/routes/_authenticated/_payment-methods/components/payment-method-bulk-actions.tsx +58 -0
  144. package/src/app/routes/_authenticated/_payment-methods/payment-methods.graphql.ts +29 -2
  145. package/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx +36 -14
  146. package/src/app/routes/_authenticated/_payment-methods/payment-methods_.$id.tsx +22 -15
  147. package/src/app/routes/_authenticated/_product-variants/components/product-variant-bulk-actions.tsx +110 -0
  148. package/src/app/routes/_authenticated/_product-variants/components/variant-price-detail.tsx +7 -6
  149. package/src/app/routes/_authenticated/_product-variants/product-variants.graphql.ts +64 -3
  150. package/src/app/routes/_authenticated/_product-variants/product-variants.tsx +39 -9
  151. package/src/app/routes/_authenticated/_product-variants/product-variants_.$id.tsx +33 -22
  152. package/src/app/routes/_authenticated/_products/components/add-product-variant-dialog.tsx +10 -10
  153. package/src/app/routes/_authenticated/_products/components/assign-facet-values-dialog.tsx +281 -0
  154. package/src/app/routes/_authenticated/_products/components/create-product-options-dialog.tsx +57 -41
  155. package/src/app/routes/_authenticated/_products/components/create-product-variants-dialog.tsx +11 -11
  156. package/src/app/routes/_authenticated/_products/components/create-product-variants.tsx +18 -14
  157. package/src/app/routes/_authenticated/_products/components/option-value-input.tsx +23 -17
  158. package/src/app/routes/_authenticated/_products/components/product-bulk-actions.tsx +123 -0
  159. package/src/app/routes/_authenticated/_products/components/product-option-select.tsx +28 -34
  160. package/src/app/routes/_authenticated/_products/components/product-variants-table.tsx +84 -53
  161. package/src/app/routes/_authenticated/_products/products.graphql.ts +70 -2
  162. package/src/app/routes/_authenticated/_products/products.tsx +36 -7
  163. package/src/app/routes/_authenticated/_products/products_.$id.tsx +34 -26
  164. package/src/app/routes/_authenticated/_profile/profile.graphql.ts +1 -1
  165. package/src/app/routes/_authenticated/_profile/profile.tsx +8 -8
  166. package/src/app/routes/_authenticated/_promotions/components/promotion-actions-selector.tsx +14 -86
  167. package/src/app/routes/_authenticated/_promotions/components/promotion-bulk-actions.tsx +82 -0
  168. package/src/app/routes/_authenticated/_promotions/components/promotion-conditions-selector.tsx +14 -86
  169. package/src/app/routes/_authenticated/_promotions/promotions.graphql.ts +27 -2
  170. package/src/app/routes/_authenticated/_promotions/promotions.tsx +31 -7
  171. package/src/app/routes/_authenticated/_promotions/promotions_.$id.tsx +20 -16
  172. package/src/app/routes/_authenticated/_roles/components/expandable-permissions.tsx +5 -5
  173. package/src/app/routes/_authenticated/_roles/components/permissions-grid.tsx +21 -17
  174. package/src/app/routes/_authenticated/_roles/components/role-bulk-actions.tsx +15 -0
  175. package/src/app/routes/_authenticated/_roles/roles.graphql.ts +10 -1
  176. package/src/app/routes/_authenticated/_roles/roles.tsx +17 -10
  177. package/src/app/routes/_authenticated/_roles/roles_.$id.tsx +16 -12
  178. package/src/app/routes/_authenticated/_sellers/components/seller-bulk-actions.tsx +15 -0
  179. package/src/app/routes/_authenticated/_sellers/sellers.graphql.ts +10 -1
  180. package/src/app/routes/_authenticated/_sellers/sellers.tsx +13 -6
  181. package/src/app/routes/_authenticated/_sellers/sellers_.$id.tsx +17 -13
  182. package/src/app/routes/_authenticated/_shipping-methods/components/fulfillment-handler-selector.tsx +6 -6
  183. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-calculator-selector.tsx +12 -80
  184. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-eligibility-checker-selector.tsx +15 -80
  185. package/src/app/routes/_authenticated/_shipping-methods/components/shipping-method-bulk-actions.tsx +61 -0
  186. package/src/app/routes/_authenticated/_shipping-methods/components/test-shipping-method-dialog.tsx +3 -3
  187. package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.graphql.ts +29 -2
  188. package/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx +25 -6
  189. package/src/app/routes/_authenticated/_shipping-methods/shipping-methods_.$id.tsx +25 -19
  190. package/src/app/routes/_authenticated/_stock-locations/components/stock-location-bulk-actions.tsx +58 -0
  191. package/src/app/routes/_authenticated/_stock-locations/stock-locations.graphql.ts +26 -1
  192. package/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx +25 -6
  193. package/src/app/routes/_authenticated/_stock-locations/stock-locations_.$id.tsx +16 -12
  194. package/src/app/routes/_authenticated/_system/components/payload-dialog.tsx +5 -5
  195. package/src/app/routes/_authenticated/_system/healthchecks.tsx +5 -5
  196. package/src/app/routes/_authenticated/_system/job-queue.graphql.ts +12 -1
  197. package/src/app/routes/_authenticated/_system/job-queue.tsx +110 -11
  198. package/src/app/routes/_authenticated/_system/scheduled-tasks.tsx +34 -28
  199. package/src/app/routes/_authenticated/_tax-categories/components/tax-category-bulk-actions.tsx +15 -0
  200. package/src/app/routes/_authenticated/_tax-categories/tax-categories.graphql.ts +11 -2
  201. package/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx +14 -7
  202. package/src/app/routes/_authenticated/_tax-categories/tax-categories_.$id.tsx +20 -16
  203. package/src/app/routes/_authenticated/_tax-rates/components/tax-rate-bulk-actions.tsx +15 -0
  204. package/src/app/routes/_authenticated/_tax-rates/tax-rates.graphql.ts +11 -2
  205. package/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx +15 -8
  206. package/src/app/routes/_authenticated/_tax-rates/tax-rates_.$id.tsx +22 -18
  207. package/src/app/routes/_authenticated/_zones/components/zone-bulk-actions.tsx +15 -0
  208. package/src/app/routes/_authenticated/_zones/components/zone-countries-sheet.tsx +4 -4
  209. package/src/app/routes/_authenticated/_zones/components/zone-countries-table.tsx +12 -15
  210. package/src/app/routes/_authenticated/_zones/zones.graphql.ts +11 -2
  211. package/src/app/routes/_authenticated/_zones/zones.tsx +13 -6
  212. package/src/app/routes/_authenticated/_zones/zones_.$id.tsx +18 -14
  213. package/src/app/routes/_authenticated/index.tsx +6 -6
  214. package/src/app/routes/_authenticated.tsx +4 -4
  215. package/src/app/routes/login.tsx +2 -2
  216. package/src/app/styles.css +5 -2
  217. package/src/lib/components/data-display/boolean.tsx +1 -1
  218. package/src/lib/components/data-display/date-time.tsx +9 -3
  219. package/src/lib/components/data-display/json.tsx +1 -1
  220. package/src/lib/components/data-display/money.tsx +2 -3
  221. package/src/lib/components/data-input/affixed-input.tsx +3 -8
  222. package/src/lib/components/data-input/combination-mode-input.tsx +52 -0
  223. package/src/lib/components/data-input/configurable-operation-list-input.tsx +433 -0
  224. package/src/lib/components/data-input/custom-field-list-input.tsx +297 -0
  225. package/src/lib/components/data-input/customer-group-input.tsx +2 -2
  226. package/src/lib/components/data-input/datetime-input.tsx +132 -146
  227. package/src/lib/components/data-input/default-relation-input.tsx +599 -0
  228. package/src/lib/components/data-input/facet-value-input.tsx +30 -22
  229. package/src/lib/components/data-input/index.ts +17 -0
  230. package/src/lib/components/data-input/money-input.tsx +5 -12
  231. package/src/lib/components/data-input/product-multi-selector.tsx +426 -0
  232. package/src/lib/components/data-input/relation-input.tsx +164 -0
  233. package/src/lib/components/data-input/relation-selector.tsx +476 -0
  234. package/src/lib/components/data-input/{richt-text-input.tsx → rich-text-input.tsx} +15 -9
  235. package/src/lib/components/data-input/select-with-options.tsx +84 -0
  236. package/src/lib/components/data-input/struct-form-input.tsx +324 -0
  237. package/src/lib/components/data-table/add-filter-menu.tsx +9 -18
  238. package/src/lib/components/data-table/data-table-bulk-action-item.tsx +101 -0
  239. package/src/lib/components/data-table/data-table-bulk-actions.tsx +108 -0
  240. package/src/lib/components/data-table/data-table-column-header.tsx +4 -22
  241. package/src/lib/components/data-table/data-table-faceted-filter.tsx +8 -8
  242. package/src/lib/components/data-table/data-table-filter-badge.tsx +16 -8
  243. package/src/lib/components/data-table/data-table-filter-dialog.tsx +8 -8
  244. package/src/lib/components/data-table/data-table-pagination.tsx +4 -4
  245. package/src/lib/components/data-table/data-table-utils.ts +34 -0
  246. package/src/lib/components/data-table/data-table-view-options.tsx +27 -23
  247. package/src/lib/components/data-table/data-table.tsx +90 -43
  248. package/src/lib/components/data-table/filters/data-table-boolean-filter.tsx +11 -8
  249. package/src/lib/components/data-table/filters/data-table-datetime-filter.tsx +14 -23
  250. package/src/lib/components/data-table/filters/data-table-id-filter.tsx +15 -10
  251. package/src/lib/components/data-table/filters/data-table-number-filter.tsx +18 -17
  252. package/src/lib/components/data-table/filters/data-table-string-filter.tsx +29 -12
  253. package/src/lib/components/data-table/human-readable-operator.tsx +3 -3
  254. package/src/lib/components/data-table/refresh-button.tsx +30 -15
  255. package/src/lib/components/data-table/use-generated-columns.tsx +322 -0
  256. package/src/lib/components/labeled-data.tsx +21 -0
  257. package/src/lib/components/layout/app-layout.tsx +8 -13
  258. package/src/lib/components/layout/app-sidebar.tsx +5 -5
  259. package/src/lib/components/layout/channel-switcher.tsx +171 -62
  260. package/src/lib/components/layout/content-language-selector.tsx +16 -10
  261. package/src/lib/components/layout/dev-mode-indicator.tsx +18 -0
  262. package/src/lib/components/layout/generated-breadcrumbs.tsx +1 -1
  263. package/src/lib/components/layout/language-dialog.tsx +7 -12
  264. package/src/lib/components/layout/manage-languages-dialog.tsx +405 -0
  265. package/src/lib/components/layout/nav-item-wrapper.tsx +107 -0
  266. package/src/lib/components/layout/nav-main.tsx +200 -111
  267. package/src/lib/components/layout/nav-projects.tsx +2 -2
  268. package/src/lib/components/layout/nav-user.tsx +7 -7
  269. package/src/lib/components/layout/prerelease-popup.tsx +1 -1
  270. package/src/lib/components/login/login-form.tsx +85 -50
  271. package/src/lib/components/shared/alerts.tsx +3 -3
  272. package/src/lib/components/shared/animated-number.tsx +2 -2
  273. package/src/lib/components/shared/asset/asset-bulk-actions.tsx +109 -0
  274. package/src/lib/components/shared/asset/asset-focal-point-editor.tsx +29 -19
  275. package/src/lib/components/shared/asset/asset-gallery.tsx +25 -20
  276. package/src/lib/components/shared/asset/asset-picker-dialog.tsx +63 -66
  277. package/src/lib/components/shared/asset/asset-preview-dialog.tsx +3 -7
  278. package/src/lib/components/shared/asset/asset-preview-selector.tsx +4 -6
  279. package/src/lib/components/shared/asset/asset-preview.tsx +7 -21
  280. package/src/lib/components/shared/asset/asset-properties.tsx +7 -9
  281. package/src/lib/components/shared/asset/focal-point-control.tsx +5 -13
  282. package/src/lib/components/shared/assign-to-channel-bulk-action.tsx +71 -0
  283. package/src/lib/components/shared/assign-to-channel-dialog.tsx +155 -0
  284. package/src/lib/components/shared/assigned-facet-values.tsx +1 -5
  285. package/src/lib/components/shared/channel-code-label.tsx +3 -4
  286. package/src/lib/components/shared/channel-selector.tsx +6 -6
  287. package/src/lib/components/shared/configurable-operation-arg-input.tsx +367 -23
  288. package/src/lib/components/shared/configurable-operation-input.tsx +87 -48
  289. package/src/lib/components/shared/configurable-operation-multi-selector.tsx +260 -0
  290. package/src/lib/components/shared/configurable-operation-selector.tsx +156 -0
  291. package/src/lib/components/shared/confirmation-dialog.tsx +2 -2
  292. package/src/lib/components/shared/copyable-text.tsx +3 -4
  293. package/src/lib/components/shared/country-selector.tsx +21 -18
  294. package/src/lib/components/shared/currency-selector.tsx +5 -5
  295. package/src/lib/components/shared/custom-fields-form.tsx +423 -50
  296. package/src/lib/components/shared/customer-address-form.tsx +18 -13
  297. package/src/lib/components/shared/customer-group-selector.tsx +6 -6
  298. package/src/lib/components/shared/customer-selector.tsx +24 -18
  299. package/src/lib/components/shared/detail-page-button.tsx +45 -1
  300. package/src/lib/components/shared/entity-assets.tsx +33 -34
  301. package/src/lib/components/shared/error-page.tsx +6 -6
  302. package/src/lib/components/shared/facet-value-chip.tsx +12 -5
  303. package/src/lib/components/shared/facet-value-selector.tsx +64 -63
  304. package/src/lib/components/shared/form-field-wrapper.tsx +47 -24
  305. package/src/lib/components/shared/history-timeline/history-entry-date.tsx +37 -0
  306. package/src/lib/components/shared/history-timeline/history-entry.tsx +146 -70
  307. package/src/lib/components/shared/history-timeline/history-note-checkbox.tsx +3 -3
  308. package/src/lib/components/shared/history-timeline/history-note-editor.tsx +4 -4
  309. package/src/lib/components/shared/history-timeline/history-note-input.tsx +7 -7
  310. package/src/lib/components/shared/history-timeline/history-timeline.tsx +8 -48
  311. package/src/lib/components/shared/language-selector.tsx +5 -5
  312. package/src/lib/components/shared/logo-mark.tsx +2 -2
  313. package/src/lib/components/shared/multi-select.tsx +6 -6
  314. package/src/lib/components/shared/navigation-confirmation.tsx +24 -9
  315. package/src/lib/components/shared/option-value-input.tsx +18 -16
  316. package/src/lib/components/shared/paginated-list-data-table.tsx +35 -230
  317. package/src/lib/components/shared/permission-guard.tsx +4 -4
  318. package/src/lib/components/shared/product-variant-selector.tsx +59 -34
  319. package/src/lib/components/shared/remove-from-channel-bulk-action.tsx +90 -0
  320. package/src/lib/components/shared/role-code-label.tsx +10 -6
  321. package/src/lib/components/shared/role-selector.tsx +4 -4
  322. package/src/lib/components/shared/seller-selector.tsx +21 -17
  323. package/src/lib/components/shared/stock-level-label.tsx +5 -5
  324. package/src/lib/components/shared/tax-category-selector.tsx +5 -5
  325. package/src/lib/components/shared/translatable-form-field.tsx +46 -23
  326. package/src/lib/components/shared/vendure-image.tsx +31 -2
  327. package/src/lib/components/shared/zone-selector.tsx +5 -6
  328. package/src/lib/components/ui/accordion.tsx +3 -3
  329. package/src/lib/components/ui/alert-dialog.tsx +10 -10
  330. package/src/lib/components/ui/alert.tsx +3 -3
  331. package/src/lib/components/ui/aspect-ratio.tsx +9 -0
  332. package/src/lib/components/ui/badge.tsx +2 -2
  333. package/src/lib/components/ui/breadcrumb.tsx +4 -4
  334. package/src/lib/components/ui/button.tsx +10 -3
  335. package/src/lib/components/ui/calendar.tsx +392 -459
  336. package/src/lib/components/ui/card.tsx +2 -2
  337. package/src/lib/components/ui/carousel.tsx +241 -0
  338. package/src/lib/components/ui/chart.tsx +351 -0
  339. package/src/lib/components/ui/checkbox.tsx +2 -2
  340. package/src/lib/components/ui/command.tsx +12 -6
  341. package/src/lib/components/ui/context-menu.tsx +252 -0
  342. package/src/lib/components/ui/dialog.tsx +2 -2
  343. package/src/lib/components/ui/drawer.tsx +133 -0
  344. package/src/lib/components/ui/dropdown-menu.tsx +7 -7
  345. package/src/lib/components/ui/form.tsx +8 -8
  346. package/src/lib/components/ui/hover-card.tsx +3 -3
  347. package/src/lib/components/ui/input-otp.tsx +77 -0
  348. package/src/lib/components/ui/input.tsx +1 -1
  349. package/src/lib/components/ui/label.tsx +2 -2
  350. package/src/lib/components/ui/menubar.tsx +274 -0
  351. package/src/lib/components/ui/navigation-menu.tsx +168 -0
  352. package/src/lib/components/ui/pagination.tsx +87 -108
  353. package/src/lib/components/ui/popover.tsx +3 -3
  354. package/src/lib/components/ui/progress.tsx +29 -0
  355. package/src/lib/components/ui/radio-group.tsx +45 -0
  356. package/src/lib/components/ui/resizable.tsx +54 -0
  357. package/src/lib/components/ui/scroll-area.tsx +2 -2
  358. package/src/lib/components/ui/select.tsx +151 -129
  359. package/src/lib/components/ui/separator.tsx +2 -2
  360. package/src/lib/components/ui/sheet.tsx +5 -5
  361. package/src/lib/components/ui/sidebar.tsx +10 -10
  362. package/src/lib/components/ui/skeleton.tsx +1 -1
  363. package/src/lib/components/ui/slider.tsx +63 -0
  364. package/src/lib/components/ui/switch.tsx +2 -2
  365. package/src/lib/components/ui/table.tsx +2 -2
  366. package/src/lib/components/ui/tabs.tsx +3 -3
  367. package/src/lib/components/ui/textarea.tsx +1 -1
  368. package/src/lib/components/ui/toggle-group.tsx +73 -0
  369. package/src/lib/components/ui/toggle.tsx +45 -0
  370. package/src/lib/components/ui/tooltip.tsx +3 -3
  371. package/src/lib/framework/alert/alert-extensions.tsx +2 -3
  372. package/src/lib/framework/alert/alert-item.tsx +5 -3
  373. package/src/lib/framework/component-registry/component-registry.tsx +33 -47
  374. package/src/lib/framework/component-registry/dynamic-component.tsx +3 -3
  375. package/src/lib/framework/dashboard-widget/base-widget.tsx +5 -13
  376. package/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx +8 -8
  377. package/src/lib/framework/dashboard-widget/latest-orders-widget/latest-orders-widget.graphql.ts +1 -1
  378. package/src/lib/framework/dashboard-widget/metrics-widget/index.tsx +7 -8
  379. package/src/lib/framework/dashboard-widget/metrics-widget/metrics-widget.graphql.ts +1 -1
  380. package/src/lib/framework/dashboard-widget/orders-summary/index.tsx +7 -8
  381. package/src/lib/framework/dashboard-widget/orders-summary/order-summary-widget.graphql.ts +1 -1
  382. package/src/lib/framework/dashboard-widget/widget-extensions.tsx +1 -1
  383. package/src/lib/framework/data-table/data-table-extensions.ts +35 -0
  384. package/src/lib/framework/defaults.ts +5 -11
  385. package/src/lib/framework/document-extension/extend-detail-form-query.ts +50 -0
  386. package/src/lib/framework/document-extension/extend-document.spec.ts +884 -0
  387. package/src/lib/framework/document-extension/extend-document.ts +159 -0
  388. package/src/lib/framework/document-introspection/add-custom-fields.ts +50 -2
  389. package/src/lib/framework/document-introspection/get-document-structure.spec.ts +321 -2
  390. package/src/lib/framework/document-introspection/get-document-structure.ts +187 -36
  391. package/src/lib/framework/document-introspection/hooks.ts +4 -1
  392. package/src/lib/framework/extension-api/define-dashboard-extension.ts +35 -49
  393. package/src/lib/framework/extension-api/display-component-extensions.tsx +69 -0
  394. package/src/lib/framework/extension-api/extension-api-types.ts +34 -98
  395. package/src/lib/framework/extension-api/input-component-extensions.tsx +73 -0
  396. package/src/lib/framework/extension-api/logic/alerts.ts +10 -0
  397. package/src/lib/framework/extension-api/logic/data-table.ts +60 -0
  398. package/src/lib/framework/extension-api/logic/detail-forms.ts +48 -0
  399. package/src/lib/framework/extension-api/logic/form-components.ts +13 -0
  400. package/src/lib/framework/extension-api/logic/index.ts +9 -0
  401. package/src/lib/framework/extension-api/logic/layout.ts +22 -0
  402. package/src/lib/framework/extension-api/logic/login.ts +17 -0
  403. package/src/lib/framework/extension-api/logic/navigation.ts +38 -0
  404. package/src/lib/framework/extension-api/logic/widgets.ts +10 -0
  405. package/src/lib/framework/extension-api/types/alerts.ts +54 -0
  406. package/src/lib/framework/extension-api/types/data-table.ts +96 -0
  407. package/src/lib/framework/extension-api/types/detail-forms.ts +94 -0
  408. package/src/lib/framework/extension-api/types/form-components.ts +43 -0
  409. package/src/lib/framework/extension-api/types/index.ts +9 -0
  410. package/src/lib/framework/extension-api/types/layout.ts +90 -0
  411. package/src/lib/framework/extension-api/types/login.ts +96 -0
  412. package/src/lib/framework/extension-api/types/navigation.ts +76 -0
  413. package/src/lib/framework/extension-api/types/widgets.ts +93 -0
  414. package/src/lib/framework/extension-api/use-dashboard-extensions.ts +2 -1
  415. package/src/lib/framework/extension-api/use-login-extensions.ts +26 -0
  416. package/src/lib/framework/form-engine/custom-form-component-extensions.ts +38 -0
  417. package/src/lib/framework/form-engine/custom-form-component.tsx +33 -0
  418. package/src/lib/framework/form-engine/form-schema-tools.spec.ts +472 -0
  419. package/src/lib/framework/form-engine/form-schema-tools.ts +341 -6
  420. package/src/lib/framework/form-engine/overridden-form-component.tsx +51 -0
  421. package/src/lib/framework/form-engine/use-generated-form.tsx +82 -24
  422. package/src/lib/framework/form-engine/utils.spec.ts +37 -0
  423. package/src/lib/framework/form-engine/utils.ts +99 -0
  424. package/src/lib/framework/layout-engine/dev-mode-button.tsx +24 -0
  425. package/src/lib/framework/layout-engine/layout-extensions.ts +1 -4
  426. package/src/lib/framework/layout-engine/location-wrapper.tsx +98 -72
  427. package/src/lib/framework/layout-engine/page-block-provider.tsx +6 -0
  428. package/src/lib/framework/layout-engine/page-layout.tsx +135 -58
  429. package/src/lib/framework/page/detail-page-route-loader.tsx +26 -7
  430. package/src/lib/framework/page/detail-page.tsx +94 -37
  431. package/src/lib/framework/page/list-page.tsx +18 -11
  432. package/src/lib/framework/page/use-detail-page.ts +47 -13
  433. package/src/lib/framework/page/use-extended-router.tsx +4 -5
  434. package/src/lib/framework/registry/global-registry.ts +4 -0
  435. package/src/lib/framework/registry/registry-types.ts +17 -5
  436. package/src/lib/graphql/api.ts +25 -3
  437. package/src/lib/graphql/common-operations.ts +18 -0
  438. package/src/lib/graphql/{fragments.tsx → fragments.ts} +1 -2
  439. package/src/lib/graphql/graphql-env.d.ts +27 -24
  440. package/src/lib/graphql/settings-store-operations.ts +17 -0
  441. package/src/lib/hooks/use-auth.tsx +1 -1
  442. package/src/lib/hooks/use-channel.ts +1 -1
  443. package/src/lib/hooks/use-extended-detail-query.ts +37 -0
  444. package/src/lib/hooks/use-extended-list-query.ts +75 -0
  445. package/src/lib/hooks/use-floating-bulk-actions.ts +82 -0
  446. package/src/lib/hooks/use-grouped-permissions.ts +3 -2
  447. package/src/lib/hooks/use-local-format.ts +20 -5
  448. package/src/lib/hooks/use-page-block.tsx +18 -0
  449. package/src/lib/hooks/use-page.tsx +2 -2
  450. package/src/lib/hooks/use-permissions.ts +3 -2
  451. package/src/lib/hooks/use-server-config.ts +1 -1
  452. package/src/lib/hooks/use-theme.ts +1 -1
  453. package/src/lib/hooks/use-user-settings.tsx +1 -1
  454. package/src/lib/index.ts +85 -7
  455. package/src/lib/lib/trans.tsx +3 -3
  456. package/src/lib/lib/utils.ts +52 -1
  457. package/src/lib/providers/auth.tsx +37 -14
  458. package/src/lib/providers/channel-provider.tsx +17 -15
  459. package/src/lib/providers/server-config.tsx +13 -11
  460. package/src/lib/providers/theme-provider.tsx +2 -3
  461. package/src/lib/providers/user-settings.tsx +78 -3
  462. package/src/lib/virtual.d.ts +26 -2
  463. package/src/vite-env.d.ts +2 -0
  464. package/vite/tests/barrel-exports.spec.ts +30 -0
  465. package/vite/tests/fixtures-barrel-exports/my-plugin/index.ts +1 -0
  466. package/vite/tests/fixtures-barrel-exports/my-plugin/src/my.plugin.ts +8 -0
  467. package/vite/tests/fixtures-barrel-exports/package.json +6 -0
  468. package/vite/tests/fixtures-barrel-exports/vendure-config.ts +19 -0
  469. package/vite/tests/fixtures-npm-plugin/fake_node_modules/test-plugin/index.js +20 -0
  470. package/vite/tests/fixtures-npm-plugin/fake_node_modules/test-plugin/package.json +8 -0
  471. package/vite/tests/fixtures-npm-plugin/package.json +6 -0
  472. package/vite/tests/fixtures-npm-plugin/vendure-config.ts +18 -0
  473. package/vite/tests/fixtures-path-alias/js-aliased/index.ts +1 -0
  474. package/vite/tests/fixtures-path-alias/js-aliased/src/js-aliased.plugin.ts +8 -0
  475. package/vite/tests/fixtures-path-alias/package.json +6 -0
  476. package/vite/tests/fixtures-path-alias/star-aliased/index.ts +1 -0
  477. package/vite/tests/fixtures-path-alias/star-aliased/src/star-aliased.plugin.ts +8 -0
  478. package/vite/tests/fixtures-path-alias/ts-aliased/index.ts +1 -0
  479. package/vite/tests/fixtures-path-alias/ts-aliased/src/ts-aliased.plugin.ts +8 -0
  480. package/vite/tests/fixtures-path-alias/vendure-config.ts +20 -0
  481. package/vite/tests/npm-plugin.spec.ts +46 -0
  482. package/vite/tests/path-alias.spec.ts +61 -0
  483. package/vite/tests/tsconfig.json +21 -0
  484. package/vite/types.ts +44 -0
  485. package/vite/utils/ast-utils.spec.ts +1 -80
  486. package/vite/utils/ast-utils.ts +0 -86
  487. package/vite/utils/compiler.ts +244 -0
  488. package/vite/utils/config-loader.ts +0 -445
  489. package/vite/utils/logger.ts +43 -0
  490. package/vite/utils/plugin-discovery.ts +494 -0
  491. package/vite/utils/tsconfig-utils.ts +79 -0
  492. package/vite/utils/ui-config.ts +30 -42
  493. package/vite/vite-plugin-config-loader.ts +25 -17
  494. package/vite/vite-plugin-config.ts +6 -7
  495. package/vite/vite-plugin-dashboard-metadata.ts +27 -16
  496. package/vite/vite-plugin-tailwind-source.ts +81 -0
  497. package/vite/vite-plugin-theme.ts +69 -69
  498. package/vite/vite-plugin-ui-config.ts +119 -17
  499. package/vite/vite-plugin-vendure-dashboard.ts +60 -16
  500. package/dist/plugin/utils/ast-utils.js +0 -96
  501. package/dist/plugin/utils/ast-utils.spec.js +0 -120
  502. package/dist/plugin/utils/config-loader.d.ts +0 -52
  503. package/dist/plugin/utils/config-loader.js +0 -343
  504. package/dist/plugin/utils/ui-config.d.ts +0 -3
  505. package/dist/plugin/utils/ui-config.js +0 -34
  506. package/dist/plugin/vite-plugin-theme.js +0 -130
  507. package/dist/plugin/vite-plugin-ui-config.d.ts +0 -15
  508. package/dist/plugin/vite-plugin-vendure-dashboard.d.ts +0 -44
  509. package/src/lib/components/shared/rich-text-editor.tsx +0 -0
  510. package/src/lib/framework/alert/types.ts +0 -13
  511. package/src/lib/framework/dashboard-widget/types.ts +0 -22
  512. /package/dist/{plugin/utils/ast-utils.spec.d.ts → vite/types.js} +0 -0
  513. /package/dist/{plugin → vite}/utils/schema-generator.d.ts +0 -0
  514. /package/dist/{plugin → vite}/utils/schema-generator.js +0 -0
  515. /package/dist/{plugin → vite}/vite-plugin-admin-api-schema.d.ts +0 -0
  516. /package/dist/{plugin → vite}/vite-plugin-admin-api-schema.js +0 -0
  517. /package/dist/{plugin → vite}/vite-plugin-config.d.ts +0 -0
  518. /package/dist/{plugin → vite}/vite-plugin-gql-tada.d.ts +0 -0
  519. /package/dist/{plugin → vite}/vite-plugin-gql-tada.js +0 -0
  520. /package/dist/{plugin → vite}/vite-plugin-theme.d.ts +0 -0
  521. /package/dist/{plugin → vite}/vite-plugin-transform-index.d.ts +0 -0
  522. /package/dist/{plugin → vite}/vite-plugin-transform-index.js +0 -0
  523. /package/src/lib/components/data-table/{data-table-types.ts → types.ts} +0 -0
@@ -1,9 +1,9 @@
1
- import { Button } from '@/components/ui/button.js';
2
- import { DashboardWidgetInstance } from '@/framework/dashboard-widget/types.js';
1
+ import { Button } from '@/vdb/components/ui/button.js';
3
2
  import {
4
3
  getDashboardWidget,
5
4
  getDashboardWidgetRegistry,
6
- } from '@/framework/dashboard-widget/widget-extensions.js';
5
+ } from '@/vdb/framework/dashboard-widget/widget-extensions.js';
6
+ import { DashboardWidgetInstance } from '@/vdb/framework/extension-api/types/widgets.js';
7
7
  import {
8
8
  FullWidthPageBlock,
9
9
  Page,
@@ -11,7 +11,7 @@ import {
11
11
  PageActionBarRight,
12
12
  PageLayout,
13
13
  PageTitle,
14
- } from '@/framework/layout-engine/page-layout.js';
14
+ } from '@/vdb/framework/layout-engine/page-layout.js';
15
15
  import { createFileRoute } from '@tanstack/react-router';
16
16
  import { useEffect, useMemo, useRef, useState } from 'react';
17
17
  import { Responsive as ResponsiveGridLayout } from 'react-grid-layout';
@@ -168,8 +168,8 @@ function DashboardPage() {
168
168
  }, [layoutWidth, editMode, widgets]);
169
169
 
170
170
  return (
171
- <Page pageId="dashboard">
172
- <PageTitle>Dashboard</PageTitle>
171
+ <Page pageId="insights">
172
+ <PageTitle>Insights</PageTitle>
173
173
  <PageActionBar>
174
174
  <PageActionBarRight>
175
175
  <Button variant="outline" onClick={() => setEditMode(prev => !prev)}>
@@ -1,6 +1,6 @@
1
- import { AppLayout } from '@/components/layout/app-layout.js';
2
- import { AUTHENTICATED_ROUTE_PREFIX } from '@/constants.js';
3
- import { useAuth } from '@/hooks/use-auth.js';
1
+ import { AppLayout } from '@/vdb/components/layout/app-layout.js';
2
+ import { AUTHENTICATED_ROUTE_PREFIX } from '@/vdb/constants.js';
3
+ import { useAuth } from '@/vdb/hooks/use-auth.js';
4
4
  import { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';
5
5
 
6
6
  export const Route = createFileRoute(AUTHENTICATED_ROUTE_PREFIX)({
@@ -15,7 +15,7 @@ export const Route = createFileRoute(AUTHENTICATED_ROUTE_PREFIX)({
15
15
  }
16
16
  },
17
17
  loader: () => ({
18
- breadcrumb: 'Dashboard',
18
+ breadcrumb: 'Insights',
19
19
  }),
20
20
  component: AuthLayout,
21
21
  });
@@ -1,5 +1,5 @@
1
- import { LoginForm } from '@/components/login/login-form.js';
2
- import { useAuth } from '@/hooks/use-auth.js';
1
+ import { LoginForm } from '@/vdb/components/login/login-form.js';
2
+ import { useAuth } from '@/vdb/hooks/use-auth.js';
3
3
  import { createFileRoute, Navigate, redirect, useRouterState } from '@tanstack/react-router';
4
4
  import { z } from 'zod';
5
5
 
@@ -1,9 +1,11 @@
1
- @import url('https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Geist:wght@100..900&display=swap');
1
+ @import url('https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Inter:wght@100..900&display=swap');
2
2
  @import 'tailwindcss';
3
3
  @import 'tw-animate-css';
4
4
 
5
5
  @custom-variant dark (&:is(.dark *));
6
6
 
7
+ /* @source rules from extensions will be added here by the dashboardTailwindSourcePlugin */
8
+
7
9
  /*
8
10
  * Important: This is not an actual import. We are pre-processing this CSS file
9
11
  * to inject the theme variables into the CSS. This import will be replaced
@@ -64,6 +66,7 @@
64
66
  * {
65
67
  @apply border-border outline-ring/50;
66
68
  }
69
+
67
70
  body {
68
71
  @apply bg-background text-foreground;
69
72
  }
@@ -87,7 +90,7 @@
87
90
  }
88
91
 
89
92
  .animate-rotate {
90
- animation: rotate 0.5s linear;
93
+ animation: rotate 0.5s linear infinite;
91
94
  }
92
95
  }
93
96
 
@@ -2,7 +2,7 @@ import { CheckIcon, XIcon } from 'lucide-react';
2
2
  import React from 'react';
3
3
  import { Badge } from '../ui/badge.js';
4
4
 
5
- export function BooleanDisplayCheckbox({ value }: { value: boolean }) {
5
+ export function BooleanDisplayCheckbox({ value }: Readonly<{ value: boolean }>) {
6
6
  return value ? <CheckIcon className="opacity-70" /> : <XIcon className="opacity-70" />;
7
7
  }
8
8
 
@@ -1,13 +1,19 @@
1
- import { useLocalFormat } from '@/hooks/use-local-format.js';
1
+ import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
2
2
 
3
- export function DateTime({ value }: { value: string | Date }) {
3
+ export function DateTime({ value }: Readonly<{ value: string | Date }>) {
4
4
  const { formatDate } = useLocalFormat();
5
5
  let renderedDate: string;
6
+ let renderedTime: string;
6
7
  try {
7
8
  renderedDate = formatDate(value);
9
+ renderedTime = formatDate(value, { timeStyle: 'long' });
8
10
  } catch (e) {
9
11
  renderedDate = value.toString();
12
+ renderedTime = '';
10
13
  console.error(e);
11
14
  }
12
- return renderedDate;
15
+ return <div className="flex flex-col">
16
+ <div className="text-sm">{renderedDate}</div>
17
+ <div className="text-xs text-muted-foreground">{renderedTime}</div>
18
+ </div>;
13
19
  }
@@ -1,5 +1,5 @@
1
1
  import { JsonEditor } from 'json-edit-react';
2
2
 
3
- export function Json({ value }: { value: any }) {
3
+ export function Json({ value }: Readonly<{ value: any }>) {
4
4
  return <JsonEditor data={value} />;
5
5
  }
@@ -1,7 +1,7 @@
1
- import { useLocalFormat } from "@/hooks/use-local-format.js";
1
+ import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
2
2
 
3
3
  // Original component
4
- function MoneyInternal({ value, currency }: { value: number, currency: string }) {
4
+ function MoneyInternal({ value, currency }: { value: number; currency: string }) {
5
5
  const { formatCurrency } = useLocalFormat();
6
6
  return formatCurrency(value, currency);
7
7
  }
@@ -12,4 +12,3 @@ export function Money(props: { value: any; [key: string]: any }) {
12
12
  const currency = rest.currency || 'USD'; // Default currency if none provided
13
13
  return MoneyInternal({ value, currency });
14
14
  }
15
-
@@ -1,13 +1,12 @@
1
- import { cn } from '@/lib/utils.js';
1
+ import { ReactNode, useEffect, useRef, useState } from 'react';
2
2
  import { Input } from '../ui/input.js';
3
- import { ReactNode, useRef, useEffect, useState } from 'react';
4
3
 
5
4
  interface AffixedInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'prefix'> {
6
5
  prefix?: ReactNode;
7
6
  suffix?: ReactNode;
8
7
  }
9
8
 
10
- export function AffixedInput({ prefix, suffix, className = '', ...props }: AffixedInputProps) {
9
+ export function AffixedInput({ prefix, suffix, className = '', ...props }: Readonly<AffixedInputProps>) {
11
10
  const prefixRef = useRef<HTMLSpanElement>(null);
12
11
  const suffixRef = useRef<HTMLSpanElement>(null);
13
12
  const [prefixWidth, setPrefixWidth] = useState(0);
@@ -34,11 +33,7 @@ export function AffixedInput({ prefix, suffix, className = '', ...props }: Affix
34
33
  {prefix}
35
34
  </span>
36
35
  )}
37
- <Input
38
- {...props}
39
- className={className}
40
- style={style}
41
- />
36
+ <Input {...props} className={className} style={style} />
42
37
  {suffix && (
43
38
  <span ref={suffixRef} className="absolute right-3 text-muted-foreground whitespace-nowrap">
44
39
  {suffix}
@@ -0,0 +1,52 @@
1
+ import { DataInputComponent } from '@/vdb/framework/component-registry/component-registry.js';
2
+ import { Trans } from '@/vdb/lib/trans.js';
3
+
4
+ export const CombinationModeInput: DataInputComponent = ({ value, onChange, position, ...props }) => {
5
+ const booleanValue = value === 'true' || value === true;
6
+
7
+ // Only show for items after the first one
8
+ const selectable = position !== undefined && position > 0;
9
+
10
+ const setCombinationModeAnd = () => {
11
+ onChange(true);
12
+ };
13
+
14
+ const setCombinationModeOr = () => {
15
+ onChange(false);
16
+ };
17
+
18
+ if (!selectable) {
19
+ return null;
20
+ }
21
+
22
+ return (
23
+ <div className="flex items-center justify-center -mt-4 -mb-4">
24
+ <div className="bg-muted border px-3 py-1.5 rounded-full flex gap-1.5 text-xs shadow-sm">
25
+ <button
26
+ type="button"
27
+ className={`px-2 py-0.5 rounded-full transition-colors ${
28
+ booleanValue
29
+ ? 'bg-primary text-background'
30
+ : 'text-muted-foreground hover:bg-muted-foreground/10'
31
+ }`}
32
+ onClick={setCombinationModeAnd}
33
+ {...props}
34
+ >
35
+ <Trans>AND</Trans>
36
+ </button>
37
+ <button
38
+ type="button"
39
+ className={`px-2 py-0.5 rounded-full transition-colors ${
40
+ !booleanValue
41
+ ? 'bg-primary text-background'
42
+ : 'text-muted-foreground hover:bg-muted-foreground/10'
43
+ }`}
44
+ onClick={setCombinationModeOr}
45
+ {...props}
46
+ >
47
+ <Trans>OR</Trans>
48
+ </button>
49
+ </div>
50
+ </div>
51
+ );
52
+ };
@@ -0,0 +1,433 @@
1
+ import { ConfigurableOperationDefFragment } from '@/vdb/graphql/fragments.js';
2
+ import { ConfigArgType } from '@vendure/core';
3
+ import { Plus, X } from 'lucide-react';
4
+ import { useState } from 'react';
5
+ import { Button } from '../ui/button.js';
6
+ import { Input } from '../ui/input.js';
7
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select.js';
8
+ import { Switch } from '../ui/switch.js';
9
+ import { Textarea } from '../ui/textarea.js';
10
+ import { DateTimeInput } from './datetime-input.js';
11
+
12
+ export interface EnhancedListInputProps {
13
+ definition: ConfigurableOperationDefFragment['args'][number];
14
+ value: string;
15
+ onChange: (value: string) => void;
16
+ readOnly?: boolean;
17
+ }
18
+
19
+ /**
20
+ * A dynamic array input component for configurable operation arguments that handle lists of values.
21
+ *
22
+ * This component allows users to add, edit, and remove multiple items from an array-type argument.
23
+ * Each item in the array is rendered using the appropriate input control based on the argument's
24
+ * type and UI configuration (e.g., text input, select dropdown, boolean switch, date picker).
25
+ *
26
+ * The component supports:
27
+ * - Adding new items with appropriate input controls
28
+ * - Editing existing items inline
29
+ * - Removing items from the array
30
+ * - Various data types: string, number, boolean, datetime, currency
31
+ * - Multiple UI components: select, textarea, currency input, etc.
32
+ * - Keyboard shortcuts (Enter to add items)
33
+ * - Read-only mode for display purposes
34
+ *
35
+ * Used primarily in configurable operations (promotions, shipping methods, payment methods)
36
+ * where an argument accepts multiple values, such as a list of product IDs, category codes,
37
+ * or discount amounts.
38
+ *
39
+ * @example
40
+ * // For a promotion condition that accepts multiple product category codes
41
+ * <EnhancedListInput
42
+ * definition={argDefinition}
43
+ * value='["electronics", "books", "clothing"]'
44
+ * onChange={handleChange}
45
+ * />
46
+ */
47
+ export function ConfigurableOperationListInput({
48
+ definition,
49
+ value,
50
+ onChange,
51
+ readOnly,
52
+ }: Readonly<EnhancedListInputProps>) {
53
+ const [newItemValue, setNewItemValue] = useState('');
54
+
55
+ // Parse the current array value
56
+ const arrayValue = parseArrayValue(value);
57
+
58
+ const handleArrayChange = (newArray: string[]) => {
59
+ onChange(JSON.stringify(newArray));
60
+ };
61
+
62
+ const handleAddItem = () => {
63
+ if (newItemValue.trim()) {
64
+ const newArray = [...arrayValue, newItemValue.trim()];
65
+ handleArrayChange(newArray);
66
+ setNewItemValue('');
67
+ }
68
+ };
69
+
70
+ const handleRemoveItem = (index: number) => {
71
+ const newArray = arrayValue.filter((_, i) => i !== index);
72
+ handleArrayChange(newArray);
73
+ };
74
+
75
+ const handleUpdateItem = (index: number, newValue: string) => {
76
+ const newArray = arrayValue.map((item, i) => (i === index ? newValue : item));
77
+ handleArrayChange(newArray);
78
+ };
79
+
80
+ const handleKeyPress = (e: React.KeyboardEvent) => {
81
+ if (e.key === 'Enter' && !e.shiftKey) {
82
+ e.preventDefault();
83
+ handleAddItem();
84
+ }
85
+ };
86
+
87
+ // Render individual item input based on the underlying type
88
+ const renderItemInput = (itemValue: string, index: number) => {
89
+ const argType = definition.type as ConfigArgType;
90
+ const uiComponent = (definition.ui as any)?.component;
91
+
92
+ const commonProps = {
93
+ value: itemValue,
94
+ onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
95
+ handleUpdateItem(index, e.target.value),
96
+ disabled: readOnly,
97
+ };
98
+
99
+ switch (uiComponent) {
100
+ case 'boolean-form-input':
101
+ return (
102
+ <Switch
103
+ checked={itemValue === 'true'}
104
+ onCheckedChange={checked => handleUpdateItem(index, checked.toString())}
105
+ disabled={readOnly}
106
+ />
107
+ );
108
+
109
+ case 'select-form-input': {
110
+ const options = (definition.ui as any)?.options || [];
111
+ return (
112
+ <Select
113
+ value={itemValue}
114
+ onValueChange={val => handleUpdateItem(index, val)}
115
+ disabled={readOnly}
116
+ >
117
+ <SelectTrigger>
118
+ <SelectValue />
119
+ </SelectTrigger>
120
+ <SelectContent>
121
+ {options.map((option: any) => (
122
+ <SelectItem key={option.value} value={option.value}>
123
+ {typeof option.label === 'string'
124
+ ? option.label
125
+ : option.label?.[0]?.value || option.value}
126
+ </SelectItem>
127
+ ))}
128
+ </SelectContent>
129
+ </Select>
130
+ );
131
+ }
132
+ case 'textarea-form-input':
133
+ return (
134
+ <Textarea
135
+ {...commonProps}
136
+ placeholder="Enter text..."
137
+ rows={2}
138
+ className="bg-background"
139
+ />
140
+ );
141
+
142
+ case 'date-form-input':
143
+ return (
144
+ <DateTimeInput
145
+ value={itemValue ? new Date(itemValue) : new Date()}
146
+ onChange={val => handleUpdateItem(index, val.toISOString())}
147
+ disabled={readOnly}
148
+ />
149
+ );
150
+
151
+ case 'number-form-input': {
152
+ const ui = definition.ui as any;
153
+ const isFloat = argType === 'float';
154
+ return (
155
+ <Input
156
+ type="number"
157
+ value={itemValue}
158
+ onChange={e => handleUpdateItem(index, e.target.value)}
159
+ disabled={readOnly}
160
+ min={ui?.min}
161
+ max={ui?.max}
162
+ step={ui?.step || (isFloat ? 0.01 : 1)}
163
+ />
164
+ );
165
+ }
166
+ case 'currency-form-input':
167
+ return (
168
+ <div className="flex items-center">
169
+ <span className="mr-2 text-sm text-muted-foreground">$</span>
170
+ <Input
171
+ type="number"
172
+ value={itemValue}
173
+ onChange={e => handleUpdateItem(index, e.target.value)}
174
+ disabled={readOnly}
175
+ min={0}
176
+ step={1}
177
+ className="flex-1"
178
+ />
179
+ </div>
180
+ );
181
+ }
182
+
183
+ // Fall back to type-based rendering
184
+ switch (argType) {
185
+ case 'boolean':
186
+ return (
187
+ <Switch
188
+ checked={itemValue === 'true'}
189
+ onCheckedChange={checked => handleUpdateItem(index, checked.toString())}
190
+ disabled={readOnly}
191
+ />
192
+ );
193
+
194
+ case 'int':
195
+ case 'float': {
196
+ const isFloat = argType === 'float';
197
+ return (
198
+ <Input
199
+ type="number"
200
+ value={itemValue}
201
+ onChange={e => handleUpdateItem(index, e.target.value)}
202
+ disabled={readOnly}
203
+ step={isFloat ? 0.01 : 1}
204
+ />
205
+ );
206
+ }
207
+ case 'datetime':
208
+ return (
209
+ <DateTimeInput
210
+ value={itemValue ? new Date(itemValue) : new Date()}
211
+ onChange={val => handleUpdateItem(index, val.toISOString())}
212
+ disabled={readOnly}
213
+ />
214
+ );
215
+
216
+ default:
217
+ return <Input type="text" {...commonProps} placeholder="Enter value..." />;
218
+ }
219
+ };
220
+
221
+ // Render new item input (similar logic but for newItemValue)
222
+ const renderNewItemInput = () => {
223
+ const argType = definition.type as ConfigArgType;
224
+ const uiComponent = (definition.ui as any)?.component;
225
+
226
+ const commonProps = {
227
+ value: newItemValue,
228
+ onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
229
+ setNewItemValue(e.target.value),
230
+ disabled: readOnly,
231
+ onKeyPress: handleKeyPress,
232
+ };
233
+
234
+ switch (uiComponent) {
235
+ case 'boolean-form-input': {
236
+ return (
237
+ <Switch
238
+ checked={newItemValue === 'true'}
239
+ onCheckedChange={checked => setNewItemValue(checked.toString())}
240
+ disabled={readOnly}
241
+ />
242
+ );
243
+ }
244
+ case 'select-form-input': {
245
+ const options = (definition.ui as any)?.options || [];
246
+ return (
247
+ <Select value={newItemValue} onValueChange={setNewItemValue} disabled={readOnly}>
248
+ <SelectTrigger>
249
+ <SelectValue placeholder="Select value..." />
250
+ </SelectTrigger>
251
+ <SelectContent>
252
+ {options.map((option: any) => (
253
+ <SelectItem key={option.value} value={option.value}>
254
+ {typeof option.label === 'string'
255
+ ? option.label
256
+ : option.label?.[0]?.value || option.value}
257
+ </SelectItem>
258
+ ))}
259
+ </SelectContent>
260
+ </Select>
261
+ );
262
+ }
263
+ case 'textarea-form-input': {
264
+ return (
265
+ <Textarea
266
+ {...commonProps}
267
+ placeholder="Enter text..."
268
+ rows={2}
269
+ className="bg-background"
270
+ />
271
+ );
272
+ }
273
+ case 'date-form-input': {
274
+ return <DateTimeInput value={newItemValue} onChange={setNewItemValue} disabled={readOnly} />;
275
+ }
276
+ case 'number-form-input': {
277
+ const ui = definition.ui as any;
278
+ const isFloat = argType === 'float';
279
+ return (
280
+ <Input
281
+ type="number"
282
+ value={newItemValue}
283
+ onChange={e => setNewItemValue(e.target.value)}
284
+ disabled={readOnly}
285
+ min={ui?.min}
286
+ max={ui?.max}
287
+ step={ui?.step || (isFloat ? 0.01 : 1)}
288
+ placeholder="Enter number..."
289
+ onKeyPress={handleKeyPress}
290
+ className="bg-background"
291
+ />
292
+ );
293
+ }
294
+ case 'currency-form-input': {
295
+ return (
296
+ <div className="flex items-center">
297
+ <span className="mr-2 text-sm text-muted-foreground">$</span>
298
+ <Input
299
+ type="number"
300
+ value={newItemValue}
301
+ onChange={e => setNewItemValue(e.target.value)}
302
+ disabled={readOnly}
303
+ min={0}
304
+ step={1}
305
+ placeholder="Enter amount..."
306
+ onKeyPress={handleKeyPress}
307
+ className="flex-1 bg-background"
308
+ />
309
+ </div>
310
+ );
311
+ }
312
+ }
313
+
314
+ // Fall back to type-based rendering
315
+ switch (argType) {
316
+ case 'boolean':
317
+ return (
318
+ <Switch
319
+ checked={newItemValue === 'true'}
320
+ onCheckedChange={checked => setNewItemValue(checked.toString())}
321
+ disabled={readOnly}
322
+ />
323
+ );
324
+ case 'int':
325
+ case 'float': {
326
+ const isFloat = argType === 'float';
327
+ return (
328
+ <Input
329
+ type="number"
330
+ value={newItemValue}
331
+ onChange={e => setNewItemValue(e.target.value)}
332
+ disabled={readOnly}
333
+ step={isFloat ? 0.01 : 1}
334
+ placeholder="Enter number..."
335
+ onKeyPress={handleKeyPress}
336
+ className="bg-background"
337
+ />
338
+ );
339
+ }
340
+ case 'datetime': {
341
+ return (
342
+ <DateTimeInput
343
+ value={newItemValue ? new Date(newItemValue) : new Date()}
344
+ onChange={val => setNewItemValue(val.toISOString())}
345
+ disabled={readOnly}
346
+ />
347
+ );
348
+ }
349
+ default: {
350
+ return (
351
+ <Input
352
+ type="text"
353
+ {...commonProps}
354
+ placeholder="Enter value..."
355
+ className="bg-background"
356
+ />
357
+ );
358
+ }
359
+ }
360
+ };
361
+
362
+ if (readOnly) {
363
+ return (
364
+ <div className="space-y-2">
365
+ {arrayValue.map((item, index) => (
366
+ <div key={index + item} className="flex items-center gap-2 p-2 bg-muted rounded-md">
367
+ <span className="flex-1">{item}</span>
368
+ </div>
369
+ ))}
370
+ {arrayValue.length === 0 && <div className="text-sm text-muted-foreground">No items</div>}
371
+ </div>
372
+ );
373
+ }
374
+
375
+ return (
376
+ <div className="space-y-2">
377
+ {/* Existing items */}
378
+ {arrayValue.map((item, index) => (
379
+ <div key={index + item} className="flex items-center gap-2">
380
+ <div className="flex-1">{renderItemInput(item, index)}</div>
381
+ <Button
382
+ variant="outline"
383
+ size="sm"
384
+ onClick={() => handleRemoveItem(index)}
385
+ disabled={readOnly}
386
+ type="button"
387
+ >
388
+ <X className="h-4 w-4" />
389
+ </Button>
390
+ </div>
391
+ ))}
392
+
393
+ {/* Add new item */}
394
+ <div className="flex items-center gap-2 p-2 border border-dashed rounded-md">
395
+ <div className="flex-1">{renderNewItemInput()}</div>
396
+ <Button
397
+ variant="outline"
398
+ size="sm"
399
+ onClick={handleAddItem}
400
+ disabled={readOnly || !newItemValue.trim()}
401
+ type="button"
402
+ >
403
+ <Plus className="h-4 w-4" />
404
+ </Button>
405
+ </div>
406
+
407
+ {arrayValue.length === 0 && (
408
+ <div className="text-sm text-muted-foreground">
409
+ No items added yet. Use the input above to add items.
410
+ </div>
411
+ )}
412
+ </div>
413
+ );
414
+ }
415
+
416
+ function parseArrayValue(value: string): string[] {
417
+ if (!value) return [];
418
+
419
+ try {
420
+ const parsed = JSON.parse(value);
421
+ return Array.isArray(parsed) ? parsed.map(String) : [String(parsed)];
422
+ } catch {
423
+ // If not JSON, try comma-separated values
424
+ return value.includes(',')
425
+ ? value
426
+ .split(',')
427
+ .map(s => s.trim())
428
+ .filter(Boolean)
429
+ : value
430
+ ? [value]
431
+ : [];
432
+ }
433
+ }