2020-06-23 23:55:17 +02:00
|
|
|
// LOC830
|
2020-06-13 00:21:58 +02:00
|
|
|
import React, { useState, useRef, useContext, useEffect } from 'react';
|
2020-06-23 22:20:53 +02:00
|
|
|
import { MENU_TYPES } from 'shared/components/TopNavbar';
|
2020-06-23 23:55:17 +02:00
|
|
|
import updateApolloCache from 'shared/utils/cache';
|
2020-06-23 22:20:53 +02:00
|
|
|
import GlobalTopNavbar, { ProjectPopup } from 'App/TopNavbar';
|
2020-06-24 03:46:45 +02:00
|
|
|
import styled, { css } from 'styled-components/macro';
|
2020-06-23 22:20:53 +02:00
|
|
|
import { Bolt, ToggleOn, Tags, CheckCircle, Sort, Filter } from 'shared/icons';
|
2020-05-27 02:53:31 +02:00
|
|
|
import { usePopup, Popup } from 'shared/components/PopupMenu';
|
2020-04-16 22:05:12 +02:00
|
|
|
import { useParams, Route, useRouteMatch, useHistory, RouteComponentProps } from 'react-router-dom';
|
2020-04-10 05:27:57 +02:00
|
|
|
import {
|
2020-06-19 01:12:15 +02:00
|
|
|
useSetTaskCompleteMutation,
|
2020-05-31 06:11:19 +02:00
|
|
|
useToggleTaskLabelMutation,
|
|
|
|
useUpdateProjectNameMutation,
|
2020-04-10 05:27:57 +02:00
|
|
|
useFindProjectQuery,
|
2020-06-19 01:12:15 +02:00
|
|
|
useUpdateTaskGroupNameMutation,
|
2020-04-10 05:27:57 +02:00
|
|
|
useUpdateTaskNameMutation,
|
2020-05-28 03:12:50 +02:00
|
|
|
useUpdateProjectLabelMutation,
|
2020-04-10 05:27:57 +02:00
|
|
|
useCreateTaskMutation,
|
2020-05-28 03:12:50 +02:00
|
|
|
useDeleteProjectLabelMutation,
|
2020-04-10 05:27:57 +02:00
|
|
|
useDeleteTaskMutation,
|
|
|
|
useUpdateTaskLocationMutation,
|
2020-04-11 04:53:03 +02:00
|
|
|
useUpdateTaskGroupLocationMutation,
|
2020-04-11 04:22:58 +02:00
|
|
|
useCreateTaskGroupMutation,
|
2020-04-11 21:24:45 +02:00
|
|
|
useDeleteTaskGroupMutation,
|
2020-04-20 05:02:55 +02:00
|
|
|
useUpdateTaskDescriptionMutation,
|
|
|
|
useAssignTaskMutation,
|
2020-05-27 02:53:31 +02:00
|
|
|
DeleteTaskDocument,
|
|
|
|
FindProjectDocument,
|
2020-05-27 23:18:50 +02:00
|
|
|
useCreateProjectLabelMutation,
|
2020-06-01 04:20:03 +02:00
|
|
|
useUnassignTaskMutation,
|
2020-06-19 01:12:15 +02:00
|
|
|
useUpdateTaskDueDateMutation,
|
2020-06-23 22:20:53 +02:00
|
|
|
FindProjectQuery,
|
2020-04-10 05:27:57 +02:00
|
|
|
} from 'shared/generated/graphql';
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-05-27 23:18:50 +02:00
|
|
|
import TaskAssignee from 'shared/components/TaskAssignee';
|
2020-04-10 04:40:22 +02:00
|
|
|
import QuickCardEditor from 'shared/components/QuickCardEditor';
|
2020-04-11 04:22:58 +02:00
|
|
|
import ListActions from 'shared/components/ListActions';
|
2020-04-13 00:45:51 +02:00
|
|
|
import MemberManager from 'shared/components/MemberManager';
|
|
|
|
import { LabelsPopup } from 'shared/components/PopupMenu/PopupMenu.stories';
|
2020-04-16 22:05:12 +02:00
|
|
|
import KanbanBoard from 'Projects/Project/KanbanBoard';
|
2020-05-31 06:11:19 +02:00
|
|
|
import SimpleLists from 'shared/components/Lists';
|
2020-05-27 02:53:31 +02:00
|
|
|
import { mixin } from 'shared/utils/styles';
|
|
|
|
import LabelManager from 'shared/components/PopupMenu/LabelManager';
|
|
|
|
import LabelEditor from 'shared/components/PopupMenu/LabelEditor';
|
|
|
|
import produce from 'immer';
|
2020-05-27 23:18:50 +02:00
|
|
|
import MiniProfile from 'shared/components/MiniProfile';
|
2020-05-28 03:12:50 +02:00
|
|
|
import Details from './Details';
|
2020-05-31 06:11:19 +02:00
|
|
|
import { useApolloClient } from '@apollo/react-hooks';
|
2020-06-01 04:20:03 +02:00
|
|
|
import UserIDContext from 'App/context';
|
2020-06-19 01:12:15 +02:00
|
|
|
import DueDateManager from 'shared/components/DueDateManager';
|
2020-05-28 03:12:50 +02:00
|
|
|
|
|
|
|
const getCacheData = (client: any, projectID: string) => {
|
2020-06-23 22:20:53 +02:00
|
|
|
const cacheData: FindProjectQuery = client.readQuery({
|
2020-05-28 03:12:50 +02:00
|
|
|
query: FindProjectDocument,
|
|
|
|
variables: {
|
|
|
|
projectId: projectID,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
return cacheData;
|
|
|
|
};
|
|
|
|
|
|
|
|
const writeCacheData = (client: any, projectID: string, cacheData: any, newData: any) => {
|
|
|
|
client.writeQuery({
|
|
|
|
query: FindProjectDocument,
|
|
|
|
variables: {
|
|
|
|
projectId: projectID,
|
|
|
|
},
|
|
|
|
data: { ...cacheData, findProject: newData },
|
|
|
|
});
|
|
|
|
};
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-04-16 22:05:12 +02:00
|
|
|
type TaskRouteProps = {
|
|
|
|
taskID: string;
|
|
|
|
};
|
2020-04-10 04:40:22 +02:00
|
|
|
|
|
|
|
interface QuickCardEditorState {
|
|
|
|
isOpen: boolean;
|
2020-06-24 03:08:48 +02:00
|
|
|
target: React.RefObject<HTMLElement> | null;
|
2020-05-31 06:51:22 +02:00
|
|
|
taskID: string | null;
|
|
|
|
taskGroupID: string | null;
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-04-10 18:31:29 +02:00
|
|
|
const TitleWrapper = styled.div`
|
|
|
|
margin-left: 38px;
|
|
|
|
margin-bottom: 15px;
|
|
|
|
`;
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
const Title = styled.span`
|
|
|
|
text-align: center;
|
|
|
|
font-size: 24px;
|
|
|
|
color: #fff;
|
|
|
|
`;
|
2020-05-27 23:18:50 +02:00
|
|
|
const ProjectMembers = styled.div`
|
|
|
|
display: flex;
|
|
|
|
padding-left: 4px;
|
|
|
|
padding-top: 4px;
|
|
|
|
align-items: center;
|
|
|
|
`;
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-05-27 02:53:31 +02:00
|
|
|
type LabelManagerEditorProps = {
|
2020-05-31 06:11:19 +02:00
|
|
|
labels: React.RefObject<Array<ProjectLabel>>;
|
|
|
|
taskLabels: null | React.RefObject<Array<TaskLabel>>;
|
2020-05-27 23:18:50 +02:00
|
|
|
projectID: string;
|
|
|
|
labelColors: Array<LabelColor>;
|
2020-05-31 06:11:19 +02:00
|
|
|
onLabelToggle?: (labelId: string) => void;
|
2020-05-27 02:53:31 +02:00
|
|
|
};
|
|
|
|
|
2020-05-31 06:11:19 +02:00
|
|
|
const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({
|
|
|
|
labels: labelsRef,
|
|
|
|
projectID,
|
|
|
|
labelColors,
|
|
|
|
onLabelToggle,
|
|
|
|
taskLabels: taskLabelsRef,
|
|
|
|
}) => {
|
2020-05-27 02:53:31 +02:00
|
|
|
const [currentLabel, setCurrentLabel] = useState('');
|
2020-05-28 03:12:50 +02:00
|
|
|
const [createProjectLabel] = useCreateProjectLabelMutation({
|
|
|
|
update: (client, newLabelData) => {
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
draftCache.findProject.labels.push({ ...newLabelData.data.createProjectLabel });
|
|
|
|
}),
|
|
|
|
{
|
|
|
|
projectId: projectID,
|
|
|
|
},
|
|
|
|
);
|
2020-05-28 03:12:50 +02:00
|
|
|
},
|
|
|
|
});
|
|
|
|
const [updateProjectLabel] = useUpdateProjectLabelMutation();
|
|
|
|
const [deleteProjectLabel] = useDeleteProjectLabelMutation({
|
|
|
|
update: (client, newLabelData) => {
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
draftCache.findProject.labels = cache.findProject.labels.filter(
|
|
|
|
label => label.id !== newLabelData.data.deleteProjectLabel.id,
|
|
|
|
);
|
|
|
|
}),
|
|
|
|
{ projectId: projectID },
|
|
|
|
);
|
2020-05-28 03:12:50 +02:00
|
|
|
},
|
|
|
|
});
|
|
|
|
const labels = labelsRef.current ? labelsRef.current : [];
|
2020-05-31 06:11:19 +02:00
|
|
|
const taskLabels = taskLabelsRef && taskLabelsRef.current ? taskLabelsRef.current : [];
|
|
|
|
const [currentTaskLabels, setCurrentTaskLabels] = useState(taskLabels);
|
|
|
|
console.log(taskLabels);
|
2020-06-24 03:16:17 +02:00
|
|
|
const { setTab, hidePopup } = usePopup();
|
2020-05-27 02:53:31 +02:00
|
|
|
return (
|
|
|
|
<>
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup title="Labels" tab={0} onClose={() => hidePopup()}>
|
2020-05-27 02:53:31 +02:00
|
|
|
<LabelManager
|
|
|
|
labels={labels}
|
2020-05-31 06:11:19 +02:00
|
|
|
taskLabels={currentTaskLabels}
|
2020-05-27 02:53:31 +02:00
|
|
|
onLabelCreate={() => {
|
|
|
|
setTab(2);
|
|
|
|
}}
|
|
|
|
onLabelEdit={labelId => {
|
|
|
|
setCurrentLabel(labelId);
|
|
|
|
setTab(1);
|
|
|
|
}}
|
|
|
|
onLabelToggle={labelId => {
|
2020-05-31 06:11:19 +02:00
|
|
|
if (onLabelToggle) {
|
|
|
|
if (currentTaskLabels.find(t => t.projectLabel.id === labelId)) {
|
|
|
|
setCurrentTaskLabels(currentTaskLabels.filter(t => t.projectLabel.id !== labelId));
|
|
|
|
} else {
|
|
|
|
const newProjectLabel = labels.find(l => l.id === labelId);
|
|
|
|
if (newProjectLabel) {
|
|
|
|
setCurrentTaskLabels([
|
|
|
|
...currentTaskLabels,
|
|
|
|
{ id: '', assignedDate: '', projectLabel: { ...newProjectLabel } },
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setCurrentLabel(labelId);
|
|
|
|
onLabelToggle(labelId);
|
|
|
|
} else {
|
|
|
|
setCurrentLabel(labelId);
|
|
|
|
setTab(1);
|
|
|
|
}
|
2020-05-27 02:53:31 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Popup>
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup onClose={() => hidePopup()} title="Edit label" tab={1}>
|
2020-05-27 02:53:31 +02:00
|
|
|
<LabelEditor
|
2020-05-27 23:18:50 +02:00
|
|
|
labelColors={labelColors}
|
2020-05-31 06:11:19 +02:00
|
|
|
label={labels.find(label => label.id === currentLabel) ?? null}
|
2020-05-28 03:12:50 +02:00
|
|
|
onLabelEdit={(projectLabelID, name, color) => {
|
|
|
|
if (projectLabelID) {
|
2020-05-31 06:11:19 +02:00
|
|
|
updateProjectLabel({ variables: { projectLabelID, labelColorID: color.id, name: name ?? '' } });
|
2020-05-28 03:12:50 +02:00
|
|
|
}
|
|
|
|
setTab(0);
|
|
|
|
}}
|
|
|
|
onLabelDelete={labelID => {
|
|
|
|
deleteProjectLabel({ variables: { projectLabelID: labelID } });
|
2020-05-27 02:53:31 +02:00
|
|
|
setTab(0);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Popup>
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup onClose={() => hidePopup()} title="Create new label" tab={2}>
|
2020-05-27 02:53:31 +02:00
|
|
|
<LabelEditor
|
2020-05-27 23:18:50 +02:00
|
|
|
labelColors={labelColors}
|
2020-05-27 02:53:31 +02:00
|
|
|
label={null}
|
|
|
|
onLabelEdit={(_labelId, name, color) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
createProjectLabel({ variables: { projectID, labelColorID: color.id, name: name ?? '' } });
|
2020-05-27 02:53:31 +02:00
|
|
|
setTab(0);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Popup>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
interface ProjectParams {
|
2020-05-28 03:12:50 +02:00
|
|
|
projectID: string;
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-05-31 06:51:22 +02:00
|
|
|
const initialQuickCardEditorState: QuickCardEditorState = {
|
|
|
|
taskID: null,
|
|
|
|
taskGroupID: null,
|
|
|
|
isOpen: false,
|
2020-06-24 03:08:48 +02:00
|
|
|
target: null,
|
2020-05-31 06:51:22 +02:00
|
|
|
};
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-05-27 23:18:50 +02:00
|
|
|
const ProjectBar = styled.div`
|
2020-05-27 02:53:31 +02:00
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
2020-06-23 22:20:53 +02:00
|
|
|
justify-content: space-between;
|
2020-05-27 02:53:31 +02:00
|
|
|
height: 40px;
|
|
|
|
padding: 0 12px;
|
|
|
|
`;
|
|
|
|
|
2020-05-27 23:18:50 +02:00
|
|
|
const ProjectActions = styled.div`
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
`;
|
|
|
|
|
2020-06-24 03:46:45 +02:00
|
|
|
const ProjectAction = styled.div<{ disabled?: boolean }>`
|
2020-05-27 02:53:31 +02:00
|
|
|
cursor: pointer;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
font-size: 15px;
|
2020-06-16 00:36:59 +02:00
|
|
|
color: rgba(${props => props.theme.colors.text.primary});
|
2020-05-27 02:53:31 +02:00
|
|
|
|
|
|
|
&:not(:last-child) {
|
|
|
|
margin-right: 16px;
|
|
|
|
}
|
|
|
|
|
|
|
|
&:hover {
|
2020-06-16 00:36:59 +02:00
|
|
|
color: rgba(${props => props.theme.colors.text.secondary});
|
2020-05-27 02:53:31 +02:00
|
|
|
}
|
2020-06-24 03:46:45 +02:00
|
|
|
${props =>
|
|
|
|
props.disabled &&
|
|
|
|
css`
|
|
|
|
opacity: 0.5;
|
|
|
|
cursor: default;
|
|
|
|
pointer-events: none;
|
|
|
|
`}
|
2020-05-27 02:53:31 +02:00
|
|
|
`;
|
|
|
|
|
|
|
|
const ProjectActionText = styled.span`
|
|
|
|
padding-left: 4px;
|
|
|
|
`;
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
const Project = () => {
|
2020-05-28 03:12:50 +02:00
|
|
|
const { projectID } = useParams<ProjectParams>();
|
2020-05-31 06:11:19 +02:00
|
|
|
const history = useHistory();
|
2020-04-16 22:05:12 +02:00
|
|
|
const match = useRouteMatch();
|
|
|
|
|
2020-04-20 05:02:55 +02:00
|
|
|
const [updateTaskDescription] = useUpdateTaskDescriptionMutation();
|
2020-04-10 04:40:22 +02:00
|
|
|
const [quickCardEditor, setQuickCardEditor] = useState(initialQuickCardEditorState);
|
2020-06-01 04:20:03 +02:00
|
|
|
const [updateTaskLocation] = useUpdateTaskLocationMutation({
|
|
|
|
update: (client, newTask) => {
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
const { previousTaskGroupID, task } = newTask.data.updateTaskLocation;
|
|
|
|
if (previousTaskGroupID !== task.taskGroup.id) {
|
|
|
|
const { taskGroups } = cache.findProject;
|
|
|
|
const oldTaskGroupIdx = taskGroups.findIndex((t: TaskGroup) => t.id === previousTaskGroupID);
|
|
|
|
const newTaskGroupIdx = taskGroups.findIndex((t: TaskGroup) => t.id === task.taskGroup.id);
|
|
|
|
if (oldTaskGroupIdx !== -1 && newTaskGroupIdx !== -1) {
|
|
|
|
draftCache.findProject.taskGroups[oldTaskGroupIdx].tasks = taskGroups[oldTaskGroupIdx].tasks.filter(
|
|
|
|
(t: Task) => t.id !== task.id,
|
|
|
|
);
|
|
|
|
draftCache.findProject.taskGroups[newTaskGroupIdx].tasks = [
|
|
|
|
...taskGroups[newTaskGroupIdx].tasks,
|
|
|
|
{ ...task },
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
{ projectId: projectID },
|
|
|
|
);
|
2020-06-01 04:20:03 +02:00
|
|
|
},
|
|
|
|
});
|
2020-05-31 06:11:19 +02:00
|
|
|
const [updateTaskGroupLocation] = useUpdateTaskGroupLocationMutation({});
|
2020-04-16 22:05:12 +02:00
|
|
|
|
2020-04-11 21:24:45 +02:00
|
|
|
const [deleteTaskGroup] = useDeleteTaskGroupMutation({
|
2020-05-31 06:11:19 +02:00
|
|
|
onCompleted: deletedTaskGroupData => {},
|
2020-05-28 03:12:50 +02:00
|
|
|
update: (client, deletedTaskGroupData) => {
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
draftCache.findProject.taskGroups = draftCache.findProject.taskGroups.filter(
|
|
|
|
(taskGroup: TaskGroup) => taskGroup.id !== deletedTaskGroupData.data.deleteTaskGroup.taskGroup.id,
|
|
|
|
);
|
|
|
|
}),
|
|
|
|
{ projectId: projectID },
|
|
|
|
);
|
2020-05-28 03:12:50 +02:00
|
|
|
},
|
2020-04-11 21:24:45 +02:00
|
|
|
});
|
2020-04-16 22:05:12 +02:00
|
|
|
|
2020-04-11 04:22:58 +02:00
|
|
|
const [createTaskGroup] = useCreateTaskGroupMutation({
|
2020-05-31 06:11:19 +02:00
|
|
|
onCompleted: newTaskGroupData => {},
|
2020-05-28 03:12:50 +02:00
|
|
|
update: (client, newTaskGroupData) => {
|
2020-06-23 22:20:53 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache => {
|
|
|
|
console.log(cache);
|
|
|
|
return produce(cache, draftCache => {
|
|
|
|
draftCache.findProject.taskGroups.push({ ...newTaskGroupData.data.createTaskGroup, tasks: [] });
|
|
|
|
});
|
|
|
|
},
|
|
|
|
{ projectId: projectID },
|
|
|
|
);
|
2020-05-28 03:12:50 +02:00
|
|
|
},
|
2020-04-11 04:22:58 +02:00
|
|
|
});
|
2020-04-16 22:05:12 +02:00
|
|
|
|
2020-04-10 05:27:57 +02:00
|
|
|
const [createTask] = useCreateTaskMutation({
|
2020-05-31 06:11:19 +02:00
|
|
|
onCompleted: newTaskData => {},
|
2020-05-27 02:53:31 +02:00
|
|
|
update: (client, newTaskData) => {
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
const { taskGroups } = cache.findProject;
|
|
|
|
const idx = taskGroups.findIndex(taskGroup => taskGroup.id === newTaskData.data.createTask.taskGroup.id);
|
|
|
|
if (idx !== -1) {
|
|
|
|
draftCache.findProject.taskGroups[idx].tasks.push({ ...newTaskData.data.createTask });
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
{ projectId: projectID },
|
|
|
|
);
|
2020-05-27 02:53:31 +02:00
|
|
|
},
|
2020-04-10 04:40:22 +02:00
|
|
|
});
|
2020-04-16 22:05:12 +02:00
|
|
|
|
2020-04-10 05:27:57 +02:00
|
|
|
const [deleteTask] = useDeleteTaskMutation({
|
2020-05-31 06:11:19 +02:00
|
|
|
onCompleted: deletedTask => {},
|
2020-04-10 04:40:22 +02:00
|
|
|
});
|
2020-04-16 22:05:12 +02:00
|
|
|
|
2020-04-10 05:27:57 +02:00
|
|
|
const [updateTaskName] = useUpdateTaskNameMutation({
|
2020-05-31 06:11:19 +02:00
|
|
|
onCompleted: newTaskData => {},
|
|
|
|
});
|
|
|
|
const [toggleTaskLabel] = useToggleTaskLabelMutation({
|
|
|
|
onCompleted: newTaskLabel => {
|
|
|
|
taskLabelsRef.current = newTaskLabel.toggleTaskLabel.task.labels;
|
|
|
|
console.log(taskLabelsRef.current);
|
2020-04-10 04:40:22 +02:00
|
|
|
},
|
|
|
|
});
|
2020-04-21 01:04:27 +02:00
|
|
|
const { loading, data, refetch } = useFindProjectQuery({
|
2020-05-28 03:12:50 +02:00
|
|
|
variables: { projectId: projectID },
|
2020-05-31 06:11:19 +02:00
|
|
|
onCompleted: newData => {},
|
2020-04-10 04:40:22 +02:00
|
|
|
});
|
2020-04-16 22:05:12 +02:00
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
const onCardCreate = (taskGroupID: string, name: string) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
if (data) {
|
|
|
|
const taskGroupTasks = data.findProject.taskGroups.filter(t => t.id === taskGroupID);
|
|
|
|
if (taskGroupTasks) {
|
|
|
|
let position = 65535;
|
|
|
|
if (taskGroupTasks.length !== 0) {
|
|
|
|
const [lastTask] = taskGroupTasks.sort((a: any, b: any) => a.position - b.position).slice(-1);
|
|
|
|
position = Math.ceil(lastTask.position) * 2 + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
createTask({ variables: { taskGroupID, name, position } });
|
|
|
|
}
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
2020-05-31 06:11:19 +02:00
|
|
|
};
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-05-31 06:11:19 +02:00
|
|
|
const onCreateTask = (taskGroupID: string, name: string) => {
|
|
|
|
if (data) {
|
|
|
|
const taskGroup = data.findProject.taskGroups.find(t => t.id === taskGroupID);
|
|
|
|
console.log(`taskGroup ${taskGroup}`);
|
|
|
|
if (taskGroup) {
|
|
|
|
let position = 65535;
|
|
|
|
if (taskGroup.tasks.length !== 0) {
|
2020-06-19 01:12:15 +02:00
|
|
|
const [lastTask] = taskGroup.tasks
|
|
|
|
.slice()
|
|
|
|
.sort((a: any, b: any) => a.position - b.position)
|
|
|
|
.slice(-1);
|
2020-05-31 06:11:19 +02:00
|
|
|
position = Math.ceil(lastTask.position) * 2 + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log(`position ${position}`);
|
2020-06-19 01:12:15 +02:00
|
|
|
createTask({
|
|
|
|
variables: { taskGroupID, name, position },
|
|
|
|
optimisticResponse: {
|
|
|
|
__typename: 'Mutation',
|
|
|
|
createTask: {
|
|
|
|
__typename: 'Task',
|
|
|
|
id: '' + Math.round(Math.random() * -1000000),
|
2020-06-23 22:20:53 +02:00
|
|
|
name,
|
|
|
|
complete: false,
|
2020-06-19 01:12:15 +02:00
|
|
|
taskGroup: {
|
|
|
|
__typename: 'TaskGroup',
|
|
|
|
id: taskGroup.id,
|
|
|
|
name: taskGroup.name,
|
|
|
|
position: taskGroup.position,
|
|
|
|
},
|
2020-06-23 22:20:53 +02:00
|
|
|
badges: {
|
|
|
|
checklist: null,
|
|
|
|
},
|
|
|
|
position,
|
2020-06-19 01:12:15 +02:00
|
|
|
dueDate: null,
|
|
|
|
description: null,
|
|
|
|
labels: [],
|
|
|
|
assigned: [],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-10 04:40:22 +02:00
|
|
|
};
|
2020-04-16 22:05:12 +02:00
|
|
|
|
|
|
|
const onListDrop = (droppedColumn: TaskGroup) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
console.log(`list drop ${droppedColumn.id}`);
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
const taskGroupIdx = cache.findProject.taskGroups.findIndex(t => t.id === droppedColumn.id);
|
|
|
|
if (taskGroupIdx !== -1) {
|
|
|
|
draftCache.findProject.taskGroups[taskGroupIdx].position = droppedColumn.position;
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
{
|
|
|
|
projectId: projectID,
|
|
|
|
},
|
|
|
|
);
|
2020-04-16 22:05:12 +02:00
|
|
|
updateTaskGroupLocation({
|
2020-05-31 06:11:19 +02:00
|
|
|
variables: { taskGroupID: droppedColumn.id, position: droppedColumn.position },
|
2020-05-28 03:12:50 +02:00
|
|
|
optimisticResponse: {
|
|
|
|
updateTaskGroupLocation: {
|
2020-05-31 06:11:19 +02:00
|
|
|
id: droppedColumn.id,
|
2020-05-28 03:12:50 +02:00
|
|
|
position: droppedColumn.position,
|
|
|
|
},
|
|
|
|
},
|
2020-04-16 22:05:12 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const onCreateList = (listName: string) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
if (data) {
|
|
|
|
const [lastColumn] = data.findProject.taskGroups.sort((a, b) => a.position - b.position).slice(-1);
|
|
|
|
let position = 65535;
|
|
|
|
if (lastColumn) {
|
|
|
|
position = lastColumn.position * 2 + 1;
|
|
|
|
}
|
|
|
|
createTaskGroup({ variables: { projectID, name: listName, position } });
|
2020-04-16 22:05:12 +02:00
|
|
|
}
|
|
|
|
};
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-04-20 05:02:55 +02:00
|
|
|
const [assignTask] = useAssignTaskMutation();
|
2020-06-01 04:20:03 +02:00
|
|
|
const [unassignTask] = useUnassignTaskMutation();
|
2020-04-20 05:02:55 +02:00
|
|
|
|
2020-06-19 01:12:15 +02:00
|
|
|
const [updateTaskGroupName] = useUpdateTaskGroupNameMutation({});
|
|
|
|
|
|
|
|
const [updateTaskDueDate] = useUpdateTaskDueDateMutation();
|
|
|
|
|
2020-06-01 04:20:03 +02:00
|
|
|
const [updateProjectName] = useUpdateProjectNameMutation({
|
|
|
|
update: (client, newName) => {
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
draftCache.findProject.name = newName.data.updateProjectName.name;
|
|
|
|
}),
|
|
|
|
{ projectId: projectID },
|
|
|
|
);
|
2020-06-01 04:20:03 +02:00
|
|
|
},
|
|
|
|
});
|
2020-05-31 06:11:19 +02:00
|
|
|
|
2020-06-19 01:12:15 +02:00
|
|
|
const [setTaskComplete] = useSetTaskCompleteMutation();
|
|
|
|
|
2020-05-31 06:11:19 +02:00
|
|
|
const client = useApolloClient();
|
2020-06-01 04:20:03 +02:00
|
|
|
const { userID } = useContext(UserIDContext);
|
2020-05-31 06:11:19 +02:00
|
|
|
|
2020-05-28 03:12:50 +02:00
|
|
|
const { showPopup, hidePopup } = usePopup();
|
2020-05-27 02:53:31 +02:00
|
|
|
const $labelsRef = useRef<HTMLDivElement>(null);
|
2020-05-31 06:11:19 +02:00
|
|
|
const labelsRef = useRef<Array<ProjectLabel>>([]);
|
|
|
|
const taskLabelsRef = useRef<Array<TaskLabel>>([]);
|
2020-06-13 00:21:58 +02:00
|
|
|
useEffect(() => {
|
|
|
|
if (data) {
|
|
|
|
document.title = `${data.findProject.name} | Citadel`;
|
|
|
|
}
|
|
|
|
}, [data]);
|
2020-04-10 04:40:22 +02:00
|
|
|
if (loading) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return (
|
|
|
|
<>
|
2020-06-21 00:49:11 +02:00
|
|
|
<GlobalTopNavbar onSaveProjectName={projectName => {}} name="" projectID={null} />
|
2020-05-27 02:53:31 +02:00
|
|
|
</>
|
|
|
|
);
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
if (data) {
|
2020-06-19 01:12:15 +02:00
|
|
|
console.log(data.findProject);
|
2020-06-24 03:08:48 +02:00
|
|
|
const onQuickEditorOpen = ($target: React.RefObject<HTMLElement>, taskID: string, taskGroupID: string) => {
|
|
|
|
if ($target && $target.current) {
|
|
|
|
const pos = $target.current.getBoundingClientRect();
|
|
|
|
const height = 120;
|
|
|
|
if (window.innerHeight - pos.bottom < height) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const taskGroup = data.findProject.taskGroups.find(t => t.id === taskGroupID);
|
|
|
|
const currentTask = taskGroup ? taskGroup.tasks.find(t => t.id === taskID) : null;
|
2020-05-31 06:11:19 +02:00
|
|
|
if (currentTask) {
|
|
|
|
setQuickCardEditor({
|
2020-06-24 03:08:48 +02:00
|
|
|
target: $target,
|
2020-05-31 06:11:19 +02:00
|
|
|
isOpen: true,
|
2020-05-31 06:51:22 +02:00
|
|
|
taskID: currentTask.id,
|
|
|
|
taskGroupID: currentTask.taskGroup.id,
|
2020-05-31 06:11:19 +02:00
|
|
|
});
|
|
|
|
}
|
2020-05-27 02:53:31 +02:00
|
|
|
};
|
2020-05-27 23:18:50 +02:00
|
|
|
|
2020-05-31 06:11:19 +02:00
|
|
|
labelsRef.current = data.findProject.labels;
|
|
|
|
|
2020-05-31 06:51:22 +02:00
|
|
|
let currentQuickTask = null;
|
|
|
|
if (quickCardEditor.taskID && quickCardEditor.taskGroupID) {
|
|
|
|
const targetGroup = data.findProject.taskGroups.find(t => t.id === quickCardEditor.taskGroupID);
|
|
|
|
if (targetGroup) {
|
|
|
|
currentQuickTask = targetGroup.tasks.find(t => t.id === quickCardEditor.taskID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
return (
|
|
|
|
<>
|
2020-05-31 06:11:19 +02:00
|
|
|
<GlobalTopNavbar
|
|
|
|
onSaveProjectName={projectName => {
|
|
|
|
updateProjectName({ variables: { projectID, name: projectName } });
|
|
|
|
}}
|
2020-06-23 22:20:53 +02:00
|
|
|
popupContent={<ProjectPopup history={history} name={data.findProject.name} projectID={projectID} />}
|
|
|
|
menuType={MENU_TYPES.PROJECT_MENU}
|
|
|
|
initialTab={0}
|
2020-05-31 06:11:19 +02:00
|
|
|
projectMembers={data.findProject.members}
|
2020-06-21 00:49:11 +02:00
|
|
|
projectID={projectID}
|
2020-05-31 06:11:19 +02:00
|
|
|
name={data.findProject.name}
|
|
|
|
/>
|
2020-05-27 23:18:50 +02:00
|
|
|
<ProjectBar>
|
2020-06-23 22:20:53 +02:00
|
|
|
<ProjectActions>
|
2020-06-24 03:46:45 +02:00
|
|
|
<ProjectAction disabled>
|
2020-06-23 22:20:53 +02:00
|
|
|
<CheckCircle width={13} height={13} />
|
|
|
|
<ProjectActionText>All Tasks</ProjectActionText>
|
|
|
|
</ProjectAction>
|
2020-06-24 03:46:45 +02:00
|
|
|
<ProjectAction disabled>
|
2020-06-23 22:20:53 +02:00
|
|
|
<Filter width={13} height={13} />
|
|
|
|
<ProjectActionText>Filter</ProjectActionText>
|
|
|
|
</ProjectAction>
|
2020-06-24 03:46:45 +02:00
|
|
|
<ProjectAction disabled>
|
2020-06-23 22:20:53 +02:00
|
|
|
<Sort width={13} height={13} />
|
|
|
|
<ProjectActionText>Sort</ProjectActionText>
|
|
|
|
</ProjectAction>
|
|
|
|
</ProjectActions>
|
2020-05-27 23:18:50 +02:00
|
|
|
<ProjectActions>
|
|
|
|
<ProjectAction
|
|
|
|
ref={$labelsRef}
|
|
|
|
onClick={() => {
|
|
|
|
showPopup(
|
|
|
|
$labelsRef,
|
2020-05-31 06:11:19 +02:00
|
|
|
<LabelManagerEditor
|
|
|
|
taskLabels={null}
|
|
|
|
labelColors={data.labelColors}
|
|
|
|
labels={labelsRef}
|
|
|
|
projectID={projectID}
|
|
|
|
/>,
|
2020-05-27 23:18:50 +02:00
|
|
|
);
|
|
|
|
}}
|
|
|
|
>
|
2020-06-16 00:36:59 +02:00
|
|
|
<Tags width={13} height={13} />
|
2020-05-27 23:18:50 +02:00
|
|
|
<ProjectActionText>Labels</ProjectActionText>
|
|
|
|
</ProjectAction>
|
2020-06-24 03:46:45 +02:00
|
|
|
<ProjectAction disabled>
|
2020-06-16 00:36:59 +02:00
|
|
|
<ToggleOn width={13} height={13} />
|
2020-05-27 23:18:50 +02:00
|
|
|
<ProjectActionText>Fields</ProjectActionText>
|
|
|
|
</ProjectAction>
|
2020-06-24 03:46:45 +02:00
|
|
|
<ProjectAction disabled>
|
2020-06-16 00:36:59 +02:00
|
|
|
<Bolt width={13} height={13} />
|
2020-05-27 23:18:50 +02:00
|
|
|
<ProjectActionText>Rules</ProjectActionText>
|
|
|
|
</ProjectAction>
|
|
|
|
</ProjectActions>
|
|
|
|
</ProjectBar>
|
2020-05-31 06:11:19 +02:00
|
|
|
<SimpleLists
|
|
|
|
onTaskClick={task => {
|
|
|
|
history.push(`${match.url}/c/${task.id}`);
|
|
|
|
}}
|
2020-06-01 04:20:03 +02:00
|
|
|
onTaskDrop={(droppedTask, previousTaskGroupID) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
updateTaskLocation({
|
|
|
|
variables: {
|
|
|
|
taskID: droppedTask.id,
|
|
|
|
taskGroupID: droppedTask.taskGroup.id,
|
|
|
|
position: droppedTask.position,
|
|
|
|
},
|
|
|
|
optimisticResponse: {
|
|
|
|
__typename: 'Mutation',
|
|
|
|
updateTaskLocation: {
|
2020-06-01 04:20:03 +02:00
|
|
|
previousTaskGroupID,
|
|
|
|
task: {
|
|
|
|
name: droppedTask.name,
|
|
|
|
id: droppedTask.id,
|
|
|
|
position: droppedTask.position,
|
|
|
|
taskGroup: {
|
|
|
|
id: droppedTask.taskGroup.id,
|
|
|
|
__typename: 'TaskGroup',
|
|
|
|
},
|
|
|
|
createdAt: '',
|
|
|
|
__typename: 'Task',
|
|
|
|
},
|
2020-05-31 06:11:19 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
onTaskGroupDrop={droppedTaskGroup => {
|
|
|
|
updateTaskGroupLocation({
|
|
|
|
variables: { taskGroupID: droppedTaskGroup.id, position: droppedTaskGroup.position },
|
|
|
|
optimisticResponse: {
|
|
|
|
__typename: 'Mutation',
|
|
|
|
updateTaskGroupLocation: {
|
|
|
|
id: droppedTaskGroup.id,
|
|
|
|
position: droppedTaskGroup.position,
|
|
|
|
__typename: 'TaskGroup',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
taskGroups={data.findProject.taskGroups}
|
|
|
|
onCreateTask={onCreateTask}
|
|
|
|
onCreateTaskGroup={onCreateList}
|
2020-05-27 23:18:50 +02:00
|
|
|
onCardMemberClick={($targetRef, taskID, memberID) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
const member = data.findProject.members.find(m => m.id === memberID);
|
|
|
|
const profileIcon = member ? member.profileIcon : null;
|
2020-05-27 23:18:50 +02:00
|
|
|
showPopup(
|
|
|
|
$targetRef,
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup
|
|
|
|
title={null}
|
|
|
|
onClose={() => {
|
|
|
|
hidePopup();
|
|
|
|
}}
|
|
|
|
tab={0}
|
|
|
|
>
|
2020-05-27 23:18:50 +02:00
|
|
|
<MiniProfile
|
2020-05-31 06:11:19 +02:00
|
|
|
profileIcon={profileIcon}
|
2020-05-27 23:18:50 +02:00
|
|
|
displayName="Jordan Knott"
|
|
|
|
username="@jordanthedev"
|
|
|
|
bio="None"
|
|
|
|
onRemoveFromTask={() => {
|
|
|
|
/* unassignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } }); */
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Popup>,
|
|
|
|
);
|
|
|
|
}}
|
2020-06-19 01:12:15 +02:00
|
|
|
onChangeTaskGroupName={(taskGroupID, name) => {
|
|
|
|
updateTaskGroupName({ variables: { taskGroupID, name } });
|
|
|
|
}}
|
2020-04-20 05:02:55 +02:00
|
|
|
onQuickEditorOpen={onQuickEditorOpen}
|
2020-05-31 06:11:19 +02:00
|
|
|
onExtraMenuOpen={(taskGroupID: string, $targetRef: any) => {
|
2020-05-27 02:53:31 +02:00
|
|
|
showPopup(
|
|
|
|
$targetRef,
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup title="List actions" tab={0} onClose={() => hidePopup()}>
|
2020-05-27 02:53:31 +02:00
|
|
|
<ListActions
|
|
|
|
taskGroupID={taskGroupID}
|
|
|
|
onArchiveTaskGroup={tgID => {
|
|
|
|
deleteTaskGroup({ variables: { taskGroupID: tgID } });
|
2020-05-28 03:12:50 +02:00
|
|
|
hidePopup();
|
2020-05-27 02:53:31 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Popup>,
|
|
|
|
);
|
2020-04-20 05:02:55 +02:00
|
|
|
}}
|
|
|
|
/>
|
2020-06-24 03:08:48 +02:00
|
|
|
{quickCardEditor.isOpen && currentQuickTask && quickCardEditor.target && (
|
2020-04-16 22:05:12 +02:00
|
|
|
<QuickCardEditor
|
2020-05-31 06:51:22 +02:00
|
|
|
task={currentQuickTask}
|
2020-04-16 22:05:12 +02:00
|
|
|
onCloseEditor={() => setQuickCardEditor(initialQuickCardEditorState)}
|
2020-06-15 02:50:35 +02:00
|
|
|
onEditCard={(_taskGroupID: string, taskID: string, cardName: string) => {
|
|
|
|
updateTaskName({ variables: { taskID, name: cardName } });
|
2020-04-13 00:45:51 +02:00
|
|
|
}}
|
2020-06-01 04:20:03 +02:00
|
|
|
onOpenMembersPopup={($targetRef, task) => {
|
|
|
|
showPopup(
|
|
|
|
$targetRef,
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup title="Members" tab={0} onClose={() => hidePopup()}>
|
2020-06-01 04:20:03 +02:00
|
|
|
<MemberManager
|
|
|
|
availableMembers={data.findProject.members}
|
|
|
|
activeMembers={task.assigned ?? []}
|
|
|
|
onMemberChange={(member, isActive) => {
|
|
|
|
if (isActive) {
|
|
|
|
assignTask({ variables: { taskID: task.id, userID: userID ?? '' } });
|
|
|
|
} else {
|
|
|
|
unassignTask({ variables: { taskID: task.id, userID: userID ?? '' } });
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Popup>,
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
onCardMemberClick={($targetRef, taskID, memberID) => {
|
|
|
|
const member = data.findProject.members.find(m => m.id === memberID);
|
|
|
|
const profileIcon = member ? member.profileIcon : null;
|
|
|
|
showPopup(
|
|
|
|
$targetRef,
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup title={null} onClose={() => hidePopup()} tab={0}>
|
2020-06-01 04:20:03 +02:00
|
|
|
<MiniProfile
|
|
|
|
profileIcon={profileIcon}
|
|
|
|
displayName="Jordan Knott"
|
|
|
|
username="@jordanthedev"
|
|
|
|
bio="None"
|
|
|
|
onRemoveFromTask={() => {
|
|
|
|
/* unassignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } }); */
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Popup>,
|
|
|
|
);
|
|
|
|
}}
|
2020-05-31 06:51:22 +02:00
|
|
|
onOpenLabelsPopup={($targetRef, task) => {
|
|
|
|
taskLabelsRef.current = task.labels;
|
|
|
|
showPopup(
|
|
|
|
$targetRef,
|
|
|
|
<LabelManagerEditor
|
|
|
|
onLabelToggle={labelID => {
|
|
|
|
toggleTaskLabel({ variables: { taskID: task.id, projectLabelID: labelID } });
|
|
|
|
}}
|
|
|
|
labelColors={data.labelColors}
|
|
|
|
labels={labelsRef}
|
|
|
|
taskLabels={taskLabelsRef}
|
|
|
|
projectID={projectID}
|
|
|
|
/>,
|
|
|
|
);
|
|
|
|
}}
|
2020-05-27 02:53:31 +02:00
|
|
|
onArchiveCard={(_listId: string, cardId: string) =>
|
|
|
|
deleteTask({
|
|
|
|
variables: { taskID: cardId },
|
2020-05-31 07:04:14 +02:00
|
|
|
update: () => {
|
2020-06-23 23:55:17 +02:00
|
|
|
updateApolloCache<FindProjectQuery>(
|
|
|
|
client,
|
|
|
|
FindProjectDocument,
|
|
|
|
cache =>
|
|
|
|
produce(cache, draftCache => {
|
|
|
|
draftCache.findProject.taskGroups = cache.findProject.taskGroups.map(taskGroup => ({
|
|
|
|
...taskGroup,
|
|
|
|
tasks: taskGroup.tasks.filter(t => t.id !== cardId),
|
|
|
|
}));
|
|
|
|
}),
|
|
|
|
{ projectId: projectID },
|
|
|
|
);
|
2020-05-27 02:53:31 +02:00
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
2020-06-19 01:12:15 +02:00
|
|
|
onOpenDueDatePopup={($targetRef, task) => {
|
|
|
|
showPopup(
|
|
|
|
$targetRef,
|
2020-06-24 03:16:17 +02:00
|
|
|
<Popup title={'Change Due Date'} tab={0} onClose={() => hidePopup()}>
|
2020-06-19 01:12:15 +02:00
|
|
|
<DueDateManager
|
|
|
|
task={task}
|
|
|
|
onRemoveDueDate={t => {
|
|
|
|
updateTaskDueDate({ variables: { taskID: t.id, dueDate: null } });
|
|
|
|
hidePopup();
|
|
|
|
}}
|
|
|
|
onDueDateChange={(t, newDueDate) => {
|
|
|
|
updateTaskDueDate({ variables: { taskID: t.id, dueDate: newDueDate } });
|
|
|
|
hidePopup();
|
|
|
|
}}
|
|
|
|
onCancel={() => {}}
|
|
|
|
/>
|
|
|
|
</Popup>,
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
onToggleComplete={task => {
|
|
|
|
setTaskComplete({ variables: { taskID: task.id, complete: !task.complete } });
|
|
|
|
}}
|
2020-06-24 03:08:48 +02:00
|
|
|
target={quickCardEditor.target}
|
2020-04-13 00:45:51 +02:00
|
|
|
/>
|
|
|
|
)}
|
2020-04-16 22:05:12 +02:00
|
|
|
<Route
|
|
|
|
path={`${match.path}/c/:taskID`}
|
|
|
|
render={(routeProps: RouteComponentProps<TaskRouteProps>) => (
|
2020-04-20 05:02:55 +02:00
|
|
|
<Details
|
2020-05-28 03:12:50 +02:00
|
|
|
refreshCache={() => {}}
|
2020-05-31 06:11:19 +02:00
|
|
|
availableMembers={data.findProject.members}
|
2020-04-20 05:02:55 +02:00
|
|
|
projectURL={match.url}
|
|
|
|
taskID={routeProps.match.params.taskID}
|
|
|
|
onTaskNameChange={(updatedTask, newName) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
updateTaskName({ variables: { taskID: updatedTask.id, name: newName } });
|
2020-04-20 05:02:55 +02:00
|
|
|
}}
|
|
|
|
onTaskDescriptionChange={(updatedTask, newDescription) => {
|
2020-05-31 06:11:19 +02:00
|
|
|
updateTaskDescription({ variables: { taskID: updatedTask.id, description: newDescription } });
|
2020-04-16 22:05:12 +02:00
|
|
|
}}
|
2020-04-20 05:02:55 +02:00
|
|
|
onDeleteTask={deletedTask => {
|
2020-05-31 06:11:19 +02:00
|
|
|
deleteTask({ variables: { taskID: deletedTask.id } });
|
|
|
|
}}
|
|
|
|
onOpenAddLabelPopup={(task, $targetRef) => {
|
|
|
|
taskLabelsRef.current = task.labels;
|
|
|
|
showPopup(
|
|
|
|
$targetRef,
|
|
|
|
<LabelManagerEditor
|
|
|
|
onLabelToggle={labelID => {
|
|
|
|
toggleTaskLabel({ variables: { taskID: task.id, projectLabelID: labelID } });
|
|
|
|
}}
|
|
|
|
labelColors={data.labelColors}
|
|
|
|
labels={labelsRef}
|
|
|
|
taskLabels={taskLabelsRef}
|
|
|
|
projectID={projectID}
|
|
|
|
/>,
|
|
|
|
);
|
2020-04-16 22:05:12 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
/>
|
2020-04-10 04:40:22 +02:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|
2020-04-20 05:02:55 +02:00
|
|
|
return <div>Error</div>;
|
2020-04-10 04:40:22 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
export default Project;
|