backstage / backstage

Backstage is an open framework for building developer portals
https://backstage.io/
Apache License 2.0
26.89k stars 5.58k forks source link

feat: customizable homepage #16744

Closed drodil closed 1 year ago

drodil commented 1 year ago

Hey, I just made a Pull Request!

Allows customizing homepage components, their placement, size, and individual settings. For maximum size and settings, the existing home components should change to use createCustomizableCardExtension function. This disables the default Settings entity and replaces it with form using react-json-schema-form.

relates to #16535

Home _ Backstage Example App

:heavy_check_mark: Checklist

backstage-goalie[bot] commented 1 year ago

Changed Packages

Package Name Package Path Changeset Bump Current Version
example-app packages/app none v0.2.82-next.3
@backstage/core-plugin-api packages/core-plugin-api patch v1.5.1-next.1
@backstage/plugin-home plugins/home minor v0.4.33-next.3
drodil commented 1 year ago

This is very much in progress still but would like to get some initial feedback, especially from @freben due to him commenting on the related issue :)

github-actions[bot] commented 1 year ago

Uffizzi Preview deployment-22428 was deleted.

drodil commented 1 year ago

Live preview available at https://pr-16744-deployment-18350-backstage.app.uffizzi.com/home

freben commented 1 year ago

Cool! Fun to play around with, haven't reviewed yet since it's getting late. In the end we probably want to have a dedicated "edit mode" that you enter and exit, and properties on a per-card basis. Maybe each card gets a floating circular button in a corner that offers a menu for delete card, edit properties, etc

drodil commented 1 year ago

Yeah, was also wondering if the edit mode should be separated or could it work in just one view. Saving the properties and allowing different components to define their own settings is the tricky part. Could the json-schema-form used by scaffolder actually work here?

Don't worry about the reviewing, the code is a mess at the moment. Just wanted to get some early feedback if this could be a good way to go forward.

freben commented 1 year ago

Yep I'm absolutely hoping that we'll be able to use rjsf for the editing, and hopefully defining the schemas using zod, as was recently added for the scaffolder

drodil commented 1 year ago

Great. I will take a look at the current scaffolder way of doing things with zod. I think it would make sense to add the settings schema as part of createCustomizableCardExtension (though not sure if that's the final name). And then it could be utilized in the edit mode to show settings for each component.

There's just quite a lot of things to do here so the PR might get huge. Would it make sense to first make this usable without the component specific settings and add those in another patch?

benjdlambert commented 1 year ago

Also wanna bring in here @tudi2d from the spotify side, as he's been looking at some simplifications to our internal homepage, and might be good to align here for the future.

drodil commented 1 year ago

Added initial edit mode and settings placeholder. Btw, does the Uffizzi environment update when the PR updates?

drodil commented 1 year ago

Oh and also cannot update the api-reports due to bug in react-use: https://github.com/streamich/react-use/issues/2074 TSC fails with:

node_modules/react-use/lib/usePermission.d.ts:6:11 - error TS2430: Interface 'IMidiPermissionDescriptor' incorrectly extends interface 'PermissionDescriptor'.
  Types of property 'name' are incompatible.
    Type '"midi"' is not assignable to type 'PermissionName'.

6 interface IMidiPermissionDescriptor extends PermissionDescriptor {
            ~~~~~~~~~~~~~~~~~~~~~~~~~
tudi2d commented 1 year ago

Hej @drodil - love the idea! As Ben said, I'm looking for simplifications of the Homepage internally at Spotify. The goal is to avoid an information overload & let the Engineer focus on a specific workflow with the tools they need.

I believe that customization itself can't really avoid information overload, therefor it could be helpful to set stronger boundaries for the user's customization. In the sketched example, the "Widgets" are in a Carousel-like component - only one Widget visible at a time with a max number of Widget's addable to the Carousel (e.g. 3).

Another way of customization are the "Shortcut's" below the Search. Here you could have a combination of "Most Visited" pages & the ability to customize them for a user. It's complementary to the "Shortcut's" plugin.

widgets

Happy about any thought's and feedback - will keep an eye on this PR. Haven't really figured out how to properly edit & store the settings as well. Will try the approach mentioned by freben :)

freben commented 1 year ago

@drodil can you "deep-import" only exactly the one hook you need, as per the suggestion at the bottom of the issue you linked?

drodil commented 1 year ago

@tudi2d thanks for the feedback! We also have encountered the issue of information overload with the home page. And when it's static, most of the information does not even matter to all people; thus the idea of customization. The carousel you have in mind might help but I think it can also be too restrictive for some users. For example, personally, I like to see all data that matters for my daily work in the same view without the need to interact with anything. And that means basically; my calendar, open PRs, CI/CD pipeline status, and list of my own components in the catalog. Of course, I don't mind having some jokes in between 😆

I added a gif to the PR description to describe the functionality a bit better if you haven't yet checked the live demo environment. Overall I think this could be a good way to allow user-specific customization and show only data important to them.

And last, I don't mind having contributions to this PR if any of you have some ideas or things you would like to name/structure in "Spotify way". I am trying to get some more time to work on this but cannot promise anything.

tudi2d commented 1 year ago

when it's static, most of the information does not even matter to all people

yes - agree! :)

