Fix project list empty (#335)
* Move all fetch project actions to layout * fixup! Move all fetch project actions to layout
This commit is contained in:
parent
a336653e23
commit
17cba48ef8
6 changed files with 45 additions and 86 deletions
|
|
@ -89,8 +89,20 @@ const Layout: React.FC<LayoutProps> = ({
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Layout no longer loads global data
|
||||
}, []);
|
||||
// Load projects into global store if not already loaded
|
||||
const loadProjects = async () => {
|
||||
if (projects.length === 0 && !isProjectsLoading) {
|
||||
try {
|
||||
const projectsData = await fetchProjects();
|
||||
setProjects(projectsData);
|
||||
} catch (error) {
|
||||
console.error('Failed to load projects in Layout:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loadProjects();
|
||||
}, [projects.length, isProjectsLoading, setProjects]);
|
||||
|
||||
const openNoteModal = (note: Note | null = null) => {
|
||||
setSelectedNote(note);
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ import {
|
|||
deleteNote as apiDeleteNote,
|
||||
updateNote as apiUpdateNote,
|
||||
} from '../../utils/notesService';
|
||||
import { createProject, fetchProjects } from '../../utils/projectsService';
|
||||
import { Project } from '../../entities/Project';
|
||||
import { createProject } from '../../utils/projectsService';
|
||||
import { useStore } from '../../store/useStore';
|
||||
|
||||
const NoteDetails: React.FC = () => {
|
||||
const { uidSlug } = useParams<{ uidSlug: string }>();
|
||||
|
|
@ -27,7 +27,8 @@ const NoteDetails: React.FC = () => {
|
|||
const [noteToDelete, setNoteToDelete] = useState<Note | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isError, setIsError] = useState(false);
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const projects = useStore((state: any) => state.projectsStore.projects);
|
||||
const { setProjects } = useStore((state: any) => state.projectsStore);
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Dispatch global modal events
|
||||
|
|
@ -51,18 +52,7 @@ const NoteDetails: React.FC = () => {
|
|||
fetchNote();
|
||||
}, [uidSlug]);
|
||||
|
||||
// Load projects for the modal
|
||||
useEffect(() => {
|
||||
const loadProjects = async () => {
|
||||
try {
|
||||
const fetchedProjects = await fetchProjects('all', '');
|
||||
setProjects(fetchedProjects);
|
||||
} catch (error) {
|
||||
console.error('Error loading projects:', error);
|
||||
}
|
||||
};
|
||||
loadProjects();
|
||||
}, []);
|
||||
// Projects are now loaded by Layout component into global store
|
||||
|
||||
const handleDeleteNote = async () => {
|
||||
if (!noteToDelete) return;
|
||||
|
|
@ -101,7 +91,7 @@ const NoteDetails: React.FC = () => {
|
|||
name,
|
||||
priority: 'low',
|
||||
});
|
||||
setProjects((prev) => [...prev, newProject]);
|
||||
setProjects([...projects, newProject]);
|
||||
return newProject;
|
||||
} catch (error) {
|
||||
console.error('Error creating project:', error);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
deleteNote as apiDeleteNote,
|
||||
} from '../utils/notesService';
|
||||
import { useStore } from '../store/useStore';
|
||||
import { createProject, fetchProjects } from '../utils/projectsService';
|
||||
import { createProject } from '../utils/projectsService';
|
||||
|
||||
const Notes: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
|
|
@ -28,7 +28,6 @@ const Notes: React.FC = () => {
|
|||
const { notes, isLoading, isError, hasLoaded, loadNotes, setNotes } =
|
||||
useStore((state) => state.notesStore);
|
||||
const projects = useStore((state) => state.projectsStore.projects);
|
||||
const { setProjects } = useStore((state) => state.projectsStore);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasLoaded && !isLoading && !isError) {
|
||||
|
|
@ -36,20 +35,7 @@ const Notes: React.FC = () => {
|
|||
}
|
||||
}, [hasLoaded, isLoading, isError, loadNotes]);
|
||||
|
||||
// Load projects if not available - force load every time for debugging
|
||||
useEffect(() => {
|
||||
const loadProjectsIfNeeded = async () => {
|
||||
try {
|
||||
// Fetch all projects (active and inactive)
|
||||
const fetchedProjects = await fetchProjects('all', '');
|
||||
setProjects(fetchedProjects);
|
||||
} catch (error) {
|
||||
console.error('Error loading projects:', error);
|
||||
}
|
||||
};
|
||||
|
||||
loadProjectsIfNeeded();
|
||||
}, []); // Remove dependencies to force it to run once
|
||||
// Projects are now loaded by Layout component into global store
|
||||
|
||||
// Sort options for notes
|
||||
const sortOptions: SortOption[] = [
|
||||
|
|
|
|||
|
|
@ -118,19 +118,7 @@ const Projects: React.FC = () => {
|
|||
loadAreas();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const loadProjects = async () => {
|
||||
try {
|
||||
const projectsData = await fetchProjects();
|
||||
setProjects(projectsData);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch projects:', error);
|
||||
setProjectsError(true);
|
||||
}
|
||||
};
|
||||
|
||||
loadProjects();
|
||||
}, []);
|
||||
// Projects are now loaded by Layout component into global store
|
||||
|
||||
// Modal state tracking removed after fixing the issue
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import TaskList from '../Task/TaskList';
|
|||
import ProjectItem from '../Project/ProjectItem';
|
||||
|
||||
import { Tag } from '../../entities/Tag';
|
||||
import { useStore } from '../../store/useStore';
|
||||
|
||||
const TagDetails: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
|
|
@ -23,10 +24,19 @@ const TagDetails: React.FC = () => {
|
|||
const [tag, setTag] = useState<Tag | null>(null);
|
||||
const [tasks, setTasks] = useState<Task[]>([]);
|
||||
const [notes, setNotes] = useState<Note[]>([]);
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const allProjects = useStore((state: any) => state.projectsStore.projects);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// Filter projects by current tag
|
||||
const projects = allProjects.filter(
|
||||
(project: any) =>
|
||||
project.tags &&
|
||||
project.tags.some(
|
||||
(projectTag: any) => projectTag.name === tag?.name
|
||||
)
|
||||
);
|
||||
|
||||
// State for ProjectItem components
|
||||
const [activeDropdown, setActiveDropdown] = useState<number | null>(null);
|
||||
const [hoveredNoteId, setHoveredNoteId] = useState<number | null>(null);
|
||||
|
|
@ -45,16 +55,10 @@ const TagDetails: React.FC = () => {
|
|||
setTag(tagData);
|
||||
|
||||
// Now fetch entities that have this tag using the tag name
|
||||
const [tasksResponse, notesResponse, projectsResponse] =
|
||||
await Promise.all([
|
||||
fetch(
|
||||
`/api/tasks?tag=${encodeURIComponent(tagData.name)}`
|
||||
),
|
||||
fetch(
|
||||
`/api/notes?tag=${encodeURIComponent(tagData.name)}`
|
||||
),
|
||||
fetch(`/api/projects`), // Projects API doesn't support tag filtering yet
|
||||
]);
|
||||
const [tasksResponse, notesResponse] = await Promise.all([
|
||||
fetch(`/api/tasks?tag=${encodeURIComponent(tagData.name)}`),
|
||||
fetch(`/api/notes?tag=${encodeURIComponent(tagData.name)}`),
|
||||
]);
|
||||
|
||||
if (tasksResponse.ok) {
|
||||
const tasksData = await tasksResponse.json();
|
||||
|
|
@ -66,20 +70,7 @@ const TagDetails: React.FC = () => {
|
|||
setNotes(notesData || []);
|
||||
}
|
||||
|
||||
if (projectsResponse.ok) {
|
||||
const projectsData = await projectsResponse.json();
|
||||
// Filter projects client-side since API doesn't support tag filtering
|
||||
const allProjects =
|
||||
projectsData.projects || projectsData || [];
|
||||
const filteredProjects = allProjects.filter(
|
||||
(project: any) =>
|
||||
project.tags &&
|
||||
project.tags.some(
|
||||
(tag: any) => tag.name === tagData.name
|
||||
)
|
||||
);
|
||||
setProjects(filteredProjects);
|
||||
}
|
||||
// Projects are now filtered from global store
|
||||
} catch {
|
||||
setError(t('tags.error'));
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import GroupedTaskList from './Task/GroupedTaskList';
|
|||
import NewTask from './Task/NewTask';
|
||||
import SortFilter from './Shared/SortFilter';
|
||||
import { Task } from '../entities/Task';
|
||||
import { Project } from '../entities/Project';
|
||||
import { getTitleAndIcon } from './Task/getTitleAndIcon';
|
||||
import { getDescription } from './Task/getDescription';
|
||||
import {
|
||||
|
|
@ -15,6 +14,7 @@ import {
|
|||
toggleTaskToday,
|
||||
GroupedTasks,
|
||||
} from '../utils/tasksService';
|
||||
import { useStore } from '../store/useStore';
|
||||
import { useToast } from './Shared/ToastContext';
|
||||
import { SortOption } from './Shared/SortFilterButton';
|
||||
import {
|
||||
|
|
@ -44,7 +44,7 @@ const Tasks: React.FC = () => {
|
|||
const { showSuccessToast } = useToast();
|
||||
const { isSidebarOpen } = useSidebar();
|
||||
const [tasks, setTasks] = useState<Task[]>([]);
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const projects = useStore((state: any) => state.projectsStore.projects);
|
||||
const [groupedTasks, setGroupedTasks] = useState<GroupedTasks | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
|
@ -184,12 +184,9 @@ const Tasks: React.FC = () => {
|
|||
|
||||
const searchParams = allTasksUrl.toString();
|
||||
|
||||
const [tasksResponse, projectsResponse] = await Promise.all([
|
||||
fetch(
|
||||
`/api/tasks?${searchParams}${tagId ? `&tag=${tagId}` : ''}`
|
||||
),
|
||||
fetch('/api/projects'),
|
||||
]);
|
||||
const tasksResponse = await fetch(
|
||||
`/api/tasks?${searchParams}${tagId ? `&tag=${tagId}` : ''}`
|
||||
);
|
||||
|
||||
if (tasksResponse.ok) {
|
||||
const tasksData = await tasksResponse.json();
|
||||
|
|
@ -199,12 +196,7 @@ const Tasks: React.FC = () => {
|
|||
throw new Error('Failed to fetch tasks.');
|
||||
}
|
||||
|
||||
if (projectsResponse.ok) {
|
||||
const projectsData = await projectsResponse.json();
|
||||
setProjects(projectsData?.projects || []);
|
||||
} else {
|
||||
throw new Error('Failed to fetch projects.');
|
||||
}
|
||||
// Projects are now loaded by Layout component into global store
|
||||
} catch (error) {
|
||||
setError((error as Error).message);
|
||||
} finally {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue