Add deadline on task
Signed-off-by: Andreas Reußner <andreas.reussner@outlook.de>
This commit is contained in:
committed by
Sacha Al Himdani
parent
02ff3b02d9
commit
fc008c27f4
@@ -109,6 +109,7 @@ import { MeasureViewRisksQuery } from "./__generated__/MeasureViewRisksQuery.gra
|
||||
import { MeasureViewDeleteMeasureMutation } from "./__generated__/MeasureViewDeleteMeasureMutation.graphql";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import { format, formatISO, parseISO } from "date-fns";
|
||||
|
||||
// Function to format ISO8601 duration to human-readable format
|
||||
const formatDuration = (isoDuration: string): string => {
|
||||
@@ -181,6 +182,7 @@ const measureViewQuery = graphql`
|
||||
description
|
||||
state
|
||||
timeEstimate
|
||||
deadline
|
||||
assignedTo {
|
||||
id
|
||||
fullName
|
||||
@@ -218,6 +220,7 @@ const updateTaskStateMutation = graphql`
|
||||
id
|
||||
state
|
||||
timeEstimate
|
||||
deadline
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,6 +238,7 @@ const createTaskMutation = graphql`
|
||||
name
|
||||
description
|
||||
timeEstimate
|
||||
deadline
|
||||
state
|
||||
assignedTo {
|
||||
id
|
||||
@@ -743,6 +747,7 @@ function MeasureViewContent({
|
||||
const [isCreateTaskOpen, setIsCreateTaskOpen] = useState(false);
|
||||
const [newTaskName, setNewTaskName] = useState("");
|
||||
const [newTaskDescription, setNewTaskDescription] = useState("");
|
||||
const [newDeadline, setNewDeadline] = useState("");
|
||||
const [timeEstimateDays, setTimeEstimateDays] = useState("");
|
||||
const [timeEstimateHours, setTimeEstimateHours] = useState("");
|
||||
const [timeEstimateMinutes, setTimeEstimateMinutes] = useState("");
|
||||
@@ -991,6 +996,7 @@ function MeasureViewContent({
|
||||
name: newTaskName,
|
||||
description: newTaskDescription,
|
||||
timeEstimate: isoTimeEstimate === "" ? null : isoTimeEstimate,
|
||||
deadline: newDeadline === "" ? null : formatISO(newDeadline),
|
||||
},
|
||||
},
|
||||
onCompleted: () => {
|
||||
@@ -1004,6 +1010,7 @@ function MeasureViewContent({
|
||||
setTimeEstimateHours("");
|
||||
setTimeEstimateMinutes("");
|
||||
setIsCreateTaskOpen(false);
|
||||
setNewDeadline("");
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
@@ -1718,9 +1725,11 @@ function MeasureViewContent({
|
||||
|
||||
// Add state variables for tracking edit mode and duration components
|
||||
const [isEditingDuration, setIsEditingDuration] = useState(false);
|
||||
const [isEditingDeadline, setIsEditingDeadline] = useState(false);
|
||||
const [editTimeEstimateDays, setEditTimeEstimateDays] = useState("");
|
||||
const [editTimeEstimateHours, setEditTimeEstimateHours] = useState("");
|
||||
const [editTimeEstimateMinutes, setEditTimeEstimateMinutes] = useState("");
|
||||
const [editDeadline, setEditDeadline] = useState("");
|
||||
|
||||
// Function to parse ISO duration string into components for editing
|
||||
const parseISODuration = useCallback(
|
||||
@@ -1750,6 +1759,40 @@ function MeasureViewContent({
|
||||
[]
|
||||
);
|
||||
|
||||
// Function to handle saving the updated deadline
|
||||
const handleSaveDeadline = useCallback(
|
||||
(taskId: string) => {
|
||||
const newDeadline = editDeadline === "" ? null : formatISO(editDeadline);
|
||||
updateTask({
|
||||
variables: {
|
||||
input: {
|
||||
taskId,
|
||||
deadline: newDeadline,
|
||||
},
|
||||
},
|
||||
onCompleted: () => {
|
||||
setIsEditingDeadline(false);
|
||||
|
||||
// Update the selected task state if it's the current task
|
||||
if (selectedTask && selectedTask.id === taskId) {
|
||||
setSelectedTask({
|
||||
...selectedTask,
|
||||
deadline: newDeadline,
|
||||
});
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: "Error updating task",
|
||||
description: error.message,
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
[editDeadline, updateTask, toast, selectedTask, setSelectedTask]
|
||||
);
|
||||
|
||||
// Function to handle saving the updated duration
|
||||
const handleSaveDuration = useCallback(
|
||||
(taskId: string) => {
|
||||
@@ -2605,6 +2648,11 @@ function MeasureViewContent({
|
||||
{formatDuration(task.timeEstimate)}
|
||||
</div>
|
||||
)}
|
||||
{task.deadline && (
|
||||
<div className="text-sm text-secondary">
|
||||
{formatDate(task.deadline)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3063,6 +3111,69 @@ function MeasureViewContent({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Deadline */}
|
||||
<div>
|
||||
<h3 className="text-sm font-medium text-secondary mb-2">
|
||||
Deadline
|
||||
</h3>
|
||||
{isEditingDeadline ? (
|
||||
<div className="space-y-2">
|
||||
<div className="flex gap-2">
|
||||
<div className="flex-1">
|
||||
<Input
|
||||
type="date"
|
||||
value={editDeadline}
|
||||
onChange={(e) =>
|
||||
setEditDeadline(e.target.value)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setIsEditingDeadline(false)}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => handleSaveDeadline(selectedTask.id)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
{selectedTask.deadline ? (
|
||||
<span>
|
||||
{formatDate(selectedTask.deadline)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-secondary">
|
||||
No deadline
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="p-1 h-auto"
|
||||
onClick={() => {
|
||||
const selectedDeadline = selectedTask.deadline ? format(selectedTask.deadline, 'yyyy-MM-dd') : "";
|
||||
setEditDeadline(selectedDeadline);
|
||||
setIsEditingDeadline(true);
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Evidence section */}
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
@@ -3846,6 +3957,15 @@ function MeasureViewContent({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid w-full items-center gap-1.5">
|
||||
<Label htmlFor="task-deadline">Deadline (optional)</Label>
|
||||
<Input
|
||||
id="task-deadline"
|
||||
type="date"
|
||||
value={newDeadline}
|
||||
onChange={(e) => setNewDeadline(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="mt-4">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<b53893b96884bbc49ad8f2dbdb22e2ea>>
|
||||
* @generated SignedSource<<d258cc7c047ea5b1e81d5ef895e63ac6>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
|
||||
export type TaskState = "DONE" | "TODO";
|
||||
export type CreateTaskInput = {
|
||||
assignedToId?: string | null | undefined;
|
||||
deadline?: string | null | undefined;
|
||||
description: string;
|
||||
measureId?: string | null | undefined;
|
||||
name: string;
|
||||
@@ -31,6 +32,7 @@ export type MeasureViewCreateTaskMutation$data = {
|
||||
readonly id: string;
|
||||
readonly primaryEmailAddress: string;
|
||||
} | null | undefined;
|
||||
readonly deadline: string | null | undefined;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
@@ -108,6 +110,13 @@ v4 = {
|
||||
"name": "timeEstimate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deadline",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -213,16 +222,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "53b934e0e7a3d4abf8789ad8672687df",
|
||||
"cacheID": "8f9aeb0df92f9535d728ef27a7dee963",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureViewCreateTaskMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureViewCreateTaskMutation(\n $input: CreateTaskInput!\n) {\n createTask(input: $input) {\n taskEdge {\n node {\n id\n name\n description\n timeEstimate\n state\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n }\n}\n"
|
||||
"text": "mutation MeasureViewCreateTaskMutation(\n $input: CreateTaskInput!\n) {\n createTask(input: $input) {\n taskEdge {\n node {\n id\n name\n description\n timeEstimate\n deadline\n state\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "0df98f5aee4233dc4ffedcff8256891a";
|
||||
(node as any).hash = "f323b5caa0912478e715f0c409898eff";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<03d8e2eca1cc7ffaf797c66ef7fa11c1>>
|
||||
* @generated SignedSource<<a6d5ebf3d09595b1da2cd16746fa1163>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -48,6 +48,7 @@ export type MeasureViewQuery$data = {
|
||||
readonly id: string;
|
||||
readonly primaryEmailAddress: string;
|
||||
} | null | undefined;
|
||||
readonly deadline: string | null | undefined;
|
||||
readonly description: string;
|
||||
readonly evidences: {
|
||||
readonly __id: string;
|
||||
@@ -261,6 +262,13 @@ v12 = {
|
||||
"storageKey": null
|
||||
},
|
||||
v13 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deadline",
|
||||
"storageKey": null
|
||||
},
|
||||
v14 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
@@ -286,14 +294,14 @@ v13 = {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v14 = [
|
||||
v15 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
v15 = [
|
||||
v16 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
@@ -363,6 +371,7 @@ return {
|
||||
(v5/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/),
|
||||
(v14/*: any*/),
|
||||
{
|
||||
"alias": "evidences",
|
||||
"args": null,
|
||||
@@ -422,7 +431,7 @@ return {
|
||||
(v6/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v14/*: any*/),
|
||||
"args": (v15/*: any*/),
|
||||
"concreteType": "EvidenceConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "evidences",
|
||||
@@ -432,7 +441,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v14/*: any*/),
|
||||
"args": (v15/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "MeasureView_evidences",
|
||||
@@ -441,7 +450,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v14/*: any*/),
|
||||
"args": (v15/*: any*/),
|
||||
"concreteType": "TaskConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "tasks",
|
||||
@@ -469,9 +478,10 @@ return {
|
||||
(v5/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/),
|
||||
(v14/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v15/*: any*/),
|
||||
"args": (v16/*: any*/),
|
||||
"concreteType": "EvidenceConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "evidences",
|
||||
@@ -481,7 +491,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v15/*: any*/),
|
||||
"args": (v16/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "MeasureView_task_evidences",
|
||||
@@ -503,7 +513,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v14/*: any*/),
|
||||
"args": (v15/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "MeasureView_tasks",
|
||||
@@ -520,7 +530,7 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "d3e4d9723d12bce8158b83eb76d05a90",
|
||||
"cacheID": "2693fa3e0141f58235566f539194fcd6",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -552,11 +562,11 @@ return {
|
||||
},
|
||||
"name": "MeasureViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query MeasureViewQuery(\n $measureId: ID!\n) {\n measure: node(id: $measureId) {\n __typename\n id\n ... on Measure {\n name\n description\n state\n category\n evidences(first: 100) {\n edges {\n node {\n id\n mimeType\n filename\n size\n state\n type\n url\n createdAt\n description\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n tasks(first: 100) {\n edges {\n node {\n id\n name\n description\n state\n timeEstimate\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n evidences(first: 50) {\n edges {\n node {\n id\n mimeType\n filename\n size\n state\n type\n url\n createdAt\n description\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
"text": "query MeasureViewQuery(\n $measureId: ID!\n) {\n measure: node(id: $measureId) {\n __typename\n id\n ... on Measure {\n name\n description\n state\n category\n evidences(first: 100) {\n edges {\n node {\n id\n mimeType\n filename\n size\n state\n type\n url\n createdAt\n description\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n tasks(first: 100) {\n edges {\n node {\n id\n name\n description\n state\n timeEstimate\n deadline\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n evidences(first: 50) {\n edges {\n node {\n id\n mimeType\n filename\n size\n state\n type\n url\n createdAt\n description\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "288412cccb1f4c14b1852504e5536af1";
|
||||
(node as any).hash = "4e211c36d94ebd914b6de254dfbdf946";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<1595fa9771d6baa14534b181f4a1384a>>
|
||||
* @generated SignedSource<<28c68c446adeac27a47de2b754d48d5d>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -11,6 +11,7 @@
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type TaskState = "DONE" | "TODO";
|
||||
export type UpdateTaskInput = {
|
||||
deadline?: string | null | undefined;
|
||||
description?: string | null | undefined;
|
||||
name?: string | null | undefined;
|
||||
state?: TaskState | null | undefined;
|
||||
@@ -23,6 +24,7 @@ export type MeasureViewUpdateTaskStateMutation$variables = {
|
||||
export type MeasureViewUpdateTaskStateMutation$data = {
|
||||
readonly updateTask: {
|
||||
readonly task: {
|
||||
readonly deadline: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly state: TaskState;
|
||||
readonly timeEstimate: any | null | undefined;
|
||||
@@ -85,6 +87,13 @@ v1 = [
|
||||
"kind": "ScalarField",
|
||||
"name": "timeEstimate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deadline",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -111,16 +120,16 @@ return {
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "f545a0b12edb8f231a1a7a7c38b6e905",
|
||||
"cacheID": "a0001fad3af2ba3fc16a1f0af4f19370",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureViewUpdateTaskStateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureViewUpdateTaskStateMutation(\n $input: UpdateTaskInput!\n) {\n updateTask(input: $input) {\n task {\n id\n state\n timeEstimate\n }\n }\n}\n"
|
||||
"text": "mutation MeasureViewUpdateTaskStateMutation(\n $input: UpdateTaskInput!\n) {\n updateTask(input: $input) {\n task {\n id\n state\n timeEstimate\n deadline\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "e1d67c030523e56d6bcd595c27fcb3dc";
|
||||
(node as any).hash = "b3b0d47e0632b106b6313edbd2de38ce";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Suspense, useEffect, useState } from "react";
|
||||
import {ChangeEvent, Suspense, useEffect, useState} from "react";
|
||||
import {
|
||||
useQueryLoader,
|
||||
graphql,
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { ListTaskViewOrganizationQuery } from "./__generated__/ListTaskViewOrganizationQuery.graphql";
|
||||
import {formatDate, parseISO} from "date-fns";
|
||||
|
||||
// Function to format ISO8601 duration to human-readable format
|
||||
const formatDuration = (isoDuration: string | null | undefined): string => {
|
||||
@@ -121,6 +122,7 @@ const createTaskMutation = graphql`
|
||||
description
|
||||
state
|
||||
timeEstimate
|
||||
deadline
|
||||
measure {
|
||||
id
|
||||
name
|
||||
@@ -164,6 +166,7 @@ const listTaskViewQuery = graphql`
|
||||
description
|
||||
state
|
||||
timeEstimate
|
||||
deadline
|
||||
measure {
|
||||
id
|
||||
name
|
||||
@@ -213,6 +216,7 @@ interface Task {
|
||||
description?: string;
|
||||
state: string;
|
||||
timeEstimate?: number | null;
|
||||
deadline?: string | null;
|
||||
assignedTo?: {
|
||||
id: string;
|
||||
fullName: string;
|
||||
@@ -273,6 +277,11 @@ function TaskCard({ task, onClick, onToggleState }: {
|
||||
{formatDuration(task.timeEstimate.toString())}
|
||||
</span>
|
||||
)}
|
||||
{task.deadline && (
|
||||
<span className="text-xs text-gray-500">
|
||||
{formatDate(task.deadline, "dd MMM yyyy")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{task.parent && (
|
||||
<div className="flex items-center gap-1 text-sm text-gray-500">
|
||||
@@ -346,6 +355,8 @@ function ListTaskContent({
|
||||
const [selectedMeasure, setSelectedMeasure] = useState<{id: string, name: string} | null>(null);
|
||||
const [timeEstimate, setTimeEstimate] = useState<number | null>(null);
|
||||
const [timeUnit, setTimeUnit] = useState<"minutes" | "hours" | "days" | "weeks">("hours");
|
||||
const [deadlineString, setDeadlineString] = useState<string>('');
|
||||
const [deadline, setDeadline] = useState<Date | null>(null);
|
||||
|
||||
// Create task mutation
|
||||
const [createTask, isCreatingTask] = useMutation(createTaskMutation);
|
||||
@@ -382,6 +393,19 @@ function ListTaskContent({
|
||||
}
|
||||
}, [environment, organization?.id]);
|
||||
|
||||
// Parse deadline string into Date-object
|
||||
const handleDeadlineChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const value = event.target.value;
|
||||
setDeadlineString(value);
|
||||
|
||||
if (value) {
|
||||
const date = parseISO(value);
|
||||
setDeadline(date);
|
||||
} else {
|
||||
setDeadline(null)
|
||||
}
|
||||
};
|
||||
|
||||
// Filter measures based on search query
|
||||
const filteredMeasures = measures.filter(measure =>
|
||||
measure.name.toLowerCase().includes(measureSearchQuery.toLowerCase()) ||
|
||||
@@ -439,6 +463,7 @@ function ListTaskContent({
|
||||
measureId: selectedMeasure?.id || null,
|
||||
assignedToId: assignee?.id,
|
||||
timeEstimate: formattedTimeEstimate,
|
||||
deadline: deadline
|
||||
},
|
||||
connections: [data.node?.tasks?.__id || ""],
|
||||
},
|
||||
@@ -462,6 +487,8 @@ function ListTaskContent({
|
||||
setTimeEstimate(null);
|
||||
setTimeUnit("hours");
|
||||
setMeasureSearchQuery("");
|
||||
setDeadlineString('');
|
||||
setDeadline(null);
|
||||
};
|
||||
|
||||
// Get initials from name
|
||||
@@ -825,6 +852,15 @@ function ListTaskContent({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Deadline */}
|
||||
<div className="flex justify-between items-center broder-b border-[rgba(2,42,2,0.08)] py-3">
|
||||
<Label className="text-sm font-medium text-gray-500">Deadline</Label>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Input type="date" value={deadlineString} onChange={handleDeadlineChange}
|
||||
className="text-sm font-medium bg-[rgba(0,39,0,0.05)] px-[10px] py-[6px] rounded-lg"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<84a35602a155b0f1fa8504cf32c10932>>
|
||||
* @generated SignedSource<<a4c4d53df4bc73d2bdc48ef0eb38a500>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
|
||||
export type TaskState = "DONE" | "TODO";
|
||||
export type CreateTaskInput = {
|
||||
assignedToId?: string | null | undefined;
|
||||
deadline?: string | null | undefined;
|
||||
description: string;
|
||||
measureId?: string | null | undefined;
|
||||
name: string;
|
||||
@@ -30,6 +31,7 @@ export type ListTaskViewCreateTaskMutation$data = {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
} | null | undefined;
|
||||
readonly deadline: string | null | undefined;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly measure: {
|
||||
@@ -119,6 +121,13 @@ v5 = {
|
||||
"name": "timeEstimate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deadline",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -223,16 +232,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "7b9680f637411402ff51239a43b44a14",
|
||||
"cacheID": "6fe245ddb913332138beda8377ebd88c",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListTaskViewCreateTaskMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation ListTaskViewCreateTaskMutation(\n $input: CreateTaskInput!\n) {\n createTask(input: $input) {\n taskEdge {\n node {\n id\n name\n description\n state\n timeEstimate\n measure {\n id\n name\n }\n assignedTo {\n id\n fullName\n }\n }\n }\n }\n}\n"
|
||||
"text": "mutation ListTaskViewCreateTaskMutation(\n $input: CreateTaskInput!\n) {\n createTask(input: $input) {\n taskEdge {\n node {\n id\n name\n description\n state\n timeEstimate\n deadline\n measure {\n id\n name\n }\n assignedTo {\n id\n fullName\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "43ccaf49d31ec84dcf3b6b3f2e3a851c";
|
||||
(node as any).hash = "934ee4a5b5bfd4c9e9c4acab49d11304";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<7732676a00f7ed0f6817555b68540aca>>
|
||||
* @generated SignedSource<<14a914bdd269eb18124d002d2c61a5b9>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -25,6 +25,7 @@ export type ListTaskViewQuery$data = {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
} | null | undefined;
|
||||
readonly deadline: string | null | undefined;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly measure: {
|
||||
@@ -120,6 +121,13 @@ v5 = [
|
||||
"name": "timeEstimate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deadline",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -301,7 +309,7 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "52b577b08c305249855293949d6e2339",
|
||||
"cacheID": "7519a481d7930f14c53c8c1a72d66f58",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -318,11 +326,11 @@ return {
|
||||
},
|
||||
"name": "ListTaskViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ListTaskViewQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n name\n tasks(first: 100) {\n edges {\n node {\n id\n name\n description\n state\n timeEstimate\n measure {\n id\n name\n }\n assignedTo {\n id\n fullName\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
"text": "query ListTaskViewQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n name\n tasks(first: 100) {\n edges {\n node {\n id\n name\n description\n state\n timeEstimate\n deadline\n measure {\n id\n name\n }\n assignedTo {\n id\n fullName\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5ca091444c547744068f2b2a83cb31df";
|
||||
(node as any).hash = "52b99d58a5b95dadd4e66bfad588d924";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<7098e326d01cc6831f293726096a7275>>
|
||||
* @generated SignedSource<<c0e5d40aeab42e5f50cf93b75ddb7328>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -11,6 +11,7 @@
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type TaskState = "DONE" | "TODO";
|
||||
export type UpdateTaskInput = {
|
||||
deadline?: string | null | undefined;
|
||||
description?: string | null | undefined;
|
||||
name?: string | null | undefined;
|
||||
state?: TaskState | null | undefined;
|
||||
|
||||
Reference in New Issue
Block a user