]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/window/Prune.js
ui: esxi import: support rendering structured warnings
[pve-manager.git] / www / manager6 / window / Prune.js
CommitLineData
e969d187
FE
1Ext.define('pve-prune-list', {
2 extend: 'Ext.data.Model',
3 fields: [
4 'type',
5 'vmid',
6 {
7 name: 'ctime',
8 type: 'date',
9 dateFormat: 'timestamp',
10 },
11 ],
12});
13
14Ext.define('PVE.PruneInputPanel', {
15 extend: 'Proxmox.panel.InputPanel',
16 alias: 'widget.pvePruneInputPanel',
17 mixins: ['Proxmox.Mixin.CBind'],
18
19 onGetValues: function(values) {
20 let me = this;
21
22 // the API expects a single prune-backups property string
23 let pruneBackups = PVE.Parser.printPropertyString(values);
24 values = {
25 'prune-backups': pruneBackups,
26 'type': me.backup_type,
27 'vmid': me.backup_id,
28 };
29
30 return values;
31 },
32
33 controller: {
34 xclass: 'Ext.app.ViewController',
35
36 init: function(view) {
37 if (!view.url) {
38 throw "no url specified";
39 }
40 if (!view.backup_type) {
41 throw "no backup_type specified";
42 }
43 if (!view.backup_id) {
44 throw "no backup_id specified";
45 }
46
47 this.reload(); // initial load
48 },
49
50 reload: function() {
51 let view = this.getView();
52
53 // helper to allow showing why a backup is kept
54 let addKeepReasons = function(backups, params) {
55 const rules = [
56 'keep-last',
57 'keep-hourly',
58 'keep-daily',
59 'keep-weekly',
60 'keep-monthly',
61 'keep-yearly',
62 'keep-all', // when all keep options are not set
63 ];
64 let counter = {};
65
0eb284ed 66 backups.sort((a, b) => b.ctime - a.ctime);
e969d187
FE
67
68 let ruleIndex = -1;
69 let nextRule = function() {
70 let rule;
71 do {
72 ruleIndex++;
73 rule = rules[ruleIndex];
74 } while (!params[rule] && rule !== 'keep-all');
75 counter[rule] = 0;
76 return rule;
77 };
78
79 let rule = nextRule();
80 for (let backup of backups) {
81 if (backup.mark === 'keep') {
82 counter[rule]++;
83 if (rule !== 'keep-all') {
84 backup.keepReason = rule + ': ' + counter[rule];
85 if (counter[rule] >= params[rule]) {
86 rule = nextRule();
87 }
88 } else {
89 backup.keepReason = rule;
90 }
91 }
92 }
93 };
94
95 let params = view.getValues();
96 let keepParams = PVE.Parser.parsePropertyString(params["prune-backups"]);
97
98 Proxmox.Utils.API2Request({
99 url: view.url,
100 method: "GET",
101 params: params,
102 callback: function() {
103 // for easy breakpoint setting
104 },
105 failure: function(response, opts) {
106 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
107 },
108 success: function(response, options) {
109 var data = response.result.data;
110 addKeepReasons(data, keepParams);
111 view.pruneStore.setData(data);
112 },
113 });
114 },
115
116 control: {
117 field: { change: 'reload' },
118 },
119 },
120
121 column1: [
122 {
123 xtype: 'pmxPruneKeepField',
124 name: 'keep-last',
125 fieldLabel: gettext('keep-last'),
126 },
127 {
128 xtype: 'pmxPruneKeepField',
129 name: 'keep-hourly',
130 fieldLabel: gettext('keep-hourly'),
131 },
132 {
133 xtype: 'pmxPruneKeepField',
134 name: 'keep-daily',
135 fieldLabel: gettext('keep-daily'),
136 },
137 {
138 xtype: 'pmxPruneKeepField',
139 name: 'keep-weekly',
140 fieldLabel: gettext('keep-weekly'),
141 },
142 {
143 xtype: 'pmxPruneKeepField',
144 name: 'keep-monthly',
145 fieldLabel: gettext('keep-monthly'),
146 },
147 {
148 xtype: 'pmxPruneKeepField',
149 name: 'keep-yearly',
150 fieldLabel: gettext('keep-yearly'),
151 },
152 ],
153
154 initComponent: function() {
155 var me = this;
156
157 me.pruneStore = Ext.create('Ext.data.Store', {
158 model: 'pve-prune-list',
159 sorters: { property: 'ctime', direction: 'DESC' },
160 });
161
162 me.column2 = [
163 {
164 xtype: 'grid',
165 height: 200,
166 store: me.pruneStore,
167 columns: [
168 {
169 header: gettext('Backup Time'),
170 sortable: true,
171 dataIndex: 'ctime',
172 renderer: function(value, metaData, record) {
173 let text = Ext.Date.format(value, 'Y-m-d H:i:s');
174 if (record.data.mark === 'remove') {
175 return '<div style="text-decoration: line-through;">'+ text +'</div>';
176 } else {
177 return text;
178 }
179 },
180 flex: 1,
181 },
182 {
183 text: 'Keep (reason)',
184 dataIndex: 'mark',
185 renderer: function(value, metaData, record) {
186 if (record.data.mark === 'keep') {
187 return 'true (' + record.data.keepReason + ')';
188 } else if (record.data.mark === 'protected') {
7fec5354
FE
189 return 'true (protected)';
190 } else if (record.data.mark === 'renamed') {
e969d187
FE
191 return 'true (renamed)';
192 } else {
193 return 'false';
194 }
195 },
196 flex: 1,
197 },
198 ],
199 },
200 ];
201
202 me.callParent();
203 },
204});
205
206Ext.define('PVE.window.Prune', {
207 extend: 'Proxmox.window.Edit',
208
209 method: 'DELETE',
210 submitText: gettext("Prune"),
211
212 fieldDefaults: { labelWidth: 130 },
213
214 isCreate: true,
215
216 initComponent: function() {
217 var me = this;
218
219 if (!me.nodename) {
220 throw "no nodename specified";
221 }
222 if (!me.storage) {
223 throw "no storage specified";
224 }
225 if (!me.backup_type) {
226 throw "no backup_type specified";
227 }
228 if (me.backup_type !== 'qemu' && me.backup_type !== 'lxc') {
229 throw "unknown backup type: " + me.backup_type;
230 }
231 if (!me.backup_id) {
232 throw "no backup_id specified";
233 }
234
235 let title = Ext.String.format(
236 gettext("Prune Backups for '{0}' on Storage '{1}'"),
237 me.backup_type + '/' + me.backup_id,
238 me.storage,
239 );
240
241 Ext.apply(me, {
242 url: '/api2/extjs/nodes/' + me.nodename + '/storage/' + me.storage + "/prunebackups",
243 title: title,
244 items: [
245 {
246 xtype: 'pvePruneInputPanel',
247 url: '/api2/extjs/nodes/' + me.nodename + '/storage/' + me.storage + "/prunebackups",
248 backup_type: me.backup_type,
249 backup_id: me.backup_id,
250 storage: me.storage,
251 },
252 ],
253 });
254
255 me.callParent();
256 },
257});