@vendure/dashboard 3.3.8-master-202507220240 → 3.3.8-master-202507240240

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 (28) hide show
  1. package/dist/plugin/utils/plugin-discovery.d.ts +1 -1
  2. package/dist/plugin/utils/plugin-discovery.js +61 -21
  3. package/dist/plugin/vite-plugin-tailwind-source.js +13 -1
  4. package/dist/plugin/vite-plugin-vendure-dashboard.d.ts +1 -1
  5. package/dist/plugin/vite-plugin-vendure-dashboard.js +2 -2
  6. package/package.json +39 -26
  7. package/src/app/routes/_authenticated/_facets/components/add-facet-value-dialog.tsx +146 -0
  8. package/src/app/routes/_authenticated/_facets/components/facet-values-table.tsx +84 -62
  9. package/src/app/routes/_authenticated/_facets/facets.graphql.ts +9 -0
  10. package/src/lib/components/data-table/use-generated-columns.tsx +20 -5
  11. package/src/lib/components/ui/aspect-ratio.tsx +9 -0
  12. package/src/lib/components/ui/carousel.tsx +241 -0
  13. package/src/lib/components/ui/chart.tsx +351 -0
  14. package/src/lib/components/ui/context-menu.tsx +252 -0
  15. package/src/lib/components/ui/drawer.tsx +133 -0
  16. package/src/lib/components/ui/input-otp.tsx +77 -0
  17. package/src/lib/components/ui/menubar.tsx +274 -0
  18. package/src/lib/components/ui/navigation-menu.tsx +168 -0
  19. package/src/lib/components/ui/progress.tsx +29 -0
  20. package/src/lib/components/ui/radio-group.tsx +45 -0
  21. package/src/lib/components/ui/resizable.tsx +54 -0
  22. package/src/lib/components/ui/slider.tsx +63 -0
  23. package/src/lib/components/ui/toggle-group.tsx +73 -0
  24. package/src/lib/components/ui/toggle.tsx +45 -0
  25. package/src/lib/index.ts +18 -0
  26. package/vite/utils/plugin-discovery.ts +67 -18
  27. package/vite/vite-plugin-tailwind-source.ts +20 -4
  28. package/vite/vite-plugin-vendure-dashboard.ts +3 -3
@@ -0,0 +1,73 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
5
+ import { type VariantProps } from "class-variance-authority"
6
+
7
+ import { cn } from "@/vdb/lib/utils"
8
+ import { toggleVariants } from "@/vdb/components/ui/toggle"
9
+
10
+ const ToggleGroupContext = React.createContext<
11
+ VariantProps<typeof toggleVariants>
12
+ >({
13
+ size: "default",
14
+ variant: "default",
15
+ })
16
+
17
+ function ToggleGroup({
18
+ className,
19
+ variant,
20
+ size,
21
+ children,
22
+ ...props
23
+ }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
24
+ VariantProps<typeof toggleVariants>) {
25
+ return (
26
+ <ToggleGroupPrimitive.Root
27
+ data-slot="toggle-group"
28
+ data-variant={variant}
29
+ data-size={size}
30
+ className={cn(
31
+ "group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
32
+ className
33
+ )}
34
+ {...props}
35
+ >
36
+ <ToggleGroupContext.Provider value={{ variant, size }}>
37
+ {children}
38
+ </ToggleGroupContext.Provider>
39
+ </ToggleGroupPrimitive.Root>
40
+ )
41
+ }
42
+
43
+ function ToggleGroupItem({
44
+ className,
45
+ children,
46
+ variant,
47
+ size,
48
+ ...props
49
+ }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
50
+ VariantProps<typeof toggleVariants>) {
51
+ const context = React.useContext(ToggleGroupContext)
52
+
53
+ return (
54
+ <ToggleGroupPrimitive.Item
55
+ data-slot="toggle-group-item"
56
+ data-variant={context.variant || variant}
57
+ data-size={context.size || size}
58
+ className={cn(
59
+ toggleVariants({
60
+ variant: context.variant || variant,
61
+ size: context.size || size,
62
+ }),
63
+ "min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
64
+ className
65
+ )}
66
+ {...props}
67
+ >
68
+ {children}
69
+ </ToggleGroupPrimitive.Item>
70
+ )
71
+ }
72
+
73
+ export { ToggleGroup, ToggleGroupItem }
@@ -0,0 +1,45 @@
1
+ import * as React from "react"
2
+ import * as TogglePrimitive from "@radix-ui/react-toggle"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "@/vdb/lib/utils"
6
+
7
+ const toggleVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-transparent",
13
+ outline:
14
+ "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
15
+ },
16
+ size: {
17
+ default: "h-9 px-2 min-w-9",
18
+ sm: "h-8 px-1.5 min-w-8",
19
+ lg: "h-10 px-2.5 min-w-10",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ variant: "default",
24
+ size: "default",
25
+ },
26
+ }
27
+ )
28
+
29
+ function Toggle({
30
+ className,
31
+ variant,
32
+ size,
33
+ ...props
34
+ }: React.ComponentProps<typeof TogglePrimitive.Root> &
35
+ VariantProps<typeof toggleVariants>) {
36
+ return (
37
+ <TogglePrimitive.Root
38
+ data-slot="toggle"
39
+ className={cn(toggleVariants({ variant, size, className }))}
40
+ {...props}
41
+ />
42
+ )
43
+ }
44
+
45
+ export { Toggle, toggleVariants }
package/src/lib/index.ts CHANGED
@@ -20,6 +20,7 @@ export * from './components/data-table/data-table-faceted-filter.js';
20
20
  export * from './components/data-table/data-table-filter-badge.js';
