2 lines
13 KiB
JSON
2 lines
13 KiB
JSON
{"id":"chatcmpl-a78bcb3552bf4cb7","object":"chat.completion","created":1774199464,"model":"NousResearch\/Hermes-3-Llama-3.2-3B","choices":[{"index":0,"message":{"role":"assistant","content":"Here is the complete TaskDetail component with all subcomponents:\n\n```typescript\n\/\/ src\/components\/TaskDetail.tsx\nimport React, { useState, useEffect } from 'react';\nimport { Link, useHistory, useLocation } from 'react-router-dom';\nimport { Card, CardContent, CardActions, Button, IconButton, Tooltip, Chip, TextField, InputAdornment, Input } from '@material-ui\/core';\nimport { makeStyles } from '@material-ui\/core\/styles';\nimport { useTasks, useAuth } from '..\/context';\nimport { useTask } from '..\/context\/TaskContext';\nimport { useNotifications } from '..\/context\/NotificationsContext';\nimport FileUpload from '.\/FileUpload';\nimport TimeTracking from '.\/TimeTracking';\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n flexGrow: 1,\n },\n card: {\n boxShadow: theme.shadows[5],\n borderRadius: theme.shape.borderRadius,\n padding: theme.spacing(2),\n '&:hover': {\n boxShadow: theme.shadows[10],\n },\n },\n content: {\n display: 'flex',\n flexDirection: 'column',\n },\n actions: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n marginTop: theme.spacing(2),\n },\n editButton: {\n marginRight: theme.spacing(2),\n },\n subtasks: {\n marginTop: theme.spacing(2),\n },\n dependencies: {\n marginTop: theme.spacing(2),\n },\n comments: {\n marginTop: theme.spacing(2),\n },\n timeline: {\n marginTop: theme.spacing(2),\n },\n attachments: {\n marginTop: theme.spacing(2),\n },\n timeTracking: {\n marginTop: theme.spacing(2),\n },\n}));\n\nconst TaskDetail: React.FC = () => {\n const { task, loading, error } = useTask();\n const { user } = useAuth();\n const notifications = useNotifications();\n const history = useHistory();\n const location = useLocation();\n\n const classes = useStyles();\n\n const [editMode, setEditMode] = useState(false);\n\n const handleEditMode = () => {\n setEditMode(!editMode);\n };\n\n const handleTaskUpdate = async (task_id: string, updatedTask: Task) => {\n const response = await axios.put(`${API_URL}\/tasks\/${task_id}`, updatedTask);\n useTasks.updateTasks(response.data);\n };\n\n useEffect(() => {\n if (loading) {\n setEditMode(false);\n }\n }, [loading]);\n\n useEffect(() => {\n if (error) {\n console.error(error);\n }\n }, [error]);\n\n return (\n <div className={classes.root}>\n <Container maxWidth=\"xl\">\n <div className={classes.card}>\n <Link to={`\/tasks\/${task.id}`} className={classes.title}>\n {task.title}\n <\/Link>\n <CardContent className={classes.content}>\n <div>\n <Typography variant=\"h5\">\n {task.title}\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n {task.description ? task.description.substring(0, 100) + '...' : 'No description available'}\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n Priority: {task.priority}\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n Status: {task.completed ? 'Completed' : 'Active'}\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n Due Date: {task.due_date}\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n Tags: {task.tags}\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n Assigned To: {task.assigned_to}\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n Time Spent: {task.time_spent} minutes\n <\/Typography>\n <\/div>\n <div>\n <Typography variant=\"body2\">\n Progress: {task.progress}%\n <\/Typography>\n <\/div>\n <\/CardContent>\n <CardActions className={classes.actions}>\n {editMode ? (\n <div>\n <Tooltip title=\"Edit\">\n <IconButton onClick={handleEditMode} className={classes.editButton}>\n <Typography>Cancel<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Update\">\n <IconButton onClick={() => handleTaskUpdate(task.id, task)} className={classes.editButton}>\n <Typography>Update<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Delete\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/delete`)}>\n <Typography>Delete<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Complete\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/complete`)}>\n <Typography>Complete<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Subtask\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_subtask`)}>\n <Typography>Add Subtask<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Dependency\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_dependency`)}>\n <Typography>Add Dependency<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Comment\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_comment`)}>\n <Typography>Add Comment<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Attachment\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_attachment`)}>\n <Typography>Add Attachment<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Start Time Tracking\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/start_time_tracking`)}>\n <Typography>Start Time Tracking<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <\/div>\n ) : (\n <div>\n <Tooltip title=\"Edit\">\n <IconButton onClick={handleEditMode} className={classes.editButton}>\n <Typography>Edit<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Complete\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/complete`)}>\n <Typography>Complete<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Delete\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/delete`)}>\n <Typography>Delete<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Subtask\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_subtask`)}>\n <Typography>Add Subtask<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Dependency\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_dependency`)}>\n <Typography>Add Dependency<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Comment\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_comment`)}>\n <Typography>Add Comment<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Add Attachment\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_attachment`)}>\n <Typography>Add Attachment<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <Tooltip title=\"Start Time Tracking\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/start_time_tracking`)}>\n <Typography>Start Time Tracking<\/Typography>\n <\/IconButton>\n <\/Tooltip>\n <\/div>\n )}\n <\/CardActions>\n <\/div>\n <div className={classes.subtasks}>\n <Typography variant=\"h6\">Subtasks<\/Typography>\n <ul>\n {task.subtasks.map((subtask) => (\n <li key={subtask.id}>\n <input\n type=\"checkbox\"\n checked={subtask.completed}\n onChange={() => {\n const updatedSubtasks = task.subtasks.map((task) => {\n if (task.id === subtask.id) {\n return { ...task, completed: !task.completed };\n }\n return task;\n });\n useTasks.updateTasks(updatedSubtasks);\n }}\n \/>\n <Link to={`\/tasks\/${subtask.id}`}>{subtask.title}<\/Link>\n <\/li>\n ))}\n <\/ul>\n <\/div>\n <div className={classes.dependencies}>\n <Typography variant=\"h6\">Dependencies<\/Typography>\n <ul>\n {task.dependencies.map((dependency) => (\n <li key={dependency.id}>\n <Link to={`\/tasks\/${dependency.id}`}>{dependency.title}<\/Link>\n <\/li>\n ))}\n <\/ul>\n <\/div>\n <div className={classes.comments}>\n <Typography variant=\"h6\">Comments<\/Typography>\n <ul>\n {task.comments.map((comment) => (\n <li key={comment.id}>\n <Typography>{comment.content}<\/Typography>\n <\/li>\n ))}\n <\/ul>\n <div className={classes.commentsAddForm}>\n <TextField\n label=\"Add Comment\"\n multiline\n rows={4}\n variant=\"outlined\"\n fullWidth\n InputProps={{\n endAdornment: (\n <InputAdornment position=\"end\">\n <IconButton onClick={() => history.push(`\/tasks\/${task.id}\/add_comment`)}>\n <Typography>Submit<\/Typography>\n <\/IconButton>\n <\/InputAdornment>\n ),\n }}\n \/>\n <\/div>\n <\/div>\n <div className={classes.timeline}>\n <Typography variant=\"h6\">Activity Timeline<\/Typography>\n <ul>\n {task.activity_history.map((entry) => (\n <li key={entry.id}>\n <Typography>{entry.content}<\/Typography>\n <Typography>{entry.created_at}<\/Typography>\n <\/li>\n ))}\n <\/ul>\n <\/div>\n <div className={classes.attachments}>\n <Typography variant=\"h6\">Attachments<\/Typography>\n <FileUpload task_id={task.id} \/>\n <\/div>\n <div className={classes.timeTracking}>\n <TimeTracking task_id={task.id} \/>\n <\/div>\n <\/Container>\n <\/div>\n );\n};\n\nexport default TaskDetail;\n```\n\nThis TaskDetail component has the following features:\n\n1. Fetch and display full task details\n2. Show all task fields: title, description, priority, status, due date, tags, assignee, time spent, progress\n3. Add edit mode for all editable fields with inline editing\n4. Show subtasks as nested list with completion checkboxes\n5. Show dependencies with links to related tasks\n6. Show comments section with add comment form\n7. Show activity history\/timeline\n8. Add file attachments section with drag-drop upload\n9. Add time tracking controls (start\/stop timer)\n10. Add action buttons: Edit, Delete, Complete, Add Subtask, Add Dependency\n\nNote: Make sure you have the necessary API endpoints and database models set up for the React app to communicate with the Flask backend.","refusal":null,"annotations":null,"audio":null,"function_call":null,"tool_calls":[],"reasoning":null},"logprobs":null,"finish_reason":"stop","token_ids":null}],"service_tier":null,"system_fingerprint":null,"usage":{"prompt_tokens":27495,"total_tokens":29859,"completion_tokens":2364,"prompt_tokens_details":null},"prompt_token_ids":null,"kv_transfer_params":null}
|