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

New page creation UX #2728

Merged
merged 27 commits into from
Oct 6, 2023
Merged

Conversation

apedroferreira
Copy link
Member

@apedroferreira apedroferreira commented Sep 27, 2023

  • File explorer-like creation UX for new pages, similar to what we have / will have for functions.
  • Ability to rename pages and page hierarchy elements by double-clicking, using the same logic/component (will also have this later in functions)
  • Sticky headers for these left-side panels, as opposed to the previous collapsible headers, and adjusted spacing/sizing
Screen.Recording.2023-10-04.at.17.40.18.mov

@apedroferreira apedroferreira added the enhancement This is not a bug, nor a new feature label Sep 27, 2023
@apedroferreira apedroferreira self-assigned this Sep 27, 2023
@apedroferreira apedroferreira marked this pull request as draft September 27, 2023 16:04
@apedroferreira apedroferreira marked this pull request as ready for review September 27, 2023 17:43
@Janpot
Copy link
Member

Janpot commented Sep 28, 2023

cc @flaviendelangle might be interested in this use case, for an x-tree-view demo or for pro features.

  • create/edit tree items + validation
  • scroll into view after creation

@mbrookes
Copy link
Member

cc @flaviendelangle might be interested in this use case, for an x-tree-view demo or for pro features.

What's the reason for using a TreeView in the first place given that pages can't be nested, and collapsing the top-level doesn't seem useful?

@Janpot
Copy link
Member

Janpot commented Sep 30, 2023

What's the reason for using a TreeView in the first place given that pages can't be nested, and collapsing the top-level doesn't seem useful?

We're looking for a UX similar to the vscode file explorer. The data roughly maps on the file system and has similar functionality around create/rename. It's true that pages can't be nested (yet), we do plan to use this pattern in some places in our UI which will have nested items. So far the other places have 1 level of nesting (function files with exported functions). It could be valuable to explore whether there are other UI patterns than a tree view to represent these.

We should probably remove the top-level "Pages" item. This is a leftover from a time when there were more top-level items.

@apedroferreira apedroferreira requested review from Janpot and a team October 4, 2023 16:44
Copy link
Member

@Janpot Janpot Oct 5, 2023

Choose a reason for hiding this comment

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

If it's for the Hierarchy explorer, then I think this file can go under the toolpad/AppEditor/HierarchyExplorer folder. Or under the shared common ancestor.
The philosphy behind the components folder is to use it for general purpose components. Basically, the missing components from MUI core

Copy link
Member Author

@apedroferreira apedroferreira Oct 5, 2023

Choose a reason for hiding this comment

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

No, I'm using this component in both the hierarchy explorer and the pages explorer. It's supposed to be the header for any "explorer" panel like this.
Eventually I can make these components part of a larger one that handles any explorer panel including the header and creatable/renamable items. I guess I wanted to keep it more modular first. But maybe I should try it already.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, I can try to move the component above just enough in the project structure probably if it makes sense, might be better than in the components folder then.

sx={pagesTreeItemSx}
/>
) : null}
{sortBy(pages, 'name').map((page) => (
Copy link
Member

Choose a reason for hiding this comment

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

This is mutating the pages array. Best to Avoid mutating variables in the render function.
It's also running a sort i every render. Feels a bit wasteful.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I noticed it was mutable, in this particular case it doesn't have too much impact but it's better to make it immutable and memoize it, I'll do it.

* Sorts an array of objects by the value of one property.
*/
export function sortBy<P extends object>(objs: P[], prop: keyof P, isAsc = true): P[] {
return objs.sort((a, b) => {
Copy link
Member

Choose a reason for hiding this comment

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

None of the other exports of this file mutate the source array. Feels a bit counterintuitive, and I feel like it could lead to bugs. An alternative could be to add a

export function createPropertyComparator<T>(propName: string): (a: T, b: T) => number;

and let the consumer decide whether they want to mutate their array or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's ok to just make this method immutable, simpler and more intuitive. At first I guess I wanted it to be more like .sort, but the way that we use it it's probably better for it just to be immutable.

Copy link
Member

Choose a reason for hiding this comment

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

How about a utils/dom.ts to be a bit broader?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's fine, I wasn't really sure where to put this.

Copy link
Member

@Janpot Janpot left a comment

Choose a reason for hiding this comment

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

Looks good. I proposed a few tweaks regarding project organization. Other remarks:

  • 🤔 For visual consistency, I feel like it would be better if these are aligned

    Screenshot 2023-10-05 at 11 11 46
  • Will it be confusing to remove the existing page name field? It's a bit obsolete now, but I feel like we could still offer a way to edit the name in that page options panel. Perhaps less obtrusive as the one we have now. In any case, we can keep it for a follow up PR if we leave the name existing editor in place.

@apedroferreira
Copy link
Member Author

  • 🤔 For visual consistency, I feel like it would be better if these are aligned

The issue is that in the hierarchy explorer we need space for the little expand/collapse arrow for nestable elements. I'll see if it works to add some more padding to the pages though, might be fine.

  • Will it be confusing to remove the existing page name field? It's a bit obsolete now, but I feel like we could still offer a way to edit the name in that page options panel. Perhaps less obtrusive as the one we have now. In any case, we can keep it for a follow up PR if we leave the name existing editor in place.

I've actually already removed it... There's pros and cons to removing it or not, on one hand it gives the users maybe a more obvious place to change the name, but on the other hand it might be confusing how it's the same thing as renaming on the left. And it might be easier for users to associate renaming in the left panel with renaming the project files. I guess I can keep the input for now and we'll see how things go from there.

@apedroferreira
Copy link
Member Author

I've added all the changes discussed. Updated UI screenshot:

Screenshot 2023-10-05 at 20 44 46

ml: -1.5,
},
};
const alphabeticallySortedPages = React.useMemo(() => sortBy(pages, 'name'), [pages]);
Copy link
Member

@Janpot Janpot Oct 6, 2023

Choose a reason for hiding this comment

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

That won't sort alphabetically. e.g. 'a' < 'B' === false.

You might want to use .localeCompare instead:

[...pages].sort((page1, page2) => page1.name.localeCompare(page2.name)

Or if we abstract it I'd do it as a collator

interface Collator<T> {
  (a: T, b: T): number
}

function createByPropCollator<T, K extends keyof T>(propName: K, collator?: Collator<T[K]>): Collator<T>;

Typesafe, composable, easy to use with both .sort and upcoming .toSorted

const pagesCollator = createByPropCollator<Page>('name', createAlphabeticCollator())

pages.toSorted(pagesCollator)

Copy link
Member Author

Choose a reason for hiding this comment

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

Uh, that's right about the alphabetical ordering... And nice, I didn't know about localeCompare or toSorted.
The first approach seems fine, I tried implementing the second abstraction you proposed but I'm not really sure how to? And we might not need that abstraction yet anyway...

Copy link
Member Author

Choose a reason for hiding this comment

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

I've tried adding these as comparators, let me know what you think and feel free to provide more feedback.

Copy link
Member

@Janpot Janpot left a comment

Choose a reason for hiding this comment

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

Great, thanks for updating!

@apedroferreira apedroferreira enabled auto-merge (squash) October 6, 2023 16:03
@apedroferreira apedroferreira merged commit c310f41 into mui:master Oct 6, 2023
11 checks passed
@Janpot
Copy link
Member

Janpot commented Oct 6, 2023

@apedroferreira The position of the scrollbar seems to be off on the pages section. I don't believe position: sticky/fixed should be used for headers. The UX feels off when the scrollbar extends over the header.

Screenshot 2023-10-07 at 01 36 54

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This is not a bug, nor a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants