all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH manager] ui: ha: add disarm/re-arm button
@ 2026-04-14 11:51 Dominik Rusovac
  2026-04-14 13:30 ` Daniel Kral
  2026-04-15  6:44 ` Dominik Rusovac
  0 siblings, 2 replies; 4+ messages in thread
From: Dominik Rusovac @ 2026-04-14 11:51 UTC (permalink / raw)
  To: pve-devel

The button to disarm HA in either of the resource modes ('freeze' or
'ignore') is disabled as long as HA is disarmed. Analogously, the
re-arming button is disabled as long as HA is not disarmed.

The icons ('unlink' and 'link') are chosen to emphasize that
"Disarm HA" and "Re-arm HA" are complements. There may be more
suitable pairs of icons though.

Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com>
---
 www/manager6/ha/Status.js     | 106 ++++++++++++++++++++++++++++++++++
 www/manager6/ha/StatusView.js |   8 +++
 2 files changed, 114 insertions(+)

diff --git a/www/manager6/ha/Status.js b/www/manager6/ha/Status.js
index b0b0feb9..d955452d 100644
--- a/www/manager6/ha/Status.js
+++ b/www/manager6/ha/Status.js
@@ -8,6 +8,107 @@ Ext.define('PVE.ha.Status', {
         align: 'stretch',
     },
 
+    viewModel: {
+        data: {
+            haDisarmed: false,
+        },
+    },
+
+    controller: {
+        xclass: 'Ext.app.ViewController',
+
+        check_ha_status: function (isDisarmed) {
+            let vm = this.getViewModel();
+            vm.set('haDisarmed', isDisarmed);
+        },
+
+        disarm: function (comp) {
+            let me = this;
+            let view = me.getView();
+            let mode = comp.mode;
+
+            Ext.Msg.confirm(
+                gettext('Confirm'),
+                mode === 'freeze'
+                    ? gettext("Are you sure you want to disarm HA with resource mode 'freeze'?")
+                    : gettext("Are you sure you want to disarm HA with resource mode 'ignore'?"),
+                function (btn) {
+                    if (btn !== 'yes') {
+                        return;
+                    }
+                    Proxmox.Utils.API2Request({
+                        url: '/cluster/ha/status/disarm-ha',
+                        params: { 'resource-mode': mode },
+                        method: 'POST',
+                        waitMsgTarget: view,
+                        failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
+                    });
+                },
+            );
+        },
+
+        rearm: function () {
+            let me = this;
+            let view = me.getView();
+
+            Ext.Msg.confirm(
+                gettext('Confirm'),
+                gettext('Are you sure you want to re-arm HA?'),
+                function (btn) {
+                    if (btn !== 'yes') {
+                        return;
+                    }
+                    Proxmox.Utils.API2Request({
+                        url: '/cluster/ha/status/arm-ha',
+                        params: {},
+                        method: 'POST',
+                        waitMsgTarget: view,
+                        failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
+                    });
+                },
+            );
+        },
+    },
+
+    dockedItems: [
+        {
+            xtype: 'toolbar',
+            dock: 'top',
+            items: [
+                {
+                    text: gettext('Disarm HA'),
+                    iconCls: 'fa fa-unlink',
+                    bind: {
+                        disabled: '{haDisarmed}',
+                    },
+                    menu: [
+                        {
+                            text: gettext('Freeze'),
+                            iconCls: 'fa fa-snowflake-o',
+                            mode: 'freeze',
+                            handler: 'disarm',
+                        },
+                        {
+                            text: gettext('Ignore'),
+                            iconCls: 'fa fa-eye-slash',
+                            mode: 'ignore',
+                            handler: 'disarm',
+                        },
+                    ],
+                },
+                {
+                    text: gettext('Re-arm HA'),
+                    iconCls: 'fa fa-link',
+                    bind: {
+                        disabled: '{!haDisarmed}',
+                    },
+                    handler: 'rearm',
+                },
+            ],
+        },
+    ],
+
+
     initComponent: function () {
         var me = this;
 
@@ -30,6 +131,11 @@ Ext.define('PVE.ha.Status', {
                 border: 0,
                 collapsible: true,
                 padding: '0 0 20 0',
+                listeners: {
+                    hastatuschange: function (isDisarmed) {
+                        me.getController().check_ha_status(isDisarmed);
+                    },
+                },
             },
             {
                 xtype: 'pveHAResourcesView',
diff --git a/www/manager6/ha/StatusView.js b/www/manager6/ha/StatusView.js
index bc2da71f..4cbe85a1 100644
--- a/www/manager6/ha/StatusView.js
+++ b/www/manager6/ha/StatusView.js
@@ -42,6 +42,13 @@ Ext.define(
                 },
             });
 
+            me.rstore.on('load', function () {
+                let fencing = store.findRecord('type', 'fencing');
+                let disarmed = fencing && fencing.get('armed-state') === 'disarmed';
+
+                me.fireEvent('hastatuschange', disarmed);
+            });
+
             Ext.apply(me, {
                 store: store,
                 stateful: false,
@@ -105,6 +112,7 @@ Ext.define(
                         return PVE.data.ResourceStore.guestName(vmid);
                     },
                 },
+                'armed-state',
             ],
             idProperty: 'id',
         });
