symfony / ux

Symfony UX initiative: a JavaScript ecosystem for Symfony
https://ux.symfony.com/
MIT License
819 stars 298 forks source link

Unified UX component container for widget systems #643

Open excitedbox opened 1 year ago

excitedbox commented 1 year ago

Since Symfony is meant as an application framework (as opposed to static websites) I think it would be great if the UX initiative offered a unified widget or component management system which allowed building dashboards, applications, and admin interfaces more easily and interactively. Several of the components for building dashboards are already part of the UX bundle (forms, charts, etc.) but I feel like the missing piece is the container that pulls the pieces together.

Think of it like a widget manager or dashboard container that loads the individual components and includes methods for dragging components around, minimizing or hiding components. Much like the windowing system of an OS it doesn't care what it displays but it takes care of loading and positioning of different components.

This would simplify developing an Ecommerce dashboard, where you may want to display sales totals, or new customer signups and displayed components may be added, removed or moved. Or maybe you are building an application with multiple tool and property panels. Instead of everybody making their own component manager, I think it could be a great functionality to offer out of the box.

Some examples: Wordpress Dashboard has some very basic widget container functionality. OpenCart Dashboard

3rd party options: Golden Layouts Dragula These could be wrapped around stimulus or twig components offering 2 levels of feature complexity but both are JS based and I believe going a fully Hotwire/Turbo/Stimulus route is better and more in line with the future plans of the UX bundle.

If the container system was made to wrap any components being rendered it would also allow mixing any and all of the currently supported frontend systems (Vue, React, Twig, Stimulus) on a single page and moving data between them.

weaverryan commented 1 year ago

Hey!

This sounds bold, but interesting. It's not an area that I have a lot of experience with as a developer (I mean, it's not something I've ever had to built before). So, the interface would be... something like this? https://golden-layout.com/examples/ And you're adding Twig/Live components from your system to different sections, with options for the data that should be passed into each? Or would it be more configured like EasyAdmin, where you have configuration that would select and add your components to the page?

Again, no idea if this makes sense for UX - but it's always fun to brainstorm and find out :).

Cheers!

excitedbox commented 1 year ago

Exactly. I think it would be part of your template instead of being configured by easyadmin. You could add easy admin forms into it though to make a blog post form like wordpress where you can pull different sections to other positions or minimize them. Or like the Wordpress widget page where you can rearrange fields. Or if you make an Ecommerce app you may have a dashboard that shows recent orders, sales charts, a map with customer locations, inventory, etc. and each of the boxes is draggable.

By making it a wrapping container that loads other components, you would be able to load twig components that interact with your symfony controllers and React components into the same page. If it was done as part of the twig component bundle you would need to load any React or Vue components as twig components which would require modifying their code which may be difficult for larger apps. I think for larger libraries, something like an OpenOffice editor it would be best to keep the code separate and use the container to display them on the same page. This also allows erecting barriers between components that are uncrossable unless specifically passing the data from one container to another.

This could be done using Turbo Frames which work kind of like an Iframe if I understood it correctly. We would need an outer container, a way to define sub containers, a method for passing data between them, and controls for the interaction (drag, minimize, hide, full screen, etc).

Just like the (golden layout) code below, you define a layout container and the component+content. In our case, each component could be a UX item like a chart or a twig component or a React component, or a Symfony form.

var config = {
  content: [{
    type: 'row',
    content: [
      {
        type:'component',
        componentName: 'example',
        componentState: { text: 'Component 1' }
      },
      {
        type:'component',
        componentName: 'example',
        componentState: { text: 'Component 2' }
      },
      {
        type:'component',
        componentName: 'example',
        componentState: { text: 'Component 3' }
      }
    ]
  }]
};

var myLayout = new GoldenLayout( config );

myLayout.registerComponent( 'example', function( container, state ){
  container.getElement().html( '<h2>' + state.text + '</h2>');
});

myLayout.init();
sabat24 commented 1 year ago

Well I use a Sylius/ResourceBundle with a Sylius/GridBundle to achieve something like that. You can define each field as twig template -> https://github.com/Sylius/SyliusGridBundle/blob/1.13/docs/field_types.md#twig-twig which in my case is a TwigComponent.

What's more I've got live components which are responsible for handling (in nice ajax way) defined resources (dashboard lists).

excitedbox commented 1 year ago

This is exactly why I think this type of component is needed. From the looks of it this is loading a twig component into a data table field. Think more like the interface of a program like Photoshop or Visual Studio with docking panels that can be rearranged.

By making each panel act like it's own iframe (wrapped by a container) you gain a lot of freedom and security. Not to mention separation. You could have a Top navigation using React, a sidebar and main window using Twig components and unless you choose to pass data between them using the container as a bridge they wouldn't know the others exist.

Your method is just rendering a bunch of layout pieces in a set of divs but keeping it as a single page made of smaller pieces. It doesn't allow drag and drop, minimizing, hiding of widgets, and any live components need to be specifically coded for each use case.

carsonbot commented 4 months ago

Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?

carsonbot commented 4 months ago

Friendly reminder that this issue exists. If I don't hear anything I'll close this.

carsonbot commented 3 months ago

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!