task-atoms.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /**
  2. * Jotai atoms for task state management.
  3. * Manages task data, loading states, filters, and errors.
  4. */
  5. import { atom } from 'jotai';
  6. /**
  7. * Task status enum
  8. */
  9. export type TaskStatus = 'pending' | 'in_progress' | 'completed';
  10. /**
  11. * Task interface matching backend API response
  12. */
  13. export interface Task {
  14. id: string;
  15. project_id: string;
  16. name: string;
  17. data: Record<string, any>;
  18. status: TaskStatus;
  19. assigned_to: string | null;
  20. created_at: string;
  21. progress: number;
  22. }
  23. /**
  24. * Task filter interface
  25. */
  26. export interface TaskFilter {
  27. status: TaskStatus | null;
  28. projectId: string | null;
  29. assignedTo: string | null;
  30. }
  31. /**
  32. * Atom storing the list of all tasks
  33. */
  34. export const tasksAtom = atom<Task[]>([]);
  35. /**
  36. * Atom storing the currently selected task
  37. */
  38. export const currentTaskAtom = atom<Task | null>(null);
  39. /**
  40. * Atom tracking task loading state
  41. */
  42. export const taskLoadingAtom = atom<boolean>(false);
  43. /**
  44. * Atom storing task-related errors
  45. */
  46. export const taskErrorAtom = atom<string | null>(null);
  47. /**
  48. * Atom storing task filter criteria
  49. */
  50. export const taskFilterAtom = atom<TaskFilter>({
  51. status: null,
  52. projectId: null,
  53. assignedTo: null,
  54. });
  55. /**
  56. * Derived atom to get filtered tasks
  57. */
  58. export const filteredTasksAtom = atom((get) => {
  59. const tasks = get(tasksAtom);
  60. const filter = get(taskFilterAtom);
  61. return tasks.filter((task) => {
  62. if (filter.status && task.status !== filter.status) {
  63. return false;
  64. }
  65. if (filter.projectId && task.project_id !== filter.projectId) {
  66. return false;
  67. }
  68. if (filter.assignedTo && task.assigned_to !== filter.assignedTo) {
  69. return false;
  70. }
  71. return true;
  72. });
  73. });
  74. /**
  75. * Derived atom to get task by ID
  76. */
  77. export const getTaskByIdAtom = atom(
  78. (get) => (taskId: string) => {
  79. const tasks = get(tasksAtom);
  80. return tasks.find((t) => t.id === taskId) || null;
  81. }
  82. );
  83. /**
  84. * Derived atom to get tasks by project ID
  85. */
  86. export const getTasksByProjectIdAtom = atom(
  87. (get) => (projectId: string) => {
  88. const tasks = get(tasksAtom);
  89. return tasks.filter((t) => t.project_id === projectId);
  90. }
  91. );
  92. /**
  93. * Derived atom to check if tasks are empty
  94. */
  95. export const hasTasksAtom = atom((get) => {
  96. const tasks = get(tasksAtom);
  97. return tasks.length > 0;
  98. });