-- 
2.47.3





^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH manager] ui: ha: add disarm/re-arm button
  2026-04-14 11:51 [PATCH manager] ui: ha: add disarm/re-arm button Dominik Rusovac
@ 2026-04-14 13:30 ` Daniel Kral
  2026-04-14 13:49   ` Dominik Rusovac
  2026-04-15  6:44 ` Dominik Rusovac
  1 sibling, 1 reply; 4+ messages in thread
From: Daniel Kral @ 2026-04-14 13:30 UTC (permalink / raw)
  To: Dominik Rusovac, pve-devel

Nice work, looks great!

I added some inline comments, but functionality-wise this works as
expected already.

On Tue Apr 14, 2026 at 1:51 PM CEST, Dominik Rusovac wrote:
> The button to disarm HA in either of the resource modes ('freeze' or
> 'ignore') is disabled as long as HA is disarmed. Analogously, the
> re-arming button is disabled as long as HA is not disarmed.
>
> The icons ('unlink' and 'link') are chosen to emphasize that
> "Disarm HA" and "Re-arm HA" are complements. There may be more
> suitable pairs of icons though.
>
> Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com>
> ---
>  www/manager6/ha/Status.js     | 106 ++++++++++++++++++++++++++++++++++
>  www/manager6/ha/StatusView.js |   8 +++
>  2 files changed, 114 insertions(+)
>
> diff --git a/www/manager6/ha/Status.js b/www/manager6/ha/Status.js
> index b0b0feb9..d955452d 100644
> --- a/www/manager6/ha/Status.js
> +++ b/www/manager6/ha/Status.js
> @@ -8,6 +8,107 @@ Ext.define('PVE.ha.Status', {
>          align: 'stretch',
>      },
>  
> +    viewModel: {
> +        data: {
> +            haDisarmed: false,
> +        },
> +    },
> +
> +    controller: {
> +        xclass: 'Ext.app.ViewController',
> +
> +        check_ha_status: function (isDisarmed) {

new method names should use cameCase according to our JS Style Guide [0]

> +            let vm = this.getViewModel();
> +            vm.set('haDisarmed', isDisarmed);
> +        },
> +
> +        disarm: function (comp) {

nit: maybe s/comp/menuItem/ would make it a little clearer where the
     information is coming from?

nit: maybe s/disarm/handleDisarmButton/ would also make it clearer where
     it is supposed to be used (instead of a generic method here)

> +            let me = this;
> +            let view = me.getView();
> +            let mode = comp.mode;
> +
> +            Ext.Msg.confirm(
> +                gettext('Confirm'),
> +                mode === 'freeze'
> +                    ? gettext("Are you sure you want to disarm HA with resource mode 'freeze'?")
> +                    : gettext("Are you sure you want to disarm HA with resource mode 'ignore'?"),

nit: the translation keys could be deduplicated with something like

    Ext.Msg.confirm(
        gettext('Confirm'),
        Ext.String.format(
            gettext("Are you sure you want to disarm HA with resource mode '{0}'?"),
            mode
        )
        ...
    );

Feel free to restructure the code snippet if you consider using it.

I also removed the mode === 'freeze' condition with just emplacing the
content of `mode`, but it would be nicer to use the same translation
keys as for the menu items (i.e., gettext('Freeze') and
gettext('Ignore')).

> +                function (btn) {
> +                    if (btn !== 'yes') {
> +                        return;
> +                    }
> +                    Proxmox.Utils.API2Request({
> +                        url: '/cluster/ha/status/disarm-ha',
> +                        params: { 'resource-mode': mode },
> +                        method: 'POST',
> +                        waitMsgTarget: view,
> +                        failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
> +                    });
> +                },
> +            );
> +        },
> +
> +        rearm: function () {

nit: maybe s/rearm/handleRearmButton/ here as well?

> +            let me = this;
> +            let view = me.getView();
> +
> +            Ext.Msg.confirm(
> +                gettext('Confirm'),
> +                gettext('Are you sure you want to re-arm HA?'),
> +                function (btn) {
> +                    if (btn !== 'yes') {
> +                        return;
> +                    }
> +                    Proxmox.Utils.API2Request({
> +                        url: '/cluster/ha/status/arm-ha',
> +                        params: {},

nit: the params is not needed here

> +                        method: 'POST',
> +                        waitMsgTarget: view,
> +                        failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
> +                    });
> +                },
> +            );
> +        },
> +    },
> +
> +    dockedItems: [
> +        {
> +            xtype: 'toolbar',
> +            dock: 'top',
> +            items: [
> +                {
> +                    text: gettext('Disarm HA'),
> +                    iconCls: 'fa fa-unlink',
> +                    bind: {
> +                        disabled: '{haDisarmed}',
> +                    },
> +                    menu: [
> +                        {
> +                            text: gettext('Freeze'),
> +                            iconCls: 'fa fa-snowflake-o',
> +                            mode: 'freeze',
> +                            handler: 'disarm',
> +                        },
> +                        {
> +                            text: gettext('Ignore'),
> +                            iconCls: 'fa fa-eye-slash',
> +                            mode: 'ignore',
> +                            handler: 'disarm',
> +                        },
> +                    ],
> +                },
> +                {
> +                    text: gettext('Re-arm HA'),

nit: wondering whether this should just be called 'Arm HA', but no hard
     feelings about this. If we go for that, should be changed for the
     other instances as well.

> +                    iconCls: 'fa fa-link',
> +                    bind: {
> +                        disabled: '{!haDisarmed}',
> +                    },
> +                    handler: 'rearm',
> +                },
> +            ],
> +        },
> +    ],
> +
> +

extra new-line that is removed with a `make -C www/manager6 tidy`

>      initComponent: function () {
>          var me = this;
>  
> @@ -30,6 +131,11 @@ Ext.define('PVE.ha.Status', {
>                  border: 0,
>                  collapsible: true,
>                  padding: '0 0 20 0',
> +                listeners: {
> +                    hastatuschange: function (isDisarmed) {
> +                        me.getController().check_ha_status(isDisarmed);
> +                    },
> +                },
>              },
>              {
>                  xtype: 'pveHAResourcesView',

[0] https://pve.proxmox.com/wiki/Javascript_Style_Guide#Casing




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH manager] ui: ha: add disarm/re-arm button
  2026-04-14 13:30 ` Daniel Kral
