feature: add ability to delete & update project labels
This commit is contained in:
@ -16,7 +16,7 @@ const Routes = ({ history }: RoutesProps) => (
|
||||
<Route exact path="/login" component={Login} />
|
||||
<Route exact path="/" component={Dashboard} />
|
||||
<Route exact path="/projects" component={Projects} />
|
||||
<Route path="/projects/:projectId" component={Project} />
|
||||
<Route path="/projects/:projectID" component={Project} />
|
||||
</Switch>
|
||||
);
|
||||
|
||||
|
@ -41,7 +41,6 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({ name, projectMembers
|
||||
if (!userID) {
|
||||
return null;
|
||||
}
|
||||
console.log(data);
|
||||
return (
|
||||
<>
|
||||
<TopNavbar
|
||||
@ -50,7 +49,7 @@ const GlobalTopNavbar: React.FC<GlobalTopNavbarProps> = ({ name, projectMembers
|
||||
firstName={data ? data.me.firstName : ''}
|
||||
lastName={data ? data.me.lastName : ''}
|
||||
initials={!data ? '' : data.me.profileIcon.initials ?? ''}
|
||||
onNotificationClick={() => console.log('beep')}
|
||||
onNotificationClick={() => {}}
|
||||
projectMembers={projectMembers}
|
||||
onProfileClick={onProfileClick}
|
||||
/>
|
||||
|
@ -106,7 +106,6 @@ const Details: React.FC<DetailsProps> = ({
|
||||
);
|
||||
}}
|
||||
onOpenAddMemberPopup={(task, $targetRef) => {
|
||||
console.log(`task: ${task.taskID}`);
|
||||
showPopup(
|
||||
$targetRef,
|
||||
<Popup title="Members" tab={0} onClose={() => {}}>
|
||||
@ -114,13 +113,11 @@ const Details: React.FC<DetailsProps> = ({
|
||||
availableMembers={availableMembers}
|
||||
activeMembers={taskMembers}
|
||||
onMemberChange={(member, isActive) => {
|
||||
console.log(`is active ${member.userID} - ${isActive}`);
|
||||
if (isActive) {
|
||||
assignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } });
|
||||
} else {
|
||||
unassignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } });
|
||||
}
|
||||
console.log(member, isActive);
|
||||
}}
|
||||
/>
|
||||
</Popup>,
|
||||
|
@ -8,7 +8,9 @@ import { useParams, Route, useRouteMatch, useHistory, RouteComponentProps } from
|
||||
import {
|
||||
useFindProjectQuery,
|
||||
useUpdateTaskNameMutation,
|
||||
useUpdateProjectLabelMutation,
|
||||
useCreateTaskMutation,
|
||||
useDeleteProjectLabelMutation,
|
||||
useDeleteTaskMutation,
|
||||
useUpdateTaskLocationMutation,
|
||||
useUpdateTaskGroupLocationMutation,
|
||||
@ -31,8 +33,28 @@ import { mixin } from 'shared/utils/styles';
|
||||
import LabelManager from 'shared/components/PopupMenu/LabelManager';
|
||||
import LabelEditor from 'shared/components/PopupMenu/LabelEditor';
|
||||
import produce from 'immer';
|
||||
import Details from './Details';
|
||||
import MiniProfile from 'shared/components/MiniProfile';
|
||||
import Details from './Details';
|
||||
|
||||
const getCacheData = (client: any, projectID: string) => {
|
||||
const cacheData: any = client.readQuery({
|
||||
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 },
|
||||
});
|
||||
};
|
||||
|
||||
type TaskRouteProps = {
|
||||
taskID: string;
|
||||
@ -63,15 +85,37 @@ const ProjectMembers = styled.div`
|
||||
`;
|
||||
|
||||
type LabelManagerEditorProps = {
|
||||
labels: Array<Label>;
|
||||
labels: React.RefObject<Array<Label>>;
|
||||
projectID: string;
|
||||
labelColors: Array<LabelColor>;
|
||||
};
|
||||
|
||||
const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initialLabels, projectID, labelColors }) => {
|
||||
const [labels, setLabels] = useState<Array<Label>>(initialLabels);
|
||||
const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: labelsRef, projectID, labelColors }) => {
|
||||
const [currentLabel, setCurrentLabel] = useState('');
|
||||
const [createProjectLabel] = useCreateProjectLabelMutation();
|
||||
const [createProjectLabel] = useCreateProjectLabelMutation({
|
||||
update: (client, newLabelData) => {
|
||||
const cacheData = getCacheData(client, projectID);
|
||||
const newData = {
|
||||
...cacheData.findProject,
|
||||
labels: [...cacheData.findProject.labels, { ...newLabelData.data.createProjectLabel }],
|
||||
};
|
||||
writeCacheData(client, projectID, cacheData, newData);
|
||||
},
|
||||
});
|
||||
const [updateProjectLabel] = useUpdateProjectLabelMutation();
|
||||
const [deleteProjectLabel] = useDeleteProjectLabelMutation({
|
||||
update: (client, newLabelData) => {
|
||||
const cacheData = getCacheData(client, projectID);
|
||||
const newData = {
|
||||
...cacheData.findProject,
|
||||
labels: cacheData.findProject.labels.filter(
|
||||
(label: any) => label.id !== newLabelData.data.deleteProjectLabel.id,
|
||||
),
|
||||
};
|
||||
writeCacheData(client, projectID, cacheData, newData);
|
||||
},
|
||||
});
|
||||
const labels = labelsRef.current ? labelsRef.current : [];
|
||||
const { setTab } = usePopup();
|
||||
return (
|
||||
<>
|
||||
@ -95,15 +139,14 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initial
|
||||
<LabelEditor
|
||||
labelColors={labelColors}
|
||||
label={labels.find(label => label.labelId === currentLabel) ?? null}
|
||||
onLabelEdit={(_labelId, name, color) => {
|
||||
setLabels(
|
||||
produce(labels, draftState => {
|
||||
const idx = labels.findIndex(label => label.labelId === currentLabel);
|
||||
if (idx !== -1) {
|
||||
draftState[idx] = { ...draftState[idx], name, labelColor: color };
|
||||
}
|
||||
}),
|
||||
);
|
||||
onLabelEdit={(projectLabelID, name, color) => {
|
||||
if (projectLabelID) {
|
||||
updateProjectLabel({ variables: { projectLabelID, labelColorID: color.id, name } });
|
||||
}
|
||||
setTab(0);
|
||||
}}
|
||||
onLabelDelete={labelID => {
|
||||
deleteProjectLabel({ variables: { projectLabelID: labelID } });
|
||||
setTab(0);
|
||||
}}
|
||||
/>
|
||||
@ -113,8 +156,6 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initial
|
||||
labelColors={labelColors}
|
||||
label={null}
|
||||
onLabelEdit={(_labelId, name, color) => {
|
||||
console.log(name, color);
|
||||
setLabels([...labels, { labelId: name, name, labelColor: color, active: false }]);
|
||||
createProjectLabel({ variables: { projectID, labelColorID: color.id, name } });
|
||||
setTab(0);
|
||||
}}
|
||||
@ -125,13 +166,12 @@ const LabelManagerEditor: React.FC<LabelManagerEditorProps> = ({ labels: initial
|
||||
};
|
||||
|
||||
interface ProjectParams {
|
||||
projectId: string;
|
||||
projectID: string;
|
||||
}
|
||||
|
||||
const initialState: BoardState = { tasks: {}, columns: {} };
|
||||
const initialPopupState = { left: 0, top: 0, isOpen: false, taskGroupID: '' };
|
||||
const initialQuickCardEditorState: QuickCardEditorState = { isOpen: false, top: 0, left: 0 };
|
||||
const initialLabelsPopupState = { taskID: '', isOpen: false, top: 0, left: 0 };
|
||||
const initialTaskDetailsState = { isOpen: false, taskID: '' };
|
||||
|
||||
const ProjectBar = styled.div`
|
||||
@ -168,14 +208,11 @@ const ProjectActionText = styled.span`
|
||||
`;
|
||||
|
||||
const Project = () => {
|
||||
const { projectId } = useParams<ProjectParams>();
|
||||
const { projectID } = useParams<ProjectParams>();
|
||||
const match = useRouteMatch();
|
||||
const history = useHistory();
|
||||
|
||||
const [updateTaskDescription] = useUpdateTaskDescriptionMutation();
|
||||
const [listsData, setListsData] = useState(initialState);
|
||||
const [popupData, setPopupData] = useState(initialPopupState);
|
||||
const [taskDetails, setTaskDetails] = useState(initialTaskDetailsState);
|
||||
const [quickCardEditor, setQuickCardEditor] = useState(initialQuickCardEditorState);
|
||||
const [updateTaskLocation] = useUpdateTaskLocationMutation();
|
||||
const [updateTaskGroupLocation] = useUpdateTaskGroupLocationMutation();
|
||||
@ -184,6 +221,17 @@ const Project = () => {
|
||||
onCompleted: deletedTaskGroupData => {
|
||||
setListsData(BoardStateUtils.deleteTaskGroup(listsData, deletedTaskGroupData.deleteTaskGroup.taskGroup.id));
|
||||
},
|
||||
update: (client, deletedTaskGroupData) => {
|
||||
const cacheData = getCacheData(client, projectID);
|
||||
const newData = {
|
||||
...cacheData.findProject,
|
||||
taskGroups: cacheData.findProject.taskGroups.filter(
|
||||
(taskGroup: any) => taskGroup.id !== deletedTaskGroupData.data.deleteTaskGroup.taskGroup.id,
|
||||
),
|
||||
};
|
||||
|
||||
writeCacheData(client, projectID, cacheData, newData);
|
||||
},
|
||||
});
|
||||
|
||||
const [createTaskGroup] = useCreateTaskGroupMutation({
|
||||
@ -195,6 +243,15 @@ const Project = () => {
|
||||
};
|
||||
setListsData(BoardStateUtils.addTaskGroup(listsData, newTaskGroup));
|
||||
},
|
||||
update: (client, newTaskGroupData) => {
|
||||
const cacheData = getCacheData(client, projectID);
|
||||
const newData = {
|
||||
...cacheData.findProject,
|
||||
taskGroups: [...cacheData.findProject.taskGroups, { ...newTaskGroupData.data.createTaskGroup, tasks: [] }],
|
||||
};
|
||||
|
||||
writeCacheData(client, projectID, cacheData, newData);
|
||||
},
|
||||
});
|
||||
|
||||
const [createTask] = useCreateTaskMutation({
|
||||
@ -208,14 +265,7 @@ const Project = () => {
|
||||
setListsData(BoardStateUtils.addTask(listsData, newTask));
|
||||
},
|
||||
update: (client, newTaskData) => {
|
||||
const cacheData: any = client.readQuery({
|
||||
query: FindProjectDocument,
|
||||
variables: {
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
console.log(cacheData);
|
||||
console.log(newTaskData);
|
||||
const cacheData = getCacheData(client, projectID);
|
||||
const newTaskGroups = produce(cacheData.findProject.taskGroups, (draftState: any) => {
|
||||
const targetIndex = draftState.findIndex(
|
||||
(taskGroup: any) => taskGroup.id === newTaskData.data.createTask.taskGroup.id,
|
||||
@ -225,18 +275,11 @@ const Project = () => {
|
||||
tasks: [...draftState[targetIndex].tasks, { ...newTaskData.data.createTask }],
|
||||
};
|
||||
});
|
||||
console.log(newTaskGroups);
|
||||
const newData = {
|
||||
...cacheData.findProject,
|
||||
taskGroups: newTaskGroups,
|
||||
};
|
||||
client.writeQuery({
|
||||
query: FindProjectDocument,
|
||||
variables: {
|
||||
projectId: projectId,
|
||||
},
|
||||
data: { findProject: newData },
|
||||
});
|
||||
writeCacheData(client, projectID, cacheData, newData);
|
||||
},
|
||||
});
|
||||
|
||||
@ -254,9 +297,8 @@ const Project = () => {
|
||||
},
|
||||
});
|
||||
const { loading, data, refetch } = useFindProjectQuery({
|
||||
variables: { projectId },
|
||||
variables: { projectId: projectID },
|
||||
});
|
||||
console.log(`loading ${loading} - ${data}`);
|
||||
|
||||
const onCardCreate = (taskGroupID: string, name: string) => {
|
||||
const taskGroupTasks = Object.values(listsData.tasks).filter(
|
||||
@ -278,14 +320,29 @@ const Project = () => {
|
||||
taskGroupID: droppedTask.taskGroup.taskGroupID,
|
||||
position: droppedTask.position,
|
||||
},
|
||||
optimisticResponse: {
|
||||
updateTaskLocation: {
|
||||
name: droppedTask.name,
|
||||
id: droppedTask.taskID,
|
||||
position: droppedTask.position,
|
||||
createdAt: '',
|
||||
},
|
||||
},
|
||||
});
|
||||
setListsData(BoardStateUtils.updateTask(listsData, droppedTask));
|
||||
};
|
||||
const onListDrop = (droppedColumn: TaskGroup) => {
|
||||
console.log(`list drop ${droppedColumn.taskGroupID}`);
|
||||
updateTaskGroupLocation({
|
||||
variables: { taskGroupID: droppedColumn.taskGroupID, position: droppedColumn.position },
|
||||
optimisticResponse: {
|
||||
updateTaskGroupLocation: {
|
||||
id: droppedColumn.taskGroupID,
|
||||
position: droppedColumn.position,
|
||||
},
|
||||
},
|
||||
});
|
||||
setListsData(BoardStateUtils.updateTaskGroup(listsData, droppedColumn));
|
||||
// setListsData(BoardStateUtils.updateTaskGroup(listsData, droppedColumn));
|
||||
};
|
||||
|
||||
const onCreateList = (listName: string) => {
|
||||
@ -296,13 +353,14 @@ const Project = () => {
|
||||
if (lastColumn) {
|
||||
position = lastColumn.position * 2 + 1;
|
||||
}
|
||||
createTaskGroup({ variables: { projectID: projectId, name: listName, position } });
|
||||
createTaskGroup({ variables: { projectID, name: listName, position } });
|
||||
};
|
||||
|
||||
const [assignTask] = useAssignTaskMutation();
|
||||
|
||||
const { showPopup } = usePopup();
|
||||
const { showPopup, hidePopup } = usePopup();
|
||||
const $labelsRef = useRef<HTMLDivElement>(null);
|
||||
const labelsRef = useRef<Array<Label>>([]);
|
||||
if (loading) {
|
||||
return (
|
||||
<>
|
||||
@ -312,6 +370,7 @@ const Project = () => {
|
||||
);
|
||||
}
|
||||
if (data) {
|
||||
console.log(data);
|
||||
const currentListsData: BoardState = { tasks: {}, columns: {} };
|
||||
data.findProject.taskGroups.forEach(taskGroup => {
|
||||
currentListsData.columns[taskGroup.id] = {
|
||||
@ -358,7 +417,6 @@ const Project = () => {
|
||||
});
|
||||
const onQuickEditorOpen = (e: ContextMenuEvent) => {
|
||||
const currentTask = Object.values(currentListsData.tasks).find(task => task.taskID === e.taskID);
|
||||
console.log(`currentTask: ${currentTask?.taskID}`);
|
||||
setQuickCardEditor({
|
||||
top: e.top,
|
||||
left: e.left,
|
||||
@ -367,6 +425,14 @@ const Project = () => {
|
||||
});
|
||||
};
|
||||
|
||||
labelsRef.current = data.findProject.labels.map(label => {
|
||||
return {
|
||||
labelId: label.id,
|
||||
name: label.name ?? '',
|
||||
labelColor: label.labelColor,
|
||||
active: false,
|
||||
};
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<GlobalTopNavbar projectMembers={availableMembers} name={data.findProject.name} />
|
||||
@ -377,18 +443,7 @@ const Project = () => {
|
||||
onClick={() => {
|
||||
showPopup(
|
||||
$labelsRef,
|
||||
<LabelManagerEditor
|
||||
labelColors={data.labelColors}
|
||||
labels={data.findProject.labels.map(label => {
|
||||
return {
|
||||
labelId: label.id,
|
||||
name: label.name ?? '',
|
||||
labelColor: label.labelColor,
|
||||
active: false,
|
||||
};
|
||||
})}
|
||||
projectID={projectId}
|
||||
/>,
|
||||
<LabelManagerEditor labelColors={data.labelColors} labels={labelsRef} projectID={projectID} />,
|
||||
);
|
||||
}}
|
||||
>
|
||||
@ -436,7 +491,7 @@ const Project = () => {
|
||||
taskGroupID={taskGroupID}
|
||||
onArchiveTaskGroup={tgID => {
|
||||
deleteTaskGroup({ variables: { taskGroupID: tgID } });
|
||||
setPopupData(initialPopupState);
|
||||
hidePopup();
|
||||
}}
|
||||
/>
|
||||
</Popup>,
|
||||
@ -453,17 +508,12 @@ const Project = () => {
|
||||
onEditCard={(_listId: string, cardId: string, cardName: string) => {
|
||||
updateTaskName({ variables: { taskID: cardId, name: cardName } });
|
||||
}}
|
||||
onOpenPopup={() => console.log()}
|
||||
onOpenPopup={() => {}}
|
||||
onArchiveCard={(_listId: string, cardId: string) =>
|
||||
deleteTask({
|
||||
variables: { taskID: cardId },
|
||||
update: client => {
|
||||
const cacheData: any = client.readQuery({
|
||||
query: FindProjectDocument,
|
||||
variables: {
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
const cacheData = getCacheData(client, projectID);
|
||||
const newData = {
|
||||
...cacheData.findProject,
|
||||
taskGroups: cacheData.findProject.taskGroups.map((taskGroup: any) => {
|
||||
@ -473,13 +523,7 @@ const Project = () => {
|
||||
};
|
||||
}),
|
||||
};
|
||||
client.writeQuery({
|
||||
query: FindProjectDocument,
|
||||
variables: {
|
||||
projectId: projectId,
|
||||
},
|
||||
data: { findProject: newData },
|
||||
});
|
||||
writeCacheData(client, projectID, cacheData, newData);
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -492,10 +536,7 @@ const Project = () => {
|
||||
path={`${match.path}/c/:taskID`}
|
||||
render={(routeProps: RouteComponentProps<TaskRouteProps>) => (
|
||||
<Details
|
||||
refreshCache={() => {
|
||||
console.log('beep 2!');
|
||||
// refetch();
|
||||
}}
|
||||
refreshCache={() => {}}
|
||||
availableMembers={availableMembers}
|
||||
projectURL={match.url}
|
||||
taskID={routeProps.match.params.taskID}
|
||||
@ -506,7 +547,6 @@ const Project = () => {
|
||||
updateTaskDescription({ variables: { taskID: updatedTask.taskID, description: newDescription } });
|
||||
}}
|
||||
onDeleteTask={deletedTask => {
|
||||
setTaskDetails(initialTaskDetailsState);
|
||||
deleteTask({ variables: { taskID: deletedTask.taskID } });
|
||||
}}
|
||||
onOpenAddLabelPopup={(task, $targetRef) => {}}
|
||||
|
@ -30,7 +30,6 @@ const ProjectLink = styled(Link)`
|
||||
|
||||
const Projects = () => {
|
||||
const { loading, data } = useGetProjectsQuery();
|
||||
console.log(loading, data);
|
||||
if (loading) {
|
||||
return (
|
||||
<>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
import ReactDOM from 'react-dom';
|
||||
import { ApolloProvider } from '@apollo/react-hooks';
|
||||
import { ApolloClient } from 'apollo-client';
|
||||
|
@ -168,7 +168,9 @@ const Card = React.forwardRef(
|
||||
</ListCardBadges>
|
||||
<CardMembers>
|
||||
{members &&
|
||||
members.map(member => <Member taskID={taskID} member={member} onCardMemberClick={onCardMemberClick} />)}
|
||||
members.map(member => (
|
||||
<Member key={member.userID} taskID={taskID} member={member} onCardMemberClick={onCardMemberClick} />
|
||||
))}
|
||||
</CardMembers>
|
||||
</ListCardDetails>
|
||||
</ListCardInnerContainer>
|
||||
|
@ -74,8 +74,6 @@ const Lists: React.FC<Props> = ({
|
||||
}),
|
||||
);
|
||||
|
||||
console.log(beforeDropDraggables);
|
||||
console.log(destination);
|
||||
const afterDropDraggables = getAfterDropDraggableList(
|
||||
beforeDropDraggables,
|
||||
droppedDraggable,
|
||||
@ -83,19 +81,16 @@ const Lists: React.FC<Props> = ({
|
||||
isSameList,
|
||||
destination,
|
||||
);
|
||||
console.log(afterDropDraggables);
|
||||
const newPosition = getNewDraggablePosition(afterDropDraggables, destination.index);
|
||||
|
||||
if (isList) {
|
||||
const droppedList = columns[droppedDraggable.id];
|
||||
console.log(`is list ${droppedList}`);
|
||||
onListDrop({
|
||||
...droppedList,
|
||||
position: newPosition,
|
||||
});
|
||||
} else {
|
||||
const droppedCard = tasks[droppedDraggable.id];
|
||||
console.log(`is card ${droppedCard}`);
|
||||
const newCard = {
|
||||
...droppedCard,
|
||||
position: newPosition,
|
||||
@ -112,6 +107,7 @@ const Lists: React.FC<Props> = ({
|
||||
return { id: column.taskGroupID, position: column.position };
|
||||
}),
|
||||
);
|
||||
console.log(orderedColumns);
|
||||
|
||||
const [currentComposer, setCurrentComposer] = useState('');
|
||||
return (
|
||||
@ -134,7 +130,7 @@ const Lists: React.FC<Props> = ({
|
||||
name={column.name}
|
||||
onOpenComposer={id => setCurrentComposer(id)}
|
||||
isComposerOpen={currentComposer === column.taskGroupID}
|
||||
onSaveName={name => console.log(name)}
|
||||
onSaveName={name => {}}
|
||||
tasks={columnCards}
|
||||
ref={columnDragProvided.innerRef}
|
||||
wrapperProps={columnDragProvided.draggableProps}
|
||||
|
@ -23,7 +23,6 @@ import {
|
||||
const Login = ({ onSubmit }: LoginProps) => {
|
||||
const [isComplete, setComplete] = useState(true);
|
||||
const { register, handleSubmit, errors, setError, formState } = useForm<LoginFormData>();
|
||||
console.log(formState);
|
||||
const loginSubmit = (data: LoginFormData) => {
|
||||
setComplete(false);
|
||||
onSubmit(data, setComplete, setError);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import LabelColors from 'shared/constants/labelColors';
|
||||
import { Checkmark } from 'shared/icons';
|
||||
import { SaveButton, DeleteButton, LabelBox, EditLabelForm, FieldLabel, FieldName } from './Styles';
|
||||
@ -7,16 +7,25 @@ type Props = {
|
||||
labelColors: Array<LabelColor>;
|
||||
label: Label | null;
|
||||
onLabelEdit: (labelId: string | null, labelName: string, labelColor: LabelColor) => void;
|
||||
onLabelDelete?: (labelId: string) => void;
|
||||
};
|
||||
|
||||
const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
|
||||
console.log(label);
|
||||
const LabelManager = ({ labelColors, label, onLabelEdit, onLabelDelete }: Props) => {
|
||||
const $fieldName = useRef<HTMLInputElement>(null);
|
||||
const [currentLabel, setCurrentLabel] = useState(label ? label.name : '');
|
||||
const [currentColor, setCurrentColor] = useState<LabelColor | null>(label ? label.labelColor : null);
|
||||
|
||||
useEffect(() => {
|
||||
if ($fieldName.current) {
|
||||
$fieldName.current.focus();
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<EditLabelForm>
|
||||
<FieldLabel>Name</FieldLabel>
|
||||
<FieldName
|
||||
ref={$fieldName}
|
||||
id="labelName"
|
||||
type="text"
|
||||
name="name"
|
||||
@ -29,6 +38,7 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
|
||||
<div>
|
||||
{labelColors.map((labelColor: LabelColor) => (
|
||||
<LabelBox
|
||||
key={labelColor.id}
|
||||
color={labelColor.colorHex}
|
||||
onClick={() => {
|
||||
setCurrentColor(labelColor);
|
||||
@ -40,6 +50,8 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
|
||||
</div>
|
||||
<div>
|
||||
<SaveButton
|
||||
value="Save"
|
||||
type="submit"
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
console.log(currentColor);
|
||||
@ -47,10 +59,17 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
|
||||
onLabelEdit(label ? label.labelId : null, currentLabel, currentColor);
|
||||
}
|
||||
}}
|
||||
type="submit"
|
||||
value="Save"
|
||||
/>
|
||||
<DeleteButton type="submit" value="Delete" />
|
||||
{label && onLabelDelete && (
|
||||
<DeleteButton
|
||||
value="Delete"
|
||||
type="submit"
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
onLabelDelete(label.labelId);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</EditLabelForm>
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Pencil, Checkmark } from 'shared/icons';
|
||||
|
||||
import {
|
||||
@ -20,12 +20,19 @@ type Props = {
|
||||
onLabelCreate: () => void;
|
||||
};
|
||||
const LabelManager: React.FC<Props> = ({ labels, onLabelToggle, onLabelEdit, onLabelCreate }) => {
|
||||
const $fieldName = useRef<HTMLInputElement>(null);
|
||||
const [currentLabel, setCurrentLabel] = useState('');
|
||||
const [currentSearch, setCurrentSearch] = useState('');
|
||||
useEffect(() => {
|
||||
if ($fieldName.current) {
|
||||
$fieldName.current.focus();
|
||||
}
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<LabelSearch
|
||||
type="text"
|
||||
ref={$fieldName}
|
||||
placeholder="search labels..."
|
||||
onChange={e => {
|
||||
setCurrentSearch(e.currentTarget.value);
|
||||
|
@ -248,36 +248,47 @@ export const LabelBox = styled.span<{ color: string }>`
|
||||
`;
|
||||
|
||||
export const SaveButton = styled.input`
|
||||
cursor: pointer;
|
||||
background-color: #5aac44;
|
||||
background: rgb(115, 103, 240);
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
ursor: pointer;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
margin: 8px 4px 0 0;
|
||||
margin-right: 4px;
|
||||
padding: 6px 12px;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
`;
|
||||
|
||||
export const DeleteButton = styled.input`
|
||||
background-color: #cf513d;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
type="submit"font-weight: 400;
|
||||
line-height: 20px;
|
||||
margin: 8px 4px 0 0;
|
||||
padding: 6px 12px;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
float: right;
|
||||
outline: none;
|
||||
border: none;
|
||||
line-height: 20px;
|
||||
padding: 6px 12px;
|
||||
background-color: transparent;
|
||||
text-align: center;
|
||||
color: #c2c6dc;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
|
||||
margin: 0 0 0 8px;
|
||||
|
||||
border-radius: 3px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-image: initial;
|
||||
border-color: #414561;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background: rgb(115, 103, 240);
|
||||
border-color: transparent;
|
||||
}
|
||||
`;
|
||||
|
||||
export const CreateLabelButton = styled.button`
|
||||
|
@ -18,6 +18,7 @@ type PopupContextState = {
|
||||
show: (target: RefObject<HTMLElement>, content: JSX.Element) => void;
|
||||
setTab: (newTab: number) => void;
|
||||
getCurrentTab: () => number;
|
||||
hide: () => void;
|
||||
};
|
||||
|
||||
type PopupProps = {
|
||||
@ -46,11 +47,12 @@ const PopupContext = createContext<PopupContextState>({
|
||||
show: () => {},
|
||||
setTab: () => {},
|
||||
getCurrentTab: () => 0,
|
||||
hide: () => {},
|
||||
});
|
||||
|
||||
export const usePopup = () => {
|
||||
const ctx = useContext<PopupContextState>(PopupContext);
|
||||
return { showPopup: ctx.show, setTab: ctx.setTab, getCurrentTab: ctx.getCurrentTab };
|
||||
return { showPopup: ctx.show, setTab: ctx.setTab, getCurrentTab: ctx.getCurrentTab, hidePopup: ctx.hide };
|
||||
};
|
||||
|
||||
type PopupState = {
|
||||
@ -80,11 +82,9 @@ const defaultState = {
|
||||
export const PopupProvider: React.FC = ({ children }) => {
|
||||
const [currentState, setState] = useState<PopupState>(defaultState);
|
||||
const show = (target: RefObject<HTMLElement>, content: JSX.Element) => {
|
||||
console.log(target);
|
||||
if (target && target.current) {
|
||||
const bounds = target.current.getBoundingClientRect();
|
||||
if (bounds.left + 304 + 30 > window.innerWidth) {
|
||||
console.log('open!');
|
||||
setState({
|
||||
isOpen: true,
|
||||
left: bounds.left + bounds.width,
|
||||
@ -95,7 +95,6 @@ export const PopupProvider: React.FC = ({ children }) => {
|
||||
content,
|
||||
});
|
||||
} else {
|
||||
console.log('open NOT INVERT!');
|
||||
setState({
|
||||
isOpen: true,
|
||||
left: bounds.left,
|
||||
@ -108,6 +107,17 @@ export const PopupProvider: React.FC = ({ children }) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
const hide = () => {
|
||||
setState({
|
||||
isOpen: false,
|
||||
left: 0,
|
||||
top: 0,
|
||||
invert: true,
|
||||
currentTab: 0,
|
||||
previousTab: 0,
|
||||
content: null,
|
||||
});
|
||||
};
|
||||
const portalTarget = canUseDOM ? document.body : null; // appease flow
|
||||
|
||||
const setTab = (newTab: number) => {
|
||||
@ -125,7 +135,7 @@ export const PopupProvider: React.FC = ({ children }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Provider value={{ show, setTab, getCurrentTab }}>
|
||||
<Provider value={{ hide, show, setTab, getCurrentTab }}>
|
||||
{portalTarget &&
|
||||
currentState.isOpen &&
|
||||
createPortal(
|
||||
|
@ -146,6 +146,14 @@ export const TaskDetailsMarkdown = styled.div`
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
color: #c2c6dc;
|
||||
|
||||
p {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
`;
|
||||
|
||||
export const TaskDetailsControls = styled.div`
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { Bin, Cross, Plus } from 'shared/icons';
|
||||
import useOnOutsideClick from 'shared/hooks/onOutsideClick';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import TaskAssignee from 'shared/components/TaskAssignee';
|
||||
|
||||
import {
|
||||
@ -48,7 +49,9 @@ const TaskContent: React.FC<TaskContentProps> = ({ description, onEditContent })
|
||||
return description === '' ? (
|
||||
<TaskDetailsAddDetailsButton onClick={onEditContent}>Add a more detailed description</TaskDetailsAddDetailsButton>
|
||||
) : (
|
||||
<TaskDetailsMarkdown onClick={onEditContent}>{description}</TaskDetailsMarkdown>
|
||||
<TaskDetailsMarkdown onClick={onEditContent}>
|
||||
<ReactMarkdown source={description} />
|
||||
</TaskDetailsMarkdown>
|
||||
);
|
||||
};
|
||||
|
||||
@ -142,7 +145,6 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
|
||||
const onAddLabel = () => {
|
||||
onOpenAddLabelPopup(task, $addLabelRef);
|
||||
};
|
||||
console.log(task);
|
||||
return (
|
||||
<>
|
||||
<TaskActions>
|
||||
|
@ -50,7 +50,6 @@ const NavBar: React.FC<NavBarProps> = ({
|
||||
}) => {
|
||||
const $profileRef: any = useRef(null);
|
||||
const handleProfileClick = () => {
|
||||
console.log('click');
|
||||
const boundingRect = $profileRef.current.getBoundingClientRect();
|
||||
onProfileClick(boundingRect.bottom, boundingRect.right);
|
||||
};
|
||||
@ -95,7 +94,7 @@ const NavBar: React.FC<NavBarProps> = ({
|
||||
{projectMembers && (
|
||||
<ProjectMembers>
|
||||
{projectMembers.map(member => (
|
||||
<TaskAssignee size={28} member={member} onMemberProfile={onMemberProfile} />
|
||||
<TaskAssignee key={member.userID} size={28} member={member} onMemberProfile={onMemberProfile} />
|
||||
))}
|
||||
<InviteButton>Invite</InviteButton>
|
||||
</ProjectMembers>
|
||||
|
@ -269,6 +269,26 @@ export type NewProjectLabel = {
|
||||
name?: Maybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
export type DeleteProjectLabel = {
|
||||
projectLabelID: Scalars['UUID'];
|
||||
};
|
||||
|
||||
export type UpdateProjectLabelName = {
|
||||
projectLabelID: Scalars['UUID'];
|
||||
name: Scalars['String'];
|
||||
};
|
||||
|
||||
export type UpdateProjectLabel = {
|
||||
projectLabelID: Scalars['UUID'];
|
||||
labelColorID: Scalars['UUID'];
|
||||
name: Scalars['String'];
|
||||
};
|
||||
|
||||
export type UpdateProjectLabelColor = {
|
||||
projectLabelID: Scalars['UUID'];
|
||||
labelColorID: Scalars['UUID'];
|
||||
};
|
||||
|
||||
export type Mutation = {
|
||||
__typename?: 'Mutation';
|
||||
createRefreshToken: RefreshToken;
|
||||
@ -276,6 +296,10 @@ export type Mutation = {
|
||||
createTeam: Team;
|
||||
createProject: Project;
|
||||
createProjectLabel: ProjectLabel;
|
||||
deleteProjectLabel: ProjectLabel;
|
||||
updateProjectLabel: ProjectLabel;
|
||||
updateProjectLabelName: ProjectLabel;
|
||||
updateProjectLabelColor: ProjectLabel;
|
||||
createTaskGroup: TaskGroup;
|
||||
updateTaskGroupLocation: TaskGroup;
|
||||
deleteTaskGroup: DeleteTaskGroupPayload;
|
||||
@ -317,6 +341,26 @@ export type MutationCreateProjectLabelArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeleteProjectLabelArgs = {
|
||||
input: DeleteProjectLabel;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateProjectLabelArgs = {
|
||||
input: UpdateProjectLabel;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateProjectLabelNameArgs = {
|
||||
input: UpdateProjectLabelName;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateProjectLabelColorArgs = {
|
||||
input: UpdateProjectLabelColor;
|
||||
};
|
||||
|
||||
|
||||
export type MutationCreateTaskGroupArgs = {
|
||||
input: NewTaskGroup;
|
||||
};
|
||||
@ -413,7 +457,7 @@ export type CreateProjectLabelMutation = (
|
||||
& Pick<ProjectLabel, 'id' | 'createdDate' | 'name'>
|
||||
& { labelColor: (
|
||||
{ __typename?: 'LabelColor' }
|
||||
& Pick<LabelColor, 'id' | 'colorHex'>
|
||||
& Pick<LabelColor, 'id' | 'colorHex' | 'name' | 'position'>
|
||||
) }
|
||||
) }
|
||||
);
|
||||
@ -459,6 +503,19 @@ export type CreateTaskGroupMutation = (
|
||||
) }
|
||||
);
|
||||
|
||||
export type DeleteProjectLabelMutationVariables = {
|
||||
projectLabelID: Scalars['UUID'];
|
||||
};
|
||||
|
||||
|
||||
export type DeleteProjectLabelMutation = (
|
||||
{ __typename?: 'Mutation' }
|
||||
& { deleteProjectLabel: (
|
||||
{ __typename?: 'ProjectLabel' }
|
||||
& Pick<ProjectLabel, 'id'>
|
||||
) }
|
||||
);
|
||||
|
||||
export type DeleteTaskMutationVariables = {
|
||||
taskID: Scalars['String'];
|
||||
};
|
||||
@ -611,6 +668,25 @@ export type UnassignTaskMutation = (
|
||||
) }
|
||||
);
|
||||
|
||||
export type UpdateProjectLabelMutationVariables = {
|
||||
projectLabelID: Scalars['UUID'];
|
||||
labelColorID: Scalars['UUID'];
|
||||
name: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
export type UpdateProjectLabelMutation = (
|
||||
{ __typename?: 'Mutation' }
|
||||
& { updateProjectLabel: (
|
||||
{ __typename?: 'ProjectLabel' }
|
||||
& Pick<ProjectLabel, 'id' | 'createdDate' | 'name'>
|
||||
& { labelColor: (
|
||||
{ __typename?: 'LabelColor' }
|
||||
& Pick<LabelColor, 'id' | 'colorHex' | 'name' | 'position'>
|
||||
) }
|
||||
) }
|
||||
);
|
||||
|
||||
export type UpdateTaskDescriptionMutationVariables = {
|
||||
taskID: Scalars['UUID'];
|
||||
description: Scalars['String'];
|
||||
@ -715,6 +791,8 @@ export const CreateProjectLabelDocument = gql`
|
||||
labelColor {
|
||||
id
|
||||
colorHex
|
||||
name
|
||||
position
|
||||
}
|
||||
name
|
||||
}
|
||||
@ -833,6 +911,38 @@ export function useCreateTaskGroupMutation(baseOptions?: ApolloReactHooks.Mutati
|
||||
export type CreateTaskGroupMutationHookResult = ReturnType<typeof useCreateTaskGroupMutation>;
|
||||
export type CreateTaskGroupMutationResult = ApolloReactCommon.MutationResult<CreateTaskGroupMutation>;
|
||||
export type CreateTaskGroupMutationOptions = ApolloReactCommon.BaseMutationOptions<CreateTaskGroupMutation, CreateTaskGroupMutationVariables>;
|
||||
export const DeleteProjectLabelDocument = gql`
|
||||
mutation deleteProjectLabel($projectLabelID: UUID!) {
|
||||
deleteProjectLabel(input: {projectLabelID: $projectLabelID}) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type DeleteProjectLabelMutationFn = ApolloReactCommon.MutationFunction<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useDeleteProjectLabelMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useDeleteProjectLabelMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useDeleteProjectLabelMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [deleteProjectLabelMutation, { data, loading, error }] = useDeleteProjectLabelMutation({
|
||||
* variables: {
|
||||
* projectLabelID: // value for 'projectLabelID'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useDeleteProjectLabelMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>) {
|
||||
return ApolloReactHooks.useMutation<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>(DeleteProjectLabelDocument, baseOptions);
|
||||
}
|
||||
export type DeleteProjectLabelMutationHookResult = ReturnType<typeof useDeleteProjectLabelMutation>;
|
||||
export type DeleteProjectLabelMutationResult = ApolloReactCommon.MutationResult<DeleteProjectLabelMutation>;
|
||||
export type DeleteProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>;
|
||||
export const DeleteTaskDocument = gql`
|
||||
mutation deleteTask($taskID: String!) {
|
||||
deleteTask(input: {taskID: $taskID}) {
|
||||
@ -1147,6 +1257,48 @@ export function useUnassignTaskMutation(baseOptions?: ApolloReactHooks.MutationH
|
||||
export type UnassignTaskMutationHookResult = ReturnType<typeof useUnassignTaskMutation>;
|
||||
export type UnassignTaskMutationResult = ApolloReactCommon.MutationResult<UnassignTaskMutation>;
|
||||
export type UnassignTaskMutationOptions = ApolloReactCommon.BaseMutationOptions<UnassignTaskMutation, UnassignTaskMutationVariables>;
|
||||
export const UpdateProjectLabelDocument = gql`
|
||||
mutation updateProjectLabel($projectLabelID: UUID!, $labelColorID: UUID!, $name: String!) {
|
||||
updateProjectLabel(input: {projectLabelID: $projectLabelID, labelColorID: $labelColorID, name: $name}) {
|
||||
id
|
||||
createdDate
|
||||
labelColor {
|
||||
id
|
||||
colorHex
|
||||
name
|
||||
position
|
||||
}
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type UpdateProjectLabelMutationFn = ApolloReactCommon.MutationFunction<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useUpdateProjectLabelMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useUpdateProjectLabelMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useUpdateProjectLabelMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [updateProjectLabelMutation, { data, loading, error }] = useUpdateProjectLabelMutation({
|
||||
* variables: {
|
||||
* projectLabelID: // value for 'projectLabelID'
|
||||
* labelColorID: // value for 'labelColorID'
|
||||
* name: // value for 'name'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useUpdateProjectLabelMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>) {
|
||||
return ApolloReactHooks.useMutation<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>(UpdateProjectLabelDocument, baseOptions);
|
||||
}
|
||||
export type UpdateProjectLabelMutationHookResult = ReturnType<typeof useUpdateProjectLabelMutation>;
|
||||
export type UpdateProjectLabelMutationResult = ApolloReactCommon.MutationResult<UpdateProjectLabelMutation>;
|
||||
export type UpdateProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectLabelMutation, UpdateProjectLabelMutationVariables>;
|
||||
export const UpdateTaskDescriptionDocument = gql`
|
||||
mutation updateTaskDescription($taskID: UUID!, $description: String!) {
|
||||
updateTaskDescription(input: {taskID: $taskID, description: $description}) {
|
||||
|
@ -5,6 +5,8 @@ mutation createProjectLabel($projectID: UUID!, $labelColorID: UUID!, $name: Stri
|
||||
labelColor {
|
||||
id
|
||||
colorHex
|
||||
name
|
||||
position
|
||||
}
|
||||
name
|
||||
}
|
||||
|
5
web/src/shared/graphql/deleteProjectLabel.graphqls
Normal file
5
web/src/shared/graphql/deleteProjectLabel.graphqls
Normal file
@ -0,0 +1,5 @@
|
||||
mutation deleteProjectLabel($projectLabelID: UUID!) {
|
||||
deleteProjectLabel(input: { projectLabelID:$projectLabelID }) {
|
||||
id
|
||||
}
|
||||
}
|
13
web/src/shared/graphql/updateProjectLabel.graphqls
Normal file
13
web/src/shared/graphql/updateProjectLabel.graphqls
Normal file
@ -0,0 +1,13 @@
|
||||
mutation updateProjectLabel($projectLabelID: UUID!, $labelColorID: UUID!, $name: String!) {
|
||||
updateProjectLabel(input:{projectLabelID:$projectLabelID, labelColorID: $labelColorID, name: $name}) {
|
||||
id
|
||||
createdDate
|
||||
labelColor {
|
||||
id
|
||||
colorHex
|
||||
name
|
||||
position
|
||||
}
|
||||
name
|
||||
}
|
||||
}
|
@ -9,9 +9,7 @@ export const moveItemWithinArray = (arr: Array<DraggableElement>, item: Draggabl
|
||||
|
||||
export const insertItemIntoArray = (arr: Array<DraggableElement>, item: DraggableElement, index: number) => {
|
||||
const arrClone = [...arr];
|
||||
console.log(arrClone, index, item);
|
||||
arrClone.splice(index, 0, item);
|
||||
console.log(arrClone);
|
||||
return arrClone;
|
||||
};
|
||||
|
||||
@ -32,21 +30,12 @@ export const getNewDraggablePosition = (afterDropDraggables: Array<DraggableElem
|
||||
return 65535;
|
||||
}
|
||||
if (!prevDraggable) {
|
||||
console.log(
|
||||
`in front of list [n/a : ${nextDraggable.id}]: ${nextDraggable.position} / 2.0 = ${nextDraggable.position / 2.0}`,
|
||||
);
|
||||
return nextDraggable.position / 2.0;
|
||||
}
|
||||
if (!nextDraggable) {
|
||||
console.log(
|
||||
`end of list [${prevDraggable.id} : n/a] : ${prevDraggable.position} * 2.0 = ${prevDraggable.position * 2.0}`,
|
||||
);
|
||||
return prevDraggable.position * 2.0;
|
||||
}
|
||||
const newPos = (prevDraggable.position + nextDraggable.position) / 2.0;
|
||||
console.log(
|
||||
`middle of two cards [${prevDraggable.id} : ${nextDraggable.id}] : ${prevDraggable.position} + ${nextDraggable.position} / 2.0 = ${newPos}`,
|
||||
);
|
||||
return newPos;
|
||||
};
|
||||
|
||||
@ -58,7 +47,6 @@ export const isPositionChanged = (source: DraggableLocation, destination: Dragga
|
||||
if (!destination) return false;
|
||||
const isSameList = destination.droppableId === source.droppableId;
|
||||
const isSamePosition = destination.index === source.index;
|
||||
console.log(`isSameList: ${isSameList} : isSamePosition: ${isSamePosition}`);
|
||||
return !isSameList || !isSamePosition;
|
||||
};
|
||||
|
||||
|
8
web/src/wdy.ts
Normal file
8
web/src/wdy.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
const whyDidYouRender = require('@welldone-software/why-did-you-render');
|
||||
whyDidYouRender(React, {
|
||||
trackAllPureComponents: true,
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user