Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor SideContentReducer #2844

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft

Conversation

RichDom2185
Copy link
Member

@RichDom2185 RichDom2185 commented Mar 16, 2024

Description

Refactors SideContentReducer to use "RTK" and Immer, as well as splitting the logic of stories and non-stories side content into separate sub-reducers for better readability.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Code quality improvements

How to test

Checklist

  • I have tested this code
  • I have updated the documentation

@RichDom2185 RichDom2185 requested a review from leeyi45 March 16, 2024 10:37
@RichDom2185 RichDom2185 self-assigned this Mar 16, 2024
@RichDom2185
Copy link
Member Author

@leeyi45 could I ask for your thoughts/preliminary comments on this proof-of-concept refactoring? If it's all good, I'll proceed to refactor the rest of the reducer.

Thanks!

@coveralls
Copy link

coveralls commented Mar 16, 2024

Pull Request Test Coverage Report for Build 8678817523

Details

  • 17 of 25 (68.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.03%) to 33.11%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/commons/sideContent/SideContentReducer.ts 17 25 68.0%
Totals Coverage Status
Change from base Build 8678811571: 0.03%
Covered Lines: 5284
Relevant Lines: 14842

💛 - Coveralls

return createReducer(defaultSideContentManager, builder => {
builder
.addCase(changeSideContentHeight, (state, action) => {
state.stories[storyEnv].height = action.payload.height;
Copy link
Member Author

@RichDom2185 RichDom2185 Mar 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that sideContentState above is outside the createReducer function; thus it is not a "writeable draft" state from Immer and should not be written to, i.e. sideContentState.XXX = YYY is not allowed.

@leeyi45
Copy link
Contributor

leeyi45 commented Mar 20, 2024

Should we call createReducer every time? I think it's sufficient to perform the workspace location check, then just call the appropriate reducer

@RichDom2185
Copy link
Member Author

Should we call createReducer every time? I think it's sufficient to perform the workspace location check, then just call the appropriate reducer

How can we capture workspaceLocation via closure, in that case?

@leeyi45
Copy link
Contributor

leeyi45 commented Mar 21, 2024

Should we call createReducer every time? I think it's sufficient to perform the workspace location check, then just call the appropriate reducer

How can we capture workspaceLocation via closure, in that case?

Do we need to capture workspaceLocation? Ideally the reducers should work for all workspaces right?

@RichDom2185
Copy link
Member Author

Should we call createReducer every time? I think it's sufficient to perform the workspace location check, then just call the appropriate reducer

How can we capture workspaceLocation via closure, in that case?

Do we need to capture workspaceLocation? Ideally the reducers should work for all workspaces right?

That's true, I had originally thought that it might be not very ideal to have to write a

const workspaceLocation = // ...
const sideContentState = // ...

every time. But now that I think of it, the duplicated getWorkspaceLocation calls in newWorkspaceLocation make more sense.

But I still feel that the reducer should be split between stories and non-story workspace locations. What do you think of something like:

export const SideContentReducer = (state, action) => {
  state = storiesSideContentReducer(state, action);
  state = nonStoriesSideContentReducer(state, action);
  return state;
};

const storiesSideContentReducer = createReducer(
  defaultSideContent,
  builder => {
    builder.addCase(someAction, (state, action) => {
      if (action.payload.workspaceLocation === 'stories') {
        // ... logic here
      }
    });
  }
);

const nonStoriesSideContentReducer = createReducer(
  defaultSideContent,
  builder => {
    builder.addCase(someAction, (state, action) => {
      if (action.payload.workspaceLocation !== 'stories') {
        // ... logic here
      }
    });
  }
);

That way we group all the logic for non-story and stories together.

Though ideally, we remove the duplication entirely since the only differences would be how we access sideContentState.

@leeyi45
Copy link
Contributor

leeyi45 commented Mar 21, 2024

Should we call createReducer every time? I think it's sufficient to perform the workspace location check, then just call the appropriate reducer

How can we capture workspaceLocation via closure, in that case?

Do we need to capture workspaceLocation? Ideally the reducers should work for all workspaces right?

That's true, I had originally thought that it might be not very ideal to have to write a

const workspaceLocation = // ...
const sideContentState = // ...

every time. But now that I think of it, the duplicated getWorkspaceLocation calls in newWorkspaceLocation make more sense.

But I still feel that the reducer should be split between stories and non-story workspace locations. What do you think of something like:

export const SideContentReducer = (state, action) => {
  state = storiesSideContentReducer(state, action);
  state = nonStoriesSideContentReducer(state, action);
  return state;
};

const storiesSideContentReducer = createReducer(
  defaultSideContent,
  builder => {
    builder.addCase(someAction, (state, action) => {
      if (action.payload.workspaceLocation === 'stories') {
        // ... logic here
      }
    });
  }
);

const nonStoriesSideContentReducer = createReducer(
  defaultSideContent,
  builder => {
    builder.addCase(someAction, (state, action) => {
      if (action.payload.workspaceLocation !== 'stories') {
        // ... logic here
      }
    });
  }
);

That way we group all the logic for non-story and stories together.

Though ideally, we remove the duplication entirely since the only differences would be how we access sideContentState.

I guess if we want to maintain the difference between story and non-story side content we could do that

What I had in mind was more like:

export const SideContentReducer = (state, action) => {
  const [workspaceLocation, storyEnv] = getLocation(action.payload.workspaceLocation)
  if (workspaceLocation === 'stories') {
    const workspace = state.stories[storyEnv]
    return {
      ...state,
      stories: {
        ...state.stories,
        [storyEnv]: reducer(workspace)
      }
    }
  }

// and the same for non-story workspace locations  
}

The whole idea is to treat each workspace identically. But I guess that's less idiomatic?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants