add virtual groups for recent and frequent

This commit is contained in:
Sean Sube 2025-06-14 18:45:30 -05:00
parent ab70385bb3
commit 08c41fa0be
No known key found for this signature in database
GPG Key ID: 3EED7B957D362AF1
4 changed files with 84 additions and 7 deletions

View File

@ -80,4 +80,44 @@ export const GET_USERS = gql`
name name
} }
} }
`;
export const GET_RECENT_TASKS = gql`
query GetRecentTasks {
recentTasks {
id
name
group_id
print_count
last_printed_at
steps {
id
name
instructions
order
print_count
last_printed_at
}
}
}
`;
export const GET_FREQUENT_TASKS = gql`
query GetFrequentTasks {
frequentTasks {
id
name
group_id
print_count
last_printed_at
steps {
id
name
instructions
order
print_count
last_printed_at
}
}
}
`; `;

View File

@ -1,6 +1,6 @@
import { useState } from 'react'; import { useState } from 'react';
import { useQuery, useMutation } from '@apollo/client'; import { useQuery, useMutation } from '@apollo/client';
import { GET_GROUPS, GET_TASKS, GET_STEP } from '../graphql/queries'; import { GET_GROUPS, GET_TASKS, GET_STEP, GET_RECENT_TASKS, GET_FREQUENT_TASKS } from '../graphql/queries';
import { PRINT_TASK, PRINT_STEP, CREATE_NOTE, CREATE_GROUP, CREATE_TASK, CREATE_STEP } from '../graphql/mutations'; import { PRINT_TASK, PRINT_STEP, CREATE_NOTE, CREATE_GROUP, CREATE_TASK, CREATE_STEP } from '../graphql/mutations';
import type { GroupWithTasks, TaskWithSteps, StepWithNotes } from '../types'; import type { GroupWithTasks, TaskWithSteps, StepWithNotes } from '../types';
import { doesExist, isArray } from '../utils/typeGuards'; import { doesExist, isArray } from '../utils/typeGuards';
@ -120,6 +120,8 @@ export function useTaskData() {
variables: { id: selectedStep?.id }, variables: { id: selectedStep?.id },
skip: !selectedStep?.id, skip: !selectedStep?.id,
}); });
const { data: recentTasksData, loading: recentTasksLoading } = useQuery(GET_RECENT_TASKS);
const { data: frequentTasksData, loading: frequentTasksLoading } = useQuery(GET_FREQUENT_TASKS);
const [printTask] = useMutation(PRINT_TASK); const [printTask] = useMutation(PRINT_TASK);
const [printStep] = useMutation(PRINT_STEP); const [printStep] = useMutation(PRINT_STEP);
@ -224,6 +226,35 @@ export function useTaskData() {
? groupsData.groups.map((group: GraphQLGroup) => toGroupWithTasks(group)).filter(doesExist) ? groupsData.groups.map((group: GraphQLGroup) => toGroupWithTasks(group)).filter(doesExist)
: []; : [];
const recentTasks = isArray(recentTasksData?.recentTasks)
? recentTasksData.recentTasks.map((task: GraphQLTask) => toTaskWithSteps(task)).filter(doesExist)
: [];
const frequentTasks = isArray(frequentTasksData?.frequentTasks)
? frequentTasksData.frequentTasks.map((task: GraphQLTask) => toTaskWithSteps(task)).filter(doesExist)
: [];
// Create virtual groups for recent and frequent tasks
const virtualGroups: GroupWithTasks[] = [
{
id: -1, // Use negative IDs for virtual groups
name: 'Recent Tasks',
created_at: new Date(),
updated_at: new Date(),
tasks: recentTasks,
},
{
id: -2,
name: 'Frequent Tasks',
created_at: new Date(),
updated_at: new Date(),
tasks: frequentTasks,
},
];
// Combine virtual groups with regular groups
const allGroups = [...virtualGroups, ...groups];
const tasks = isArray(tasksData?.tasks) const tasks = isArray(tasksData?.tasks)
? tasksData.tasks.map((task: GraphQLTask) => toTaskWithSteps(task)).filter(doesExist) ? tasksData.tasks.map((task: GraphQLTask) => toTaskWithSteps(task)).filter(doesExist)
: []; : [];
@ -231,10 +262,10 @@ export function useTaskData() {
const step = stepData?.step ? toStepWithNotes(stepData.step) : undefined; const step = stepData?.step ? toStepWithNotes(stepData.step) : undefined;
return { return {
groups, groups: allGroups,
tasks, tasks,
step, step,
loading: groupsLoading || tasksLoading || stepLoading, loading: groupsLoading || tasksLoading || stepLoading || recentTasksLoading || frequentTasksLoading,
selectedGroup, selectedGroup,
selectedTask, selectedTask,
selectedStep, selectedStep,

View File

@ -29,6 +29,8 @@ export function DesktopLayout({
<Typography variant="h6">Groups</Typography> <Typography variant="h6">Groups</Typography>
<CreateButtons type="group" /> <CreateButtons type="group" />
</Box> </Box>
{/* Groups List */}
{groups.map((group) => ( {groups.map((group) => (
<Box <Box
key={group.id} key={group.id}
@ -50,7 +52,7 @@ export function DesktopLayout({
<Box sx={{ width: 250, borderRight: 1, borderColor: 'divider', p: 2 }}> <Box sx={{ width: 250, borderRight: 1, borderColor: 'divider', p: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}> <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6">Tasks</Typography> <Typography variant="h6">Tasks</Typography>
<CreateButtons type="task" parentId={String(selectedGroup.id)} /> {selectedGroup.id > 0 && <CreateButtons type="task" parentId={String(selectedGroup.id)} />}
</Box> </Box>
{selectedGroup.tasks.map((task) => ( {selectedGroup.tasks.map((task) => (
<Box <Box

View File

@ -8,11 +8,11 @@ function isGroupView(selectedGroup?: GroupWithTasks) {
} }
function isTaskView(selectedGroup?: GroupWithTasks, selectedTask?: TaskWithSteps) { function isTaskView(selectedGroup?: GroupWithTasks, selectedTask?: TaskWithSteps) {
return !!selectedGroup && !selectedTask; return selectedGroup && !selectedTask;
} }
function isStepView(selectedTask?: TaskWithSteps, selectedStep?: StepWithNotes) { function isStepView(selectedTask?: TaskWithSteps, selectedStep?: StepWithNotes) {
return !!selectedTask && !selectedStep; return selectedTask && !selectedStep;
} }
export function MobileLayout({ export function MobileLayout({
@ -76,12 +76,16 @@ export function MobileLayout({
<Typography variant="h6">Groups</Typography> <Typography variant="h6">Groups</Typography>
<CreateButtons type="group" /> <CreateButtons type="group" />
</Box> </Box>
{/* Groups List */}
{groupList.map((group) => ( {groupList.map((group) => (
<Box <Box
key={group.id} key={group.id}
sx={{ sx={{
p: 2, p: 2,
cursor: 'pointer', cursor: 'pointer',
bgcolor: selectedGroup?.id === group.id ? 'action.selected' : 'transparent',
'&:hover': { bgcolor: 'action.hover' },
}} }}
onClick={() => onGroupSelect(group)} onClick={() => onGroupSelect(group)}
> >
@ -95,7 +99,7 @@ export function MobileLayout({
<> <>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}> <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6">Tasks</Typography> <Typography variant="h6">Tasks</Typography>
<CreateButtons type="task" parentId={String(selectedGroup?.id)} /> {selectedGroup.id > 0 && <CreateButtons type="task" parentId={String(selectedGroup.id)} />}
</Box> </Box>
<Box> <Box>
{taskList.map((task) => ( {taskList.map((task) => (