Parcourir la source

fix(dashboard): Update channel switcher when Channel added/updated

Michael Bromley il y a 4 mois
Parent
commit
1cd7652bd6

+ 3 - 0
packages/dashboard/src/app/routes/_authenticated/_channels/channels_.$id.tsx

@@ -22,6 +22,7 @@ import {
 } from '@/vdb/framework/layout-engine/page-layout.js';
 import { detailPageRouteLoader } from '@/vdb/framework/page/detail-page-route-loader.js';
 import { useDetailPage } from '@/vdb/framework/page/use-detail-page.js';
+import { useChannel } from '@/vdb/hooks/use-channel.js';
 import { Trans, useLingui } from '@/vdb/lib/trans.js';
 import { createFileRoute, useNavigate } from '@tanstack/react-router';
 import { toast } from 'sonner';
@@ -49,6 +50,7 @@ function ChannelDetailPage() {
     const navigate = useNavigate();
     const creatingNewEntity = params.id === NEW_ENTITY_PATH;
     const { i18n } = useLingui();
+    const { refreshChannels } = useChannel();
 
     const { form, submitHandler, entity, isPending, resetForm } = useDetailPage({
         pageId,
@@ -81,6 +83,7 @@ function ChannelDetailPage() {
         onSuccess: async data => {
             if (data.__typename === 'Channel') {
                 toast(i18n.t('Successfully updated channel'));
+                refreshChannels();
                 resetForm();
                 if (creatingNewEntity) {
                     await navigate({ to: `../$id`, params: { id: data.id } });

+ 8 - 0
packages/dashboard/src/lib/providers/auth.tsx

@@ -21,6 +21,7 @@ export interface AuthContext {
     logout: (onSuccess?: () => void) => Promise<void>;
     user: ResultOf<typeof CurrentUserQuery>['activeAdministrator'] | undefined;
     channels: NonNullable<ResultOf<typeof CurrentUserQuery>['me']>['channels'] | undefined;
+    refreshCurrentUser: () => void;
 }
 
 const LoginMutation = graphql(`
@@ -174,6 +175,12 @@ export function AuthProvider({ children }: Readonly<{ children: React.ReactNode
         }
     }, [isLoading, currentUserData, currentUserError, status, isLoginLogoutInProgress]);
 
+    const refreshCurrentUser = () => {
+        queryClient.invalidateQueries({
+            queryKey: ['currentUser'],
+        });
+    };
+
     return (
         <AuthContext.Provider
             value={{
@@ -184,6 +191,7 @@ export function AuthProvider({ children }: Readonly<{ children: React.ReactNode
                 channels: currentUserData?.me?.channels,
                 login,
                 logout,
+                refreshCurrentUser,
             }}
         >
             {children}

+ 15 - 6
packages/dashboard/src/lib/providers/channel-provider.tsx

@@ -1,5 +1,5 @@
 import { api } from '@/vdb/graphql/api.js';
-import { ResultOf, graphql } from '@/vdb/graphql/graphql.js';
+import { graphql, ResultOf } from '@/vdb/graphql/graphql.js';
 import { useAuth } from '@/vdb/hooks/use-auth.js';
 import { useQuery, useQueryClient } from '@tanstack/react-query';
 import * as React from 'react';
@@ -57,6 +57,7 @@ export interface ChannelContext {
     selectedChannel: Channel | undefined;
     isLoading: boolean;
     setSelectedChannel: (channelId: string) => void;
+    refreshChannels: () => void;
 }
 
 // Create the context
@@ -68,7 +69,7 @@ const SELECTED_CHANNEL_TOKEN_KEY = 'vendure-selected-channel-token';
 
 export function ChannelProvider({ children }: Readonly<{ children: React.ReactNode }>) {
     const queryClient = useQueryClient();
-    const { channels: userChannels, isAuthenticated } = useAuth();
+    const { channels: userChannels, isAuthenticated, refreshCurrentUser } = useAuth();
     const [selectedChannelId, setSelectedChannelId] = React.useState<string | undefined>(() => {
         // Initialize from localStorage if available
         try {
@@ -90,15 +91,15 @@ export function ChannelProvider({ children }: Readonly<{ children: React.ReactNo
 
     // Filter channels based on user permissions
     const channels = React.useMemo(() => {
-        // If user has specific channels assigned (non-superadmin), use those
+        // If user has specific channels assigned, use those
         if (userChannels && userChannels.length > 0) {
             // Map user channels to match the Channel type structure
             return userChannels.map(ch => {
                 const fullChannelData = channelsData?.channels.items.find(c => c.id === ch.id);
                 return {
                     id: ch.id,
-                    code: ch.code,
-                    token: ch.token,
+                    code: fullChannelData?.code ?? ch.code,
+                    token: fullChannelData?.token ?? ch.token,
                     defaultLanguageCode: fullChannelData?.defaultLanguageCode || 'en',
                     defaultCurrencyCode: fullChannelData?.defaultCurrencyCode || 'USD',
                     pricesIncludeTax: fullChannelData?.pricesIncludeTax || false,
@@ -106,7 +107,7 @@ export function ChannelProvider({ children }: Readonly<{ children: React.ReactNo
                 };
             });
         }
-        // Otherwise use all channels (superadmin)
+        // Otherwise use all channels
         return channelsData?.channels.items || [];
     }, [userChannels, channelsData?.channels.items]);
 
@@ -167,6 +168,13 @@ export function ChannelProvider({ children }: Readonly<{ children: React.ReactNo
         return channels.find(channel => channel.id === selectedChannelId);
     }, [channels, selectedChannelId]);
 
+    const refreshChannels = () => {
+        refreshCurrentUser();
+        queryClient.invalidateQueries({
+            queryKey: ['channels', isAuthenticated],
+        });
+    };
+
     const contextValue: ChannelContext = {
         activeChannel,
         channels,
@@ -174,6 +182,7 @@ export function ChannelProvider({ children }: Readonly<{ children: React.ReactNo
         selectedChannel,
         isLoading,
         setSelectedChannel,
+        refreshChannels,
     };
 
     return <ChannelContext.Provider value={contextValue}>{children}</ChannelContext.Provider>;