]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/window/GuestDiskReassign.js
ui: fix duplicate references when using multiple disk storage selectors
[pve-manager.git] / www / manager6 / window / GuestDiskReassign.js
CommitLineData
3bde324f 1Ext.define('PVE.window.GuestDiskReassign', {
a8d854af
AL
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: {
d72ad78b 40 title: get => get('isQemu') ? gettext('Reassign Disk') : gettext('Reassign Volume'),
a8d854af
AL
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) {
6c067839
TL
75 let view = this.getView();
76 view.getViewModel().set('mpType', value.getValue());
77 view.lookup('mpIdSelector').validate();
a8d854af
AL
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
6c067839 90 let url = `/nodes/${view.nodename}/${view.type}/${vmid}/config`;
a8d854af
AL
91 Proxmox.Utils.API2Request({
92 url: url,
93 method: 'GET',
94 failure: response => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
6c067839 95 success: function({ result }, options) {
a8d854af 96 if (view.qemu) {
6c067839 97 diskSelector.setVMConfig(result.data);
a8d854af
AL
98 diskSelector.setDisabled(false);
99 } else {
100 let mpIdSelector = view.lookup('mpIdSelector');
101 let mpType = view.lookup('mpType');
102
6c067839 103 view.VMConfig = result.data;
a8d854af
AL
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
2281ca32 121 defaultFocus: 'sourceDisk',
a8d854af
AL
122 items: [
123 {
14ea602f
TL
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',
14ea602f
TL
135 name: 'targetVmid',
136 allowBlank: false,
d72ad78b 137 fieldLabel: gettext('Target Guest'),
14ea602f
TL
138 store: {
139 model: 'PVEResources',
140 autoLoad: true,
141 sorters: 'vmid',
142 cbind: {}, // for nested cbinds
143 filters: [
144 {
145 property: 'type',
6c067839 146 cbind: { value: '{type}' },
14ea602f
TL
147 },
148 {
149 property: 'node',
6c067839 150 cbind: { value: '{nodename}' },
14ea602f 151 },
6c067839 152 // FIXME: remove, artificial restriction that doesn't gains us anything..
14ea602f
TL
153 {
154 property: 'vmid',
155 operator: '!=',
6c067839 156 cbind: { value: '{vmid}' },
14ea602f
TL
157 },
158 {
159 property: 'template',
160 value: 0,
161 },
162 ],
163 },
164 listeners: { change: 'onTargetVMChange' },
165 },
166 {
167 xtype: 'pveControllerSelector',
168 reference: 'diskSelector',
169 withUnused: true,
170 disabled: true,
171 cbind: {
172 hidden: '{!isQemu}',
173 },
174 },
175 {
176 xtype: 'container',
177 layout: 'hbox',
178 cbind: {
179 hidden: '{isQemu}',
180 disabled: '{isQemu}',
a8d854af
AL
181 },
182 items: [
183 {
14ea602f 184 xtype: 'pmxDisplayEditField',
a8d854af 185 cbind: {
14ea602f
TL
186 editable: get => !get('disk').match(/^unused\d+/),
187 value: get => get('disk').match(/^unused\d+/) ? 'unused' : 'mp',
a8d854af 188 },
14ea602f
TL
189 disabled: true,
190 name: 'mpType',
191 reference: 'mpType',
192 fieldLabel: gettext('Add as'),
193 submitValue: true,
194 flex: 4,
195 editConfig: {
196 xtype: 'proxmoxKVComboBox',
197 name: 'mpTypeCombo',
14ea602f
TL
198 deleteEmpty: false,
199 cbind: {
200 hidden: '{isQemu}',
201 },
202 comboItems: [
203 ['mp', gettext('Mount Point')],
204 ['unused', gettext('Unused')],
a8d854af 205 ],
14ea602f 206 listeners: { change: 'onMpTypeChange' },
a8d854af 207 },
a8d854af
AL
208 },
209 {
14ea602f
TL
210 xtype: 'proxmoxintegerfield',
211 name: 'mpId',
212 reference: 'mpIdSelector',
213 minValue: 0,
214 flex: 1,
215 allowBlank: false,
216 validateOnChange: true,
a8d854af 217 disabled: true,
14ea602f
TL
218 bind: {
219 maxValue: '{mpMaxCount}',
a8d854af 220 },
14ea602f
TL
221 validator: function(value) {
222 let view = this.up('window');
223 let type = view.getViewModel().get('mpType');
224 if (Ext.isDefined(view.VMConfig[`${type}${value}`])) {
225 return "Mount point is already in use.";
226 }
227 return true;
a8d854af 228 },
a8d854af
AL
229 },
230 ],
231 },
232 ],
233
234 initComponent: function() {
235 let me = this;
236
237 if (!me.nodename) {
238 throw "no node name specified";
239 }
240
241 if (!me.vmid) {
242 throw "no VM ID specified";
243 }
244
245 if (!me.type) {
246 throw "no type specified";
247 }
248
249 me.callParent();
250 },
251});