Yeah - I've tried the live demo & it's cool! I think it's a legit use case & you shouldn't change your concept just because I personally had something else in mind for a specific implementation! :) The restrictions don't have to be there by design, but could be decided instance-to-instance specific later on. IMO it will be super hard to keep a consistend UI/Design & a good information architecture when giving every end user full flexibility how to structure their Homepage. Maybe something to keep in mind & think of in a follow-up issue/PR.

Just to understand the PR a bit better: With the <CustomHomepageGrid> you could also make a part of the Homepage static, while the rest is customizable, right? e.g.:

<>
  <Logo />
  <HomePageSearchBar />
  <CustomHomepageGrid>
    <HomePageCalendar />
    <MicrosoftCalendarCard />
  </CustomHomepageGrid>
</>
drodil commented 1 year ago

Yeah, you can absolutely do that. Only the parts inside the <CustomHomepageGrid> are customizable.

I also added a way to define a default layout and components for the grid with a config attribute to the CustomHomePageGrid. The default layout is used until the user first time customizes the layout.

I think the biggest thing still missing is the widget-specific settings part. I was thinking to add the following for the createCustomizableCardExtension:

customizationOptions?: {
    // ...
   settingsForm?: RJSFSchema
   // ...
  };

And render the form in the editMode for each widget if available. Changing the values would save the settings for each widget and those would be then passed as parameters to the components themselves. Initial thought, not sure if it's going to work...

drodil commented 1 year ago

Apparently, it was pretty straightforward to get widget-specific settings in place. This PR is ready for review while it might still have some issues I haven't noticed. @freben, @benjdlambert, @tudi2d any chance you could take a look at the code and check also the latest live demo?

jgrumboe commented 1 year ago

Hi @drodil, this customizable home screen is awesome! I really like how to configure which components/widgets are allowed! 😍 Looking forward to seeing it merged.

drodil commented 1 year ago

@jgrumboe thanks a lot for the feedback, I really like it as well and was able to integrate it with the existing components available in the home plugin :) If you want to help out, you can also check the code or try to break it in the demo environment. I've tried to catch all bugs but, as everyone knows, it's hard to check your own code 😆

drodil commented 1 year ago

Already couple of future features for this in mind:

  1. Saving the layout and settings to the database for the user
  2. Allowing multiple home pages per user

But I think those are topics of another issue/PR.

tudi2d commented 1 year ago

This is great - hope to have some time later to review the code!

drodil commented 1 year ago

Had to refactor the saving of widgets a bit so that the layout and settings live in the same object. Makes it easier for future development; for example adding multiple home screens for each user. Now I am happy and leave it for the review to find out more problems 😄

drodil commented 1 year ago

@tudi2d did some more cleaning up and actually got rid of the additional properties for createCardExtension completely. Now all widget configurations can be passed inside the data property. This also allows the components using the createComponentExtension to be added to the grid without extra functions; all I had to do is add the possibility to add that extra data from there as well. This all is documented in the README.

Did also rename some things and added more validation using zod in the mix. After some last fine-tuning to the UI part, I am very happy with this even though it's quite a big PR. Please re-review when you have time, I'm also excited to get this merged as we have big plans for this internally!

jgrumboe commented 1 year ago

How cool would it be to get it reviewedand merged before Tuesday and have it in 1.12.0 ... 😊

drodil commented 1 year ago

@jgrumboe yeah, let's see if we can make it. Personally I still have some time on Monday to fix if there's some findings. One month is long time to wait for the next window 😁

awanlin commented 1 year ago

