diff --git a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartContent.tsx b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartContent.tsx index 107e837068..c4cbbc5c47 100644 --- a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartContent.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartContent.tsx @@ -20,11 +20,18 @@ interface OrgChartData { interface OrgChartContentProps { chartData: OrgChartData | null; members: OrgChartMember[]; + onChartChange: () => void | Promise; } -export function OrgChartContent({ chartData, members }: OrgChartContentProps) { +export function OrgChartContent({ + chartData, + members, + onChartChange, +}: OrgChartContentProps) { if (!chartData) { - return ; + return ( + + ); } if (chartData.type === 'uploaded' && chartData.signedImageUrl) { @@ -32,6 +39,7 @@ export function OrgChartContent({ chartData, members }: OrgChartContentProps) { ); } @@ -57,6 +65,7 @@ export function OrgChartContent({ chartData, members }: OrgChartContentProps) { initialEdges={chartData.edges} members={members} updatedAt={chartData.updatedAt ?? null} + onChartChange={onChartChange} /> ); } diff --git a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEditor.tsx b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEditor.tsx index 077c2970a4..c2fad40905 100644 --- a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEditor.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEditor.tsx @@ -18,7 +18,6 @@ import { } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; import { formatDistanceToNow } from 'date-fns'; -import { useRouter } from 'next/navigation'; import { useCallback, useMemo, useRef, useState } from 'react'; import { toast } from 'sonner'; import type { OrgChartMember } from '../types'; @@ -30,6 +29,7 @@ interface OrgChartEditorProps { initialEdges: Edge[]; members: OrgChartMember[]; updatedAt: string | null; + onChartChange: () => void | Promise; } export function OrgChartEditor({ @@ -37,9 +37,9 @@ export function OrgChartEditor({ initialEdges, members, updatedAt, + onChartChange, }: OrgChartEditorProps) { const api = useApi(); - const router = useRouter(); const reactFlowWrapper = useRef(null); const [reactFlowInstance, setReactFlowInstance] = useState(null); @@ -161,7 +161,12 @@ export function OrgChartEditor({ setLastSavedAt(new Date().toISOString()); } toast.success('Org chart saved'); - router.refresh(); + + try { + await onChartChange(); + } catch { + // Save already succeeded; a refresh failure shouldn't surface as a save error. + } } catch { toast.error('Failed to save org chart'); } finally { diff --git a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEmptyState.tsx b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEmptyState.tsx index e677a87262..2da1050a56 100644 --- a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEmptyState.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartEmptyState.tsx @@ -9,9 +9,13 @@ import type { OrgChartMember } from '../types'; interface OrgChartEmptyStateProps { members: OrgChartMember[]; + onChartChange: () => void | Promise; } -export function OrgChartEmptyState({ members }: OrgChartEmptyStateProps) { +export function OrgChartEmptyState({ + members, + onChartChange, +}: OrgChartEmptyStateProps) { const [mode, setMode] = useState<'empty' | 'create' | 'upload'>('empty'); if (mode === 'create') { @@ -21,12 +25,18 @@ export function OrgChartEmptyState({ members }: OrgChartEmptyStateProps) { initialEdges={[]} members={members} updatedAt={null} + onChartChange={onChartChange} /> ); } if (mode === 'upload') { - return setMode('empty')} />; + return ( + setMode('empty')} + onUploaded={onChartChange} + /> + ); } return ( diff --git a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartImageView.tsx b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartImageView.tsx index 6eeed4d7f0..f0c0bbd3f9 100644 --- a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartImageView.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartImageView.tsx @@ -5,20 +5,20 @@ import { Button } from '@trycompai/design-system'; import { TrashCan, Upload } from '@trycompai/design-system/icons'; import { useApi } from '@/hooks/use-api'; import { toast } from 'sonner'; -import { useRouter } from 'next/navigation'; import { UploadOrgChartDialog } from './UploadOrgChartDialog'; interface OrgChartImageViewProps { imageUrl: string; chartName: string; + onChartChange: () => void | Promise; } export function OrgChartImageView({ imageUrl, chartName, + onChartChange, }: OrgChartImageViewProps) { const api = useApi(); - const router = useRouter(); const [isDeleting, setIsDeleting] = useState(false); const [showReplace, setShowReplace] = useState(false); @@ -33,7 +33,12 @@ export function OrgChartImageView({ } toast.success('Org chart deleted'); - router.refresh(); + + try { + await onChartChange(); + } catch { + // Delete already succeeded; a refresh failure shouldn't surface as a delete error. + } } catch { toast.error('Failed to delete org chart'); } finally { @@ -42,7 +47,12 @@ export function OrgChartImageView({ }; if (showReplace) { - return setShowReplace(false)} />; + return ( + setShowReplace(false)} + onUploaded={onChartChange} + /> + ); } return ( diff --git a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartTabContent.tsx b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartTabContent.tsx index a0cc7f7129..7a01fc0e3c 100644 --- a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartTabContent.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/OrgChartTabContent.tsx @@ -10,7 +10,7 @@ interface OrgChartTabContentProps { } export function OrgChartTabContent({ organizationId }: OrgChartTabContentProps) { - const { orgChart } = useOrgChart(); + const { orgChart, mutate } = useOrgChart(); const { members } = useTeamMembers({ organizationId }); const chartMembers: OrgChartMember[] = members @@ -25,5 +25,11 @@ export function OrgChartTabContent({ organizationId }: OrgChartTabContentProps) jobTitle: m.jobTitle ?? null, })); - return ; + return ( + + ); } diff --git a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/UploadOrgChartDialog.tsx b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/UploadOrgChartDialog.tsx index 56fa6b55a4..41e5683aea 100644 --- a/apps/app/src/app/(app)/[orgId]/people/org-chart/components/UploadOrgChartDialog.tsx +++ b/apps/app/src/app/(app)/[orgId]/people/org-chart/components/UploadOrgChartDialog.tsx @@ -6,15 +6,17 @@ import { Button } from '@trycompai/design-system'; import { Upload, Close } from '@trycompai/design-system/icons'; import { useApi } from '@/hooks/use-api'; import { toast } from 'sonner'; -import { useRouter } from 'next/navigation'; interface UploadOrgChartDialogProps { onClose: () => void; + onUploaded: () => void | Promise; } -export function UploadOrgChartDialog({ onClose }: UploadOrgChartDialogProps) { +export function UploadOrgChartDialog({ + onClose, + onUploaded, +}: UploadOrgChartDialogProps) { const api = useApi(); - const router = useRouter(); const [isUploading, setIsUploading] = useState(false); const [selectedFile, setSelectedFile] = useState(null); @@ -60,8 +62,13 @@ export function UploadOrgChartDialog({ onClose }: UploadOrgChartDialogProps) { } toast.success('Org chart uploaded'); - router.refresh(); onClose(); + + try { + await onUploaded(); + } catch { + // Upload already succeeded; a refresh failure shouldn't surface as an upload error. + } } catch { toast.error('Failed to upload org chart'); } finally {