]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/grid/BackupView.js
ui: change comment column to notes
[pve-manager.git] / www / manager6 / grid / BackupView.js
CommitLineData
7bd89462
DM
1Ext.define('PVE.grid.BackupView', {
2 extend: 'Ext.grid.GridPanel',
3
4 alias: ['widget.pveBackupView'],
5
ba93a9c6 6 onlineHelp: 'chapter_vzdump',
7bd89462 7
a61607a8
DC
8 stateful: true,
9 stateId: 'grid-guest-backup',
10
7bd89462
DM
11 initComponent : function() {
12 var me = this;
13
14 var nodename = me.pveSelNode.data.node;
15 if (!nodename) {
16 throw "no node name specified";
17 }
18
19 var vmid = me.pveSelNode.data.vmid;
20 if (!vmid) {
21 throw "no VM ID specified";
22 }
23
24 var vmtype = me.pveSelNode.data.type;
25 if (!vmtype) {
26 throw "no VM type specified";
27 }
28
2685b382 29 var vmtypeFilter;
3b8f599b 30 if (vmtype === 'lxc' || vmtype === 'openvz') {
2685b382 31 vmtypeFilter = function(item) {
3b8f599b 32 return PVE.Utils.volume_is_lxc_backup(item.data.volid, item.data.format);
7bd89462
DM
33 };
34 } else if (vmtype === 'qemu') {
2685b382 35 vmtypeFilter = function(item) {
3b8f599b 36 return PVE.Utils.volume_is_qemu_backup(item.data.volid, item.data.format);
7bd89462
DM
37 };
38 } else {
39 throw "unsupported VM type '" + vmtype + "'";
40 }
41
ce76a18a
EK
42 var searchFilter = {
43 property: 'volid',
201b89db 44 value: '',
ce76a18a
EK
45 anyMatch: true,
46 caseSensitive: false
47 };
48
201b89db
DC
49 var vmidFilter = {
50 property: 'vmid',
51 value: vmid,
496eb1cc 52 exactMatch: true,
201b89db
DC
53 };
54
7bd89462
DM
55 me.store = Ext.create('Ext.data.Store', {
56 model: 'pve-storage-content',
57 sorters: {
58 property: 'volid',
59 order: 'DESC'
60 },
ce76a18a 61 filters: [
2685b382 62 vmtypeFilter,
201b89db
DC
63 searchFilter,
64 vmidFilter,
ce76a18a 65 ]
7bd89462
DM
66 });
67
201b89db
DC
68 let updateFilter = function() {
69 me.store.filter([
70 vmtypeFilter,
71 searchFilter,
72 vmidFilter,
73 ]);
74 };
75
7bd89462 76 var reload = Ext.Function.createBuffered(function() {
8dfd00cd 77 if (me.store) {
7bd89462
DM
78 me.store.load();
79 }
80 }, 100);
81
82 var setStorage = function(storage) {
83 var url = '/api2/json/nodes/' + nodename + '/storage/' + storage + '/content';
84 url += '?content=backup';
85
86 me.store.setProxy({
56a353b9 87 type: 'proxmox',
7bd89462
DM
88 url: url
89 });
90
91 reload();
92 };
93
94 var storagesel = Ext.create('PVE.form.StorageSelector', {
95 nodename: nodename,
96 fieldLabel: gettext('Storage'),
97 labelAlign: 'right',
98 storageContent: 'backup',
99 allowBlank: false,
100 listeners: {
101 change: function(f, value) {
957a53bd
DC
102 let storage = f.getStore().findRecord('storage', value);
103 if (storage) {
814c5942 104 let isPBS = storage.data.type === 'pbs';
957a53bd
DC
105 me.getColumns().forEach((column) => {
106 if (column.dataIndex === 'verification') {
814c5942 107 column.setHidden(!isPBS);
957a53bd
DC
108 }
109 });
110 }
7bd89462
DM
111 setStorage(value);
112 }
113 }
114 });
115
116 var storagefilter = Ext.create('Ext.form.field.Text', {
117 fieldLabel: gettext('Search'),
118 labelWidth: 50,
119 labelAlign: 'right',
120 enableKeyEvents: true,
ce76a18a 121 value: searchFilter.value,
7bd89462
DM
122 listeners: {
123 buffer: 500,
124 keyup: function(field) {
125 me.store.clearFilter(true);
ce76a18a 126 searchFilter.value = field.getValue();
201b89db 127 updateFilter();
7bd89462
DM
128 }
129 }
130 });
131
201b89db 132 var vmidfilterCB = Ext.create('Ext.form.field.Checkbox', {
a7c90b40 133 boxLabel: gettext('Filter VMID'),
201b89db
DC
134 value: '1',
135 listeners: {
136 change: function(cb, value) {
814c5942 137 vmidFilter.value = value ? vmid : '';
ac27dd32 138 vmidFilter.exactMatch = !!value;
201b89db
DC
139 updateFilter();
140 },
141 },
142 });
143
7bd89462
DM
144 var sm = Ext.create('Ext.selection.RowModel', {});
145
146 var backup_btn = Ext.create('Ext.button.Button', {
147 text: gettext('Backup now'),
148 handler: function() {
149 var win = Ext.create('PVE.window.Backup', {
150 nodename: nodename,
151 vmid: vmid,
152 vmtype: vmtype,
e83e60bf
EK
153 storage: storagesel.getValue(),
154 listeners : {
155 close: function() {
156 reload();
157 }
158 }
7bd89462
DM
159 });
160 win.show();
161 }
162 });
163
5720fafa 164 var restore_btn = Ext.create('Proxmox.button.Button', {
7bd89462
DM
165 text: gettext('Restore'),
166 disabled: true,
167 selModel: sm,
168 enableFn: function(rec) {
169 return !!rec;
170 },
171 handler: function(b, e, rec) {
814c5942 172 let win = Ext.create('PVE.window.Restore', {
7bd89462
DM
173 nodename: nodename,
174 vmid: vmid,
175 volid: rec.data.volid,
176 volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec),
177 vmtype: vmtype
178 });
179 win.show();
180 win.on('destroy', reload);
181 }
182 });
183
3b1ca3ff 184 var delete_btn = Ext.create('Proxmox.button.StdRemoveButton', {
7bd89462 185 selModel: sm,
3b1ca3ff 186 dangerous: true,
4d23cdef 187 delay: 5,
7bd89462
DM
188 confirmMsg: function(rec) {
189 var msg = Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
190 "'" + rec.data.volid + "'");
16152937 191 msg += " " + gettext('This will permanently erase all data.');
7bd89462
DM
192
193 return msg;
194 },
3b1ca3ff 195 getUrl: function(rec) {
7bd89462 196 var storage = storagesel.getValue();
3b1ca3ff
DC
197 return '/nodes/' + nodename + '/storage/' + storage + '/content/' + rec.data.volid;
198 },
199 callback: function() {
200 reload();
7bd89462
DM
201 }
202 });
203
5720fafa 204 var config_btn = Ext.create('Proxmox.button.Button', {
79f305de
DC
205 text: gettext('Show Configuration'),
206 disabled: true,
207 selModel: sm,
208 enableFn: function(rec) {
209 return !!rec;
210 },
211 handler: function(b, e, rec) {
212 var storage = storagesel.getValue();
213 if (!storage) {
214 return;
215 }
216
6da4aea8
DC
217 var win = Ext.create('PVE.window.BackupConfig', {
218 volume: rec.data.volid,
219 pveSelNode: me.pveSelNode
79f305de
DC
220 });
221
6da4aea8 222 win.show();
79f305de
DC
223 }
224 });
225
7bd89462 226 Ext.apply(me, {
7bd89462 227 selModel: sm,
201b89db
DC
228 tbar: {
229 overflowHandler: 'scroller',
a7c90b40 230 items: [ backup_btn, restore_btn, delete_btn,config_btn, '->', storagesel, '-', vmidfilterCB, storagefilter ],
201b89db 231 },
7bd89462
DM
232 columns: [
233 {
234 header: gettext('Name'),
425e05d7 235 flex: 2,
7bd89462
DM
236 sortable: true,
237 renderer: PVE.Utils.render_storage_content,
238 dataIndex: 'volid'
239 },
425e05d7 240 {
ef402242
DC
241 header: gettext('Notes'),
242 dataIndex: 'notes',
425e05d7
TL
243 flex: 1,
244 renderer: Ext.htmlEncode,
245 },
afd3b071
TL
246 {
247 header: gettext('Date'),
248 width: 150,
249 dataIndex: 'vdate'
250 },
7bd89462
DM
251 {
252 header: gettext('Format'),
253 width: 100,
254 dataIndex: 'format'
255 },
256 {
257 header: gettext('Size'),
258 width: 100,
e7ade592 259 renderer: Proxmox.Utils.format_size,
7bd89462 260 dataIndex: 'size'
201b89db
DC
261 },
262 {
263 header: gettext('VMID'),
264 dataIndex: 'vmid',
265 hidden: true,
266 },
957a53bd
DC
267 {
268 header: gettext('Verify State'),
269 dataIndex: 'verification',
270 renderer: function(v) {
271 let i = (cls, txt) => `<i class="fa fa-fw fa-${cls}"></i> ${txt}`;
272 if (v === undefined || v === null) {
273 return i('question-circle-o warning', gettext('None'));
274 }
275 let tip = ""
276 let txt = gettext('Failed');
277 let iconCls = 'times critical';
278 if (v.state === 'ok') {
279 txt = gettext('OK');
280 iconCls = 'check good';
281 let now = Date.now() / 1000;
282 let task = Proxmox.Utils.parse_task_upid(v.upid);
c9a35168
TL
283 let verify_time = Proxmox.Utils.render_timestamp(task.starttime);
284 tip = `Last verify task started on ${verify_time}`;
957a53bd
DC
285 if (now - v.starttime > 30 * 24 * 60 * 60) {
286 tip = `Last verify task over 30 days ago: ${verify_time}`;
287 iconCls = 'check warning';
288 }
289 }
290 return `<span data-qtip="${tip}"> ${i(iconCls, txt)} </span>`;
291 }
292 }
8dfd00cd 293 ]
7bd89462
DM
294 });
295
296 me.callParent();
297 }
298});