- Introduced a new function `quoteMarkdown` to format task comments with markdown quotes for better readability. - Updated the `buildCommentNotificationMessage` to utilize `quoteMarkdown`, ensuring comments are displayed correctly. - Refactored member role detection across multiple services to use `isLeadMember` for consistency and clarity in identifying team leads. - Enhanced various components to improve handling of team member roles, ensuring accurate representation in UI and logic. - Adjusted tests to reflect changes in comment formatting and member role checks, improving overall reliability.
70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
/**
|
|
* Project slice - manages project list state and selection.
|
|
*/
|
|
|
|
import { api } from '@renderer/api';
|
|
|
|
import { getSessionResetState } from '../utils/stateResetHelpers';
|
|
|
|
import type { AppState } from '../types';
|
|
import type { Project } from '@renderer/types/data';
|
|
import type { StateCreator } from 'zustand';
|
|
|
|
// =============================================================================
|
|
// Slice Interface
|
|
// =============================================================================
|
|
|
|
export interface ProjectSlice {
|
|
// State
|
|
projects: Project[];
|
|
selectedProjectId: string | null;
|
|
projectsLoading: boolean;
|
|
projectsError: string | null;
|
|
|
|
// Actions
|
|
fetchProjects: () => Promise<void>;
|
|
selectProject: (id: string) => void;
|
|
}
|
|
|
|
// =============================================================================
|
|
// Slice Creator
|
|
// =============================================================================
|
|
|
|
export const createProjectSlice: StateCreator<AppState, [], [], ProjectSlice> = (set, get) => ({
|
|
// Initial state
|
|
projects: [],
|
|
selectedProjectId: null,
|
|
projectsLoading: false,
|
|
projectsError: null,
|
|
|
|
// Fetch all projects from main process
|
|
fetchProjects: async () => {
|
|
// Guard: prevent concurrent fetches (component mount + centralized init chain)
|
|
if (get().projectsLoading) return;
|
|
set({ projectsLoading: true, projectsError: null });
|
|
try {
|
|
const projects = await api.getProjects();
|
|
// Sort by most recent session (descending)
|
|
const sorted = [...projects].sort(
|
|
(a, b) => (b.mostRecentSession ?? 0) - (a.mostRecentSession ?? 0)
|
|
);
|
|
set({ projects: sorted, projectsLoading: false });
|
|
} catch (error) {
|
|
set({
|
|
projectsError: error instanceof Error ? error.message : 'Failed to fetch projects',
|
|
projectsLoading: false,
|
|
});
|
|
}
|
|
},
|
|
|
|
// Select a project and fetch its sessions (paginated)
|
|
selectProject: (id: string) => {
|
|
set({
|
|
selectedProjectId: id,
|
|
...getSessionResetState(),
|
|
});
|
|
|
|
// Fetch sessions for this project (paginated)
|
|
void get().fetchSessionsInitial(id);
|
|
},
|
|
});
|