opens a window with the parameters for the sync and two buttons: 'preview' and 'sync'
both open the taskviewer, but the 'preview' one sets the 'no-write' parameter so that it does not get written out to the user.cfg loads the realm config and prefills the selection with values from the config Signed-off-by: Dominik Csapak <d.csa...@proxmox.com> --- changes from v1: * load realm config and set appropriate values * mark loaded values as such ({0} (from Config)) * wrapped the ipanel in a form to easier get the validity * changed to a controller to better to have better access to the components and their handlers * remove the 'default' options from fields that do not have one, set the initial value to '' and allowBlank to false so that they are not valid by default (either set from config or manually chosen) i am not completely happy with how manual this whole thing is, but i (for now) could not come up with a better method without completely changing the ux (e.g showing the defaults separately; which i do not want) there are a few possibilities to make this easier when we want some of those features elsewhere, but for now it does not make sense to refactor it (e.g. the changing of text of a kvcombobox, or the manual management of buttons in an edit window) www/manager6/Makefile | 1 + www/manager6/dc/AuthView.js | 21 ++++ www/manager6/dc/SyncWindow.js | 185 ++++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 www/manager6/dc/SyncWindow.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index 057a4211..ff93b224 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -232,6 +232,7 @@ JSSRC= \ dc/RoleView.js \ dc/RoleEdit.js \ dc/ACLView.js \ + dc/SyncWindow.js \ dc/AuthView.js \ dc/AuthEditBase.js \ dc/AuthEditAD.js \ diff --git a/www/manager6/dc/AuthView.js b/www/manager6/dc/AuthView.js index a2486fef..3e5a8517 100644 --- a/www/manager6/dc/AuthView.js +++ b/www/manager6/dc/AuthView.js @@ -73,6 +73,19 @@ Ext.define('PVE.dc.AuthView', { me.openEditWindow(rec.data.type, rec.data.realm); }, + open_sync_window: function() { + let me = this; + let rec = me.getSelection()[0]; + if (!rec) { + return; + } + Ext.create('PVE.dc.SyncWindow', { + realm: rec.data.realm, + listeners: { + destroy: () => me.reload(), + }, + }).show(); + }, initComponent: function() { var me = this; @@ -107,6 +120,14 @@ Ext.define('PVE.dc.AuthView', { enableFn: (rec) => PVE.Utils.authSchema[rec.data.type].add, callback: () => me.reload(), }, + '-', + { + xtype: 'proxmoxButton', + text: gettext('Sync'), + disabled: true, + enableFn: (rec) => Boolean(PVE.Utils.authSchema[rec.data.type].syncipanel), + handler: () => me.open_sync_window(), + }, ], listeners: { activate: () => me.reload(), diff --git a/www/manager6/dc/SyncWindow.js b/www/manager6/dc/SyncWindow.js new file mode 100644 index 00000000..0865ef14 --- /dev/null +++ b/www/manager6/dc/SyncWindow.js @@ -0,0 +1,185 @@ +Ext.define('PVE.dc.SyncWindow', { + extend: 'Ext.window.Window', + + title: gettext('Realm Sync'), + + bodyPadding: 10, + modal: true, + resizable: false, + + controller: { + xclass: 'Ext.app.ViewController', + + control: { + 'form': { + validitychange: function(field, valid) { + let me = this; + me.lookup('preview_btn').setDisabled(!valid); + me.lookup('sync_btn').setDisabled(!valid); + }, + }, + 'button': { + click: function(btn) { + this.sync_realm(btn.reference === 'preview_btn'); + }, + }, + }, + + sync_realm: function(is_preview) { + let me = this; + let view = me.getView(); + let ipanel = me.lookup('ipanel'); + let params = ipanel.getValues(); + params['dry-run'] = is_preview ? 1 : 0; + Proxmox.Utils.API2Request({ + url: `/access/domains/${view.realm}/sync`, + waitMsgTarget: view, + method: 'POST', + params, + failure: function(response) { + view.show(); + Ext.Msg.alert(gettext('Error'), response.htmlStatus); + }, + success: function(response) { + view.hide(); + Ext.create('Proxmox.window.TaskViewer', { + upid: response.result.data, + listeners: { + destroy: function() { + view.close(); + }, + }, + }).show(); + }, + }); + }, + }, + + items: [ + { + xtype: 'form', + reference: 'form', + border: false, + items: [{ + xtype: 'inputpanel', + reference: 'ipanel', + column1: [ + { + xtype: 'proxmoxKVComboBox', + name: 'scope', + fieldLabel: gettext('Scope'), + value: '', + deleteEmpty: false, + allowBlank: false, + comboItems: [ + ['users', gettext('Users')], + ['groups', gettext('Groups')], + ['both', gettext('Users and Groups')], + ], + }, + { + xtype: 'proxmoxKVComboBox', + value: '', + deleteEmpty: false, + allowBlank: false, + comboItems: [ + ['1', Proxmox.Utils.yesText], + ['0', Proxmox.Utils.noText], + ], + name: 'full', + fieldLabel: gettext('Full'), + }, + ], + + column2: [ + { + xtype: 'proxmoxKVComboBox', + value: '__default__', + deleteEmpty: false, + allowBlank: false, + comboItems: [ + [ + '__default__', + Ext.String.format( + gettext("{0} ({1})"), + Proxmox.Utils.yesText, + Proxmox.Utils.defaultText, + ), + ], + ['1', Proxmox.Utils.yesText], + ['0', Proxmox.Utils.noText], + ], + name: 'enable-new', + fieldLabel: gettext('Enable new'), + }, + { + xtype: 'proxmoxKVComboBox', + value: '', + deleteEmpty: false, + allowBlank: false, + comboItems: [ + ['1', Proxmox.Utils.yesText], + ['0', Proxmox.Utils.noText], + ], + name: 'purge', + fieldLabel: gettext('Purge'), + }, + ], + }] + }, + ], + + buttons: [ + { + text: gettext('Preview'), + reference: 'preview_btn', + }, + { + text: gettext('Sync'), + reference: 'sync_btn', + }, + ], + + initComponent: function() { + let me = this; + + if (!me.realm) { + throw "no realm defined"; + } + + me.callParent(); + + Proxmox.Utils.API2Request({ + url: `/access/domains/${me.realm}`, + waitMsgTarget: me, + method: 'GET', + failure: function(response) { + Ext.Msg.alert(gettext('Error'), response.htmlStatus); + me.close(); + }, + success: function(response) { + let data = response.result.data; + let options = PVE.Parser + .parsePropertyString(data['sync-defaults-options']); + + let ipanel = me.lookup('ipanel'); + ipanel.setValues(options); + + for (const [name, value] of Object.entries(options)) { + let field = me.down(`field[name=${name}]`); + if (!field) continue; + + let entry = field.getStore().findRecord('key', value); + if (entry) { + let oldval = entry.get('value'); + entry.set('value', Ext.String.format(gettext('{0} (from Config)'), oldval)); + entry.commit(true); + } + } + + // check validity for button state + me.lookup('form').isValid(); + }, + }); + }, +}); -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel