]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/panel/IPSet.js
ui: fix align mode of two column container
[pve-manager.git] / www / manager6 / panel / IPSet.js
1 Ext.define('pve-fw-ipsets', {
2 extend: 'Ext.data.Model',
3 fields: ['name', 'comment', 'digest'],
4 idProperty: 'name',
5 });
6
7 Ext.define('PVE.IPSetList', {
8 extend: 'Ext.grid.Panel',
9 alias: 'widget.pveIPSetList',
10
11 stateful: true,
12 stateId: 'grid-firewall-ipsetlist',
13
14 ipset_panel: undefined,
15
16 base_url: undefined,
17
18 addBtn: undefined,
19 removeBtn: undefined,
20 editBtn: undefined,
21
22 initComponent: function() {
23 var me = this;
24
25 if (typeof me.ipset_panel === 'undefined') {
26 throw "no rule panel specified";
27 }
28
29 if (typeof me.ipset_panel === 'undefined') {
30 throw "no base_url specified";
31 }
32
33 var store = new Ext.data.Store({
34 model: 'pve-fw-ipsets',
35 proxy: {
36 type: 'proxmox',
37 url: "/api2/json" + me.base_url,
38 },
39 sorters: {
40 property: 'name',
41 direction: 'ASC',
42 },
43 });
44
45 var caps = Ext.state.Manager.get('GuiCap');
46 let canEdit = !!caps.vms['VM.Config.Network'] || !!caps.dc['Sys.Modify'] || !!caps.nodes['Sys.Modify'];
47
48 var sm = Ext.create('Ext.selection.RowModel', {});
49
50 var reload = function() {
51 var oldrec = sm.getSelection()[0];
52 store.load(function(records, operation, success) {
53 if (oldrec) {
54 var rec = store.findRecord('name', oldrec.data.name, 0, false, true, true);
55 if (rec) {
56 sm.select(rec);
57 }
58 }
59 });
60 };
61
62 var run_editor = function() {
63 var rec = sm.getSelection()[0];
64 if (!rec || !canEdit) {
65 return;
66 }
67 var win = Ext.create('Proxmox.window.Edit', {
68 subject: "IPSet '" + rec.data.name + "'",
69 url: me.base_url,
70 method: 'POST',
71 digest: rec.data.digest,
72 items: [
73 {
74 xtype: 'hiddenfield',
75 name: 'rename',
76 value: rec.data.name,
77 },
78 {
79 xtype: 'textfield',
80 name: 'name',
81 value: rec.data.name,
82 fieldLabel: gettext('Name'),
83 allowBlank: false,
84 },
85 {
86 xtype: 'textfield',
87 name: 'comment',
88 value: rec.data.comment,
89 fieldLabel: gettext('Comment'),
90 },
91 ],
92 });
93 win.show();
94 win.on('destroy', reload);
95 };
96
97 me.editBtn = new Proxmox.button.Button({
98 text: gettext('Edit'),
99 disabled: true,
100 enableFn: rec => canEdit,
101 selModel: sm,
102 handler: run_editor,
103 });
104
105 me.addBtn = new Proxmox.button.Button({
106 text: gettext('Create'),
107 handler: function() {
108 sm.deselectAll();
109 var win = Ext.create('Proxmox.window.Edit', {
110 subject: 'IPSet',
111 url: me.base_url,
112 method: 'POST',
113 items: [
114 {
115 xtype: 'textfield',
116 name: 'name',
117 value: '',
118 fieldLabel: gettext('Name'),
119 allowBlank: false,
120 },
121 {
122 xtype: 'textfield',
123 name: 'comment',
124 value: '',
125 fieldLabel: gettext('Comment'),
126 },
127 ],
128 });
129 win.show();
130 win.on('destroy', reload);
131 },
132 });
133
134 me.removeBtn = Ext.create('Proxmox.button.StdRemoveButton', {
135 enableFn: rec => canEdit,
136 selModel: sm,
137 baseurl: me.base_url + '/',
138 callback: reload,
139 });
140
141 Ext.apply(me, {
142 store: store,
143 tbar: ['<b>IPSet:</b>', me.addBtn, me.removeBtn, me.editBtn],
144 selModel: sm,
145 columns: [
146 {
147 header: 'IPSet',
148 dataIndex: 'name',
149 minWidth: 150,
150 flex: 1,
151 },
152 {
153 header: gettext('Comment'),
154 dataIndex: 'comment',
155 renderer: Ext.String.htmlEncode,
156 flex: 4,
157 },
158 ],
159 listeners: {
160 itemdblclick: run_editor,
161 select: function(_, rec) {
162 var url = me.base_url + '/' + rec.data.name;
163 me.ipset_panel.setBaseUrl(url);
164 },
165 deselect: function() {
166 me.ipset_panel.setBaseUrl(undefined);
167 },
168 show: reload,
169 },
170 });
171
172 if (!canEdit) {
173 me.addBtn.setDisabled(true);
174 }
175
176 me.callParent();
177
178 store.load();
179 },
180 });
181
182 Ext.define('PVE.IPSetCidrEdit', {
183 extend: 'Proxmox.window.Edit',
184
185 cidr: undefined,
186
187 initComponent: function() {
188 var me = this;
189
190 me.isCreate = me.cidr === undefined;
191
192
193 if (me.isCreate) {
194 me.url = '/api2/extjs' + me.base_url;
195 me.method = 'POST';
196 } else {
197 me.url = '/api2/extjs' + me.base_url + '/' + me.cidr;
198 me.method = 'PUT';
199 }
200
201 var column1 = [];
202
203 if (me.isCreate) {
204 if (!me.list_refs_url) {
205 throw "no alias_base_url specified";
206 }
207
208 column1.push({
209 xtype: 'pveIPRefSelector',
210 name: 'cidr',
211 ref_type: 'alias',
212 autoSelect: false,
213 editable: true,
214 base_url: me.list_refs_url,
215 allowBlank: false,
216 fieldLabel: gettext('IP/CIDR'),
217 });
218 } else {
219 column1.push({
220 xtype: 'displayfield',
221 name: 'cidr',
222 value: '',
223 fieldLabel: gettext('IP/CIDR'),
224 });
225 }
226
227 var ipanel = Ext.create('Proxmox.panel.InputPanel', {
228 isCreate: me.isCreate,
229 column1: column1,
230 column2: [
231 {
232 xtype: 'proxmoxcheckbox',
233 name: 'nomatch',
234 checked: false,
235 uncheckedValue: 0,
236 fieldLabel: 'nomatch',
237 },
238 ],
239 columnB: [
240 {
241 xtype: 'textfield',
242 name: 'comment',
243 value: '',
244 fieldLabel: gettext('Comment'),
245 },
246 ],
247 });
248
249 Ext.apply(me, {
250 subject: gettext('IP/CIDR'),
251 items: [ipanel],
252 });
253
254 me.callParent();
255
256 if (!me.isCreate) {
257 me.load({
258 success: function(response, options) {
259 var values = response.result.data;
260 ipanel.setValues(values);
261 },
262 });
263 }
264 },
265 });
266
267 Ext.define('PVE.IPSetGrid', {
268 extend: 'Ext.grid.Panel',
269 alias: 'widget.pveIPSetGrid',
270
271 stateful: true,
272 stateId: 'grid-firewall-ipsets',
273
274 base_url: undefined,
275 list_refs_url: undefined,
276
277 addBtn: undefined,
278 removeBtn: undefined,
279 editBtn: undefined,
280
281 setBaseUrl: function(url) {
282 var me = this;
283
284 me.base_url = url;
285
286 if (url === undefined) {
287 me.addBtn.setDisabled(true);
288 me.store.removeAll();
289 } else {
290 if (me.canEdit) {
291 me.addBtn.setDisabled(false);
292 }
293 me.removeBtn.baseurl = url + '/';
294 me.store.setProxy({
295 type: 'proxmox',
296 url: '/api2/json' + url,
297 });
298
299 me.store.load();
300 }
301 },
302
303 initComponent: function() {
304 var me = this;
305
306 if (!me.list_refs_url) {
307 throw "no1 list_refs_url specified";
308 }
309
310 var store = new Ext.data.Store({
311 model: 'pve-ipset',
312 });
313
314 var reload = function() {
315 store.load();
316 };
317
318 var sm = Ext.create('Ext.selection.RowModel', {});
319
320 me.caps = Ext.state.Manager.get('GuiCap');
321 me.canEdit = !!me.caps.vms['VM.Config.Network'] || !!me.caps.dc['Sys.Modify'] || !!me.caps.nodes['Sys.Modify'];
322
323 var run_editor = function() {
324 var rec = sm.getSelection()[0];
325 if (!rec || !me.canEdit) {
326 return;
327 }
328 var win = Ext.create('PVE.IPSetCidrEdit', {
329 base_url: me.base_url,
330 cidr: rec.data.cidr,
331 });
332 win.show();
333 win.on('destroy', reload);
334 };
335
336 me.editBtn = new Proxmox.button.Button({
337 text: gettext('Edit'),
338 disabled: true,
339 enableFn: rec => me.canEdit,
340 selModel: sm,
341 handler: run_editor,
342 });
343
344 me.addBtn = new Proxmox.button.Button({
345 text: gettext('Add'),
346 disabled: true,
347 enableFn: rec => me.canEdit,
348 handler: function() {
349 if (!me.base_url) {
350 return;
351 }
352 var win = Ext.create('PVE.IPSetCidrEdit', {
353 base_url: me.base_url,
354 list_refs_url: me.list_refs_url,
355 });
356 win.show();
357 win.on('destroy', reload);
358 },
359 });
360
361 me.removeBtn = Ext.create('Proxmox.button.StdRemoveButton', {
362 disabled: true,
363 enableFn: rec => me.canEdit,
364 selModel: sm,
365 baseurl: me.base_url + '/',
366 callback: reload,
367 });
368
369 var render_errors = function(value, metaData, record) {
370 var errors = record.data.errors;
371 if (errors) {
372 var msg = errors.cidr || errors.nomatch;
373 if (msg) {
374 metaData.tdCls = 'proxmox-invalid-row';
375 var html = '<p>' + Ext.htmlEncode(msg) + '</p>';
376 metaData.tdAttr = 'data-qwidth=600 data-qtitle="ERROR" data-qtip="' +
377 html.replace(/"/g, '&quot;') + '"';
378 }
379 }
380 return value;
381 };
382
383 Ext.apply(me, {
384 tbar: ['<b>IP/CIDR:</b>', me.addBtn, me.removeBtn, me.editBtn],
385 store: store,
386 selModel: sm,
387 listeners: {
388 itemdblclick: run_editor,
389 },
390 columns: [
391 {
392 xtype: 'rownumberer',
393 // cannot use width on instantiation as rownumberer hard-wires that in the
394 // constructor to avoid being overridden by applyDefaults
395 minWidth: 40,
396 },
397 {
398 header: gettext('IP/CIDR'),
399 dataIndex: 'cidr',
400 minWidth: 150,
401 flex: 1,
402 renderer: function(value, metaData, record) {
403 value = render_errors(value, metaData, record);
404 if (record.data.nomatch) {
405 return '<b>! </b>' + value;
406 }
407 return value;
408 },
409 },
410 {
411 header: gettext('Comment'),
412 dataIndex: 'comment',
413 flex: 3,
414 renderer: function(value) {
415 return Ext.util.Format.htmlEncode(value);
416 },
417 },
418 ],
419 });
420
421 me.callParent();
422
423 if (me.base_url) {
424 me.setBaseUrl(me.base_url); // load
425 }
426 },
427 }, function() {
428 Ext.define('pve-ipset', {
429 extend: 'Ext.data.Model',
430 fields: [{ name: 'nomatch', type: 'boolean' },
431 'cidr', 'comment', 'errors'],
432 idProperty: 'cidr',
433 });
434 });
435
436 Ext.define('PVE.IPSet', {
437 extend: 'Ext.panel.Panel',
438 alias: 'widget.pveIPSet',
439
440 title: 'IPSet',
441
442 onlineHelp: 'pve_firewall_ip_sets',
443
444 list_refs_url: undefined,
445
446 initComponent: function() {
447 var me = this;
448
449 if (!me.list_refs_url) {
450 throw "no list_refs_url specified";
451 }
452
453 var ipset_panel = Ext.createWidget('pveIPSetGrid', {
454 region: 'center',
455 list_refs_url: me.list_refs_url,
456 border: false,
457 });
458
459 var ipset_list = Ext.createWidget('pveIPSetList', {
460 region: 'west',
461 ipset_panel: ipset_panel,
462 base_url: me.base_url,
463 width: '50%',
464 border: false,
465 split: true,
466 });
467
468 Ext.apply(me, {
469 layout: 'border',
470 items: [ipset_list, ipset_panel],
471 listeners: {
472 show: function() {
473 ipset_list.fireEvent('show', ipset_list);
474 },
475 },
476 });
477
478 me.callParent();
479 },
480 });