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