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

Make DataTable vertically resizeable #700

Merged
merged 2 commits into from
Aug 1, 2022

Conversation

apedroferreira
Copy link
Member

@apedroferreira apedroferreira commented Jul 27, 2022

  • Support vertically resizable components with resizableHeightProp
  • Make DataGrid component resizable
Screen.Recording.2022-07-28.at.18.36.20.mov

(cursor while dragging is wrong in the video but fixed already)

@render
Copy link

render bot commented Jul 27, 2022

@oliviertassinari oliviertassinari requested a deployment to vertical-element-resizing - toolpad-db PR #700 July 27, 2022 19:15 — with Render Abandoned
@oliviertassinari oliviertassinari added the new feature New feature or request label Jul 28, 2022
@apedroferreira apedroferreira requested a review from a team July 28, 2022 17:39
const resizePreviewRect = resizePreviewElement?.getBoundingClientRect();

if (draggedNodeRect && resizePreviewRect) {
const normalizeColumnSize = (size: number) =>
Math.max(0, size * parentChildren.length) / totalLayoutColumnSizes;
if (draggedEdge === RECTANGLE_EDGE_LEFT || draggedEdge === RECTANGLE_EDGE_RIGHT) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd suggest to brainstorm how this code could be made flatter, it's cyclomatic complexity seems to keep growing. In addition we should also consider how to split this file into smaller chuncks as +1.5k LoC doesn't seem to be very scalable IMO

Copy link
Member

Choose a reason for hiding this comment

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

With the risk of turning this in a religious debate, I don't like using LoC as a metric for maintainability. I've seen people trash projects by splitting code that semantically belongs together purely for the sake of reducing LoC per file.
I have no problem with 5k LoC in a file, nor do I have problems with having 100 files in a folder. As long as code is semantically grouped together, and the principle of single responsibility is respected.

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 not using LoC as a metric, but at certain number I'd say it signals that it could be split and that it might be doing too many things. Without spending too much time in the code my initial impressions that the code inside this component should be mostly responsible for rendering panel. This most recent addition takes care of resizing - so that might be considered as another responsibility, then skimming through the code I see mentions of:

  • dragging/dropping
  • selecting
  • node management with deletion, etc..
  • key handling
  • runtime events handling
    all of which IMO could be considered as a separate responsibility.

I'm fine with you keeping the structure as it is if you don't find it more difficult to navigate and deal with the code.

It would be just interesting to understand what would be a good examples of:

  • semantic grouping
  • principles of single responsibility
    So that it's easier to know when is the right time to consider splitting/extracting things out?

Copy link
Member Author

Choose a reason for hiding this comment

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

hey Vytautas, I understand your points and both points of view on the subject.

there is logic here that could be separated in different files according to its different responsibilities, but we would have to decide on which way to go about that:

  • i've previously suggested a non-reusable hook, but that also has it's own disadvantages and might be a misleading pattern?
  • i could try to move much of this logic into functions in separate files, but there could be obstacles in passing all the arguments we need to those functions without making them bloated - however there might be a way to make it be clean enough with some effort

Copy link
Contributor

Choose a reason for hiding this comment

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

For now please disregard my suggestion and feel free to proceed with merging when you feel comfortable. I think we could have a separate discussion where we discuss these sort of things, until we have a clear path and agreement we should not block development :)

Copy link
Member Author

@apedroferreira apedroferreira Jul 29, 2022

Choose a reason for hiding this comment

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

in regards to the many nested if statements, i might at least be able to make things flatter by just stopping the function execution when some of them are false, by returning or so - might be more doable in some cases than others but i can always make an extra effort with that in mind

Copy link
Member Author

Choose a reason for hiding this comment

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

For now please disregard my suggestion and feel free to proceed with merging when you feel comfortable. I think we could have a separate discussion where we discuss these sort of things, until we have a clear path and agreement we should not block development :)

ok, i have it noted to try to improve and make this component more concise and readable whenever i have the chance - but if we can set some common practices and standards that might be helpful!

@@ -1318,43 +1326,59 @@ export default function RenderPanel({ className }: RenderPanelProps) {
const cursorPos = canvasHostRef.current?.getViewCoordinates(event.clientX, event.clientY);

if (draggedNodeRect && parentRect && resizePreviewElement && cursorPos) {
let snappedToGridCursorPosX =
Math.round(cursorPos.x / RESIZE_SNAP_UNITS) * RESIZE_SNAP_UNITS;
if (draggedEdge === RECTANGLE_EDGE_LEFT || draggedEdge === RECTANGLE_EDGE_RIGHT) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that there is a lot of this "resizing" logic going on in this component. Could we maybe abstract it away to some ResizeablePanel component? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

in addition to the above, i haven't considered this approach so will see if there's a way to move this logic into a separate React component. thanks for the suggestion!

@apedroferreira apedroferreira merged commit 67f1dd2 into master Aug 1, 2022
@apedroferreira apedroferreira deleted the vertical-element-resizing branch August 1, 2022 14:23
@oliviertassinari
Copy link
Member

Nice 👌

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

Successfully merging this pull request may close these issues.

4 participants