21
21
  export * from './components/data-table/data-table-filter-dialog.js';
22
22
  export * from './components/data-table/data-table-pagination.js';
23
+ export * from './components/data-table/data-table-utils.js';
23
24
  export * from './components/data-table/data-table-view-options.js';
24
25
  export * from './components/data-table/data-table.js';
25
26
  export * from './components/data-table/filters/data-table-boolean-filter.js';
@@ -30,6 +31,8 @@ export * from './components/data-table/filters/data-table-string-filter.js';
30
31
  export * from './components/data-table/human-readable-operator.js';
31
32
  export * from './components/data-table/refresh-button.js';
32
33
  export * from './components/data-table/types.js';
34
+ export * from './components/data-table/use-generated-columns.js';
35
+ export * from './components/labeled-data.js';
33
36
  export * from './components/layout/app-layout.js';
34
37
  export * from './components/layout/app-sidebar.js';
35
38
  export * from './components/layout/channel-switcher.js';
@@ -101,33 +104,47 @@ export * from './components/shared/zone-selector.js';
101
104
  export * from './components/ui/accordion.js';
102
105
  export * from './components/ui/alert-dialog.js';
103
106
  export * from './components/ui/alert.js';
107
+ export * from './components/ui/aspect-ratio.js';
104
108
  export * from './components/ui/badge.js';
105
109
  export * from './components/ui/breadcrumb.js';
106
110
  export * from './components/ui/button.js';
107
111
  export * from './components/ui/calendar.js';
108
112
  export * from './components/ui/card.js';
113
+ export * from './components/ui/carousel.js';
114
+ export * from './components/ui/chart.js';
109
115
  export * from './components/ui/checkbox.js';
110
116
  export * from './components/ui/collapsible.js';
111
117
  export * from './components/ui/command.js';
118
+ export * from './components/ui/context-menu.js';
112
119
  export * from './components/ui/dialog.js';
120
+ export * from './components/ui/drawer.js';
113
121
  export * from './components/ui/dropdown-menu.js';
114
122
  export * from './components/ui/form.js';
115
123
  export * from './components/ui/hover-card.js';
124
+ export * from './components/ui/input-otp.js';
116
125
  export * from './components/ui/input.js';
117
126
  export * from './components/ui/label.js';
127
+ export * from './components/ui/menubar.js';
128
+ export * from './components/ui/navigation-menu.js';
118
129
  export * from './components/ui/pagination.js';
119
130
  export * from './components/ui/popover.js';
131
+ export * from './components/ui/progress.js';
132
+ export * from './components/ui/radio-group.js';
133
+ export * from './components/ui/resizable.js';
120
134
  export * from './components/ui/scroll-area.js';
121
135
  export * from './components/ui/select.js';
122
136
  export * from './components/ui/separator.js';
123
137
  export * from './components/ui/sheet.js';
124
138
  export * from './components/ui/sidebar.js';
125
139
  export * from './components/ui/skeleton.js';
140
+ export * from './components/ui/slider.js';
126
141
  export * from './components/ui/sonner.js';
127
142
  export * from './components/ui/switch.js';
128
143
  export * from './components/ui/table.js';
129
144
  export * from './components/ui/tabs.js';
130
145
  export * from './components/ui/textarea.js';
146
+ export * from './components/ui/toggle-group.js';
147
+ export * from './components/ui/toggle.js';
131
148
  export * from './components/ui/tooltip.js';
132
149
  export * from './framework/alert/alert-extensions.js';
133
150
  export * from './framework/alert/alert-item.js';
@@ -169,6 +186,7 @@ export * from './framework/extension-api/use-dashboard-extensions.js';
169
186
  export * from './framework/form-engine/custom-form-component-extensions.js';
170
187
  export * from './framework/form-engine/custom-form-component.js';
171
188
  export * from './framework/form-engine/form-schema-tools.js';
