feature: ability to delete task groups

This commit is contained in:
Jordan Knott
2020-04-11 14:24:45 -05:00
parent 063be79b89
commit c250ce574b
27 changed files with 824 additions and 221 deletions

View File

@ -33,6 +33,7 @@
"react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }],
"react/prop-types": 0,
"react/jsx-props-no-spreading": "off",
"no-param-reassign": "off",
"import/extensions": [
"error",
"ignorePackages",

View File

@ -39,6 +39,7 @@
"graphql": "^15.0.0",
"graphql-tag": "^2.10.3",
"history": "^4.10.1",
"immer": "^6.0.3",
"lodash": "^4.17.15",
"prop-types": "^15.7.2",
"react": "^16.12.0",

View File

@ -1,4 +1,5 @@
import React, { useState } from 'react';
import produce from 'immer';
import styled from 'styled-components/macro';
import { useParams } from 'react-router-dom';
import {
@ -9,6 +10,7 @@ import {
useUpdateTaskLocationMutation,
useUpdateTaskGroupLocationMutation,
useCreateTaskGroupMutation,
useDeleteTaskGroupMutation,
} from 'shared/generated/graphql';
import Navbar from 'App/Navbar';
@ -79,6 +81,26 @@ const Project = () => {
const [quickCardEditor, setQuickCardEditor] = useState(initialQuickCardEditorState);
const [updateTaskLocation] = useUpdateTaskLocationMutation();
const [updateTaskGroupLocation] = useUpdateTaskGroupLocationMutation();
const [deleteTaskGroup] = useDeleteTaskGroupMutation({
onCompleted: deletedTaskGroupData => {
const nextState = produce(listsData, (draftState: State) => {
delete draftState.columns[deletedTaskGroupData.deleteTaskGroup.taskGroup.taskGroupID];
const filteredTasks = Object.keys(listsData.tasks)
.filter(
taskID =>
listsData.tasks[taskID].taskGroup.taskGroupID !==
deletedTaskGroupData.deleteTaskGroup.taskGroup.taskGroupID,
)
.reduce((obj: TaskState, key: string) => {
obj[key] = listsData.tasks[key];
return obj;
}, {});
draftState.tasks = filteredTasks;
});
setListsData(nextState);
},
});
const [createTaskGroup] = useCreateTaskGroupMutation({
onCompleted: newTaskGroupData => {
const newListsData = {
@ -167,9 +189,14 @@ const Project = () => {
setListsData(newListsData);
},
});
const onCardDrop = (droppedTask: any) => {
const onCardDrop = (droppedTask: Task) => {
console.log(droppedTask);
updateTaskLocation({
variables: { taskID: droppedTask.taskID, taskGroupID: droppedTask.taskGroupID, position: droppedTask.position },
variables: {
taskID: droppedTask.taskID,
taskGroupID: droppedTask.taskGroup.taskGroupID,
position: droppedTask.position,
},
});
const newState = {
...listsData,
@ -229,6 +256,14 @@ const Project = () => {
</TitleWrapper>
<Board>
<Lists
onExtraMenuOpen={(taskGroupID, pos, size) => {
setPopupData({
isOpen: true,
left: pos.left,
top: pos.top + size.height + 5,
taskGroupID,
});
}}
onQuickEditorOpen={onQuickEditorOpen}
onCardCreate={onCardCreate}
{...listsData}
@ -271,7 +306,13 @@ const Project = () => {
onClose={() => setPopupData(initialPopupState)}
left={popupData.left}
>
<ListActions taskGroupID={popupData.taskGroupID} />
<ListActions
taskGroupID={popupData.taskGroupID}
onArchiveTaskGroup={taskGroupID => {
deleteTaskGroup({ variables: { taskGroupID } });
setPopupData(initialPopupState);
}}
/>
</PopupMenu>
)}
</>

View File

@ -1,3 +1,8 @@
interface DraggableElement {
id: string;
position: number;
}
type ContextMenuEvent = {
left: number;
top: number;

View File

@ -1,6 +1,8 @@
import styled, { css } from 'styled-components';
import TextareaAutosize from 'react-autosize-textarea/lib';
export const Container = styled.div``;
export const Wrapper = styled.div<{ editorOpen: boolean }>`
display: inline-block;
background-color: hsla(0, 0%, 100%, 0.24);

View File

@ -3,6 +3,7 @@ import { Plus, Cross } from 'shared/icons';
import useOnOutsideClick from 'shared/hooks/onOutsideClick';
import {
Container,
Wrapper,
Placeholder,
AddIconWrapper,
@ -79,26 +80,28 @@ const AddList: React.FC<AddListProps> = ({ onSave }) => {
useOnOutsideClick($wrapperRef, editorOpen, onOutsideClick, null);
return (
<Wrapper
ref={$wrapperRef}
editorOpen={editorOpen}
onClick={() => {
if (!editorOpen) {
setEditorOpen(true);
}
}}
>
{editorOpen ? (
<NameEditor onCancel={() => setEditorOpen(false)} onSave={onSave} />
) : (
<Placeholder>
<AddIconWrapper>
<Plus size={12} color="#c2c6dc" />
</AddIconWrapper>
Add another list
</Placeholder>
)}
</Wrapper>
<Container>
<Wrapper
ref={$wrapperRef}
editorOpen={editorOpen}
onClick={() => {
if (!editorOpen) {
setEditorOpen(true);
}
}}
>
{editorOpen ? (
<NameEditor onCancel={() => setEditorOpen(false)} onSave={onSave} />
) : (
<Placeholder>
<AddIconWrapper>
<Plus size={12} color="#c2c6dc" />
</AddIconWrapper>
Add another list
</Placeholder>
)}
</Wrapper>
</Container>
);
};

View File

@ -1,4 +1,5 @@
import React from 'react';
import { action } from '@storybook/addon-actions';
import ListActions from '.';
export default {
@ -13,5 +14,5 @@ export default {
};
export const Default = () => {
return <ListActions taskGroupID="1" />;
return <ListActions taskGroupID="1" onArchiveTaskGroup={action('on archive task group')} />;
};

View File

@ -3,8 +3,10 @@ import { ListActionsWrapper, ListActionItemWrapper, ListActionItem, ListSeparato
type Props = {
taskGroupID: string;
onArchiveTaskGroup: (taskGroupID: string) => void;
};
const LabelManager = ({ taskGroupID }: Props) => {
const LabelManager: React.FC<Props> = ({ taskGroupID, onArchiveTaskGroup }) => {
return (
<>
<ListActionsWrapper>
@ -38,7 +40,7 @@ const LabelManager = ({ taskGroupID }: Props) => {
</ListActionsWrapper>
<ListSeparator />
<ListActionsWrapper>
<ListActionItemWrapper>
<ListActionItemWrapper onClick={() => onArchiveTaskGroup(taskGroupID)}>
<ListActionItem>Archive This List</ListActionItem>
</ListActionItemWrapper>
</ListActionsWrapper>

View File

@ -70,25 +70,28 @@ export const Default = () => {
...listsData,
tasks: {
...listsData.tasks,
[droppedTask.id]: droppedTask,
[droppedTask.taskGroupID]: droppedTask,
},
};
console.log(newState);
setListsData(newState);
};
const onListDrop = (droppedColumn: any) => {
console.log(droppedColumn);
const newState = {
...listsData,
columns: {
...listsData.columns,
[droppedColumn.id]: droppedColumn,
[droppedColumn.taskGroupID]: droppedColumn,
},
};
console.log(newState);
setListsData(newState);
};
return (
<Lists
{...listsData}
onExtraMenuOpen={action('extra menu open')}
onQuickEditorOpen={action('card composer open')}
onCardDrop={onCardDrop}
onListDrop={onListDrop}
@ -203,6 +206,7 @@ export const ListsWithManyList = () => {
onCardDrop={onCardDrop}
onListDrop={onListDrop}
onCreateList={action('create list')}
onExtraMenuOpen={action('extra menu open')}
/>
);
};

View File

@ -1,7 +1,6 @@
import styled from 'styled-components';
export const Container = styled.div`
flex-grow: 1;
user-select: none;
white-space: nowrap;
margin-bottom: 8px;
@ -10,4 +9,7 @@ export const Container = styled.div`
padding-bottom: 8px;
`;
export const BoardWrapper = styled.div`
display: flex;
`;
export default Container;

View File

@ -11,7 +11,7 @@ import {
getAfterDropDraggableList,
} from 'shared/utils/draggables';
import { Container } from './Styles';
import { Container, BoardWrapper } from './Styles';
interface Columns {
[key: string]: TaskGroup;
@ -23,25 +23,56 @@ interface Tasks {
type Props = {
columns: Columns;
tasks: Tasks;
onCardDrop: any;
onListDrop: any;
onCardDrop: (task: Task) => void;
onListDrop: (taskGroup: TaskGroup) => void;
onCardCreate: (taskGroupID: string, name: string) => void;
onQuickEditorOpen: (e: ContextMenuEvent) => void;
onCreateList: (listName: string) => void;
onExtraMenuOpen: (taskGroupID: string, pos: ElementPosition, size: ElementSize) => void;
};
const Lists = ({ columns, tasks, onCardDrop, onListDrop, onCardCreate, onQuickEditorOpen, onCreateList }: Props) => {
const Lists: React.FC<Props> = ({
columns,
tasks,
onCardDrop,
onListDrop,
onCardCreate,
onQuickEditorOpen,
onCreateList,
onExtraMenuOpen,
}) => {
const onDragEnd = ({ draggableId, source, destination, type }: DropResult) => {
if (typeof destination === 'undefined') return;
if (!isPositionChanged(source, destination)) return;
const isList = type === 'column';
const isSameList = destination.droppableId === source.droppableId;
const droppedDraggable = isList ? columns[draggableId] : tasks[draggableId];
const droppedDraggable: DraggableElement = isList
? {
id: draggableId,
position: columns[draggableId].position,
}
: {
id: draggableId,
position: tasks[draggableId].position,
};
const beforeDropDraggables = isList
? getSortedDraggables(Object.values(columns))
: getSortedDraggables(Object.values(tasks).filter((t: any) => t.taskGroupID === destination.droppableId));
? getSortedDraggables(
Object.values(columns).map(column => {
return { id: column.taskGroupID, position: column.position };
}),
)
: getSortedDraggables(
Object.values(tasks)
.filter((t: any) => t.taskGroup.taskGroupID === destination.droppableId)
.map(task => {
return { id: task.taskID, position: task.position };
}),
);
console.log(beforeDropDraggables);
console.log(destination);
console.log(droppedDraggable);
const afterDropDraggables = getAfterDropDraggableList(
beforeDropDraggables,
droppedDraggable,
@ -49,16 +80,19 @@ const Lists = ({ columns, tasks, onCardDrop, onListDrop, onCardCreate, onQuickEd
isSameList,
destination,
);
console.log(afterDropDraggables);
const newPosition = getNewDraggablePosition(afterDropDraggables, destination.index);
if (isList) {
const droppedList = columns[droppedDraggable.id];
onListDrop({
...droppedDraggable,
...droppedList,
position: newPosition,
});
} else {
const droppedCard = tasks[droppedDraggable.id];
const newCard = {
...droppedDraggable,
...droppedCard,
position: newPosition,
taskGroupID: destination.droppableId,
};
@ -66,89 +100,96 @@ const Lists = ({ columns, tasks, onCardDrop, onListDrop, onCardCreate, onQuickEd
}
};
const orderedColumns = getSortedDraggables(Object.values(columns));
const orderedColumns = getSortedDraggables(
Object.values(columns).map(column => {
return { id: column.taskGroupID, position: column.position };
}),
);
const [currentComposer, setCurrentComposer] = useState('');
return (
<DragDropContext onDragEnd={onDragEnd}>
<Droppable direction="horizontal" type="column" droppableId="root">
{provided => (
<Container {...provided.droppableProps} ref={provided.innerRef}>
{orderedColumns.map((column: TaskGroup, index: number) => {
const columnCards = getSortedDraggables(
Object.values(tasks).filter((t: Task) => t.taskGroup.taskGroupID === column.taskGroupID),
);
return (
<Draggable draggableId={column.taskGroupID} key={column.taskGroupID} index={index}>
{columnDragProvided => (
<List
id={column.taskGroupID}
name={column.name}
key={column.taskGroupID}
onOpenComposer={id => setCurrentComposer(id)}
isComposerOpen={currentComposer === column.taskGroupID}
onSaveName={name => console.log(name)}
index={index}
tasks={columnCards}
ref={columnDragProvided.innerRef}
wrapperProps={columnDragProvided.draggableProps}
headerProps={columnDragProvided.dragHandleProps}
onExtraMenuOpen={(taskGroupID, pos, size) => console.log(taskGroupID, pos, size)}
>
<Droppable type="tasks" droppableId={column.taskGroupID}>
{columnDropProvided => (
<ListCards ref={columnDropProvided.innerRef} {...columnDropProvided.droppableProps}>
{columnCards.map((task: Task, taskIndex: any) => {
return (
<Draggable key={task.taskID} draggableId={task.taskID} index={taskIndex}>
{taskProvided => {
return (
<Card
wrapperProps={{
...taskProvided.draggableProps,
...taskProvided.dragHandleProps,
}}
ref={taskProvided.innerRef}
taskID={task.taskID}
taskGroupID={column.taskGroupID}
description=""
title={task.name}
labels={task.labels}
onClick={e => console.log(e)}
onContextMenu={onQuickEditorOpen}
/>
);
}}
</Draggable>
);
})}
{columnDropProvided.placeholder}
<BoardWrapper>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable direction="horizontal" type="column" droppableId="root">
{provided => (
<Container {...provided.droppableProps} ref={provided.innerRef}>
{orderedColumns.map((columnDraggable, index: number) => {
const column = columns[columnDraggable.id];
const columnCards = Object.values(tasks)
.filter((t: Task) => t.taskGroup.taskGroupID === column.taskGroupID)
.sort((a, b) => a.position - b.position);
return (
<Draggable draggableId={column.taskGroupID} key={column.taskGroupID} index={index}>
{columnDragProvided => (
<List
id={column.taskGroupID}
name={column.name}
key={column.taskGroupID}
onOpenComposer={id => setCurrentComposer(id)}
isComposerOpen={currentComposer === column.taskGroupID}
onSaveName={name => console.log(name)}
index={index}
tasks={columnCards}
ref={columnDragProvided.innerRef}
wrapperProps={columnDragProvided.draggableProps}
headerProps={columnDragProvided.dragHandleProps}
onExtraMenuOpen={onExtraMenuOpen}
>
<Droppable type="tasks" droppableId={column.taskGroupID}>
{columnDropProvided => (
<ListCards ref={columnDropProvided.innerRef} {...columnDropProvided.droppableProps}>
{columnCards.map((task: Task, taskIndex: any) => {
return (
<Draggable key={task.taskID} draggableId={task.taskID} index={taskIndex}>
{taskProvided => {
return (
<Card
wrapperProps={{
...taskProvided.draggableProps,
...taskProvided.dragHandleProps,
}}
ref={taskProvided.innerRef}
taskID={task.taskID}
taskGroupID={column.taskGroupID}
description=""
title={task.name}
labels={task.labels}
onClick={e => console.log(e)}
onContextMenu={onQuickEditorOpen}
/>
);
}}
</Draggable>
);
})}
{columnDropProvided.placeholder}
{currentComposer === column.taskGroupID && (
<CardComposer
onClose={() => {
setCurrentComposer('');
}}
onCreateCard={name => {
onCardCreate(column.taskGroupID, name);
}}
isOpen
/>
)}
</ListCards>
)}
</Droppable>
</List>
)}
</Draggable>
);
})}
{provided.placeholder}
<AddList onSave={onCreateList} />
</Container>
)}
</Droppable>
</DragDropContext>
{currentComposer === column.taskGroupID && (
<CardComposer
onClose={() => {
setCurrentComposer('');
}}
onCreateCard={name => {
onCardCreate(column.taskGroupID, name);
}}
isOpen
/>
)}
</ListCards>
)}
</Droppable>
</List>
)}
</Draggable>
);
})}
{provided.placeholder}
</Container>
)}
</Droppable>
</DragDropContext>
<AddList onSave={onCreateList} />
</BoardWrapper>
);
};

View File

@ -77,7 +77,7 @@ export const ListActionsPopup = () => {
onClose={() => setPopupData(initalState)}
left={popupData.left}
>
<ListActions taskGroupID="1" />
<ListActions taskGroupID="1" onArchiveTaskGroup={action('archive task group')} />
</PopupMenu>
)}
<button

View File

@ -180,6 +180,17 @@ export type NewTaskGroupLocation = {
position: Scalars['Float'];
};
export type DeleteTaskGroupInput = {
taskGroupID: Scalars['UUID'];
};
export type DeleteTaskGroupPayload = {
__typename?: 'DeleteTaskGroupPayload';
ok: Scalars['Boolean'];
affectedRows: Scalars['Int'];
taskGroup: TaskGroup;
};
export type Mutation = {
__typename?: 'Mutation';
createRefreshToken: RefreshToken;
@ -189,11 +200,12 @@ export type Mutation = {
createProject: Project;
createTaskGroup: TaskGroup;
updateTaskGroupLocation: TaskGroup;
deleteTaskGroup: DeleteTaskGroupPayload;
createTask: Task;
updateTaskLocation: Task;
logoutUser: Scalars['Boolean'];
updateTaskName: Task;
deleteTask: DeleteTaskPayload;
logoutUser: Scalars['Boolean'];
};
@ -232,6 +244,11 @@ export type MutationUpdateTaskGroupLocationArgs = {
};
export type MutationDeleteTaskGroupArgs = {
input: DeleteTaskGroupInput;
};
export type MutationCreateTaskArgs = {
input: NewTask;
};
@ -242,11 +259,6 @@ export type MutationUpdateTaskLocationArgs = {
};
export type MutationLogoutUserArgs = {
input: LogoutUser;
};
export type MutationUpdateTaskNameArgs = {
input: UpdateTaskName;
};
@ -256,6 +268,11 @@ export type MutationDeleteTaskArgs = {
input: DeleteTaskInput;
};
export type MutationLogoutUserArgs = {
input: LogoutUser;
};
export type CreateTaskMutationVariables = {
taskGroupID: Scalars['String'];
name: Scalars['String'];
@ -303,6 +320,27 @@ export type DeleteTaskMutation = (
) }
);
export type DeleteTaskGroupMutationVariables = {
taskGroupID: Scalars['UUID'];
};
export type DeleteTaskGroupMutation = (
{ __typename?: 'Mutation' }
& { deleteTaskGroup: (
{ __typename?: 'DeleteTaskGroupPayload' }
& Pick<DeleteTaskGroupPayload, 'ok' | 'affectedRows'>
& { taskGroup: (
{ __typename?: 'TaskGroup' }
& Pick<TaskGroup, 'taskGroupID'>
& { tasks: Array<(
{ __typename?: 'Task' }
& Pick<Task, 'taskID' | 'name'>
)> }
) }
) }
);
export type FindProjectQueryVariables = {
projectId: Scalars['String'];
};
@ -494,6 +532,46 @@ export function useDeleteTaskMutation(baseOptions?: ApolloReactHooks.MutationHoo
export type DeleteTaskMutationHookResult = ReturnType<typeof useDeleteTaskMutation>;
export type DeleteTaskMutationResult = ApolloReactCommon.MutationResult<DeleteTaskMutation>;
export type DeleteTaskMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteTaskMutation, DeleteTaskMutationVariables>;
export const DeleteTaskGroupDocument = gql`
mutation deleteTaskGroup($taskGroupID: UUID!) {
deleteTaskGroup(input: {taskGroupID: $taskGroupID}) {
ok
affectedRows
taskGroup {
taskGroupID
tasks {
taskID
name
}
}
}
}
`;
export type DeleteTaskGroupMutationFn = ApolloReactCommon.MutationFunction<DeleteTaskGroupMutation, DeleteTaskGroupMutationVariables>;
/**
* __useDeleteTaskGroupMutation__
*
* To run a mutation, you first call `useDeleteTaskGroupMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useDeleteTaskGroupMutation` 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 [deleteTaskGroupMutation, { data, loading, error }] = useDeleteTaskGroupMutation({
* variables: {
* taskGroupID: // value for 'taskGroupID'
* },
* });
*/
export function useDeleteTaskGroupMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<DeleteTaskGroupMutation, DeleteTaskGroupMutationVariables>) {
return ApolloReactHooks.useMutation<DeleteTaskGroupMutation, DeleteTaskGroupMutationVariables>(DeleteTaskGroupDocument, baseOptions);
}
export type DeleteTaskGroupMutationHookResult = ReturnType<typeof useDeleteTaskGroupMutation>;
export type DeleteTaskGroupMutationResult = ApolloReactCommon.MutationResult<DeleteTaskGroupMutation>;
export type DeleteTaskGroupMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteTaskGroupMutation, DeleteTaskGroupMutationVariables>;
export const FindProjectDocument = gql`
query findProject($projectId: String!) {
findProject(input: {projectId: $projectId}) {

View File

@ -0,0 +1,13 @@
mutation deleteTaskGroup($taskGroupID: UUID!) {
deleteTaskGroup(input: { taskGroupID: $taskGroupID }) {
ok
affectedRows
taskGroup {
taskGroupID
tasks {
taskID
name
}
}
}
}

View File

@ -1,22 +0,0 @@
export const moveItemWithinArray = (arr: any, item: any, newIndex: number) => {
const arrClone = [...arr];
const oldIndex = arrClone.indexOf(item);
arrClone.splice(newIndex, 0, arrClone.splice(oldIndex, 1)[0]);
return arrClone;
};
export const insertItemIntoArray = (arr: any, item: any, index: number) => {
const arrClone = [...arr];
arrClone.splice(index, 0, item);
return arrClone;
};
export const updateArrayItemById = (arr: any, itemId: any, fields: any) => {
const arrClone = [...arr];
const item = arrClone.find(({ id }) => id === itemId);
if (item) {
const itemIndex = arrClone.indexOf(item);
arrClone.splice(itemIndex, 1, { ...item, ...fields });
}
return arrClone;
};

View File

@ -1,26 +1,58 @@
import { moveItemWithinArray, insertItemIntoArray } from 'shared/utils/arrays';
import { DraggableLocation } from 'react-beautiful-dnd';
export const getNewDraggablePosition = (afterDropDraggables: any, draggableIndex: any) => {
export const moveItemWithinArray = (arr: Array<DraggableElement>, item: DraggableElement, newIndex: number) => {
const arrClone = [...arr];
const oldIndex = arrClone.findIndex(i => i.id === item.id);
arrClone.splice(newIndex, 0, arrClone.splice(oldIndex, 1)[0]);
return arrClone;
};
export const insertItemIntoArray = (arr: Array<DraggableElement>, item: DraggableElement, index: number) => {
const arrClone = [...arr];
arrClone.splice(index, 0, item);
return arrClone;
};
export const updateArrayItemById = (arr: Array<DraggableElement>, itemId: string, fields: any) => {
const arrClone = [...arr];
const item = arrClone.find(({ id }) => id === itemId);
if (item) {
const itemIndex = arrClone.indexOf(item);
arrClone.splice(itemIndex, 1, { ...item, ...fields });
}
return arrClone;
};
export const getNewDraggablePosition = (afterDropDraggables: Array<DraggableElement>, draggableIndex: number) => {
const prevDraggable = afterDropDraggables[draggableIndex - 1];
const nextDraggable = afterDropDraggables[draggableIndex + 1];
if (!prevDraggable && !nextDraggable) {
return 1;
return 65535;
}
if (!prevDraggable) {
return nextDraggable.position - 1;
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) {
return prevDraggable.position + 1;
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;
};
export const getSortedDraggables = (draggables: any) => {
export const getSortedDraggables = (draggables: Array<DraggableElement>) => {
return draggables.sort((a: any, b: any) => a.position - b.position);
};
export const isPositionChanged = (source: any, destination: any) => {
export const isPositionChanged = (source: DraggableLocation, destination: DraggableLocation) => {
if (!destination) return false;
const isSameList = destination.droppableId === source.droppableId;
const isSamePosition = destination.index === source.index;
@ -28,11 +60,11 @@ export const isPositionChanged = (source: any, destination: any) => {
};
export const getAfterDropDraggableList = (
beforeDropDraggables: any,
droppedDraggable: any,
isList: any,
isSameList: any,
destination: any,
beforeDropDraggables: Array<DraggableElement>,
droppedDraggable: DraggableElement,
isList: boolean,
isSameList: boolean,
destination: DraggableLocation,
) => {
if (isList) {
return moveItemWithinArray(beforeDropDraggables, droppedDraggable, destination.index);

View File

@ -8748,6 +8748,11 @@ immer@1.10.0:
resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d"
integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==
immer@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/immer/-/immer-6.0.3.tgz#94d5051cd724668160a900d66d85ec02816f29bd"
integrity sha512-12VvNrfSrXZdm/BJgi/KDW2soq5freVSf3I1+4CLunUM8mAGx2/0Njy0xBVzi5zewQZiwM7z1/1T+8VaI7NkmQ==
immutable@~3.7.6:
version "3.7.6"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b"