]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/grid/BackupView.js
ui: change comment column to notes
[pve-manager.git] / www / manager6 / grid / BackupView.js
1 Ext.define('PVE.grid.BackupView', {
2 extend: 'Ext.grid.GridPanel',
3
4 alias: ['widget.pveBackupView'],
5
6 onlineHelp: 'chapter_vzdump',
7
8 stateful: true,
9 stateId: 'grid-guest-backup',
10
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
29 var vmtypeFilter;
30 if (vmtype === 'lxc' || vmtype === 'openvz') {
31 vmtypeFilter = function(item) {
32 return PVE.Utils.volume_is_lxc_backup(item.data.volid, item.data.format);
33 };
34 } else if (vmtype === 'qemu') {
35 vmtypeFilter = function(item) {
36 return PVE.Utils.volume_is_qemu_backup(item.data.volid, item.data.format);
37 };
38 } else {
39 throw "unsupported VM type '" + vmtype + "'";
40 }
41
42 var searchFilter = {
43 property: 'volid',
44 value: '',
45 anyMatch: true,
46 caseSensitive: false
47 };
48
49 var vmidFilter = {
50 property: 'vmid',
51 value: vmid,
52 exactMatch: true,
53 };
54
55 me.store = Ext.create('Ext.data.Store', {
56 model: 'pve-storage-content',
57 sorters: {
58 property: 'volid',
59 order: 'DESC'
60 },
61 filters: [
62 vmtypeFilter,
63 searchFilter,
64 vmidFilter,
65 ]
66 });
67
68 let updateFilter = function() {
69 me.store.filter([
70 vmtypeFilter,
71 searchFilter,
72 vmidFilter,
73 ]);
74 };
75
76 var reload = Ext.Function.createBuffered(function() {
77 if (me.store) {
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({
87 type: 'proxmox',
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) {
102 let storage = f.getStore().findRecord('storage', value);
103 if (storage) {
104 let isPBS = storage.data.type === 'pbs';
105 me.getColumns().forEach((column) => {
106 if (column.dataIndex === 'verification') {
107 column.setHidden(!isPBS);
108 }
109 });
110 }
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,
121 value: searchFilter.value,
122 listeners: {
123 buffer: 500,
124 keyup: function(field) {
125 me.store.clearFilter(true);
126 searchFilter.value = field.getValue();
127 updateFilter();
128 }
129 }
130 });
131
132 var vmidfilterCB = Ext.create('Ext.form.field.Checkbox', {
133 boxLabel: gettext('Filter VMID'),
134 value: '1',
135 listeners: {
136 change: function(cb, value) {
137 vmidFilter.value = value ? vmid : '';
138 vmidFilter.exactMatch = !!value;
139 updateFilter();
140 },
141 },
142 });
143
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,
153 storage: storagesel.getValue(),
154 listeners : {
155 close: function() {
156 reload();
157 }
158 }
159 });
160 win.show();
161 }
162 });
163
164 var restore_btn = Ext.create('Proxmox.button.Button', {
165 text: gettext('Restore'),
166 disabled: true,
167 selModel: sm,
168 enableFn: function(rec) {
169 return !!rec;
170 },
171 handler: function(b, e, rec) {
172 let win = Ext.create('PVE.window.Restore', {
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
184 var delete_btn = Ext.create('Proxmox.button.StdRemoveButton', {
185 selModel: sm,
186 dangerous: true,
187 delay: 5,
188 confirmMsg: function(rec) {
189 var msg = Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
190 "'" + rec.data.volid + "'");
191 msg += " " + gettext('This will permanently erase all data.');
192
193 return msg;
194 },
195 getUrl: function(rec) {
196 var storage = storagesel.getValue();
197 return '/nodes/' + nodename + '/storage/' + storage + '/content/' + rec.data.volid;
198 },
199 callback: function() {
200 reload();
201 }
202 });
203
204 var config_btn = Ext.create('Proxmox.button.Button', {
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
217 var win = Ext.create('PVE.window.BackupConfig', {
218 volume: rec.data.volid,
219 pveSelNode: me.pveSelNode
220 });
221
222 win.show();
223 }
224 });
225
226 Ext.apply(me, {
227 selModel: sm,
228 tbar: {
229 overflowHandler: 'scroller',
230 items: [ backup_btn, restore_btn, delete_btn,config_btn, '->', storagesel, '-', vmidfilterCB, storagefilter ],
231 },
232 columns: [
233 {
234 header: gettext('Name'),
235 flex: 2,
236 sortable: true,
237 renderer: PVE.Utils.render_storage_content,
238 dataIndex: 'volid'
239 },
240 {
241 header: gettext('Notes'),
242 dataIndex: 'notes',
243 flex: 1,
244 renderer: Ext.htmlEncode,
245 },
246 {
247 header: gettext('Date'),
248 width: 150,
249 dataIndex: 'vdate'
250 },
251 {
252 header: gettext('Format'),
253 width: 100,
254 dataIndex: 'format'
255 },
256 {
257 header: gettext('Size'),
258 width: 100,
259 renderer: Proxmox.Utils.format_size,
260 dataIndex: 'size'
261 },
262 {
263 header: gettext('VMID'),
264 dataIndex: 'vmid',
265 hidden: true,
266 },
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);
283 let verify_time = Proxmox.Utils.render_timestamp(task.starttime);
284 tip = `Last verify task started on ${verify_time}`;
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 }
293 ]
294 });
295
296 me.callParent();
297 }
298 });