]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/GuestDiskReassign.js
ui: restore: group override settings in a fieldset
[pve-manager.git] / www / manager6 / window / GuestDiskReassign.js
1 Ext.define('PVE.window.GuestDiskReassign', {
2 extend: 'Proxmox.window.Edit',
3 mixins: ['Proxmox.Mixin.CBind'],
4
5 resizable: false,
6 modal: true,
7 width: 350,
8 border: false,
9 layout: 'fit',
10 showReset: false,
11 showProgress: true,
12 method: 'POST',
13
14 viewModel: {
15 data: {
16 mpType: '',
17 },
18 formulas: {
19 mpMaxCount: get => get('mpType') === 'mp'
20 ? PVE.Utils.mp_counts.mps - 1
21 : PVE.Utils.mp_counts.unused - 1,
22 },
23 },
24
25 cbindData: function() {
26 let me = this;
27 return {
28 vmid: me.vmid,
29 disk: me.disk,
30 isQemu: me.type === 'qemu',
31 nodename: me.nodename,
32 url: () => {
33 let endpoint = me.type === 'qemu' ? 'move_disk' : 'move_volume';
34 return `/nodes/${me.nodename}/${me.type}/${me.vmid}/${endpoint}`;
35 },
36 };
37 },
38
39 cbind: {
40 title: get => get('isQemu') ? gettext('Reassign Disk') : gettext('Reassign Volume'),
41 submitText: get => get('title'),
42 qemu: '{isQemu}',
43 url: '{url}',
44 },
45
46 getValues: function() {
47 let me = this;
48 let values = me.formPanel.getForm().getValues();
49
50 let params = {
51 vmid: me.vmid,
52 'target-vmid': values.targetVmid,
53 };
54
55 params[me.qemu ? 'disk' : 'volume'] = me.disk;
56
57 if (me.qemu) {
58 params['target-disk'] = `${values.controller}${values.deviceid}`;
59 } else {
60 params['target-volume'] = `${values.mpType}${values.mpId}`;
61 }
62 return params;
63 },
64
65 controller: {
66 xclass: 'Ext.app.ViewController',
67
68 initViewModel: function(model) {
69 let view = this.getView();
70 let mpTypeValue = view.disk.match(/^unused\d+/) ? 'unused' : 'mp';
71 model.set('mpType', mpTypeValue);
72 },
73
74 onMpTypeChange: function(value) {
75 let view = this.getView();
76 view.getViewModel().set('mpType', value.getValue());
77 view.lookup('mpIdSelector').validate();
78 },
79
80 onTargetVMChange: function(f, vmid) {
81 let me = this;
82 let view = me.getView();
83 let diskSelector = view.lookup('diskSelector');
84 if (!vmid) {
85 diskSelector.setVMConfig(null);
86 me.VMConfig = null;
87 return;
88 }
89
90 let url = `/nodes/${view.nodename}/${view.type}/${vmid}/config`;
91 Proxmox.Utils.API2Request({
92 url: url,
93 method: 'GET',
94 failure: response => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
95 success: function({ result }, options) {
96 if (view.qemu) {
97 diskSelector.setVMConfig(result.data);
98 diskSelector.setDisabled(false);
99 } else {
100 let mpIdSelector = view.lookup('mpIdSelector');
101 let mpType = view.lookup('mpType');
102
103 view.VMConfig = result.data;
104
105 mpIdSelector.setValue(
106 PVE.Utils.nextFreeMP(
107 view.getViewModel().get('mpType'),
108 view.VMConfig,
109 ).id,
110 );
111
112 mpType.setDisabled(false);
113 mpIdSelector.setDisabled(false);
114 mpIdSelector.validate();
115 }
116 },
117 });
118 },
119 },
120
121 defaultFocus: 'sourceDisk',
122 items: [
123 {
124 xtype: 'displayfield',
125 name: 'sourceDisk',
126 fieldLabel: gettext('Source'),
127 cbind: {
128 name: get => get('isQemu') ? 'disk' : 'volume',
129 value: '{disk}',
130 },
131 allowBlank: false,
132 },
133 {
134 xtype: 'vmComboSelector',
135 reference: 'targetVMID',
136 name: 'targetVmid',
137 allowBlank: false,
138 fieldLabel: gettext('Target Guest'),
139 bind: {
140 value: '{targetVMID}',
141 },
142 store: {
143 model: 'PVEResources',
144 autoLoad: true,
145 sorters: 'vmid',
146 cbind: {}, // for nested cbinds
147 filters: [
148 {
149 property: 'type',
150 cbind: { value: '{type}' },
151 },
152 {
153 property: 'node',
154 cbind: { value: '{nodename}' },
155 },
156 // FIXME: remove, artificial restriction that doesn't gains us anything..
157 {
158 property: 'vmid',
159 operator: '!=',
160 cbind: { value: '{vmid}' },
161 },
162 {
163 property: 'template',
164 value: 0,
165 },
166 ],
167 },
168 listeners: { change: 'onTargetVMChange' },
169 },
170 {
171 xtype: 'pveControllerSelector',
172 reference: 'diskSelector',
173 withUnused: true,
174 disabled: true,
175 cbind: {
176 hidden: '{!isQemu}',
177 },
178 },
179 {
180 xtype: 'container',
181 layout: 'hbox',
182 cbind: {
183 hidden: '{isQemu}',
184 disabled: '{isQemu}',
185 },
186 items: [
187 {
188 xtype: 'pmxDisplayEditField',
189 cbind: {
190 editable: get => !get('disk').match(/^unused\d+/),
191 value: get => get('disk').match(/^unused\d+/) ? 'unused' : 'mp',
192 },
193 disabled: true,
194 name: 'mpType',
195 reference: 'mpType',
196 fieldLabel: gettext('Add as'),
197 submitValue: true,
198 flex: 4,
199 editConfig: {
200 xtype: 'proxmoxKVComboBox',
201 name: 'mpTypeCombo',
202 deleteEmpty: false,
203 cbind: {
204 hidden: '{isQemu}',
205 },
206 comboItems: [
207 ['mp', gettext('Mount Point')],
208 ['unused', gettext('Unused')],
209 ],
210 listeners: { change: 'onMpTypeChange' },
211 },
212 },
213 {
214 xtype: 'proxmoxintegerfield',
215 name: 'mpId',
216 reference: 'mpIdSelector',
217 minValue: 0,
218 flex: 1,
219 allowBlank: false,
220 validateOnChange: true,
221 disabled: true,
222 bind: {
223 maxValue: '{mpMaxCount}',
224 },
225 validator: function(value) {
226 let view = this.up('window');
227 let type = view.getViewModel().get('mpType');
228 if (Ext.isDefined(view.VMConfig[`${type}${value}`])) {
229 return "Mount point is already in use.";
230 }
231 return true;
232 },
233 },
234 ],
235 },
236 ],
237
238 initComponent: function() {
239 let me = this;
240
241 if (!me.nodename) {
242 throw "no node name specified";
243 }
244
245 if (!me.vmid) {
246 throw "no VM ID specified";
247 }
248
249 if (!me.type) {
250 throw "no type specified";
251 }
252
253 me.callParent();
254 },
255 });