189
+ export * from './framework/form-engine/overridden-form-component.js';
172
190
  export * from './framework/form-engine/use-generated-form.js';
173
191
  export * from './framework/form-engine/utils.js';
174
192
  export * from './framework/layout-engine/layout-extensions.js';
@@ -30,6 +30,7 @@ export async function discoverPlugins({
30
30
  // Analyze source files to find local plugins and package imports
31
31
  const { localPluginLocations, packageImports } = await analyzeSourceFiles(
32
32
  vendureConfigPath,
33
+ pluginPackageScanner?.nodeModulesRoot ?? guessNodeModulesRoot(vendureConfigPath, logger),
33
34
  logger,
34
35
  transformTsConfigPathMappings,
35
36
  );
@@ -137,6 +138,29 @@ function getDecoratorObjectProps(decorator: any): any[] {
137
138
  return [];
138
139
  }
139
140
 
141
+ async function isSymlinkedLocalPackage(
142
+ packageName: string,
143
+ nodeModulesRoot: string,
144
+ ): Promise<string | undefined> {
145
+ try {
146
+ const packagePath = path.join(nodeModulesRoot, packageName);
147
+ const stats = await fs.lstat(packagePath);
148
+ if (stats.isSymbolicLink()) {
149
+ // Get the real path that the symlink points to
150
+ const realPath = await fs.realpath(packagePath);
151
+ // If the real path is within the project directory (i.e. not in some other node_modules),
152
+ // then it's a local package
153
+ if (!realPath.includes('node_modules')) {
154
+ return realPath;
155
+ }
156
+ }
157
+ } catch (e) {
158
+ // Package doesn't exist or other error - not a local package
159
+ return undefined;
160
+ }
161
+ return undefined;
162
+ }
163
+
140
164
  /**
141
165
  * Analyzes TypeScript source files starting from the config file to discover:
142
166
  * 1. Local Vendure plugins
@@ -144,6 +168,7 @@ function getDecoratorObjectProps(decorator: any): any[] {
144
168
  */
145
169
  export async function analyzeSourceFiles(
146
170
  vendureConfigPath: string,
171
+ nodeModulesRoot: string,
147
172
  logger: Logger,
148
173
  transformTsConfigPathMappings: TransformTsConfigPathMappingsFn,
149
174
  ): Promise<{
@@ -186,7 +211,7 @@ export async function analyzeSourceFiles(
186
211
  // Track imports to follow
187
212
  const importsToFollow: string[] = [];
188
213
 
189
- function visit(node: ts.Node) {
214
+ async function visit(node: ts.Node) {
190
215
  // Look for VendurePlugin decorator
191
216
  const vendurePluginClassName = getVendurePluginClassName(node);
192
217
  if (vendurePluginClassName) {
@@ -204,7 +229,20 @@ export async function analyzeSourceFiles(
204
229
  // Track non-local imports (packages)
205
230
  const npmPackageName = getNpmPackageNameFromImport(importPath);
206
231
  if (npmPackageName) {
207
- packageImportsSet.add(npmPackageName);
232
+ // Check if this is actually a symlinked local package
233
+ const localPackagePath = await isSymlinkedLocalPackage(
234
+ npmPackageName,
235
+ nodeModulesRoot,
236
+ );
237
+ if (localPackagePath) {
238
+ // If it is local, follow it like a local import
239
+ importsToFollow.push(localPackagePath);
240
+ logger.debug(
241
+ `Found symlinked local package "${npmPackageName}" at ${localPackagePath}`,
242
+ );
243
+ } else {
244
+ packageImportsSet.add(npmPackageName);
245
+ }
208
246
  }
209
247
  // Handle path aliases and local imports
210
248
  const pathAliasImports = getPotentialPathAliasImportPaths(importPath, tsConfigInfo);
@@ -219,10 +257,15 @@ export async function analyzeSourceFiles(
219
257
  }
220
258
  }
221
259
 
222
- ts.forEachChild(node, visit);
260
+ // Visit children
261
+ const promises: Array<Promise<void>> = [];
262
+ ts.forEachChild(node, child => {
263
+ promises.push(visit(child));
264
+ });
265
+ await Promise.all(promises);
223
266
  }
224
267
 
225
- visit(sourceFile);
268
+ await visit(sourceFile);
226
269
 
227
270
  // Follow imports
228
271
  for (const importPath of importsToFollow) {
@@ -352,19 +395,7 @@ export async function findVendurePluginFiles({
352
395
  let nodeModulesRoot = providedNodeModulesRoot;
353
396
  const readStart = Date.now();
354
397
  if (!nodeModulesRoot) {
355
- // If the node_modules root path has not been explicitly
356
- // specified, we will try to guess it by resolving the
357
- // `@vendure/core` package.
358
- try {
359
- const coreUrl = import.meta.resolve('@vendure/core');
360
- logger.debug(`Found core URL: ${coreUrl}`);
361
- const corePath = fileURLToPath(coreUrl);
362
- logger.debug(`Found core path: ${corePath}`);
363
- nodeModulesRoot = path.join(path.dirname(corePath), '..', '..');
364
- } catch (e) {
365
- logger.warn(`Failed to resolve @vendure/core: ${e instanceof Error ? e.message : String(e)}`);
366
- nodeModulesRoot = path.dirname(vendureConfigPath);
367
- }
398
+ nodeModulesRoot = guessNodeModulesRoot(vendureConfigPath, logger);
368
399
  }
369
400
 
370
401
  const patterns = [
@@ -372,7 +403,7 @@ export async function findVendurePluginFiles({
372
403
  path.join(outputPath, '**/*.js'),
373
404
  // Node modules patterns
374
405
  ...packageGlobs.map(pattern => path.join(nodeModulesRoot, pattern)),
375
- ];
406
+ ].map(p => p.replace(/\\/g, '/'));
376
407
 
377
408
  logger.debug(`Finding Vendure plugins using patterns: ${patterns.join('\n')}`);
378
409
 
@@ -443,3 +474,21 @@ export async function findVendurePluginFiles({
443
474
 
444
475
  return potentialPluginFiles;
445
476
  }
477
+
478
+ function guessNodeModulesRoot(vendureConfigPath: string, logger: Logger): string {
479
+ let nodeModulesRoot: string;
480
+ // If the node_modules root path has not been explicitly
481
+ // specified, we will try to guess it by resolving the
482
+ // `@vendure/core` package.
483
+ try {
484
+ const coreUrl = import.meta.resolve('@vendure/core');
485
+ logger.debug(`Found core URL: ${coreUrl}`);
486
+ const corePath = fileURLToPath(coreUrl);
487
+ logger.debug(`Found core path: ${corePath}`);
488
+ nodeModulesRoot = path.join(path.dirname(corePath), '..', '..');
489
+ } catch (e) {
490
+ logger.warn(`Failed to resolve @vendure/core: ${e instanceof Error ? e.message : String(e)}`);
491
+ nodeModulesRoot = path.dirname(vendureConfigPath);
492
+ }
493
+ return nodeModulesRoot;
494
+ }
@@ -27,10 +27,26 @@ export function dashboardTailwindSourcePlugin(): Plugin {
27
27
  const { pluginInfo } = loadVendureConfigResult;
28
28
  const dashboardExtensionDirs =
29
29
  pluginInfo
30
- ?.map(
31
- ({ dashboardEntryPath, pluginPath }) =>
32
- dashboardEntryPath && path.join(pluginPath, path.dirname(dashboardEntryPath)),
33
- )
30
+ ?.flatMap(({ dashboardEntryPath, sourcePluginPath, pluginPath }) => {
31
+ if (!dashboardEntryPath) {
32
+ return [];
33
+ }
34
+ const sourcePaths = [];
35
+ if (sourcePluginPath) {
36
+ sourcePaths.push(
37
+ path.join(
38
+ path.dirname(sourcePluginPath),
39
+ path.dirname(dashboardEntryPath),
40
+ ),
41
+ );
42
+ }
43
+ if (pluginPath) {
44
+ sourcePaths.push(
45
+ path.join(path.dirname(pluginPath), path.dirname(dashboardEntryPath)),
46
+ );
47
+ }
48
+ return sourcePaths;
49
+ })
34
50
  .filter(x => x != null) ?? [];
35
51
  const sources = dashboardExtensionDirs
36
52
  .map(extension => {
@@ -76,7 +76,7 @@ export type VitePluginVendureDashboardOptions = {
76
76
  * @description
77
77
  * The path to the directory where the generated GraphQL Tada files will be output.
78
78
  */
79
- gqlTadaOutputPath?: string;
79
+ gqlOutputPath?: string;
80
80
  tempCompilationDir?: string;
81
81
  disableTansStackRouterPlugin?: boolean;
82
82
  /**
@@ -134,8 +134,8 @@ export function vendureDashboardPlugin(options: VitePluginVendureDashboardOption
134
134
  adminApiSchemaPlugin(),
135
135
  dashboardMetadataPlugin(),
136
136
  uiConfigPlugin({ adminUiConfig: options.adminUiConfig }),
137
- ...(options.gqlTadaOutputPath
138
- ? [gqlTadaPlugin({ gqlTadaOutputPath: options.gqlTadaOutputPath, tempDir, packageRoot })]
137
+ ...(options.gqlOutputPath
138
+ ? [gqlTadaPlugin({ gqlTadaOutputPath: options.gqlOutputPath, tempDir, packageRoot })]
139
139
  : []),
140
140
  transformIndexHtmlPlugin(),
141
141
  ];