Skip to content

Commit

Permalink
Merge pull request #891 from Codeminer42/bug/drag-and-drop
Browse files Browse the repository at this point in the history
Fix: drag and drop
  • Loading branch information
GabrielRMuller authored Aug 12, 2024
2 parents 7bb2ca4 + c662595 commit 11c868d
Show file tree
Hide file tree
Showing 9 changed files with 470 additions and 401 deletions.
3 changes: 1 addition & 2 deletions app/assets/javascripts/actions/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default keyMirror({
RECEIVE_HISTORY_ERROR: null,
CLOSE_HISTORY: null,
UPDATE_STORY_SUCCESS: null,
SORT_STORIES_SUCCESS: null,
SORT_STORIES: null,
STORY_FAILURE: null,
SET_LOADING_STORY: null,
ADD_TASK: null,
Expand All @@ -45,5 +45,4 @@ export default keyMirror({
TOGGLE_COLUMN_VISIBILITY: null,
REVERT_TO_CALCULATED_VELOCITY: null,
SIMULATE_SPRINT_VELOCITY: null,
OPTIMISTICALLY_UPDATE: null,
});
26 changes: 15 additions & 11 deletions app/assets/javascripts/actions/story.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,12 @@ export const updateStorySuccess = (story, from) => ({
from,
});

export const sortStoriesSuccess = (stories, from) => ({
type: actionTypes.SORT_STORIES_SUCCESS,
export const sortStories = (stories, from) => ({
type: actionTypes.SORT_STORIES,
stories,
from,
});

export const optimisticallyUpdate = (story, from) => ({
type: actionTypes.OPTIMISTICALLY_UPDATE,
story,
from,
});

export const storyFailure = (id, error, from) => ({
type: actionTypes.STORY_FAILURE,
id,
Expand Down Expand Up @@ -227,13 +221,19 @@ export const dragDropStory =

const newStory = Story.addNewAttributes(story, newAttributes);

const storiesWithUpdatedPositions = Story.sortOptimistically(
storiesWithScope(stories, from),
newStory
);

try {
dispatch(optimisticallyUpdate(newStory, from));
// Optimistic Update:
dispatch(sortStories(storiesWithUpdatedPositions, from));

const updatedStories = await Story.updatePosition(newStory);

await wait(300);
return dispatch(sortStoriesSuccess(updatedStories, from));
return dispatch(sortStories(updatedStories, from));
} catch (error) {
dispatch(sendErrorNotification(error));
return dispatch(storyFailure(story.id, error, from));
Expand All @@ -256,7 +256,11 @@ export const saveStory =
Story.needConfirmation,
{
onConfirmed: async () => {
const newStory = await Story.post(story._editing, projectId);
const newPosition = Story.getHighestNewPosition(
storiesWithScope(stories, from)
);
const storyWithNewPosition = { ...story._editing, newPosition };
const newStory = await Story.post(storyWithNewPosition, projectId);
dispatch(
addStory({ story: newStory, id: story._editing.id }, from)
);
Expand Down
32 changes: 30 additions & 2 deletions app/assets/javascripts/models/beta/story.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export const needConfirmation = story =>
story.state === status.RELEASE;

export const comparePosition = (a, b) => {
const positionA = a.newPosition;
const positionB = b.newPosition;
const positionA = Number(a.newPosition);
const positionB = Number(b.newPosition);

return compareValues(positionA, positionB);
};
Expand Down Expand Up @@ -138,6 +138,16 @@ export const update = async (story, projectId, options) => {
return deserialize(data.story, options);
};

export const getHighestNewPosition = stories => {
if (stories.length === 1) {
return 1;
}
const storiesNewPosition = stories.map(story => story.newPosition);
const highestPositionValue = Math.max(...storiesNewPosition);

return highestPositionValue + 1;
};

export const post = async (story, projectId) => {
const serializedStory = serialize(story);

Expand Down Expand Up @@ -469,3 +479,21 @@ export const donePoints = stories =>

export const remainingPoints = stories =>
totalPoints(stories) - donePoints(stories);

export const sortOptimistically = (stories, newStory) => {
const isChillyBinStory = isUnscheduled(newStory);
const targetStories = stories.filter(
story => isUnscheduled(story) === isChillyBinStory
);

const storiesToUpdate = targetStories.filter(
story =>
story.newPosition >= newStory.newPosition && story.id !== newStory.id
);
const updatedPositions = storiesToUpdate.map(story => ({
...story,
newPosition: story.newPosition + 1,
}));

return [...updatedPositions, newStory];
};
16 changes: 1 addition & 15 deletions app/assets/javascripts/reducers/stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ const storiesReducer = (state = initialState, action) => {
);
})
);
case actionTypes.SORT_STORIES_SUCCESS:
case actionTypes.SORT_STORIES:
return normalizeAllScopes(
allScopes(state, null, stories => {
return stories.map(story => {
Expand All @@ -152,20 +152,6 @@ const storiesReducer = (state = initialState, action) => {
});
})
);
case actionTypes.OPTIMISTICALLY_UPDATE:
return normalizeAllScopes(
allScopes(state, action.story.id, stories => {
return stories.map(
updateIfSameId(action.story.id, story => {
const newStory = setLoadingValue(action.story, true);
return addNewAttributes(story, {
...newStory,
needsToSave: false,
});
})
);
})
);
case actionTypes.STORY_FAILURE:
return {
...state,
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def select_stories_by_params
def allowed_params
params.require(:story).permit(
:title, :description, :estimate, :story_type, :release_date,
:state, :requested_by_id, :owned_by_id, :position, :labels,
:state, :requested_by_id, :owned_by_id, :position, :new_position, :labels,
tasks_attributes: %i[id name done],
notes_attributes: %i[id note]
)
Expand Down
5 changes: 5 additions & 0 deletions app/services/beta/sort_stories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def initialize(story, sort_params)
def call
update_current_story
update_stories_positions
notify_story_update
stories
end

Expand All @@ -18,6 +19,10 @@ def update_current_story
@story.update(new_position: @new_position, state: @new_state, position: @position)
end

def notify_story_update
StoryOperations::PusherNotification.notify_changes(@story)
end

def stories_to_update
stories.where.not(id: @story.id)
end
Expand Down
Loading

0 comments on commit 11c868d

Please sign in to comment.