]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/dc/BackupJobDetail.js
1 Ext
.define('PVE.dc.BackupDiskTree', {
2 extend
: 'Ext.tree.Panel',
3 alias
: 'widget.pveBackupDiskTree',
16 tooltip
: gettext('Expand All'),
17 callback
: panel
=> panel
.expandAll(),
21 tooltip
: gettext('Collapse All'),
22 callback
: panel
=> panel
.collapseAll(),
29 text
: gettext('Guest Image'),
30 renderer: function(value
, meta
, record
) {
31 if (record
.data
.type
) {
34 if (record
.data
.name
) {
35 ret
+= " (" + record
.data
.name
+ ")";
39 // extJS needs unique IDs but we only want to show the volumes key from "vmid:key"
40 return value
.split(':')[1] + " - " + record
.data
.name
;
47 text
: gettext('Type'),
52 text
: gettext('Backup Job'),
53 renderer
: PVE
.Utils
.render_backup_status
,
54 dataIndex
: 'included',
61 let sm
= me
.getSelectionModel();
63 Proxmox
.Utils
.API2Request({
64 url
: `/cluster/backup/${me.jobid}/included_volumes`,
67 failure: function(response
, opts
) {
68 Proxmox
.Utils
.setErrorMask(me
, response
.htmlStatus
);
70 success: function(response
, opts
) {
72 me
.setRootNode(response
.result
.data
);
78 initComponent: function() {
82 throw "no job id specified";
85 var sm
= Ext
.create('Ext.selection.TreeModel', {});
89 fields
: ['id', 'type',
93 calculate: function(data
) {
94 var txt
= 'fa x-fa-tree fa-';
95 if (data
.leaf
&& !data
.type
) {
97 } else if (data
.type
=== 'qemu') {
98 return txt
+ 'desktop';
99 } else if (data
.type
=== 'lxc') {
102 return txt
+ 'question-circle';
110 fieldLabel
: gettext('Search'),
112 emptyText
: 'Name, VMID, Type',
115 enableKeyEvents
: true,
118 keyup: function(field
) {
119 let searchValue
= field
.getValue().toLowerCase();
120 me
.store
.clearFilter(true);
121 me
.store
.filterBy(function(record
) {
123 if (record
.data
.depth
=== 0) {
125 } else if (record
.data
.depth
=== 1) {
127 } else if (record
.data
.depth
=== 2) {
128 data
= record
.parentNode
.data
;
131 for (const property
of ['name', 'id', 'type']) {
132 if (!data
[property
]) {
135 let v
= data
[property
].toString();
136 if (v
!== undefined) {
138 if (v
.includes(searchValue
)) {
157 Ext
.define('PVE.dc.BackupInfo', {
158 extend
: 'Proxmox.panel.InputPanel',
159 alias
: 'widget.pveBackupInfo',
163 retentionType
: 'none',
166 hasRetention
: (get) => get('retentionType') !== 'none',
167 retentionKeepAll
: (get) => get('retentionType') === 'all',
175 xtype
: 'displayfield',
177 fieldLabel
: gettext('Node'),
178 renderer
: value
=> value
|| `-- ${gettext('All')} --`,
181 xtype
: 'displayfield',
183 fieldLabel
: gettext('Storage'),
186 xtype
: 'displayfield',
188 fieldLabel
: gettext('Schedule'),
191 xtype
: 'displayfield',
193 fieldLabel
: gettext('Next Run'),
194 renderer
: PVE
.Utils
.render_next_event
,
197 xtype
: 'displayfield',
199 fieldLabel
: gettext('Selection mode'),
204 xtype
: 'displayfield',
205 name
: 'notification-policy',
206 fieldLabel
: gettext('Notification'),
207 renderer: function(value
) {
208 let record
= this.up('pveBackupInfo')?.record
;
210 // Fall back to old value, in case this option is not migrated yet.
211 let policy
= value
|| record
?.mailnotification
|| 'always';
213 let when
= gettext('Always');
214 if (policy
=== 'failure') {
215 when
= gettext('On failure only');
216 } else if (policy
=== 'never') {
217 when
= gettext('Never');
220 // Notification-target takes precedence
221 let target
= record
?.['notification-target'] ||
223 gettext('No target configured');
225 return `${when} (${target})`;
229 xtype
: 'displayfield',
231 fieldLabel
: gettext('Compression'),
234 xtype
: 'displayfield',
236 fieldLabel
: gettext('Mode'),
237 renderer: function(value
) {
238 const modeToDisplay
= {
239 snapshot
: gettext('Snapshot'),
240 stop
: gettext('Stop'),
241 suspend
: gettext('Snapshot'),
243 return modeToDisplay
[value
] ?? gettext('Unknown');
247 xtype
: 'displayfield',
249 fieldLabel
: gettext('Enabled'),
250 renderer
: v
=> PVE
.Parser
.parseBoolean(v
.toString()) ? gettext('Yes') : gettext('No'),
253 xtype
: 'displayfield',
255 fieldLabel
: gettext('Pool to backup'),
261 xtype
: 'displayfield',
263 fieldLabel
: gettext('Comment'),
264 renderer
: Ext
.String
.htmlEncode
,
268 title
: gettext('Retention Configuration'),
277 hidden
: '{!hasRetention}',
286 xtype
: 'displayfield',
288 fieldLabel
: gettext('Keep All'),
289 renderer
: Proxmox
.Utils
.format_boolean
,
291 hidden
: '{!retentionKeepAll}',
295 ['keep-last', gettext('Keep Last')],
296 ['keep-hourly', gettext('Keep Hourly')],
299 xtype
: 'displayfield',
303 hidden
: '{!hasRetention || retentionKeepAll}',
315 ['keep-daily', gettext('Keep Daily')],
316 ['keep-weekly', gettext('Keep Weekly')],
319 xtype
: 'displayfield',
323 hidden
: '{!hasRetention || retentionKeepAll}',
334 ['keep-monthly', gettext('Keep Monthly')],
335 ['keep-yearly', gettext('Keep Yearly')],
338 xtype
: 'displayfield',
342 hidden
: '{!hasRetention || retentionKeepAll}',
351 setValues: function(values
) {
353 let vm
= me
.getViewModel();
355 Ext
.iterate(values
, function(fieldId
, val
) {
356 let field
= me
.query('[isFormField][name=' + fieldId
+ ']')[0];
362 if (values
['prune-backups'] || values
.maxfiles
!== undefined) {
364 if (values
['prune-backups']) {
365 keepValues
= values
['prune-backups'];
366 } else if (values
.maxfiles
> 0) {
367 keepValues
= { 'keep-last': values
.maxfiles
};
369 keepValues
= { 'keep-all': 1 };
372 vm
.set('retentionType', keepValues
['keep-all'] ? 'all' : 'other');
374 // set values of all keep-X fields
375 ['all', 'last', 'hourly', 'daily', 'weekly', 'monthly', 'yearly'].forEach(time
=> {
376 let name
= `keep-${time}`;
377 me
.query(`[isFormField][name=${name}]`)[0]?.setValue(keepValues
[name
]);
380 vm
.set('retentionType', 'none');
383 // selection Mode depends on the presence/absence of several keys
384 let selModeField
= me
.query('[isFormField][name=selMode]')[0];
385 let selMode
= 'none';
387 selMode
= gettext('Include selected VMs');
390 selMode
= gettext('All');
392 if (values
.exclude
) {
393 selMode
= gettext('Exclude selected VMs');
396 selMode
= gettext('Pool based');
398 selModeField
.setValue(selMode
);
401 let poolField
= me
.query('[isFormField][name=pool]')[0];
402 poolField
.setVisible(0);
406 initComponent: function() {
410 throw "no data provided";
414 me
.setValues(me
.record
);
419 Ext
.define('PVE.dc.BackedGuests', {
420 extend
: 'Ext.grid.GridPanel',
421 alias
: 'widget.pveBackedGuests',
424 stateId
: 'grid-dc-backed-guests',
430 header
: gettext('Type'),
432 renderer
: PVE
.Utils
.render_resource_type
,
443 header
: gettext('Name'),
454 initComponent: function() {
457 me
.store
.clearFilter(true);
462 gettext('Search') + ':',
467 emptyText
: 'Name, VMID, Type',
468 enableKeyEvents
: true,
471 keyup: function(field
) {
472 let searchValue
= field
.getValue().toLowerCase();
473 me
.store
.clearFilter(true);
474 me
.store
.filterBy(function(record
) {
475 let data
= record
.data
;
476 for (const property
of ['name', 'vmid', 'type']) {
477 if (data
[property
] === null) {
480 let v
= data
[property
].toString();
481 if (v
!== undefined) {
482 if (v
.toLowerCase().includes(searchValue
)) {