@ 2026-04-14 13:49   ` Dominik Rusovac
  0 siblings, 0 replies; 4+ messages in thread
From: Dominik Rusovac @ 2026-04-14 13:49 UTC (permalink / raw)
  To: Daniel Kral, pve-devel

On Tue Apr 14, 2026 at 3:30 PM CEST, Daniel Kral wrote:
> Nice work, looks great!
>
> I added some inline comments, but functionality-wise this works as
> expected already.
>

thx! will incorporate your suggestions in a v2.

> On Tue Apr 14, 2026 at 1:51 PM CEST, Dominik Rusovac wrote:
>> The button to disarm HA in either of the resource modes ('freeze' or
>> 'ignore') is disabled as long as HA is disarmed. Analogously, the
>> re-arming button is disabled as long as HA is not disarmed.
>>
>> The icons ('unlink' and 'link') are chosen to emphasize that
>> "Disarm HA" and "Re-arm HA" are complements. There may be more
>> suitable pairs of icons though.
>>
>> Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com>
>> ---
>>  www/manager6/ha/Status.js     | 106 ++++++++++++++++++++++++++++++++++
>>  www/manager6/ha/StatusView.js |   8 +++
>>  2 files changed, 114 insertions(+)
>>

[snip]




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH manager] ui: ha: add disarm/re-arm button
  2026-04-14 11:51 [PATCH manager] ui: ha: add disarm/re-arm button Dominik Rusovac
  2026-04-14 13:30 ` Daniel Kral
@ 2026-04-15  6:44 ` Dominik Rusovac
  1 sibling, 0 replies; 4+ messages in thread
From: Dominik Rusovac @ 2026-04-15  6:44 UTC (permalink / raw)
  To: Dominik Rusovac, pve-devel

Superseded-by: https://lore.proxmox.com/all/20260415064118.33290-1-d.rusovac@proxmox.com/T/#u

On Tue Apr 14, 2026 at 1:51 PM CEST, Dominik Rusovac wrote:
> The button to disarm HA in either of the resource modes ('freeze' or
> 'ignore') is disabled as long as HA is disarmed. Analogously, the
> re-arming button is disabled as long as HA is not disarmed.
>
> The icons ('unlink' and 'link') are chosen to emphasize that
> "Disarm HA" and "Re-arm HA" are complements. There may be more
> suitable pairs of icons though.
>
> Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com>
> ---
>  www/manager6/ha/Status.js     | 106 ++++++++++++++++++++++++++++++++++
>  www/manager6/ha/StatusView.js |   8 +++
>  2 files changed, 114 insertions(+)
>

[snip]




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-04-15  6:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-14 11:51 [PATCH manager] ui: ha: add disarm/re-arm button Dominik Rusovac
2026-04-14 13:30 ` Daniel Kral
2026-04-14 13:49   ` Dominik Rusovac
2026-04-15  6:44 ` Dominik Rusovac

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal