]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/GuestDiskReassign.js
ui: disk reassign: improve title and field-label
[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 this.getView().getViewModel().set('mpType', value.getValue());
76 this.getView().lookup('mpIdSelector').validate();
77 },
78
79 onTargetVMChange: function(f, vmid) {
80 let me = this;
81 let view = me.getView();
82 let diskSelector = view.lookup('diskSelector');
83 if (!vmid) {
84 diskSelector.setVMConfig(null);
85 me.VMConfig = null;
86 return;
87 }
88
89 let type = view.qemu ? 'qemu' : 'lxc';
90
91 let url = `/nodes/${view.nodename}/${type}/${vmid}/config`;
92 Proxmox.Utils.API2Request({
93 url: url,
94 method: 'GET',
95 failure: response => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
96 success: function(response, options) {
97 if (view.qemu) {
98 diskSelector.setVMConfig(response.result.data);
99 diskSelector.setDisabled(false);
100 } else {
101 let mpIdSelector = view.lookup('mpIdSelector');
102 let mpType = view.lookup('mpType');
103
104 view.VMConfig = response.result.data;
105
106 mpIdSelector.setValue(
107 PVE.Utils.nextFreeMP(
108 view.getViewModel().get('mpType'),
109 view.VMConfig,
110 ).id,
111 );
112
113 mpType.setDisabled(false);
114 mpIdSelector.setDisabled(false);
115 mpIdSelector.validate();
116 }
117 },
118 });
119 },
120 },
121
122 defaultFocus: 'sourceDisk',
123 items: [
124 {
125 xtype: 'displayfield',
126 name: 'sourceDisk',
127 fieldLabel: gettext('Source'),
128 cbind: {
129 name: get => get('isQemu') ? 'disk' : 'volume',
130 value: '{disk}',
131 },
132 allowBlank: false,
133 },
134 {
135 xtype: 'vmComboSelector',
136 reference: 'targetVMID',
137 name: 'targetVmid',
138 allowBlank: false,
139 fieldLabel: gettext('Target Guest'),
140 bind: {
141 value: '{targetVMID}',
142 },
143 store: {
144 model: 'PVEResources',
145 autoLoad: true,
146 sorters: 'vmid',
147 cbind: {}, // for nested cbinds
148 filters: [
149 {
150 property: 'type',
151 cbind: {
152 value: get => get('isQemu') ? 'qemu' : 'lxc',
153 },
154 },
155 {
156 property: 'node',
157 cbind: {
158 value: '{nodename}',
159 },
160 },
161 {
162 property: 'vmid',
163 operator: '!=',
164 cbind: {
165 value: '{vmid}',
166 },
167 },
168 {
169 property: 'template',
170 value: 0,
171 },
172 ],
173 },
174 listeners: { change: 'onTargetVMChange' },
175 },
176 {
177 xtype: 'pveControllerSelector',
178 reference: 'diskSelector',
179 withUnused: true,
180 disabled: true,
181 cbind: {
182 hidden: '{!isQemu}',
183 },
184 },
185 {
186 xtype: 'container',
187 layout: 'hbox',
188 cbind: {
189 hidden: '{isQemu}',
190 disabled: '{isQemu}',
191 },
192 items: [
193 {
194 xtype: 'pmxDisplayEditField',
195 cbind: {
196 editable: get => !get('disk').match(/^unused\d+/),
197 value: get => get('disk').match(/^unused\d+/) ? 'unused' : 'mp',
198 },
199 disabled: true,
200 name: 'mpType',
201 reference: 'mpType',
202 fieldLabel: gettext('Add as'),
203 submitValue: true,
204 flex: 4,
205 editConfig: {
206 xtype: 'proxmoxKVComboBox',
207 name: 'mpTypeCombo',
208 reference: 'mpTypeCombo',
209 deleteEmpty: false,
210 cbind: {
211 hidden: '{isQemu}',
212 },
213 comboItems: [
214 ['mp', gettext('Mount Point')],
215 ['unused', gettext('Unused')],
216 ],
217 listeners: { change: 'onMpTypeChange' },
218 },
219 },
220 {
221 xtype: 'proxmoxintegerfield',
222 name: 'mpId',
223 reference: 'mpIdSelector',
224 minValue: 0,
225 flex: 1,
226 allowBlank: false,
227 validateOnChange: true,
228 disabled: true,
229 bind: {
230 maxValue: '{mpMaxCount}',
231 },
232 validator: function(value) {
233 let view = this.up('window');
234 let type = view.getViewModel().get('mpType');
235 if (Ext.isDefined(view.VMConfig[`${type}${value}`])) {
236 return "Mount point is already in use.";
237 }
238 return true;
239 },
240 },
241 ],
242 },
243 ],
244
245 initComponent: function() {
246 let me = this;
247
248 if (!me.nodename) {
249 throw "no node name specified";
250 }
251
252 if (!me.vmid) {
253 throw "no VM ID specified";
254 }
255
256 if (!me.type) {
257 throw "no type specified";
258 }
259
260 me.callParent();
261 },
262 });