]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/window/Backup.js
ui: migrate: fix disabled migrate button glitch
[pve-manager.git] / www / manager6 / window / Backup.js
CommitLineData
56c8ef92
DM
1Ext.define('PVE.window.Backup', {
2 extend: 'Ext.window.Window',
3
4 resizable: false,
5
8058410f 6 initComponent: function() {
56c8ef92
DM
7 var me = this;
8
9 if (!me.nodename) {
10 throw "no node name specified";
11 }
12
13 if (!me.vmid) {
14 throw "no VM ID specified";
15 }
16
17 if (!me.vmtype) {
18 throw "no VM type specified";
19 }
20
62ce8928
TL
21 let compressionSelector = Ext.create('PVE.form.CompressionSelector', {
22 name: 'compress',
23 value: 'zstd',
24 fieldLabel: gettext('Compression'),
25 });
26
fddb0412
FE
27 let modeSelector = Ext.create('PVE.form.BackupModeSelector', {
28 fieldLabel: gettext('Mode'),
29 value: 'snapshot',
30 name: 'mode',
31 });
32
33 let mailtoField = Ext.create('Ext.form.field.Text', {
34 fieldLabel: gettext('Send email to'),
35 name: 'mailto',
36 emptyText: Proxmox.Utils.noneText,
37 });
38
170f8fb4
FE
39 const keepNames = [
40 ['keep-last', gettext('Keep Last')],
41 ['keep-hourly', gettext('Keep Hourly')],
42 ['keep-daily', gettext('Keep Daily')],
43 ['keep-weekly', gettext('Keep Weekly')],
44 ['keep-monthly', gettext('Keep Monthly')],
45 ['keep-yearly', gettext('Keep Yearly')],
46 ];
47
48 let pruneSettings = keepNames.map(
49 name => Ext.create('Ext.form.field.Display', {
50 name: name[0],
51 fieldLabel: name[1],
52 hidden: true,
53 }),
54 );
55
56 let removeCheckbox = Ext.create('Proxmox.form.Checkbox', {
57 name: 'remove',
58 checked: false,
59 hidden: true,
60 uncheckedValue: 0,
61 fieldLabel: gettext('Prune'),
62 autoEl: {
63 tag: 'div',
64 'data-qtip': gettext('Prune older backups afterwards'),
65 },
66 handler: function(checkbox, value) {
67 pruneSettings.forEach(field => field.setHidden(!value));
f2e174da 68 me.down('label[name="pruneLabel"]').setHidden(!value);
170f8fb4
FE
69 },
70 });
71
fddb0412
FE
72 let initialDefaults = false;
73
56c8ef92
DM
74 var storagesel = Ext.create('PVE.form.StorageSelector', {
75 nodename: me.nodename,
76 name: 'storage',
56c8ef92
DM
77 fieldLabel: gettext('Storage'),
78 storageContent: 'backup',
62ce8928
TL
79 allowBlank: false,
80 listeners: {
81 change: function(f, v) {
5ad3fbfa
FE
82 if (!initialDefaults) {
83 me.setLoading(false);
84 }
85
6d52223b
FE
86 if (v === null || v === undefined || v === '') {
87 return;
88 }
89
62ce8928 90 let store = f.getStore();
8267aa63 91 let rec = store.findRecord('storage', v, 0, false, true, true);
62ce8928
TL
92
93 if (rec && rec.data && rec.data.type === 'pbs') {
94 compressionSelector.setValue('zstd');
95 compressionSelector.setDisabled(true);
96 } else if (!compressionSelector.getEditable()) {
97 compressionSelector.setDisabled(false);
98 }
fddb0412
FE
99
100 Proxmox.Utils.API2Request({
101 url: `/nodes/${me.nodename}/vzdump/defaults`,
102 method: 'GET',
103 params: {
104 storage: v,
105 },
106 waitMsgTarget: me,
107 success: function(response, opts) {
108 const data = response.result.data;
109
110 if (!initialDefaults && data.mailto !== undefined) {
111 mailtoField.setValue(data.mailto);
112 }
113 if (!initialDefaults && data.mode !== undefined) {
114 modeSelector.setValue(data.mode);
115 }
c4dca88b 116 if (!initialDefaults && (data['notes-template'] ?? false)) {
6a3052b2
FE
117 me.down('field[name=notes-template]').setValue(
118 PVE.Utils.unEscapeNotesTemplate(data['notes-template']),
119 );
c4dca88b 120 }
fddb0412
FE
121
122 initialDefaults = true;
170f8fb4
FE
123
124 // always update storage dependent properties
125 if (data['prune-backups'] !== undefined) {
126 const keepParams = PVE.Parser.parsePropertyString(
127 data["prune-backups"],
128 );
129 if (!keepParams['keep-all']) {
130 removeCheckbox.setHidden(false);
131 pruneSettings.forEach(function(field) {
132 const keep = keepParams[field.name];
133 if (keep) {
134 field.setValue(keep);
135 } else {
136 field.reset();
137 }
138 });
139 return;
140 }
141 }
142
143 // no defaults or keep-all=1
144 removeCheckbox.setHidden(true);
145 removeCheckbox.setValue(false);
146 pruneSettings.forEach(field => field.reset());
fddb0412
FE
147 },
148 failure: function(response, opts) {
b0d716e4 149 initialDefaults = true;
01a69af4
FE
150
151 removeCheckbox.setHidden(true);
152 removeCheckbox.setValue(false);
153 pruneSettings.forEach(field => field.reset());
154
fddb0412
FE
155 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
156 },
157 });
f6710aac 158 },
62ce8928 159 },
56c8ef92
DM
160 });
161
5e73ffe6
FE
162 let protectedCheckbox = Ext.create('Proxmox.form.Checkbox', {
163 name: 'protected',
164 checked: false,
165 uncheckedValue: 0,
166 fieldLabel: gettext('Protected'),
167 });
168
bef57f5c 169 me.formPanel = Ext.create('Proxmox.panel.InputPanel', {
56c8ef92
DM
170 bodyPadding: 10,
171 border: false,
0b240dbf 172 column1: [
56c8ef92 173 storagesel,
fddb0412 174 modeSelector,
5e73ffe6 175 protectedCheckbox,
0b240dbf
FE
176 ],
177 column2: [
62ce8928 178 compressionSelector,
fddb0412 179 mailtoField,
5e73ffe6 180 removeCheckbox,
aa396ea6 181 ],
f2e174da 182 columnB: [
5e73ffe6
FE
183 {
184 xtype: 'textareafield',
185 name: 'notes-template',
186 fieldLabel: gettext('Notes'),
187 anchor: '100%',
188 value: '{{guestname}}',
03875d7a
FE
189 },
190 {
191 xtype: 'box',
192 style: {
193 margin: '8px 0px',
194 'line-height': '1.5em',
5e73ffe6 195 },
03875d7a
FE
196 html: Ext.String.format(
197 gettext('Possible template variables are: {0}'),
198 PVE.Utils.notesTemplateVars.map(v => `<code>{{${v}}}</code>`).join(', '),
199 ),
5e73ffe6 200 },
f2e174da
TL
201 {
202 xtype: 'label',
203 name: 'pruneLabel',
204 text: gettext('Storage Retention Configuration') + ':',
205 hidden: true,
170f8fb4 206 },
f2e174da
TL
207 {
208 layout: 'hbox',
209 border: false,
210 defaults: {
211 border: false,
212 layout: 'anchor',
213 flex: 1,
170f8fb4 214 },
f2e174da
TL
215 items: [
216 {
217 padding: '0 10 0 0',
218 defaults: {
219 labelWidth: 110,
220 },
221 items: [
222 pruneSettings[0],
223 pruneSettings[2],
224 pruneSettings[4],
225 ],
170f8fb4 226 },
f2e174da
TL
227 {
228 padding: '0 0 0 10',
229 defaults: {
230 labelWidth: 110,
231 },
232 items: [
233 pruneSettings[1],
234 pruneSettings[3],
235 pruneSettings[5],
236 ],
237 },
238 ],
239 },
240 ],
56c8ef92
DM
241 });
242
56c8ef92
DM
243 var submitBtn = Ext.create('Ext.Button', {
244 text: gettext('Backup'),
8058410f 245 handler: function() {
56c8ef92 246 var storage = storagesel.getValue();
bef57f5c 247 let values = me.formPanel.getValues();
56c8ef92
DM
248 var params = {
249 storage: storage,
250 vmid: me.vmid,
251 mode: values.mode,
170f8fb4 252 remove: values.remove,
56c8ef92 253 };
8b8a4583 254
8058410f 255 if (values.mailto) {
8b8a4583
DC
256 params.mailto = values.mailto;
257 }
258
56c8ef92
DM
259 if (values.compress) {
260 params.compress = values.compress;
261 }
262
5e73ffe6
FE
263 if (values.protected) {
264 params.protected = values.protected;
265 }
266
267 if (values['notes-template']) {
268 params['notes-template'] = PVE.Utils.escapeNotesTemplate(
269 values['notes-template']);
270 }
271
e7ade592 272 Proxmox.Utils.API2Request({
56c8ef92
DM
273 url: '/nodes/' + me.nodename + '/vzdump',
274 params: params,
275 method: 'POST',
8058410f 276 failure: function(response, opts) {
f6710aac 277 Ext.Msg.alert('Error', response.htmlStatus);
56c8ef92
DM
278 },
279 success: function(response, options) {
e83e60bf
EK
280 // close later so we reload the grid
281 // after the task has completed
282 me.hide();
283
56c8ef92 284 var upid = response.result.data;
2a4971d8 285
8cbc11a7 286 var win = Ext.create('Proxmox.window.TaskViewer', {
e83e60bf
EK
287 upid: upid,
288 listeners: {
289 close: function() {
290 me.close();
f6710aac
TL
291 },
292 },
56c8ef92
DM
293 });
294 win.show();
f6710aac 295 },
56c8ef92 296 });
f6710aac 297 },
56c8ef92
DM
298 });
299
672a6270 300 var helpBtn = Ext.create('Proxmox.button.Help', {
0de33b54
EK
301 onlineHelp: 'chapter_vzdump',
302 listenToGlobalEvent: false,
f6710aac 303 hidden: false,
0de33b54
EK
304 });
305
2a4971d8 306 var title = gettext('Backup') + " " +
53e3ea84 307 (me.vmtype === 'lxc' ? "CT" : "VM") +
56c8ef92
DM
308 " " + me.vmid;
309
310 Ext.apply(me, {
311 title: title,
56c8ef92
DM
312 modal: true,
313 layout: 'auto',
314 border: false,
5e73ffe6 315 width: 600,
8058410f
TL
316 items: [me.formPanel],
317 buttons: [helpBtn, '->', submitBtn],
5ad3fbfa
FE
318 listeners: {
319 afterrender: function() {
320 /// cleared within the storage selector's change listener
321 me.setLoading(gettext('Please wait...'));
322 storagesel.setValue(me.storage);
323 },
324 },
56c8ef92
DM
325 });
326
327 me.callParent();
f6710aac 328 },
56c8ef92 329});