diff --git a/src/renderer/hooks/useCompanyController.ts b/src/renderer/hooks/useCompanyController.ts index fd053463..9a79bdbd 100644 --- a/src/renderer/hooks/useCompanyController.ts +++ b/src/renderer/hooks/useCompanyController.ts @@ -181,6 +181,7 @@ export function useCompanyController() { selectedApproval: companyData.selectedApproval, selectedRun: companyData.selectedRun, selectedAgent: companyData.selectedAgent, + editingAgent: companyData.editingAgent, selectedGoal: companyData.selectedGoal, selectedProject: companyData.selectedProject, selectedWorkspace: companyData.selectedWorkspace, diff --git a/src/renderer/hooks/useCompanyData.ts b/src/renderer/hooks/useCompanyData.ts index c458fa26..ac825110 100644 --- a/src/renderer/hooks/useCompanyData.ts +++ b/src/renderer/hooks/useCompanyData.ts @@ -19,6 +19,7 @@ export function useCompanyData( const selectedTaskId = useAppStore((s) => s.selectedTaskId); const selectedApprovalId = useAppStore((s) => s.selectedApprovalId); const selectedAgentId = useAppStore((s) => s.selectedAgentId); + const editingAgentId = useAppStore((s) => s.editingAgentId); const selectedGoalId = useAppStore((s) => s.selectedGoalId); const selectedProjectId = useAppStore((s) => s.selectedProjectId); const selectedWorkspaceId = useAppStore((s) => s.selectedWorkspaceId); @@ -58,6 +59,10 @@ export function useCompanyData( () => companyAgents.find((a) => a.id === selectedAgentId) ?? null, [companyAgents, selectedAgentId], ); + const editingAgent = useMemo( + () => companyAgents.find((a) => a.id === editingAgentId) ?? null, + [companyAgents, editingAgentId], + ); const selectedGoal = useMemo( () => companyGoals.find((g) => g.id === selectedGoalId) ?? null, [companyGoals, selectedGoalId], @@ -104,6 +109,7 @@ export function useCompanyData( selectedApproval, selectedRun, selectedAgent, + editingAgent, selectedGoal, selectedProject, selectedWorkspace, @@ -128,6 +134,7 @@ export function useCompanyData( selectedApproval, selectedRun, selectedAgent, + editingAgent, selectedGoal, selectedProject, selectedWorkspace, diff --git a/src/renderer/i18n/en.ts b/src/renderer/i18n/en.ts index 70547af2..e6395b8c 100644 --- a/src/renderer/i18n/en.ts +++ b/src/renderer/i18n/en.ts @@ -342,6 +342,7 @@ export const en: Record = { "org.agentRoster": "Agent roster", "org.newHireRequest": "New hire request", "org.editAgent": "Edit", + "org.editAgentTitle": "Edit {name} ({role})", "org.requestNewHire": "Request new hire", "org.goalStack": "Goal stack", "org.newGoal": "New goal", diff --git a/src/renderer/i18n/zh.ts b/src/renderer/i18n/zh.ts index 29c398f5..9007e1d5 100644 --- a/src/renderer/i18n/zh.ts +++ b/src/renderer/i18n/zh.ts @@ -342,6 +342,7 @@ export const zh: Record = { "org.agentRoster": "智能体名册", "org.newHireRequest": "新招聘申请", "org.editAgent": "编辑", + "org.editAgentTitle": "编辑 {name}({role})", "org.requestNewHire": "申请新招聘", "org.goalStack": "目标栈", "org.newGoal": "新目标", diff --git a/src/renderer/state/slices/selection.ts b/src/renderer/state/slices/selection.ts index 5b78d614..b9d9dfb0 100644 --- a/src/renderer/state/slices/selection.ts +++ b/src/renderer/state/slices/selection.ts @@ -6,7 +6,14 @@ export interface SelectionSlice { selectedConnectorId: string | null; selectedApprovalId: string | null; selectedRunId: string | null; + /** Highlighted agent (roster row / orgchart card). Navigation target. + * Does NOT control the Edit modal — see editingAgentId. */ selectedAgentId: string | null; + /** Agent whose Edit modal is currently open, or NEW_ENTITY_ID for the + * new-hire request modal. Only set by explicit user action (row click, + * card click, "Request new hire" button); never by navigation or + * onboarding defaults. Cleared on modal close. */ + editingAgentId: string | null; selectedGoalId: string | null; selectedProjectId: string | null; selectedWorkspaceId: string | null; @@ -16,6 +23,7 @@ export interface SelectionSlice { setSelectedApprovalId: (id: string | null) => void; setSelectedRunId: (id: string | null) => void; setSelectedAgentId: (id: string | null) => void; + setEditingAgentId: (id: string | null) => void; setSelectedGoalId: (id: string | null) => void; setSelectedProjectId: (id: string | null) => void; setSelectedWorkspaceId: (id: string | null) => void; @@ -34,6 +42,7 @@ export const createSelectionSlice: StateCreator< selectedApprovalId: null, selectedRunId: null, selectedAgentId: null, + editingAgentId: null, selectedGoalId: null, selectedProjectId: null, selectedWorkspaceId: null, @@ -58,6 +67,10 @@ export const createSelectionSlice: StateCreator< set((state) => { state.selectedAgentId = id; }), + setEditingAgentId: (id) => + set((state) => { + state.editingAgentId = id; + }), setSelectedGoalId: (id) => set((state) => { state.selectedGoalId = id; @@ -80,6 +93,7 @@ export const createSelectionSlice: StateCreator< state.selectedApprovalId = null; state.selectedRunId = null; state.selectedAgentId = null; + state.editingAgentId = null; state.selectedGoalId = null; state.selectedProjectId = null; state.selectedWorkspaceId = null; diff --git a/src/renderer/views/sections/OrganizationSections.tsx b/src/renderer/views/sections/OrganizationSections.tsx index 8fa0b104..dd6cf631 100644 --- a/src/renderer/views/sections/OrganizationSections.tsx +++ b/src/renderer/views/sections/OrganizationSections.tsx @@ -35,7 +35,7 @@ export function OrganizationSections({ section }: OrganizationSectionsProps) { companyGoals, companyProjects, companyWorkspaces, - selectedAgent, + editingAgent, selectedGoal, selectedProject, } = useSectionContext(); @@ -43,53 +43,67 @@ export function OrganizationSections({ section }: OrganizationSectionsProps) { const selectedAgentId = useAppStore((s) => s.selectedAgentId); const setSelectedAgentId = useAppStore((s) => s.setSelectedAgentId); + const editingAgentId = useAppStore((s) => s.editingAgentId); + const setEditingAgentId = useAppStore((s) => s.setEditingAgentId); const selectedGoalId = useAppStore((s) => s.selectedGoalId); const setSelectedGoalId = useAppStore((s) => s.setSelectedGoalId); const selectedProjectId = useAppStore((s) => s.selectedProjectId); const setSelectedProjectId = useAppStore((s) => s.setSelectedProjectId); const setSection = useAppStore((s) => s.setSection); + // Open the Edit modal on row / card click. `selectedAgentId` is updated + // alongside so the roster highlight follows the user's last interaction + // even after the modal closes. + const openAgentEditor = (id: string) => { + setSelectedAgentId(id); + setEditingAgentId(id); + }; + if (!snapshot || !currentCompany) return null; return ( <> {section === "agents" ? ( <> - setSelectedAgentId(id)} /> - setSelectedAgentId(NEW_ENTITY_ID)} />}> + + setEditingAgentId(NEW_ENTITY_ID)} />}> - setSelectedAgentId(null)}> + setEditingAgentId(null)}> { - setSelectedAgentId(null); + setEditingAgentId(null); setSection("hiring"); await refresh(); }} /> - setSelectedAgentId(null)}> - {selectedAgent ? ( + setEditingAgentId(null)} + > + {editingAgent ? ( setSelectedAgentId(null)} - onDeleted={async () => { setSelectedAgentId(null); await refresh(); }} + onCancel={() => setEditingAgentId(null)} + onDeleted={async () => { setEditingAgentId(null); await refresh(); }} /> ) : null}