-
Notifications
You must be signed in to change notification settings - Fork 8
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
Demo: Use grid in dialog as multi-select, forward data-grid-props #2428
base: main
Are you sure you want to change the base?
Conversation
0b55c33
to
5e31321
Compare
<AssignProductsGrid productCategoryId={productCategoryId} /> | ||
</DialogContent> | ||
<DialogActions> | ||
{/* TODO Missing close-dialog-unsaved-changes-check */} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that should be working correclty, <Savable hasChanges is true it should work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked again, it does not trigger a popup. I currently don't know why... probably because of the subRoutePath? opening the dialog does not change the path/url. it's still the same as for the routerTab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look: you are using a plain mui Dialog. That obviously doesn't integrate our SaveBoundary.
You have to use our EditDialog instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I started with comet-EditDialog but it had some issues with RouterTabs and StackPage so @thomasdax98 recommended to use plain mui Dialog. (probably you missed it: https://vividplanet.slack.com/archives/CTBMBLF38/p1718879902959449)
const initialValues = useMemo(() => { | ||
return data?.products.nodes ? data.products.nodes.map((product) => product.id) : []; | ||
}, [data]); | ||
const [values, setValues] = useState<string[]>(initialValues); | ||
useEffect(() => { | ||
setValues(initialValues); | ||
}, [initialValues]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure that can be done simpler. You now have 4 things that work somehow together: useQuery, useMemo, useState and useEffect. That is too complicated. (I would not care if you do that in an application, but we are creating best practice here - that might serve as template for code generation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alright, I have no idea... maybe use useReducer? do you have any idea? or @johnnyomair?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, useReducer would be an overkill. We could probably eliminate initialValues altogether:
- For reset, we can use data.products.nodes
- For hasChanges, we can also use data.products.nodes. We could also add a
hasChanges
which is only updated in onChange, which would remove the need to sort the arrays in hasChanges
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only managed to remove useMemo, it's still required to use useEffect because data.products
is initially undefined so values
has to be updated. (and useState can't be called after if (loading) ...
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the best I've came up with, eliminating two out of four:
const { data, error, loading } = useQuery<GQLGetProductIdsForProductCategoryQuery, GQLGetProductIdsForProductCategoryQueryVariables>(
getProductIdsForProductCategory,
{
variables: { id: productCategoryId },
onCompleted: (data) => {
setValues(data.products.nodes.map((product) => product.id));
},
},
);
const [values, setValues] = useState<string[]>([]);
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, I'd still suggest having a hasChanges state instead of comparing and sorting two arrays at every rendern. But this is probably premature optimization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think?
I'll take it :-D
BTW, I'd still suggest having a hasChanges state instead of comparing and sorting two arrays at every rendern. But this is probably premature optimization
I already added a console.log and it seems it's not called that often. probably nearly as often as the hasChange-state would change/needed to be checked. (for every click on one of the checkboxes, and additionally on closing the dialog)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it needed that this is an additional grid? Couldn't this be the "normal" products grid with a pre-applied filter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was before. but you mentioned a second grid. It was also discussed to do more specific generating instead of generating an ultra generic grid because generating already reduces the cost of duplication. (at least that's what I understood) and maybe we would also do some config-sharing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure back then and I'm still not sure now 😁
Maybe my "problem" is with having a second handmade grid. For the generator it should be okay though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's a dilemma, because we said want to generate how we would implement :-D
to achieve this it would probably require some additional changes in admin-generator... e.g. allow to change delete-button behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep it like this and defer the decision to later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix the lint error
@johnnyomair I think this pull-request is ready. But this demo-code should probably use EditDialog instead of Dialog, but there are still some issues as far as I know. |
Requirement
Select many entities, probably required to search for them by applying filters.
The UX-Team defined using a grid with checkboxes and filter-button, similar to all other grids. If there are already items selected they have to be preselected regardless of paging. There is no special sorting for preselected items to be on first page.
Example
This can be used in multiple cases like assigning them to another entity, adding them to some kind of list or queue. It just provides the list of selected id's.
Solution
Using selection-feature of
DataGrid
, hiding away grid-config (e.g. columns, filter, sorting) in demo/admin/src/products/categories/ProductsSelectGrid.tsx, but forwardingDataGrid
selection-feature-props to allow to add selection-behavior.Notes
DataGrid
-Props. Everything else is identically.FinalForm
-Form to add id's to the create/update mutation of the base-entity. We should probably add this use case as well. (And check with UX-Team if this should really be supported)Open issues
SaveDialog
to provide required default-features likeSaveBoundary
andcheck-unsaved-changes-on-close-dialog
FinalForm
-Form.AssignedProductsGrid
. (Differences: Add-Button-behavior, CrudContextMenu-Delete-Button-behaviour, probably no copy/paste behavior)