Skip to content

Commit

Permalink
refactor: move stories normalize and denormalize functions from model…
Browse files Browse the repository at this point in the history
…s to reducers
  • Loading branch information
Guilherme-NL committed Nov 3, 2023
1 parent 6ce9990 commit 8515d58
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 349 deletions.
12 changes: 6 additions & 6 deletions app/assets/javascripts/actions/story.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "./notifications";
import { wait } from "../services/promises";
import { storyScopes } from "../libs/beta/constants";
import { getStoriesByScope } from "../selectors/stories";
import { storiesWithScope } from "../reducers/stories";

export const createStory = (attributes, from) => ({
type: actionTypes.CREATE_STORY,
Expand Down Expand Up @@ -155,7 +155,7 @@ export const showHistory =
async (dispatch, getState, { Story }) => {
const { stories, users } = getState();

const story = Story.findById(getStoriesByScope(stories, from), storyId);
const story = Story.findById(storiesWithScope(stories, from), storyId);
dispatch(loadHistory(story.title));
try {
const activities = await Story.getHistory(
Expand All @@ -175,7 +175,7 @@ export const updateCollapsedStory =
async (dispatch, getState, { Story }) => {
const { stories } = getState();

const story = Story.findById(getStoriesByScope(stories, from), storyId);
const story = Story.findById(storiesWithScope(stories, from), storyId);
const newStory = { ...story, ...newAttributes };

return await confirmBeforeSaveIfNeeded(
Expand Down Expand Up @@ -223,7 +223,7 @@ export const dragDropStory =
async (dispatch, getState, { Story }) => {
const { stories } = getState();

const story = Story.findById(getStoriesByScope(stories, from), storyId);
const story = Story.findById(storiesWithScope(stories, from), storyId);

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

Expand All @@ -245,7 +245,7 @@ export const saveStory =
async (dispatch, getState, { Story }) => {
const { stories } = getState();

const story = Story.findById(getStoriesByScope(stories, from), storyId);
const story = Story.findById(storiesWithScope(stories, from), storyId);

dispatch(setLoadingStory(story.id, from));

Expand Down Expand Up @@ -347,7 +347,7 @@ export const deleteStory =
const { stories } = getState();

const storyTitle = Story.findById(
getStoriesByScope(stories, from),
storiesWithScope(stories, from),
storyId
).title;

Expand Down
45 changes: 0 additions & 45 deletions app/assets/javascripts/models/beta/story.js
Original file line number Diff line number Diff line change
Expand Up @@ -469,48 +469,3 @@ export const donePoints = (stories) =>

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

export const normalizeStories = (stories) => {
return stories.reduce(
(acc, story) => {
const storyId = story.id;

acc.stories.byId[storyId] = { ...story };
acc.stories.allIds.push(storyId);

return acc;
},
{
stories: {
byId: {},
allIds: [],
},
}
);
};

export const denormalizeStories = (stories) => {
const normalizedStories = stories.stories;

if (!normalizedStories || normalizedStories.allIds.length === 0) {
return [];
}

const denormalizedStories = normalizedStories.allIds.map((storyId) => {
return normalizedStories.byId[storyId];
});

return denormalizedStories;
};

export const denormalizeState = (state) => ({
epic: denormalizeStories(state[storyScopes.EPIC]),
all: denormalizeStories(state[storyScopes.ALL]),
search: denormalizeStories(state[storyScopes.SEARCH]),
});

export const normalizeState = (state) => ({
epic: normalizeStories(state[storyScopes.EPIC]),
all: normalizeStories(state[storyScopes.ALL]),
search: normalizeStories(state[storyScopes.SEARCH]),
});
2 changes: 1 addition & 1 deletion app/assets/javascripts/reducers/pastIterations.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const denormalizePastIterations = (pastIterations) => {
return denormalizedPastIterations;
};

export const getDenormalizedIterations = (pastIterations) =>
export const denormalizedIterations = (pastIterations) =>
denormalizePastIterations(pastIterations);

export default pastIterationsReducer;
76 changes: 58 additions & 18 deletions app/assets/javascripts/reducers/stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,7 @@ import * as Task from "models/beta/task";
import * as Label from "models/beta/label";
import { updateIfSameId } from "../services/updateIfSameId";
import { storyScopes } from "./../libs/beta/constants";
import {
denormalizeStories,
isEpic,
isSearch,
normalizeStories,
isNew,
normalizeState,
} from "../models/beta/story";
import { getStoriesByScope } from "../selectors/stories";
import { isEpic, isSearch, isNew } from "../models/beta/story";

const initialState = {
[storyScopes.ALL]: {},
Expand Down Expand Up @@ -129,7 +121,7 @@ const storiesReducer = (state = initialState, action) => {
),
};
case actionTypes.UPDATE_STORY_SUCCESS:
return normalizeState(
return normalizeAllScopes(
allScopes(state, action.story.id, (stories) => {
return stories.map(
updateIfSameId(action.story.id, (story) =>
Expand All @@ -143,7 +135,7 @@ const storiesReducer = (state = initialState, action) => {
})
);
case actionTypes.SORT_STORIES_SUCCESS:
return normalizeState(
return normalizeAllScopes(
allScopes(state, null, (stories) => {
return stories.map((story) => {
const editingStory = action.stories.find(
Expand All @@ -161,7 +153,7 @@ const storiesReducer = (state = initialState, action) => {
})
);
case actionTypes.OPTIMISTICALLY_UPDATE:
return normalizeState(
return normalizeAllScopes(
allScopes(state, action.story.id, (stories) => {
return stories.map(
updateIfSameId(action.story.id, (story) => {
Expand Down Expand Up @@ -226,7 +218,7 @@ const storiesReducer = (state = initialState, action) => {
),
};
case actionTypes.DELETE_STORY_SUCCESS:
return normalizeState(
return normalizeAllScopes(
allScopes(state, action.id, (stories) => {
return stories.filter((story) => story.id !== action.id);
})
Expand Down Expand Up @@ -317,11 +309,9 @@ const withScope = (reducer) => (state, action) => {
};

const allScopes = (stories, storyId, mutation) => ({
[storyScopes.ALL]: mutation(getStoriesByScope(stories, storyScopes.ALL)),
[storyScopes.SEARCH]: mutation(
getStoriesByScope(stories, storyScopes.SEARCH)
),
[storyScopes.EPIC]: mutation(getStoriesByScope(stories, storyScopes.EPIC)),
[storyScopes.ALL]: mutation(storiesWithScope(stories, storyScopes.ALL)),
[storyScopes.SEARCH]: mutation(storiesWithScope(stories, storyScopes.SEARCH)),
[storyScopes.EPIC]: mutation(storiesWithScope(stories, storyScopes.EPIC)),
});

const mergeWithFetchedStories = (currentStories, fetchedStories) => {
Expand Down Expand Up @@ -421,4 +411,54 @@ const filterAndRemoveStories = (mergedStories, fetchedStories) => {
return updatedMergedStories;
};

const normalizeStories = (stories) => {
return stories.reduce(
(acc, story) => {
const storyId = story.id;

acc.stories.byId[storyId] = { ...story };
acc.stories.allIds.push(storyId);

return acc;
},
{
stories: {
byId: {},
allIds: [],
},
}
);
};

const denormalizeStories = (stories) => {
const normalizedStories = stories.stories;

if (!normalizedStories || normalizedStories.allIds.length === 0) {
return [];
}

const denormalizedStories = normalizedStories.allIds.map((storyId) => {
return normalizedStories.byId[storyId];
});

return denormalizedStories;
};

export const storiesWithScope = (state, scope) => {
const stories = state[scope || storyScopes.ALL];
return denormalizeStories(stories);
};

export const denormalizeAllScopes = (state) => ({
epic: storiesWithScope(state, storyScopes.EPIC),
all: storiesWithScope(state, storyScopes.ALL),
search: storiesWithScope(state, storyScopes.SEARCH),
});

const normalizeAllScopes = (state) => ({
epic: normalizeStories(state[storyScopes.EPIC]),
all: normalizeStories(state[storyScopes.ALL]),
search: normalizeStories(state[storyScopes.SEARCH]),
});

export default withScope(storiesReducer);
18 changes: 8 additions & 10 deletions app/assets/javascripts/selectors/columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { mountPastIterations } from "./done";
import * as Column from "../models/beta/column";
import { comparePosition } from "../models/beta/story";
import { property, last } from "underscore";
import { getStoriesByScope } from "./stories";
import { getDenormalizedIterations } from "../reducers/pastIterations";
import { denormalizedIterations } from "../reducers/pastIterations";
import { storiesWithScope } from "../reducers/stories";

const getStories = property("stories");
const getColumn = property("column");
Expand All @@ -17,19 +17,17 @@ export const getColumns = createSelector(
(column, stories, project, pastIterations) => {
switch (column) {
case Column.CHILLY_BIN:
return getStoriesByScope(stories)
return storiesWithScope(stories)
.filter(Column.isChillyBin)
.sort(comparePosition);
case Column.BACKLOG:
const orderedStories = orderByState(
getStoriesByScope(stories).filter((story) =>
storiesWithScope(stories).filter((story) =>
Column.isBacklog(story, project)
)
);

const lastPastIteration = last(
getDenormalizedIterations(pastIterations)
);
const lastPastIteration = last(denormalizedIterations(pastIterations));
const firstSprintNumber = lastPastIteration
? lastPastIteration.iterationNumber + 1
: 1;
Expand All @@ -40,11 +38,11 @@ export const getColumns = createSelector(
);
case Column.DONE:
return mountPastIterations(
getDenormalizedIterations(pastIterations),
getStoriesByScope(stories)
denormalizedIterations(pastIterations),
storiesWithScope(stories)
);
case Column.EPIC:
return getStoriesByScope(stories, Column.EPIC);
return storiesWithScope(stories, Column.EPIC);
}
}
);
Loading

0 comments on commit 8515d58

Please sign in to comment.