]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/dc/CorosyncLinkEdit.js
1 Ext
.define('PVE.form.CorosyncLinkEditorController', {
2 extend
: 'Ext.app.ViewController',
3 alias
: 'controller.pveCorosyncLinkEditorController',
5 addLinkIfEmpty: function() {
6 let view
= this.getView();
7 if (view
.items
|| view
.items
.length
== 0) {
12 addEmptyLink: function() {
13 // discard parameters to allow being called from 'handler'
17 addLink: function(link
) {
19 let view
= me
.getView();
20 let vm
= view
.getViewModel();
22 let linkCount
= vm
.get('linkCount');
23 if (linkCount
>= vm
.get('maxLinkCount')) {
29 if (link
.number
=== undefined) {
30 link
.number
= me
.getNextFreeNumber();
32 if (link
.value
=== undefined) {
33 link
.value
= me
.getNextFreeNetwork();
36 let linkSelector
= Ext
.create('PVE.form.CorosyncLinkSelector', {
37 maxLinkNumber
: vm
.get('maxLinkCount') - 1,
38 allowNumberEdit
: vm
.get('allowNumberEdit'),
39 allowBlankNetwork
: link
.allowBlank
,
40 initNumber
: link
.number
,
41 initNetwork
: link
.value
,
43 emptyText
: link
.emptyText
,
45 // needs to be set here, because we need to update the viewmodel
46 removeBtnHandler: function() {
47 let curLinkCount
= vm
.get('linkCount');
49 if (curLinkCount
<= 1) {
53 vm
.set('linkCount', curLinkCount
- 1);
55 // 'this' is the linkSelector here
58 me
.updateDeleteButtonState();
62 view
.add(linkSelector
);
65 vm
.set('linkCount', linkCount
);
67 me
.updateDeleteButtonState();
70 // ExtJS trips on binding this for some reason, so do it manually
71 updateDeleteButtonState: function() {
72 let view
= this.getView();
73 let vm
= view
.getViewModel();
75 let disabled
= vm
.get('linkCount') <= 1;
77 let deleteButtons
= view
.query('button[cls=removeLinkBtn]');
78 Ext
.Array
.each(deleteButtons
, btn
=> {
79 btn
.setDisabled(disabled
);
83 getNextFreeNetwork: function() {
84 let view
= this.getView();
85 let vm
= view
.getViewModel();
86 let netsInUse
= Ext
.Array
.map(
87 view
.query('proxmoxNetworkSelector'), selector
=> selector
.value
);
89 // default to empty field, user has to set up link manually
90 let retval
= undefined;
92 let nets
= vm
.get('networks');
93 Ext
.Array
.each(nets
, net
=> {
94 if (!Ext
.Array
.contains(netsInUse
, net
)) {
96 return false; // break
103 getNextFreeNumber: function() {
104 let view
= this.getView();
105 let vm
= view
.getViewModel();
106 let numbersInUse
= Ext
.Array
.map(
107 view
.query('numberfield'), field
=> field
.value
);
109 for (let i
= 0; i
< vm
.get('maxLinkCount'); i
++) {
110 if (!Ext
.Array
.contains(numbersInUse
, i
)) {
115 // all numbers in use, this should never happen since add button is
116 // disabled automatically
121 Ext
.define('PVE.form.CorosyncLinkSelector', {
122 extend
: 'Ext.panel.Panel',
123 xtype
: 'pveCorosyncLinkSelector',
125 mixins
: ['Proxmox.Mixin.CBind'],
130 allowNumberEdit
: true,
131 allowBlankNetwork
: false,
132 removeBtnHandler
: undefined,
146 xtype
: 'displayfield',
149 hidden
: '{allowNumberEdit}',
150 value
: '{initNumber}',
157 xtype
: 'numberfield',
160 maxValue
: '{maxLinkNumber}',
161 hidden
: '{!allowNumberEdit}',
162 value
: '{initNumber}',
167 submitValue
: false, // see getSubmitValue of network selector
171 xtype
: 'proxmoxNetworkSelector',
173 allowBlank
: '{allowBlankNetwork}',
174 value
: '{initNetwork}',
175 emptyText
: '{emptyText}',
178 valueField
: 'address',
179 displayField
: 'address',
181 margin
: '0 5px 0 5px',
182 getSubmitValue: function() {
183 // link number is encoded into key, so we need to set field
184 // name before value retrieval
186 let numSelect
= me
.prev('numberfield'); // always the correct one
187 let linkNumber
= numSelect
.getValue();
188 me
.name
= 'link' + linkNumber
;
189 return me
.getValue();
194 iconCls
: 'fa fa-trash-o',
195 cls
: 'removeLinkBtn',
197 hidden
: '{!allowNumberEdit}',
199 handler: function() {
201 let parent
= me
.up('pveCorosyncLinkSelector');
202 if (parent
.removeBtnHandler
!== undefined) {
203 parent
.removeBtnHandler();
209 margin
: '-1px 0 0 5px',
212 cls
: 'x-form-item-label-default',
220 initComponent: function() {
225 let numSelect
= me
.down('numberfield');
226 let netSelect
= me
.down('proxmoxNetworkSelector');
228 numSelect
.validator
= this.createNoDuplicatesValidator(
230 gettext("Duplicate link number not allowed."),
233 netSelect
.validator
= this.createNoDuplicatesValidator(
234 'proxmoxNetworkSelector',
235 gettext("Duplicate link address not allowed."),
239 createNoDuplicatesValidator: function(queryString
, errorMsg
) {
243 return function(val
) {
245 let form
= me
.up('form');
246 let linkEditor
= me
.up('pveCorosyncLinkEditor');
248 if (!form
.validating
) {
249 // avoid recursion/double validation by setting temporary states
250 curField
.validating
= true;
251 form
.validating
= true;
253 // validate all other fields as well, to always mark both
254 // parties involved in a 'duplicate' error
257 form
.validating
= false;
258 curField
.validating
= false;
259 } else if (curField
.validating
) {
260 // we'll be validated by the original call in the other
261 // if-branch, avoid double work
265 if (val
=== undefined || val
instanceof String
&& val
.length
=== 0) {
266 // let this be caught by allowBlank, if at all
270 let allFields
= linkEditor
.query(queryString
);
272 Ext
.Array
.each(allFields
, field
=> {
273 if (field
!= curField
&& field
.getValue() == val
) {
275 return false; // break
284 Ext
.define('PVE.form.CorosyncLinkEditor', {
285 extend
: 'Ext.panel.Panel',
286 xtype
: 'pveCorosyncLinkEditor',
288 controller
: 'pveCorosyncLinkEditorController',
290 // only initial config, use setter otherwise
291 allowNumberEdit
: true,
298 allowNumberEdit
: true,
302 addDisabled: function(get) {
303 return !get('allowNumberEdit') ||
304 get('linkCount') >= get('maxLinkCount');
306 dockHidden: function(get) {
307 return !(get('allowNumberEdit') || get('infoText'));
315 defaultButtonUI
: 'default',
319 hidden
: '{dockHidden}',
324 text
: gettext('Add'),
326 disabled
: '{addDisabled}',
327 hidden
: '{!allowNumberEdit}',
329 handler
: 'addEmptyLink',
340 setInfoText: function(text
) {
342 let vm
= me
.getViewModel();
344 vm
.set('infoText', text
|| '');
347 setLinks: function(links
) {
349 let controller
= me
.getController();
350 let vm
= me
.getViewModel();
353 vm
.set('linkCount', 0);
355 Ext
.Array
.each(links
, link
=> controller
.addLink(link
));
358 setDefaultLinks: function() {
360 let controller
= me
.getController();
361 let vm
= me
.getViewModel();
364 vm
.set('linkCount', 0);
365 controller
.addLink();
369 setAllowNumberEdit: function(allow
) {
371 let vm
= me
.getViewModel();
372 vm
.set('allowNumberEdit', allow
);
374 vm
.set('linkCount', 0);
378 // No links is never a valid scenario, but can occur during a slow load
379 xtype
: 'hiddenfield',
381 isValid: function() {
383 let vm
= me
.up('pveCorosyncLinkEditor').getViewModel();
384 return vm
.get('linkCount') > 0;
388 initComponent: function() {
390 let vm
= me
.getViewModel();
391 let controller
= me
.getController();
393 vm
.set('allowNumberEdit', me
.allowNumberEdit
);
394 vm
.set('infoText', me
.infoText
|| '');
398 // Request local node networks to pre-populate first link.
399 Proxmox
.Utils
.API2Request({
400 url
: '/nodes/localhost/network',
403 success
: response
=> {
404 let data
= response
.result
.data
;
405 if (data
.length
> 0) {
406 data
.sort((a
, b
) => a
.iface
.localeCompare(b
.iface
));
408 for (let net
of data
) {
410 addresses
.push(net
.address
);
413 addresses
.push(net
.address6
);
417 vm
.set('networks', addresses
);
420 // Always have at least one link, but account for delay in API,
421 // someone might have called 'setLinks' in the meantime -
422 // except if 'allowNumberEdit' is false, in which case we're
423 // probably waiting for the user to input the join info
424 if (vm
.get('allowNumberEdit')) {
425 controller
.addLinkIfEmpty();
429 if (vm
.get('allowNumberEdit')) {
430 controller
.addLinkIfEmpty();