Browse Source

fix(dashboard): Dashboard fixes (#3448)

Michael Bromley 9 months ago
parent
commit
3a9e51bf9f
24 changed files with 279 additions and 269 deletions
  1. 0 1
      packages/dashboard/src/app/routes/__root.tsx
  2. 9 11
      packages/dashboard/src/app/routes/_authenticated/_administrators/administrators.tsx
  3. 13 15
      packages/dashboard/src/app/routes/_authenticated/_channels/channels.tsx
  4. 11 11
      packages/dashboard/src/app/routes/_authenticated/_collections/collections.tsx
  5. 12 14
      packages/dashboard/src/app/routes/_authenticated/_countries/countries.tsx
  6. 15 17
      packages/dashboard/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx
  7. 15 17
      packages/dashboard/src/app/routes/_authenticated/_customers/customers.tsx
  8. 18 17
      packages/dashboard/src/app/routes/_authenticated/_facets/facets.tsx
  9. 8 12
      packages/dashboard/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx
  10. 1 5
      packages/dashboard/src/app/routes/_authenticated/_product-variants/product-variants.tsx
  11. 10 12
      packages/dashboard/src/app/routes/_authenticated/_products/products.tsx
  12. 15 17
      packages/dashboard/src/app/routes/_authenticated/_promotions/promotions.tsx
  13. 13 14
      packages/dashboard/src/app/routes/_authenticated/_roles/roles.tsx
  14. 8 10
      packages/dashboard/src/app/routes/_authenticated/_sellers/sellers.tsx
  15. 13 15
      packages/dashboard/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx
  16. 13 14
      packages/dashboard/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx
  17. 12 14
      packages/dashboard/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx
  18. 14 16
      packages/dashboard/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx
  19. 11 13
      packages/dashboard/src/app/routes/_authenticated/_zones/zones.tsx
  20. 7 1
      packages/dashboard/src/lib/components/layout/app-layout.tsx
  21. 38 0
      packages/dashboard/src/lib/components/layout/prerelease-popup.tsx
  22. 17 21
      packages/dashboard/src/lib/components/shared/history-timeline/history-entry.tsx
  23. 2 2
      packages/dashboard/src/lib/components/shared/history-timeline/history-note-input.tsx
  24. 4 0
      packages/dashboard/src/lib/providers/user-settings.tsx

+ 0 - 1
packages/dashboard/src/app/routes/__root.tsx

@@ -19,7 +19,6 @@ function RootComponent() {
     return (
         <>
             <Outlet />
-            <TanStackRouterDevtools position="bottom-right" />
         </>
     );
 }

+ 9 - 11
packages/dashboard/src/app/routes/_authenticated/_administrators/administrators.tsx

@@ -3,10 +3,10 @@ import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { RoleCodeLabel } from '@/components/shared/role-code-label.js';
 import { Badge } from '@/components/ui/badge.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { administratorListDocument, deleteAdministratorDocument } from './administrators.graphql.js';
 
@@ -71,18 +71,16 @@ function AdministratorListPage() {
             }}
             defaultColumnOrder={['name', 'emailAddress', 'roles']}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateAdministrator']}>
-                        <Button asChild>
-                            <Link to="./new">
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateAdministrator']}>
+                    <Button asChild>
+                        <Link to="./new">
                             <PlusIcon />
                             New Administrator
                         </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 13 - 15
packages/dashboard/src/app/routes/_authenticated/_channels/channels.tsx

