Duet3D / DuetWebControl

A completely new web interface for the Duet electronics
GNU General Public License v3.0
408 stars 230 forks source link

Configurable main menu #388

Closed abates-dentsu closed 1 year ago

abates-dentsu commented 2 years ago

Was just an idea that maybe a main menu that's configurable could be handy for people, based on a forum thread, and that I was using a hacked up menu myself on my CNC machine.

Note: I'm a rando coder nobody knows about, and I have no idea if should I set this up to PR into dev or the beta branch, or whatever branch, just selecting the latest. Let me know if it should be set up some other way, or if there's no chance, or whatever :)

This moves the configuration to the store vuex, as well as changing the configuration to work off of string placeholders in the configuration, to be replaced by the internal components replacing the placeholders by looking for a key. Users can configure the menu they're after by defining the structure of these placeholders. To do this, the groupings (Control, Files, etc) are a json structure with a name, can can also be requested by how components previously registered themselves with the structure (the route config components used to provide work as a kind of suggestion, looking for the group as named, or if specifically placed by path reference, can be over-ruled by that mechanism).

Edit: the configuration was buried in store/settings.js but the implications of how it updates required more code. I move it all to mainMenu.js, that contains all the hassle, leaving the rest cleaner... this did mean that the config is in a dwc-mainMenu.json file, that if it's not found/404'd it just ignores it and uses the default from the script itself.

The internal/system components are registered and routed before the json file is downloaded, so there's a little clearing out of the menu when it does download so that it can set it back up based on the configuration.

Examples:

This replicates the default structure, with the key placeholders that will be replaced by the component route registrations (look for the keys in each of the page level components). Note that this is what is used if nothing is custom configured...

        mainMenu: [
            {
                name: 'Control',
                icon: 'mdi-tune',
                caption: 'menu.control.caption',
                pages: [
                    'control-dashboard',
                    'control-console'
                ]
            },
            {
                name: 'Job',
                icon: 'mdi-printer',
                caption: 'menu.job.caption',
                pages: [
                    'job-status',
                    'job-webcam'
                ]
            },
            {
                name: 'Files',
                icon: 'mdi-sd',
                caption: 'menu.files.caption',
                pages: [
                    'files-jobs',
                    'files-macros',
                    'files-filaments',
                    'files-system'
                ]
            },
            {
                name: 'Plugins',
                icon: 'mdi-puzzle',
                caption: 'menu.plugins.caption',
                pages: []
            },
            {
                name: 'Settings',
                icon: 'mdi-wrench',
                caption: 'menu.settings.caption',
                pages: [
                    'settings-general',
                    'settings-machine'
                ]
            }
        ]

The paths of the page components also work, including paths for installed plugins. Here is an example of a flat menu with no groups, but also a custom plugin ("/MoveItMoveIt" is my own plugin's path). If the user saved this to the dwc-mainMenu.json file, it would load when the settings is downloaded off SD...

{ "mainMenu": [
            '/MoveItMoveIt',
            'control-console',
            'job-status',
            'job-webcam',
            'files-jobs',
            'files-macros',
            'files-filaments',
            'files-system',
            'settings-general',
            'settings-machine'
        ]
}

The configuration does allow for a complext structure type that sets up a custom item in the menu, with a manually configured routing path (which is pushed to the VueJS router when clicked), that sets the text, icon, and with an option to render it more like a button ("button":true) rather than the list-item. Here is an example of item configs that makes a custom titled link to the dashboard (translation works if the user uses a translation key, but otherwise just uses the String, which is the current system behavior anyway (nothing new here)), and the second item is rendered as a button, and fires a home gcode (people could make a handy menu-based macro set of buttons... only because it's easy enough, and why not? :) )...

      { "caption": "Extra Dashboard!", "icon": "mdi-wrench", "path": "/", "button": true },
      { "caption": "Home Sweet Home!", "icon": "mdi-tune", "gcode": "G28", "color": "warning", "button": true },
dmason1992 commented 1 year ago

Any news on when this may get merged? I would also like the ability to clear up the 3d printer clutter on my CNC use of RRF

chrishamm commented 1 year ago

I will rework the menu backend in v3.6 and possibly add the option to define custom layouts as well. Unfortunately I cannot merge your PR at this time, sorry.