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

UIIN-1406 Allow remote storage locations to be changed to non-remote storage location when moving the items between holdings #1318

Merged
merged 19 commits into from
Feb 26, 2021

Conversation

axelhunn
Copy link
Contributor

https://issues.folio.org/browse/UIIN-1406
Allow remote storage locations to be changed to non-remote storage location when moving the items between holdings

Purpose

Approach

TODOS and Open Questions

Learning

Pre-Merge Checklist

Before merging this PR, please go through the following list and take appropriate actions.

  • I've added appropriate record to the CHANGELOG.md
  • Does this PR meet or exceed the expected quality standards?
    • Code coverage on new code is 80% or greater
    • Duplications on new code is 3% or less
    • There are no major code smells or security issues
  • Does this introduce breaking changes?
    • If any API-related changes - okapi interfaces and permissions are reviewed/changed correspondingly
    • There are no breaking changes in this PR.

If there are breaking changes, please STOP and consider the following:

  • What other modules will these changes impact?
  • Do JIRAs exist to update the impacted modules?
    • If not, please create them
    • Do they contain the appropriate level of detail? Which endpoints/schemas changed, etc.
    • Do they have all they appropriate links to blocked/related issues?
  • Are the JIRAs under active development?
    • If not, contact the project's PO and make sure they're aware of the urgency.
  • Do PRs exist for these changes?
    • If so, have they been approved?

Ideally all of the PRs involved in breaking changes would be merged in the same day to avoid breaking the folio-testing environment. Communication is paramount if that is to be achieved, especially as the number of intermodule and inter-team dependencies increase.

While it's helpful for reviewers to help identify potential problems, ensuring that it's safe to merge is ultimately the responsibility of the PR assignee.

@id-jenkins
Copy link

@id-jenkins
Copy link

Copy link
Contributor

@aliaksei-chumakou aliaksei-chumakou left a comment

Choose a reason for hiding this comment

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

interesting style of grouping modal parts... At least kind of unique

Copy link
Contributor

@mkuklis mkuklis left a comment

Choose a reason for hiding this comment

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

Nice and clean @axelhunn. It's great to see react query in use too.


history.push({
pathname: `/inventory/view/${instanceId}`,
search: location.search,
});
});
}, [history, location, instanceFrom, instanceTo]);
Copy link
Contributor

@mkuklis mkuklis Feb 25, 2021

Choose a reason for hiding this comment

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

@axelhunn the history and location are objects and useCallback doesn't use deep comparison

facebook/react#14476

so this won't work as expected (it will basically recreate onClose more often). I would suggest either removing them from the dependency array or using something similar to:

https://github.com/kotarella1110/use-custom-compare

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing this out. In fact I made this change for linter not to yell at me.
It happens the history is a mutable object (see https://reactrouter.com/web/api/history).
It is the same object every time, so we can rely on === comparison.

As for the location - it's not needed here, we can use history.location instead,

I've refactored the thing.

Copy link
Contributor

@doytch doytch left a comment

Choose a reason for hiding this comment

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

This looks good! I love the separation of smart/dumb work you've accomplished here with hooks. It looks easier to maintain and reason through than the previous mixing of business logic into components. Hopefully that bears out in the future!

And definitely a novel way of project structure compared to other spots in Folio but I see the good it brings.

I just put a couple of notes on minor things that I noticed.

src/Instance/Move/useMoveItems.js Outdated Show resolved Hide resolved
@@ -0,0 +1,3 @@
export * as Check from './Check';
Copy link
Contributor

Choose a reason for hiding this comment

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

I like the way you built up the chain for these components. They're clearly related and encoding that relationship in their access (eg, RemoteStorage.Warning.ForHoldings) hammers it into the readers head.

import { Translate } from '../common';


export const Heading = () => <Translate id="Removing from remote storage" />;
Copy link
Contributor

Choose a reason for hiding this comment

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

I do like how this looks when browsing the code... 😆

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, but we batted it around at #stripes-architecture 2021-02-05 ago and specifically decided against it.

I agree with you, @doytch, this does read nicely, but instead of ignoring established precedent and the decision we made as a group, @axelhunn please raise this again at #stripes-architecture and we can discuss the existing tools that are built into react-intl that provide the same functionality with description or defaultMessage? Maybe we can have the best of both worlds here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@zburke sorry, didn't get it we decided against it.
Anyway, I made this part as more of a POC.
Reverted to unified way now, please review.

export const useByLocation = () => {
const remoteMap = useRemoteStorageMappings();

return ({ fromLocationId, toLocationId }) => (fromLocationId in remoteMap) && !(toLocationId in remoteMap);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this be called with an undefined for either of the location ids? There're too many usages throughout the PR for me to track down completely, but it caught my eye. undefined in remoteMap will evaluate to false. The first thing that came to mind was situations where you could have some stale data or something.

It's legitimate to say that "no, that should never happen and it should spectacularly and loudly fail if it does." 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The point here is to return true only if we move something from remote location to non-remote location.

  • when toLocationId is undefined - it could be a black hole, but it's not marked as remote, so
    (depends-on-from) && !(false) === depends-on-from

  • when fromLocationId is undefined - it certainly is not known remote location,
    (false) && !(whatever) === false

  • when both of them are undefined - the fromLocationId is undefined enough
    (false) && !(false) === false

const { holdingsById } = useHoldings();
const check = useByLocation();

return ({ fromHoldingsId, toHoldingsId }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

@axelhunn I wonder if this should be wrapped in useCallback. Otherwise I think it will be recreated on every render. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since I've read this article by Kent C. Dodds, I try not to overuse the useCallback.

But you're right, this function is used in dependencies of another useCallbacks and useMemos.
Fixed it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for sharing that article @axelhunn

Co-authored-by: Mark Deutsch <[email protected]>
@id-jenkins
Copy link

@axelhunn axelhunn requested a review from zburke February 25, 2021 22:15
@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

@id-jenkins
Copy link

  browserDisconnectTolerance: 10,
  browserNoActivityTimeout: 100000,
  flags: [
    '--disable-gpu',
    '--no-sandbox'
  ],
@id-jenkins
Copy link

@id-jenkins
Copy link

@sonarqubecloud
Copy link

@axelhunn axelhunn merged commit 3fb5cbb into master Feb 26, 2021
@axelhunn axelhunn deleted the UIIN-1406-2 branch February 26, 2021 12:04
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.

7 participants