@@ -1,12 +1,12 @@
+import { ChannelCodeLabel } from '@/components/shared/channel-code-label.js';
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
-import { ChannelCodeLabel } from '@/components/shared/channel-code-label.js';
 import { channelListQuery, deleteChannelDocument } from './channels.graphql.js';
 
 export const Route = createFileRoute('/_authenticated/_channels/channels')({
@@ -45,18 +45,16 @@ function ChannelListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateChannel']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon className="mr-2 h-4 w-4" />
-                                New Channel
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateChannel']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon className="mr-2 h-4 w-4" />
+                            New Channel
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 11 - 11
packages/dashboard/src/app/routes/_authenticated/_collections/collections.tsx

@@ -1,7 +1,7 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarLeft, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
 import { createFileRoute, Link } from '@tanstack/react-router';
@@ -29,7 +29,9 @@ function CollectionListPage() {
                 breadcrumbs: {
                     cell: ({ cell }) => {
                         const value = cell.getValue();
-                        if (!Array.isArray(value)) return null;
+                        if (!Array.isArray(value)) {
+                            return null;
+                        }
                         return (
                             <div>
                                 {value
@@ -68,18 +70,16 @@ function CollectionListPage() {
             }}
             route={Route}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateCollection', 'CreateCatalog']}>
-                        <Button asChild>
-                            <Link to="./new">
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateCollection', 'CreateCatalog']}>
+                    <Button asChild>
+                        <Link to="./new">
                             <PlusIcon className="mr-2 h-4 w-4" />
                             <Trans>New Collection</Trans>
                         </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 12 - 14
packages/dashboard/src/app/routes/_authenticated/_countries/countries.tsx

@@ -1,10 +1,10 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { countriesListQuery, deleteCountryDocument } from './countries.graphql.js';
 
@@ -52,18 +52,16 @@ function CountryListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateCountry']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon />
-                                <Trans>Add Country</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateCountry']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon />
+                            <Trans>Add Country</Trans>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 15 - 17
packages/dashboard/src/app/routes/_authenticated/_customer-groups/customer-groups.tsx

@@ -1,15 +1,13 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { CustomerGroupMembersSheet } from './components/customer-group-members-sheet.js';
 import { customerGroupListDocument, deleteCustomerGroupDocument } from './customer-groups.graphql.js';
-import { useMutation } from '@tanstack/react-query';
-import { api } from '@/graphql/api.js';
 
 export const Route = createFileRoute('/_authenticated/_customer-groups/customer-groups')({
     component: CustomerGroupListPage,
@@ -33,7 +31,9 @@ function CustomerGroupListPage() {
                     header: () => <Trans>Values</Trans>,
                     cell: ({ cell }) => {
                         const value = cell.getValue();
-                        if (!value) return null;
+                        if (!value) {
+                            return null;
+                        }
                         return (
                             <div className="flex flex-wrap gap-2 items-center">
                                 <CustomerGroupMembersSheet
@@ -53,18 +53,16 @@ function CustomerGroupListPage() {
                 };
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateCustomerGroup']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon className="mr-2 h-4 w-4" />
-                                <Trans>New Customer Group</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateCustomerGroup']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon className="mr-2 h-4 w-4" />
+                            <Trans>New Customer Group</Trans>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 15 - 17
packages/dashboard/src/app/routes/_authenticated/_customers/customers.tsx

@@ -1,14 +1,14 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
+import { PermissionGuard } from '@/components/shared/permission-guard.js';
+import { Button } from '@/components/ui/button.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
 import { createFileRoute, Link } from '@tanstack/react-router';
+import { PlusIcon } from 'lucide-react';
 import { CustomerStatusBadge } from './components/customer-status-badge.js';
 import { customerListDocument, deleteCustomerDocument } from './customers.graphql.js';
-import { PageActionBar } from '@/framework/layout-engine/page-layout.js';
-import { PlusIcon } from 'lucide-react';
-import { PermissionGuard } from '@/components/shared/permission-guard.js';
-import { Button } from '@/components/ui/button.js';
-import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+
 export const Route = createFileRoute('/_authenticated/_customers/customers')({
     component: CustomerListPage,
     loader: () => ({ breadcrumb: () => <Trans>Customers</Trans> }),
@@ -67,18 +67,16 @@ function CustomerListPage() {
                 lastName: false,
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateCustomer']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon />
-                                <Trans>New Customer</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateCustomer']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon />
+                            <Trans>New Customer</Trans>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 18 - 17
packages/dashboard/src/app/routes/_authenticated/_facets/facets.tsx

@@ -1,16 +1,15 @@
+import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { FacetValueChip } from '@/components/shared/facet-value-chip.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
 import { createFileRoute, Link } from '@tanstack/react-router';
-import { PlusIcon } from 'lucide-react';
-import { facetListDocument, deleteFacetDocument } from './facets.graphql.js';
-
-import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { ResultOf } from 'gql.tada';
+import { PlusIcon } from 'lucide-react';
 import { FacetValuesSheet } from './components/facet-values-sheet.js';
+import { deleteFacetDocument, facetListDocument } from './facets.graphql.js';
 
 export const Route = createFileRoute('/_authenticated/_facets/facets')({
     component: FacetListPage,
@@ -33,7 +32,9 @@ function FacetListPage() {
                     header: () => <Trans>Values</Trans>,
                     cell: ({ cell }) => {
                         const value = cell.getValue();
-                        if (!value) return null;
+                        if (!value) {
+                            return null;
+                        }
                         const list = value as any as ResultOf<
                             typeof facetListDocument
                         >['facets']['items'][0]['valueList'];
@@ -56,8 +57,10 @@ function FacetListPage() {
                                     {list.totalItems > 3 ? (
                                         <div>
                                             <Trans>+ {list.totalItems - 3} more</Trans>
-                                        </div>) : <Trans>View values</Trans>
-                                    }
+                                        </div>
+                                    ) : (
+                                        <Trans>View values</Trans>
+                                    )}
                                 </FacetValuesSheet>
                             </div>
                         );
@@ -79,18 +82,16 @@ function FacetListPage() {
             }}
             route={Route}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateFacet', 'CreateCatalog']}>
-                        <Button asChild>
-                            <Link to="./new">
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateFacet', 'CreateCatalog']}>
+                    <Button asChild>
+                        <Link to="./new">
                             <PlusIcon className="mr-2 h-4 w-4" />
                             <Trans>New Facet</Trans>
                         </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 8 - 12
packages/dashboard/src/app/routes/_authenticated/_payment-methods/payment-methods.tsx

@@ -2,7 +2,6 @@ import { BooleanDisplayBadge } from '@/components/data-display/boolean.js';
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
 import { createFileRoute, Link } from '@tanstack/react-router';
@@ -52,17 +51,14 @@ function PaymentMethodListPage() {
                 },
             }}
         >
-            {' '}
-            <PageActionBar>
-                <PermissionGuard requires={['CreatePaymentMethod']}>
-                    <Button asChild>
-                        <Link to="./new">
-                            <PlusIcon className="mr-2 h-4 w-4" />
-                            New Payment Method
-                        </Link>
-                    </Button>
-                </PermissionGuard>
-            </PageActionBar>
+            <PermissionGuard requires={['CreatePaymentMethod']}>
+                <Button asChild>
+                    <Link to="./new">
+                        <PlusIcon className="mr-2 h-4 w-4" />
+                        New Payment Method
+                    </Link>
+                </Button>
+            </PermissionGuard>
         </ListPage>
     );
 }

+ 1 - 5
packages/dashboard/src/app/routes/_authenticated/_product-variants/product-variants.tsx

@@ -73,10 +73,6 @@ function ProductListPage() {
                 };
             }}
             route={Route}
-        >
-            <PageActionBar>
-                <div></div>
-            </PageActionBar>
-        </ListPage>
+        ></ListPage>
     );
 }

+ 10 - 12
packages/dashboard/src/app/routes/_authenticated/_products/products.tsx

@@ -33,18 +33,16 @@ function ProductListPage() {
             }}
             route={Route}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateProduct', 'CreateCatalog']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon className="mr-2 h-4 w-4" />
-                                New Product
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateProduct', 'CreateCatalog']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon className="mr-2 h-4 w-4" />
+                            New Product
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 15 - 17
packages/dashboard/src/app/routes/_authenticated/_promotions/promotions.tsx

@@ -1,20 +1,20 @@
+import { BooleanDisplayBadge } from '@/components/data-display/boolean.js';
+import { DetailPageButton } from '@/components/shared/detail-page-button.js';
+import { PermissionGuard } from '@/components/shared/permission-guard.js';
+import { Button } from '@/components/ui/button.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
-import { DetailPageButton } from '@/components/shared/detail-page-button.js';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
-import { Button } from '@/components/ui/button.js';
-import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { deletePromotionDocument, promotionListDocument } from './promotions.graphql.js';
-import { BooleanDisplayBadge } from '@/components/data-display/boolean.js';
 
 export const Route = createFileRoute('/_authenticated/_promotions/promotions')({
     component: PromotionListPage,
     loader: () => ({ breadcrumb: () => <Trans>Promotions</Trans> }),
 });
 
-function PromotionListPage() {  
+function PromotionListPage() {
     return (
         <ListPage
             pageId="promotion-list"
@@ -46,18 +46,16 @@ function PromotionListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreatePromotion']}>
-                        <Button asChild>
-                            <Link to="./new">
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreatePromotion']}>
+                    <Button asChild>
+                        <Link to="./new">
                             <PlusIcon className="mr-2 h-4 w-4" />
                             <Trans>New Promotion</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 13 - 14
packages/dashboard/src/app/routes/_authenticated/_roles/roles.tsx

@@ -1,17 +1,18 @@
+import { ChannelCodeLabel } from '@/components/shared/channel-code-label.js';
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { RoleCodeLabel } from '@/components/shared/role-code-label.js';
 import { Badge } from '@/components/ui/badge.js';
 import { Button } from '@/components/ui/button.js';
 import { CUSTOMER_ROLE_CODE, SUPER_ADMIN_ROLE_CODE } from '@/constants.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
 import { createFileRoute, Link } from '@tanstack/react-router';
 import { LayersIcon, PlusIcon } from 'lucide-react';
-import { ChannelCodeLabel } from '@/components/shared/channel-code-label.js';
 import { ExpandablePermissions } from './components/expandable-permissions.js';
 import { deleteRoleDocument, roleListQuery } from './roles.graphql.js';
+
 export const Route = createFileRoute('/_authenticated/_roles/roles')({
     component: RoleListPage,
     loader: () => ({ breadcrumb: () => <Trans>Roles</Trans> }),
@@ -80,18 +81,16 @@ function RoleListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateAdministrator']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon className="mr-2 h-4 w-4" />
-                                New Role
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateAdministrator']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon className="mr-2 h-4 w-4" />
+                            New Role
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 8 - 10
packages/dashboard/src/app/routes/_authenticated/_sellers/sellers.tsx

@@ -1,10 +1,10 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { deleteSellerDocument, sellerListQuery } from './sellers.graphql.js';
 
@@ -36,18 +36,16 @@ function SellerListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>    
-                    <PermissionGuard requires={['CreateSeller']}>
-                        <Button asChild>
-                            <Link to="./new">
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateSeller']}>
+                    <Button asChild>
+                        <Link to="./new">
                             <PlusIcon className="mr-2 h-4 w-4" />
                             New Seller
                         </Link>
                     </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 13 - 15
packages/dashboard/src/app/routes/_authenticated/_shipping-methods/shipping-methods.tsx

@@ -1,10 +1,10 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { TestShippingMethodDialog } from './components/test-shipping-method-dialog.js';
 import { deleteShippingMethodDocument, shippingMethodListQuery } from './shipping-methods.graphql.js';
@@ -39,19 +39,17 @@ function ShippingMethodListPage() {
                 };
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateShippingMethod']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon className="mr-2 h-4 w-4" />
-                                <Trans>New Shipping Method</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                    <TestShippingMethodDialog />
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateShippingMethod']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon className="mr-2 h-4 w-4" />
+                            <Trans>New Shipping Method</Trans>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+                <TestShippingMethodDialog />
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 13 - 14
packages/dashboard/src/app/routes/_authenticated/_stock-locations/stock-locations.tsx

@@ -1,12 +1,13 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { deleteStockLocationDocument, stockLocationListQuery } from './stock-locations.graphql.js';
+
 export const Route = createFileRoute('/_authenticated/_stock-locations/stock-locations')({
     component: StockLocationListPage,
     loader: () => ({ breadcrumb: () => <Trans>Stock Locations</Trans> }),
@@ -32,18 +33,16 @@ function StockLocationListPage() {
                 };
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateStockLocation']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon className="mr-2 h-4 w-4" />
-                                New Stock Location
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateStockLocation']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon className="mr-2 h-4 w-4" />
+                            New Stock Location
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 12 - 14
packages/dashboard/src/app/routes/_authenticated/_tax-categories/tax-categories.tsx

@@ -2,10 +2,10 @@ import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Badge } from '@/components/ui/badge.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { deleteTaxCategoryDocument, taxCategoryListQuery } from './tax-categories.graphql.js';
 
@@ -50,18 +50,16 @@ function TaxCategoryListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateTaxCategory']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon />
-                                <Trans>New Tax Category</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateTaxCategory']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon />
+                            <Trans>New Tax Category</Trans>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 14 - 16
packages/dashboard/src/app/routes/_authenticated/_tax-rates/tax-rates.tsx

@@ -2,15 +2,15 @@ import { BooleanDisplayBadge } from '@/components/data-display/boolean.js';
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { api } from '@/graphql/api.js';
 import { Trans } from '@/lib/trans.js';
-import { Link, createFileRoute } from '@tanstack/react-router';
+import { createFileRoute, Link } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
-import { deleteTaxRateDocument, taxRateListQuery } from './tax-rates.graphql.js';
-import { zoneListQuery } from '../_zones/zones.graphql.js';
 import { taxCategoryListQuery } from '../_tax-categories/tax-categories.graphql.js';
+import { zoneListQuery } from '../_zones/zones.graphql.js';
+import { deleteTaxRateDocument, taxRateListQuery } from './tax-rates.graphql.js';
 
 export const Route = createFileRoute('/_authenticated/_tax-rates/tax-rates')({
     component: TaxRateListPage,
@@ -93,18 +93,16 @@ function TaxRateListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateTaxRate']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon />
-                                <Trans>New Tax Rate</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateTaxRate']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon />
+                            <Trans>New Tax Rate</Trans>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 11 - 13
packages/dashboard/src/app/routes/_authenticated/_zones/zones.tsx

@@ -1,7 +1,7 @@
 import { DetailPageButton } from '@/components/shared/detail-page-button.js';
 import { PermissionGuard } from '@/components/shared/permission-guard.js';
 import { Button } from '@/components/ui/button.js';
-import { PageActionBar, PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
+import { PageActionBarRight } from '@/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/framework/page/list-page.js';
 import { Trans } from '@/lib/trans.js';
 import { createFileRoute, Link } from '@tanstack/react-router';
@@ -42,18 +42,16 @@ function ZoneListPage() {
                 },
             }}
         >
-            <PageActionBar>
-                <PageActionBarRight>
-                    <PermissionGuard requires={['CreateZone']}>
-                        <Button asChild>
-                            <Link to="./new">
-                                <PlusIcon />
-                                <Trans>New Zone</Trans>
-                            </Link>
-                        </Button>
-                    </PermissionGuard>
-                </PageActionBarRight>
-            </PageActionBar>
+            <PageActionBarRight>
+                <PermissionGuard requires={['CreateZone']}>
+                    <Button asChild>
+                        <Link to="./new">
+                            <PlusIcon />
+                            <Trans>New Zone</Trans>
+                        </Link>
+                    </Button>
+                </PermissionGuard>
+            </PageActionBarRight>
         </ListPage>
     );
 }

+ 7 - 1
packages/dashboard/src/lib/components/layout/app-layout.tsx

@@ -1,5 +1,6 @@
 import { AppSidebar } from '@/components/layout/app-sidebar.js';
 import { GeneratedBreadcrumbs } from '@/components/layout/generated-breadcrumbs.js';
+import { PrereleasePopup } from '@/components/layout/prerelease-popup.js';
 import { Badge } from '@/components/ui/badge.js';
 import { Separator } from '@/components/ui/separator.js';
 import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar.js';
@@ -23,7 +24,11 @@ export function AppLayout() {
                                 <GeneratedBreadcrumbs />
                             </div>
                             <div className="flex items-center justify-end gap-2">
-                                {settings.devMode && <Badge variant="destructive"><Trans>Dev Mode</Trans></Badge>}
+                                {settings.devMode && (
+                                    <Badge variant="destructive">
+                                        <Trans>Dev Mode</Trans>
+                                    </Badge>
+                                )}
                                 <Alerts />
                             </div>
                         </div>
@@ -31,6 +36,7 @@ export function AppLayout() {
                     <Outlet />
                 </div>
             </SidebarInset>
+            <PrereleasePopup />
         </SidebarProvider>
     );
 }

+ 38 - 0
packages/dashboard/src/lib/components/layout/prerelease-popup.tsx

@@ -0,0 +1,38 @@
+import { useUserSettings } from '@/hooks/use-user-settings.js';
+import { useState } from 'react';
+import { toast } from 'sonner';
+
+export function PrereleasePopup() {
+    const { settings, setHasSeenOnboarding } = useUserSettings();
+    const [isOpen, setIsOpen] = useState(false);
+    if (!settings.hasSeenOnboarding && !isOpen) {
+        setIsOpen(true);
+        toast('Welcome to the new Dashboard!', {
+            description: (
+                <div className="space-y-2">
+                    <p>
+                        This is an <span className="font-bold">alpha</span> version of our new Vendure
+                        Dashboard!
+                    </p>
+                    <p>
+                        This release allows you to explore the new interface and functionality, but it's not
+                        yet ready for production use.
+                    </p>
+                    <p>
+                        If you find missing or broken functionality, you don't need to report it on GitHub at
+                        this point - we're already working on it!
+                    </p>
+                </div>
+            ),
+            duration: 1000 * 60,
+            action: {
+                label: 'Got it',
+                onClick: () => {
+                    setHasSeenOnboarding(true);
+                    setIsOpen(false);
+                },
+            },
+        });
+    }
+    return null;
+}

+ 17 - 21
packages/dashboard/src/lib/components/shared/history-timeline/history-entry.tsx

@@ -33,42 +33,38 @@ interface HistoryEntryProps {
     children: React.ReactNode;
 }
 
-export function HistoryEntry({
-    entry,
-    isNoteEntry,
-    timelineIcon,
-    title,
-    children,
-}: HistoryEntryProps) {
+export function HistoryEntry({ entry, isNoteEntry, timelineIcon, title, children }: HistoryEntryProps) {
     const { formatDate } = useLocalFormat();
     const { editNote, deleteNote } = useHistoryTimeline();
 
-
-    const formatDateTime = useCallback((date: string) => {
-        return formatDate(date, {
-            year: 'numeric',
-            month: 'long',
-            day: 'numeric',
-            hour: 'numeric',
-            minute: 'numeric',
-            second: 'numeric',
-        });
-    }, [formatDate]);
+    const formatDateTime = useCallback(
+        (date: string) => {
+            return formatDate(date, {
+                year: 'numeric',
+                month: 'long',
+                day: 'numeric',
+                hour: 'numeric',
+                minute: 'numeric',
+                second: 'numeric',
+            });
+        },
+        [formatDate],
+    );
 
     return (
         <div key={entry.id} className="relative mb-4 pl-11">
             <div className="absolute left-0 w-10 flex items-center justify-center">
                 <div className={`rounded-full flex items-center justify-center h-6 w-6`}>
                     <div
-                        className={`rounded-full bg-gray-200 text-muted-foreground flex items-center justify-center h-6 w-6`}
+                        className={`rounded-full bg-muted text-muted-foreground flex items-center justify-center h-6 w-6`}
                     >
                         {timelineIcon}
                     </div>
                 </div>
             </div>
 
-            <div className="bg-white px-4 rounded-md">
-                <div className="mt-2 text-sm text-gray-500 flex items-center">
+            <div className="px-4 rounded-md">
+                <div className="mt-2 text-sm text-muted-foreground flex items-center">
                     <span>{formatDateTime(entry.createdAt)}</span>
                     {entry.administrator && (
                         <span className="ml-2">

+ 2 - 2
packages/dashboard/src/lib/components/shared/history-timeline/history-note-input.tsx

@@ -19,7 +19,7 @@ export function HistoryNoteInput({ onAddNote }: HistoryNoteInputProps) {
     };
 
     return (
-        <div className="border rounded-md p-4 bg-gray-50">
+        <div className="border rounded-md p-4">
             <div className="flex flex-col space-y-4">
                 <Textarea
                     placeholder="Add a note..."
@@ -36,4 +36,4 @@ export function HistoryNoteInput({ onAddNote }: HistoryNoteInputProps) {
             </div>
         </div>
     );
-} 
+}

+ 4 - 0
packages/dashboard/src/lib/providers/user-settings.tsx

@@ -10,6 +10,7 @@ export interface UserSettings {
     mainNavExpanded: boolean;
     activeChannelId: string;
     devMode: boolean;
+    hasSeenOnboarding: boolean;
 }
 
 const defaultSettings: UserSettings = {
@@ -21,6 +22,7 @@ const defaultSettings: UserSettings = {
     mainNavExpanded: true,
     activeChannelId: '',
     devMode: false,
+    hasSeenOnboarding: false,
 };
 
 export interface UserSettingsContextType {
@@ -33,6 +35,7 @@ export interface UserSettingsContextType {
     setMainNavExpanded: (expanded: boolean) => void;
     setActiveChannelId: (channelId: string) => void;
     setDevMode: (devMode: boolean) => void;
+    setHasSeenOnboarding: (hasSeen: boolean) => void;
 }
 
 export const UserSettingsContext = createContext<UserSettingsContextType | undefined>(undefined);
@@ -79,6 +82,7 @@ export const UserSettingsProvider: React.FC<React.PropsWithChildren<{}>> = ({ ch
         setMainNavExpanded: expanded => updateSetting('mainNavExpanded', expanded),
         setActiveChannelId: channelId => updateSetting('activeChannelId', channelId),
         setDevMode: devMode => updateSetting('devMode', devMode),
+        setHasSeenOnboarding: hasSeen => updateSetting('hasSeenOnboarding', hasSeen),
     };
 
     return <UserSettingsContext.Provider value={contextValue}>{children}</UserSettingsContext.Provider>;