On Tue, Aug 26, 2025 at 5:00 AM Daniel Kral <d.k...@proxmox.com> wrote:
>
> Hm, the buttons might be a little ambiguous that these are only for LRM
> entries... But I think it's a good start as there isn't a dedicated list
> for the LRMs which gives more room for action buttons that can be done
> on all items. But let's wait for other feedback.

I wasn't sure where the best place for buttons to go would be, but
Thomas Lamprecht suggested in [1] to place in the HA overview, so
that's where I figured it would fit best. I agree with his logic on
needing to check HA status before enabling/disabling the maintenance.
Selectable grid was an easy implementation there and the status was
already being polled.

[1]: 
https://lore.proxmox.com/pve-devel/90de8fa6-0e31-4273-adf3-ad337ec39...@proxmox.com/

> On Mon Aug 25, 2025 at 6:11 AM CEST, Thomas Skinner wrote:
> > Signed-off-by: Thomas Skinner <tho...@atskinner.net>
> > ---
> >  www/manager6/ha/StatusView.js | 85 +++++++++++++++++++++++++++++++++++
> >  1 file changed, 85 insertions(+)
> >
> > diff --git a/www/manager6/ha/StatusView.js b/www/manager6/ha/StatusView.js
> > index 50ad8e84..79e12df5 100644
> > --- a/www/manager6/ha/StatusView.js
> > +++ b/www/manager6/ha/StatusView.js
> > @@ -41,12 +41,58 @@ Ext.define(
> >                  },
> >              });
> >
> > +            let sm = Ext.create('Ext.selection.RowModel', {});
> > +
> > +            let caps = Ext.state.Manager.get('GuiCap');
> > +
> > +            var node_maintenance_disable = function (disable) {
>
> var mustn't be used for new code anymore [0], and new variable names
> should be in camelCase [1].
>
> [0] https://pve.proxmox.com/wiki/Javascript_Style_Guide#Variables
> [1] https://pve.proxmox.com/wiki/Javascript_Style_Guide#Casing

Some copypasta got the best of me here. Will update for v2.

> this could be an arrow function and the function's variable name is
> rather fragile as 'disable' can be set and then does a rather different
> action to the node maintenance.. Maybe just "setNodeMaintenance"?
>
> > +                let rec = sm.getSelection()[0];
> > +                if (!rec || rec.data.type !== "lrm") {
> > +                    return;
> > +                }
> > +                let nodename = rec.get('node');
> > +                let enableText = disable ? 'Disable' : 'Enable';
> > +                let msg = Ext.String.format(gettext("{0} maintenance mode 
> > on node '{1}'?"), enableText, nodename);
> > +                Ext.Msg.confirm(gettext('Confirm'), msg, (btn) => {
> > +                    if (btn === 'yes') {
> > +                        Proxmox.Utils.API2Request({
> > +                            params: { disable: disable ? 1 : 0 },
> > +                            url: '/cluster/ha/nodes/' + nodename + 
> > '/maintenance',
> > +                            method: 'POST',
> > +                            waitMsgTarget: me,
> > +                            failure: function (response, opts) {
> > +                                Ext.Msg.alert(gettext('Error'), 
> > response.htmlStatus);
> > +                            },
> > +                        });
> > +                    }
> > +                });
> > +            };
> > +
> >              Ext.apply(me, {
> >                  store: store,
> > +                selModel: sm,
> >                  stateful: false,
> >                  viewConfig: {
> >                      trackOver: false,
> >                  },
> > +                tbar: [
> > +                    {
> > +                        text: gettext('Enable Maintenance Mode'),
> > +                        itemId: 'enableMaintBtn',
> > +                        disabled: true,
> > +                        handler: function () {
> > +                            node_maintenance_disable(false);
> > +                        },
>
> nit: use an arrow function instead
>
>     handler: () => node_maintenance_disable(false),

Oh, I didn't know that was possible. Will fix up this one and the next.

> > +                    },
> > +                    {
> > +                        text: gettext('Disable Maintenance Mode'),
> > +                        itemId: 'disableMaintBtn',
> > +                        disabled: true,
> > +                        handler: function () {
> > +                            node_maintenance_disable(true);
>
> nit: same here
>
> > +                        },
> > +                    },
> > +                ],
> >                  columns: [
> >                      {
> >                          header: gettext('Type'),
> > @@ -60,12 +106,50 @@ Ext.define(
> >                          dataIndex: 'status',
> >                      },
> >                  ],
> > +                listeners: {
> > +                    beforeselect: function (tree, record, index, eopts) {
> > +                        if (!caps.nodes['Sys.Console']) {
> > +                            return;
> > +                        }
> > +                        let enableMaintBtnDisable = true;
> > +                        let disableMaintBtnDisable = true;
> > +                        if (record && record.data.type === "lrm") {
> > +                            if (record.data.lrm_mode && 
> > record.data.lrm_mode === 'maintenance') {
> > +                                disableMaintBtnDisable = false;
> > +                            } else {
> > +                                enableMaintBtnDisable = false;
> > +                            }
> > +                        }
> > +                        
> > me.down('#enableMaintBtn').setDisabled(enableMaintBtnDisable);
> > +                        
> > me.down('#disableMaintBtn').setDisabled(disableMaintBtnDisable);
> > +                    },
> > +                }
> >              });
> >
> >              me.callParent();
> >
> >              me.on('activate', me.rstore.startUpdate);
> >              me.on('destroy', me.rstore.stopUpdate);
> > +
> > +            me.mon(me.rstore, 'load', function (curstore, results) {
> > +                let rec = sm.getSelection()[0];
> > +                if (!rec || rec.data.type !== "lrm") {
> > +                    return;
> > +                }
> > +                for (const { data } of results) {
> > +                    switch (data.type) {
> > +                        case 'lrm':
> > +                            if (rec.data.node === data.node) {
> > +                                let inMaint = rec.data.lrm_mode === 
> > 'maintenance';
> > +                                
> > me.down('#enableMaintBtn').setDisabled(inMaint);
> > +                                
> > me.down('#disableMaintBtn').setDisabled(!inMaint);
> > +                            }
> > +                            break;
> > +                        default:
> > +                            break;
> > +                    }
> > +                }
> > +            });
> >          },
> >      },
> >      function () {
> > @@ -88,6 +172,7 @@ Ext.define(
> >                  'type',
> >                  'crm_state',
> >                  'request_state',
> > +                'lrm_mode',
> >                  {
> >                      name: 'vname',
> >                      convert: function (value, record) {
>
>

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to