فهرست منبع

docs: More dashboard docs

Michael Bromley 3 ماه پیش
والد
کامیت
a3606bb708

BIN
docs/docs/guides/extending-the-dashboard/action-bar-items/action-bar-button.webp


BIN
docs/docs/guides/extending-the-dashboard/action-bar-items/action-bar-dropdown.webp


+ 35 - 7
docs/docs/guides/extending-the-dashboard/action-bar-items/index.md

@@ -2,10 +2,12 @@
 title: 'Action Bar Items'
 ---
 
-Like in the old Admin UI, we have the concept of the "action bar", which is the bar at the top of the page where you can add
+The Action Bar is the bar at the top of the page where you can add
 buttons and other actions.
 
-Currently, we only support adding buttons, but dropdown menu support is coming soon.
+:::info
+All available options are documented in the [DashboardActionBarItem reference](/reference/dashboard/extensions-api/action-bar#dashboardactionbaritem)
+:::
 
 ## Basic Action Bar Item
 
@@ -15,7 +17,7 @@ Here's a simple example of adding a button to the action bar:
 import { Button, defineDashboardExtension } from '@vendure/dashboard';
 import { useState } from 'react';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     actionBarItems: [
         {
             pageId: 'product-detail',
@@ -32,6 +34,8 @@ export default defineDashboardExtension({
 });
 ```
 
+![Action bar button](./action-bar-button.webp)
+
 ## Context Data
 
 The `context` prop provides access to:
@@ -40,6 +44,30 @@ The `context` prop provides access to:
 - **`form`**: The React Hook Form instance for the current page (if applicable)
 - **`route`**: Route information and parameters
 
+## Dropdown Menu
+
+You can also define dropdown menu items for the Action Bar. This is useful for secondary actions that are needed
+less often by administrators.
+
+Make sure to always wrap these in the `DropdownMenuItem` component for consistent styling.
+
+```tsx
+import { DropdownMenuItem, defineDashboardExtension } from '@vendure/dashboard';
+import { useState } from 'react';
+
+defineDashboardExtension({
+    actionBarItems: [
+        {
+            pageId: 'product-list',
+            type: 'dropdown',
+            component: () => <DropdownMenuItem variant="default">My Item</DropdownMenuItem>
+        }
+    ],
+});
+```
+
+![Action bar dropdown](./action-bar-dropdown.webp)
+
 ## Practical Examples
 
 ### Export Button
@@ -48,7 +76,7 @@ The `context` prop provides access to:
 import { Button, defineDashboardExtension } from '@vendure/dashboard';
 import { DownloadIcon } from 'lucide-react';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     actionBarItems: [
         {
             pageId: 'product-detail',
@@ -89,7 +117,7 @@ import { RefreshCwIcon } from 'lucide-react';
 import { useState } from 'react';
 import { toast } from 'sonner';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     actionBarItems: [
         {
             pageId: 'product-detail',
@@ -134,7 +162,7 @@ You can conditionally show action bar items based on the entity or user permissi
 import { Button, defineDashboardExtension, PermissionGuard } from '@vendure/dashboard';
 import { SendIcon } from 'lucide-react';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     actionBarItems: [
         {
             pageId: 'customer-detail',
@@ -173,7 +201,7 @@ You can add multiple action bar items to the same page:
 import { Button, defineDashboardExtension } from '@vendure/dashboard';
 import { DownloadIcon, RefreshCwIcon, SendIcon } from 'lucide-react';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     actionBarItems: [
         {
             pageId: 'product-detail',

+ 1 - 1
docs/docs/guides/extending-the-dashboard/creating-pages/detail-pages.md

@@ -125,7 +125,7 @@ import { articleList } from './article-list';
 // highlight-next-line
 import { articleDetail } from './article-detail';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     routes: [
         articleList,
         // highlight-next-line

+ 1 - 1
docs/docs/guides/extending-the-dashboard/creating-pages/list-pages.md

@@ -122,7 +122,7 @@ import { defineDashboardExtension } from '@vendure/dashboard';
 // highlight-next-line
 import { articleList } from './article-list';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     routes: [
         // highlight-next-line
         articleList,

+ 2 - 2
docs/docs/guides/extending-the-dashboard/custom-form-components/index.md

@@ -92,7 +92,7 @@ First we need to register the component with the `defineDashboardExtension` func
 import { defineDashboardExtension } from '@vendure/dashboard';
 import { ColorPickerComponent } from './components/color-picker';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     customFormComponents: {
         // Custom field components for custom fields
         customFields: [
@@ -195,7 +195,7 @@ You can then use this component in your detail form definition:
 import { defineDashboardExtension } from '@vendure/dashboard';
 import { MarkdownEditorComponent } from './components/markdown-editor';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     detailForms: [
         {
             // highlight-start

+ 1 - 1
docs/docs/guides/extending-the-dashboard/custom-form-components/relation-selectors.md

@@ -451,7 +451,7 @@ import {
     ActiveCustomerSelectorComponent,
 } from './components';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     detailForms: [
         {
             pageId: 'product-detail',

+ 20 - 0
docs/docs/guides/extending-the-dashboard/data-fetching/index.md

@@ -1,3 +1,7 @@
+---
+title: 'Data Fetching'
+---
+
 ## API Client
 
 The API client is the primary way to send queries and mutations to the Vendure backend. It handles channel tokens and authentication automatically.
@@ -104,3 +108,19 @@ function ProductForm({ product }) {
     );
 }
 ```
+
+## Type Safety
+
+The Dashboard Vite plugin incorporates [gql.tada](https://gql-tada.0no.co/), which gives you type safety _without_ any code generation step!
+
+It works by analyzing your Admin API schema (including all your custom fields and other API extensions), and outputs the results
+to a file - by default you can find it at `src/gql/graphql-env.d.ts`.
+
+When you then use the `import { graphql } from '@/gql'` function to define your queries and mutations, you get automatic
+type safety when using the results in your components!
+
+When you have the `@/gql` path mapping correctly [set up as per the getting started guide](/guides/extending-the-dashboard/getting-started/#installation--setup), you should see that
+your IDE is able to infer the TypeScript type of your queries and mutations, including the correct inputs and return
+types!
+
+![Type inference](./type-inference.webp)

BIN
docs/docs/guides/extending-the-dashboard/data-fetching/type-inference.webp


+ 4 - 4
docs/docs/guides/extending-the-dashboard/navigation/index.md

@@ -11,7 +11,7 @@ The simplest way to add navigation is to add menu items to existing sections. Th
 ```tsx title="src/plugins/my-plugin/dashboard/index.tsx"
 import { defineDashboardExtension } from '@vendure/dashboard';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     routes: [
         {
             path: '/my-custom-page',
@@ -55,7 +55,7 @@ You can create entirely new navigation sections with their own icons and orderin
 import { defineDashboardExtension } from '@vendure/dashboard';
 import { FileTextIcon, SettingsIcon } from 'lucide-react';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     // Define custom navigation sections
     navSections: [
         {
@@ -111,7 +111,7 @@ The navigation sidebar is divided into two areas:
 ### Placement Examples
 
 ```tsx
-export default defineDashboardExtension({
+defineDashboardExtension({
     navSections: [
         {
             id: 'reports',
@@ -201,7 +201,7 @@ Here's a comprehensive example showing how to create a complete navigation struc
 import { defineDashboardExtension } from '@vendure/dashboard';
 import { FileTextIcon, ImageIcon, TagIcon, FolderIcon, SettingsIcon } from 'lucide-react';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     // Create custom navigation sections
     navSections: [
         {

+ 52 - 7
docs/docs/guides/extending-the-dashboard/page-blocks/index.md

@@ -7,6 +7,10 @@ app (see [Dev Mode](/guides/extending-the-dashboard/extending-overview/#dev-mode
 
 You can also define your own blocks, which can be added to any page and can even replace the default blocks.
 
+:::info
+All available options are documented in the [DashboardPageBlockDefinition reference](/reference/dashboard/extensions-api/page-blocks#dashboardpageblockdefinition)
+:::
+
 ## Basic Page Block Example
 
 Here's an example of how to define a custom page block:
@@ -14,7 +18,7 @@ Here's an example of how to define a custom page block:
 ```tsx title="src/plugins/my-plugin/dashboard/index.tsx"
 import { defineDashboardExtension } from '@vendure/dashboard';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     pageBlocks: [
         {
             id: 'related-articles',
@@ -99,6 +103,50 @@ The `context` prop provides access to:
 - **`form`**: The React Hook Form instance for the current page (if applicable)
 - **`route`**: Route information and parameters
 
+## Block Visibility
+
+The visibility of a block can be dynamically controlled using the `shouldRender` function. This function receives the same
+context object as the block component, and should return a boolean to determine whether the block should be rendered.
+
+```ts
+import { defineDashboardExtension } from '@vendure/dashboard';
+
+import { AdvancedTaxInfo } from './advanced-tax-info.tsx';
+
+defineDashboardExtension({
+    pageBlocks: [
+        {
+            id: 'advanced-tax-info',
+            location: {
+                pageId: 'product-variant-detail',
+                column: 'side',
+                position: {
+                    blockId: 'facet-values',
+                    order: 'after',
+                },
+            },
+            component: AdvancedTaxInfo,
+            shouldRender: context => {
+                // You can use custom and build-in hooks
+                // in this function
+                const { activeChannel } = useChannel();
+
+                const hasTaxSettings = context.entity?.customFields?.taxSettings
+                // This block will only render if the entity has the
+                // expected custom field data, and the active channel has
+                // the given tax setting
+                return hasTaxSettings && activeChannel.pricesIncludeTax === false;
+            },
+        },
+    ],
+});
+```
+
+:::tip
+The `shouldRender` function can be used to hide built-in blocks by combining it with the "replace" position
+on an existing blockId.
+:::
+
 ## Advanced Example
 
 Here's a more complex example that shows different types of blocks:
@@ -107,7 +155,7 @@ Here's a more complex example that shows different types of blocks:
 import { defineDashboardExtension, Button } from '@vendure/dashboard';
 import { useState } from 'react';
 
-export default defineDashboardExtension({
+defineDashboardExtension({
     pageBlocks: [
         // Analytics block for product page
         {
@@ -185,14 +233,11 @@ To find the `pageId` and `blockId` values for positioning your blocks:
 3. Hover over existing blocks to see their IDs
 4. Use these IDs in your block positioning configuration
 
-## TypeScript Support
-
-The dashboard provides full TypeScript support for page blocks. The `context` prop is typed based on the page you're targeting, giving you autocomplete and type safety for the entity properties.
-
-## Best Practices
+:::tip Best Practices
 
 1. **Use descriptive IDs**: Choose clear, unique IDs for your blocks
 2. **Position thoughtfully**: Consider the user experience when placing blocks
 3. **Handle loading states**: Show appropriate loading indicators for async operations
 4. **Follow design patterns**: Use the dashboard's existing UI components for consistency
 5. **Test thoroughly**: Verify your blocks work correctly on different screen sizes
+:::

+ 1 - 0
docs/sidebars.js

@@ -154,6 +154,7 @@ const sidebars = {
                 'guides/extending-the-dashboard/navigation/index',
                 'guides/extending-the-dashboard/page-blocks/index',
                 'guides/extending-the-dashboard/action-bar-items/index',
+                'guides/extending-the-dashboard/data-fetching/index',
                 'guides/extending-the-dashboard/theming/index',
                 {
                     type: 'category',