]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/storage/Base.js
fix #3182 #3183: change backup retention mask logic
[pve-manager.git] / www / manager6 / storage / Base.js
CommitLineData
f28ec3e4
TL
1Ext.define('PVE.panel.StorageBase', {
2 extend: 'Proxmox.panel.InputPanel',
3 controller: 'storageEdit',
4
5 type: '',
6
7 onGetValues: function(values) {
8 var me = this;
9
10 if (me.isCreate) {
11 values.type = me.type;
12 } else {
13 delete values.storage;
14 }
15
16 values.disable = values.enable ? 0 : 1;
17 delete values.enable;
18
19 return values;
20 },
21
22 initComponent : function() {
23 var me = this;
24
25 me.column1.unshift({
26 xtype: me.isCreate ? 'textfield' : 'displayfield',
27 name: 'storage',
28 value: me.storageId || '',
29 fieldLabel: 'ID',
30 vtype: 'StorageId',
31 allowBlank: false
32 });
33
e194ea7c 34 me.column2 = me.column2 || [];
f28ec3e4
TL
35 me.column2.unshift(
36 {
37 xtype: 'pveNodeSelector',
38 name: 'nodes',
39 disabled: me.storageId === 'local',
40 fieldLabel: gettext('Nodes'),
41 emptyText: gettext('All') + ' (' + gettext('No restrictions') +')',
42 multiSelect: true,
43 autoSelect: false
44 },
45 {
46 xtype: 'proxmoxcheckbox',
47 name: 'enable',
48 checked: true,
49 uncheckedValue: 0,
50 fieldLabel: gettext('Enable')
51 }
52 );
53
54 me.callParent();
55 }
56});
57
017889f1
TL
58Ext.define('PVE.panel.StoragePruneInputPanel', {
59 extend: 'Proxmox.panel.PruneInputPanel',
60 xtype: 'pveStoragePruneInputPanel',
61 mixins: ['Proxmox.Mixin.CBind'],
62
54a589be
TL
63 onlineHelp: 'vzdump_retention',
64
017889f1
TL
65 keepLastEmptyText: gettext('1'),
66
67 onGetValues: function(formValues) {
a55b3b71
TL
68 if (this.needMask) { // isMasked() may not yet be true if not rendered once
69 return {};
e3022813
TL
70 } else if (this.isCreate && !this.rendered) {
71 return { 'prune-backups': 'keep-all=1' };
a55b3b71 72 }
017889f1
TL
73 delete formValues.delete;
74 let retention = PVE.Parser.printPropertyString(formValues)
017889f1 75 if (retention === '') {
93489d89
DJ
76 if (this.isCreate) {
77 return {};
93489d89 78 }
c2d24034
TL
79 // always delete old 'maxfiles' on edit, we map it to keep-last on window load
80 return {
81 delete: ['prune-backups','maxfiles'],
82 };
017889f1 83 }
93489d89
DJ
84 let options = { 'prune-backups': retention };
85 if (!this.isCreate) {
86 options.delete = 'maxfiles';
017889f1 87 }
93489d89 88 return options;
017889f1
TL
89 },
90
56fad7c4
FE
91 updateComponents: function() {
92 let panel = this;
93
94 let keepAll = panel.down('proxmoxcheckbox[name=keep-all]').getValue();
95 let anyValue = false;
96 panel.query('pmxPruneKeepField').forEach(field => {
97 anyValue = anyValue || field.getValue() !== null;
98 field.setDisabled(keepAll);
99 });
100 panel.down('component[name=no-keeps-hint]').setHidden(anyValue || keepAll);
101 },
102
017889f1
TL
103 listeners: {
104 afterrender: function(panel) {
105 if (panel.needMask) {
106 panel.down('component[name=no-keeps-hint]').setHtml('');
107 panel.mask(
108 gettext('Backup content type not available for this storage.'),
109 );
110 } else if (panel.isCreate) {
017889f1
TL
111 panel.down('proxmoxcheckbox[name=keep-all]').setValue(true);
112 }
5b7ab402 113 panel.down('component[name=pbs-hint]').setHidden(!panel.isPBS);
56fad7c4
FE
114
115 panel.query('pmxPruneKeepField').forEach(field => {
116 field.on('change', panel.updateComponents, panel);
117 });
118 panel.updateComponents();
017889f1
TL
119 },
120 },
121
122 columnT: {
123 xtype: 'proxmoxcheckbox',
124 name: 'keep-all',
125 boxLabel: gettext('Keep all backups'),
126 listeners: {
127 change: function(field, newValue) {
128 let panel = field.up('pveStoragePruneInputPanel');
56fad7c4 129 panel.updateComponents();
017889f1
TL
130 },
131 },
132 },
133
5b7ab402
TL
134 columnB: [
135 {
136 xtype: 'component',
137 userCls: 'pmx-hint',
138 name: 'no-keeps-hint',
139 hidden: true,
140 padding: '5 1',
141 html: gettext('Without any keep option, the nodes vzdump.conf or `keep-last 1` is used as fallback for backup jobs'),
142 },
143 {
144 xtype: 'component',
145 userCls: 'pmx-hint',
146 name: 'pbs-hint',
147 hidden: true,
148 padding: '5 1',
149 html: gettext("It's preferred to configure backup retention directly on the Proxmox Backup Server."),
150 },
151 ],
017889f1
TL
152});
153
f28ec3e4
TL
154Ext.define('PVE.storage.BaseEdit', {
155 extend: 'Proxmox.window.Edit',
156
71dec88f
TL
157 apiCallDone: function(success, response, options) {
158 let me = this;
159 if (typeof me.ipanel.apiCallDone === "function") {
160 me.ipanel.apiCallDone(success, response, options);
161 }
162 },
163
f28ec3e4
TL
164 initComponent : function() {
165 var me = this;
166
167 me.isCreate = !me.storageId;
168
169 if (me.isCreate) {
f3c1eac7
TL
170 me.url = '/api2/extjs/storage';
171 me.method = 'POST';
172 } else {
173 me.url = '/api2/extjs/storage/' + me.storageId;
174 me.method = 'PUT';
175 }
f28ec3e4 176
71dec88f 177 me.ipanel = Ext.create(me.paneltype, {
232415d9 178 title: gettext('General'),
f28ec3e4
TL
179 type: me.type,
180 isCreate: me.isCreate,
181 storageId: me.storageId
182 });
183
184 Ext.apply(me, {
185 subject: PVE.Utils.format_storage_type(me.type),
186 isAdd: true,
232415d9
TL
187 bodyPadding: 0,
188 items: {
189 xtype: 'tabpanel',
190 region: 'center',
191 layout: 'fit',
192 bodyPadding: 10,
193 items: [
194 me.ipanel,
017889f1
TL
195 {
196 xtype: 'pveStoragePruneInputPanel',
197 title: gettext('Backup Retention'),
198 isCreate: me.isCreate,
5b7ab402 199 isPBS: me.ipanel.isPBS,
017889f1 200 },
232415d9
TL
201 ],
202 },
f28ec3e4
TL
203 });
204
d994d2a7
TL
205 if (me.ipanel.extraTabs) {
206 me.ipanel.extraTabs.forEach(panel => {
207 panel.isCreate = me.isCreate;
208 me.items.items.push(panel);
209 });
210 }
211
f28ec3e4
TL
212 me.callParent();
213
06c8315d 214 if (!me.canDoBackups) {
017889f1
TL
215 // cannot mask now, not fully rendered until activated
216 me.down('pmxPruneInputPanel').needMask = true;
217 }
218
f28ec3e4
TL
219 if (!me.isCreate) {
220 me.load({
221 success: function(response, options) {
222 var values = response.result.data;
223 var ctypes = values.content || '';
224
225 values.content = ctypes.split(',');
226
227 if (values.nodes) {
228 values.nodes = values.nodes.split(',');
229 }
230 values.enable = values.disable ? 0 : 1;
017889f1
TL
231 if (values['prune-backups']) {
232 let retention = PVE.Parser.parsePropertyString(values['prune-backups']);
233 delete values['prune-backups'];
234 Object.assign(values, retention);
235 } else if (values.maxfiles !== undefined) {
236 if (values.maxfiles > 0) {
237 values['keep-last'] = values.maxfiles;
238 }
239 delete values.maxfiles;
240 }
f28ec3e4 241
232415d9
TL
242 me.query('inputpanel').forEach(panel => {
243 panel.setValues(values);
244 });
f28ec3e4
TL
245 }
246 });
247 }
248 }
249});