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

Chore(ArrayField): add support for storeKey to manage independent selection states #10390

Open
wants to merge 4 commits into
base: next
Choose a base branch
from

Conversation

Aijeyomah
Copy link

@Aijeyomah Aijeyomah commented Dec 1, 2024

Problem

#10382
Describe the problem this PR solves

Solution

  • Introduced a storeKey property for ArrayField to enable distinct selection state storage for multiple instances of the same data source.
  • Added documentation and examples to demonstrate usage.

Describe the solution this PR implements

How To Test

Describe the steps required to test the changes

Additional Checks

  • The PR targets master for a bugfix, or next for a feature
  • The PR includes unit tests (if not possible, describe why)
  • The PR includes one or several stories (if not possible, describe why)
  • The documentation is up to date

Also, please make sure to read the contributing guidelines.

@Aijeyomah Aijeyomah changed the title chore: add storeKey to arrayfield to handle resources with same ids **Chore(ArrayField): add support for storeKey to manage independent selection states** Dec 1, 2024
@Aijeyomah Aijeyomah changed the title **Chore(ArrayField): add support for storeKey to manage independent selection states** Chore(ArrayField): add support for storeKey to manage independent selection states Dec 1, 2024
@Aijeyomah
Copy link
Author

Aijeyomah commented Dec 4, 2024

@fzaninotto Can you review? thanks

@djhi
Copy link
Collaborator

djhi commented Dec 4, 2024

Thanks for the PR! As this is a new feature, can you target the next branch? Besides, in order to test it, we'll need stories and unit tests. Can you add some, taking inspiration from the ListBase component?

@Aijeyomah
Copy link
Author

Thanks for the PR! As this is a new feature, can you target the next branch? Besides, in order to test it, we'll need stories and unit tests. Can you add some, taking inspiration from the ListBase component?

Yes, I can. Thanks

@Aijeyomah Aijeyomah changed the base branch from master to next December 17, 2024 10:02
@Aijeyomah
Copy link
Author

Thanks for the PR! As this is a new feature, can you target the next branch? Besides, in order to test it, we'll need stories and unit tests. Can you add some, taking inspiration from the ListBase component?

@djhi @fzaninotto I have updated the target branch as well as written the necessary stories and tests for the feature. Please re-review. Thanks

Copy link
Contributor

@slax57 slax57 left a comment

Choose a reason for hiding this comment

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

Too bad you took a wrong direction with the fix, but we appreciate the effort to provide good stories, tests, and documentation! Thanks!

Comment on lines +105 to +132
useEffect(() => {
if (!resource) return;
// Check if storeKey exists in the pagination store
const currentPagination = storeKeyPaginationRef.current[resource];
if (currentPagination) {
// Restore existing pagination state for the storeKey
if (
page !== currentPagination.page ||
perPage !== currentPagination.perPage
) {
setPage(currentPagination.page);
setPerPage(currentPagination.perPage);
}
} else {
setPage(initialPage);
setPerPage(initialPerPage);
}
storeKeyPaginationRef.current[resource] = { page, perPage };
}, [
resource,
setPage,
setPerPage,
initialPage,
initialPerPage,
page,
perPage,
]);

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm afraid you are going in the wrong direction here 😬 . The fix for #10382 suggested by @fzaninotto was to allow to override the storeKey used to store the selection state (i.e. used in useRecordSelection), but not the pagination state.

You can have a look at what was done in useReferenceManyFieldController for an example:

const [selectedIds, selectionModifiers] = useRecordSelection({
resource: storeKey,
});

Comment on lines +144 to +154
export const ListsWithoutStoreKeys = () => (
<CoreAdminContext store={localStorageStore()} dataProvider={dataProvider}>
<CoreAdminUI layout={Layout}>
<CustomRoutes>
<Route path="/store" element={StorePosts} />
<Route path="/nostore" element={NoStorePosts} />
</CustomRoutes>
<Resource name="posts" />
</CoreAdminUI>
</CoreAdminContext>
);
Copy link
Contributor

Choose a reason for hiding this comment

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

This Story is a bit misleading, StorePosts is still using a storeKey.

Besides, storeKey={false} is not the same as having no storeKey (for NoStorePosts ). I'd expect both lists in ListsWithoutStoreKeys to have no storeKey.

Comment on lines +90 to +108
const Layout = (props: CoreLayoutProps) => (
<div style={styles.mainContainer}>
<Link aria-label="top" to={`/top`}>
Go to Top Posts
</Link>
<Link aria-label="flop" to={`/flop`}>
Go to Flop Posts
</Link>
<Link aria-label="store" to={`/store`}>
Go to Store List
</Link>
<Link aria-label="nostore" to={`/nostore`}>
Go to No-Store List
</Link>

<br />
{props.children}
</div>
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Layout should not be shared across stories since both stories do not implement the same routes


When displaying multiple lists with the same data source, you may need to distinguish their selection states. To achieve this, assign a unique `storeKey` to each `ArrayField`. This allows each list to maintain its own selection state independently.

In the example below, two `ArrayField` components display the same data source (`books`), but each stores its selection state under a different key (`books.selectedIds` and `custom.selectedIds`). This ensures that both components can coexist on the same page without interfering with each other's state.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
In the example below, two `ArrayField` components display the same data source (`books`), but each stores its selection state under a different key (`books.selectedIds` and `custom.selectedIds`). This ensures that both components can coexist on the same page without interfering with each other's state.
In the example below, two `ArrayField` components display the same data source (`books`), but each stores its selection state under a different key (`customOne.selectedIds` and `customTwo.selectedIds`). This ensures that both components can coexist on the same page without interfering with each other's state.

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