@drodil @jgrumboe I think this feature is pretty awesome but we shouldn't rush it. The Home plugin has been around for a good chunk of time without this and I think the Community will be good with waiting a few weeks to have an awesome experience. For those eager they can get it early by using the next release line.

I'm just speaking from some personal experience. I got the Linguist plugin merged just before I went on vacation. Unexpectedly it got promoted in the release notes and in the Roadie newsletter, this was really great but I missed a bug that made broke it in a way that created a poor and confusing experience. Add on that last week's next release broke the Catalog so it was unusable. I think it's wise to take some time with this.

drodil commented 1 year ago

@awanlin agree that there's always chance that changes introduce some new bugs and they should not be rushed. Especially changes to existing functionality. But in this case the change doesn't change existing home plugin functionality so the risk is IMHO a lot smaller.

Anyways, it's up to Backstage maintainers, like yourself, to come up with the release content. Wishes can be presented from community but again, it's your product so you make the final decisions.

awanlin commented 1 year ago

@drodil just want to clarify something: I'm not a Maintainer just an active contributor and member of the Community like you. I just wanted to highlight my concern about rushing things and instead seeing the advantages of using the next release line to make this even better based on feedback. I've done that and I don't want to impact this PR with noise on this topic as it's an important feature that I know many in the Community want. 🚀 🥳

drodil commented 1 year ago

Ah, sorry, my mistake. Thought you were part of the team as you've been so active 😊 Keep it going!

tudi2d commented 1 year ago

Heads-up that the following issue let's the checks fail:

Incorrect type dependencies in @backstage/plugin-home:
  Move from devDependencies to dependencies: @types/react-grid-layout
drodil commented 1 year ago

Ah. I moved the gridProps to public interface to allow more customization from the user point of view and that's why it fails. I think this is somewhat crucial for users to get the grid as they like so I will move it to actual dependencies.

drodil commented 1 year ago

Any chance of getting this reviewed again? For some reason, the E2E tests failed in cypress not finding Chrome.

tudi2d commented 1 year ago

E2E tests pass after retriggering ✅

jgrumboe commented 1 year ago

Any ETA when this PR will be merged? I would really like to try it out with a .next version. 🙏

drodil commented 1 year ago

@jgrumboe hopefully soon. I will demo this in today's community session if you are interested.

drodil commented 1 year ago

Any chances to get merged for the next release? @freben @benjdlambert @tudi2d

Rugvip commented 1 year ago

@backstage/discoverability-maintainers, what are your thoughts on this?

drodil commented 1 year ago

@freben got the changes you proposed done. At least the public API is now much cleaner. Care to do a re-review? Thanks!

freben commented 1 year ago

@Rugvip @tudi2d ready to unblock?

github-actions[bot] commented 1 year ago

This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution!

drodil commented 1 year ago

Not stale, on vacation.

drodil commented 1 year ago

@Rugvip could you check the latest changes? Thanks!

camilaibs commented 1 year ago

Taking a final look :)

freben commented 1 year ago

note that it needs a rebase too - i wasn't allowed to force push a rebase myself

freben commented 1 year ago

And as you do so - the collision is because @rjsf was upgraded in the repo, so do make sure that you depend on the right versions of it. Compare to the scaffolder package (you'll want to use 5.6.0 for utils for example)

freben commented 1 year ago

@camilaibs Let me know! About to hit the button in a little while for the release if there aren't any objections :)

github-actions[bot] commented 1 year ago

Thank you for contributing to Backstage! The changes in this pull request will be part of the 1.13.0 release, scheduled for Tue, 18 Apr 2023.

awanlin commented 1 year ago

So exciting!!! Thanks for all the hard work on this one @drodil!!! 🚀 🎉 🚀

Nitinvonage commented 12 months ago

thanks for the wonderful customisable home template, is there any way we can fix some of our components/widgets in this template so that user can't edit/remove those. And for other components its upto user to add as per there choice.

drodil commented 12 months ago

@Nitinvonage thanks for the feedback. Currently, it's not possible to have fixed widgets on the home page. That would require some additional functionality to the plugin though it might be quite easy to do by having just new property for the static configuration and checking that property to whether or not to show the delete button / allow dragging. Unfortunately, there would still be a way for users to bypass this by modifying their local storage settings value for the homepage. Removing that possibility would need some additional checks. I think your best bet is to create a new issue to this project explaining the use-case a bit more in detail, would you like to do that?