elsa-workflows / elsa-core

A .NET workflows library
https://v3.elsaworkflows.io/
MIT License
6.06k stars 1.1k forks source link

Customize Elsa dashboard with tabs on top #2482

Closed ghost closed 2 years ago

ghost commented 2 years ago

I would to customize the Elsa dashboard by putting some tabs on top that redirect to other pages or a tab near 'Webhook Definitions'.

image

I use Bootstrap tabs and these piece as suggested by Bootstrap doc

<script>
        $('#myTab a').on('click', function (e) {
            e.preventDefault()
            $(this).tab('show')
        })
        $('#myTab li:nth-child(2) a').tab('show') // Select 2th tab
    </script>

BUT tabs doesn't change.

If I comment the next from Elsa dashboard into Host.cshtml

<script src="/_content/Elsa.Designer.Components.Web/monaco-editor/min/vs/loader.js"></script>
<script type="module" src="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/elsa-workflows-studio.esm.js"></script>

it WORKS, the tabs change BUT the styling is very messy

I think there is a conflict between JQuery on bootstrap and JQuery lib inside Elsa project

Is there a way to add way to add tabs on top or inside the Dashboard?

sfmskywalker commented 2 years ago

The dashboard doesn't use Bootstrap or jQuery to display these tabs. The UI is implemented with TailwindCSS and the interactivity implemented with StencilJS.

The application has an increasingly rich extensibility surface however, so that you can write a plugin to add custom menu items and screens.

Requires Elsa 2.4 (preview)

With Elsa 2.4 preview, you can implement plugin using a JavaScript function like this:


<elsa-studio-root id="elsaStudioRoot"></elsa-studio-root>

<script>

// Define a new plugin.
function MyCustomMenuItemPlugin(elsaStudio){

  const { eventBus } = elsaStudio;
  eventBus.on('dashboard.appearing', e => {

      // Define a list of menu items to append.
      const menuItems: any[] = [["my-custom-path", "Authorization Rules"]];

     // Define a list of routes to register with the router.
      const routes: any[] = [["my-custom-path", "my-custom-component"]];

      // Append custom menu items to existing list of menu items.
      e.data.menuItems = [...e.data.menuItems, ...menuItems];

      // Append custom routes to existing list of routes.
      e.data.routes = [...e.data.routes, ...routes];

  });
}

// Get a reference to the elsaStudioRoot element.
const elsaStudioRoot = document.getElementById('elsaStudioRoot');

// Register the custom plugin once the elsa studio component has been initialized.
elsaStudioRoot.addEventListener('initializing', e => {
  const elsa = e.detail;
  elsa.pluginManager.registerPlugin(MyCustomMenuItemPlugin);
});

</script>

The interesting part however is: how to create a custom component to be displayed? Thus far I have only experimented with components built with StencilJS, but it's possible that any custom element might work (again, not sure).

I found that the easiest way to extend the dashboard with custom screens is to create a new Stencil project and reference the Elsa Workflows NPM package.

I then create a new Stencil component that acts as the root of the application, which then hosts Elsa Studio Root. Doing this from a Stencil project simplifies everything, including creating custom screen components.

The result will be a new distributable (a JavaScript bundle) you include with your web app.

I'll make a note to update the documentation website with a guide to demonstrate this process.