]> git.proxmox.com Git - pmg-gui.git/blob - js/RuleInfo.js
fix #5251: login: set autocomplete on password and user
[pmg-gui.git] / js / RuleInfo.js
1 Ext.define('PMG.RuleInfo', {
2 extend: 'Ext.panel.Panel',
3 xtype: 'pmgRuleInfo',
4
5 controller: {
6 xclass: 'Ext.app.ViewController',
7
8 setBaseUrl: function(baseurl) {
9 var me = this;
10 me.getViewModel().set('baseurl', baseurl);
11 me.reload();
12 },
13
14 reload: function() {
15 var me = this;
16 var viewmodel = me.getViewModel();
17 var baseurl = viewmodel.get('baseurl');
18
19 if (!baseurl) {
20 me.setRuleInfo(undefined);
21 return;
22 }
23
24 Proxmox.Utils.API2Request({
25 url: baseurl + "/config",
26 method: 'GET',
27 success: function(response, opts) {
28 me.setRuleInfo(response.result.data);
29 },
30 failure: function(response, opts) {
31 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
32 },
33 });
34 },
35
36 removeObjectGroup: function(rec) {
37 var me = this;
38 Ext.Msg.confirm(
39 gettext('Confirm'),
40 Ext.String.format(
41 gettext('Are you sure you want to remove entry {0}'),
42 "'" + rec.data.name + "'"),
43 function(button) {
44 if (button === 'yes') {
45 Proxmox.Utils.API2Request({
46 url: me.getViewModel().get('baseurl') + '/' + rec.data.oclass + '/'+ rec.data.typeid,
47 method: 'DELETE',
48 waitMsgTarget: me.getView(),
49 callback: function() {
50 me.reload();
51 },
52 failure: function(response, opts) {
53 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
54 },
55 });
56 }
57 },
58 );
59 },
60
61 addObjectGroup: function(type, record) {
62 var me = this;
63 var baseurl = me.getViewModel().get('baseurl');
64 var url = baseurl + '/' + type;
65 var id = type === 'action'?record.data.ogroup:record.data.id;
66 Proxmox.Utils.API2Request({
67 url: url,
68 params: { ogroup: id },
69 method: 'POST',
70 waitMsgTarget: me.getView(),
71 callback: function() {
72 me.reload();
73 },
74 failure: function(response, opts) {
75 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
76 },
77 });
78 },
79
80 setRuleInfo: function(ruledata) {
81 var me = this;
82
83 var viewmodel = me.getViewModel();
84
85 if (ruledata === undefined) {
86 viewmodel.set('selectedRule', null);
87 viewmodel.get('objects').setData([]);
88 } else {
89 viewmodel.set('selectedRule', ruledata);
90
91 let data = {
92 leaf: false,
93 expanded: true,
94 children: [],
95 };
96 Ext.Array.each(['from', 'to', 'when', 'what', 'action'], function(oc) {
97 var store = viewmodel.get(oc + 'objects');
98 if (ruledata[oc] === undefined || store === undefined) { return; }
99
100 // we build a filter for the objects,
101 // which are already added to the rule,
102 // so what we only show the ones,
103 // which are still available
104
105 var ids = Ext.Array.pluck(ruledata[oc], 'id');
106 // for the actions, we have a different id field
107 var idField = oc === 'action'?'ogroup':'id';
108 store.clearFilter();
109 store.addFilter({
110 filterFn: function(record) {
111 // FIXME
112 // actions have the ogroup as a string
113 // -> parseInt
114 return ids.indexOf(parseInt(record.data[idField], 10)) === -1;
115 },
116 });
117 store.load();
118
119 let group = {
120 name: oc,
121 oclass: oc,
122 type: true,
123 invert: ruledata[`${oc}-invert`],
124 and: ruledata[`${oc}-and`],
125 leaf: false,
126 expanded: true,
127 expandable: false,
128 children: [],
129 };
130 Ext.Array.each(ruledata[oc], function(og) {
131 group.children.push({ oclass: oc, name: og.name, typeid: og.id, leaf: true });
132 });
133
134 if (group.children.length) {
135 data.children.push(group);
136 }
137 });
138 viewmodel.get('objects').setRoot(data);
139 }
140 },
141
142 removeIconClick: function(gridView, rowindex, colindex, button, event, record) {
143 var me = this;
144 me.removeObjectGroup(record);
145 },
146
147 removeDrop: function(gridView, data, overModel) {
148 var me = this;
149 var record = data.records[0]; // only one
150 me.removeObjectGroup(record);
151 return true;
152 },
153
154 addIconClick: function(gridView, rowindex, colindex, button, event, record) {
155 var me = this;
156 me.addObjectGroup(gridView.panel.type, record);
157 return true;
158 },
159
160 addDrop: function(gridView, data, overModel) {
161 var me = this;
162 var record = data.records[0]; // only one
163 me.addObjectGroup(data.view.panel.type, record);
164 return true;
165 },
166
167 updateMode: function(field, value) {
168 let me = this;
169 let vm = me.getViewModel();
170 let oclass = field.getWidgetRecord().data.oclass;
171
172 let params = {};
173 params[`${oclass}-invert`] = value.startsWith('not') ? 1 : 0;
174 params[`${oclass}-and`] = value.endsWith('all') ? 1 : 0;
175
176 Proxmox.Utils.API2Request({
177 url: `${vm.get('baseurl')}/config`,
178 method: 'PUT',
179 params,
180 success: () => me.reload(),
181 });
182 },
183
184 control: {
185 'treepanel[reference=usedobjects]': {
186 drop: 'addDrop',
187 },
188 'tabpanel[reference=availobjects] > grid': {
189 drop: 'removeDrop',
190 },
191 'pmgMatchModeSelector': {
192 change: 'updateMode',
193 },
194 },
195 },
196
197 viewModel: {
198 data: {
199 baseurl: '',
200 },
201
202 stores: {
203 objects: {
204 type: 'tree',
205 fields: ['oclass', 'name', 'typeid'],
206 groupField: 'oclass',
207 sorters: 'name',
208 },
209
210 actionobjects: {
211 model: 'pmg-action-list',
212 proxy: {
213 type: 'proxmox',
214 url: "/api2/json/config/ruledb/action/objects",
215 },
216 sorters: 'name',
217 },
218 fromobjects: {
219 model: 'pmg-object-group',
220 proxy: {
221 type: 'proxmox',
222 url: "/api2/json/config/ruledb/who",
223 },
224 sorters: 'name',
225 },
226 toobjects: {
227 model: 'pmg-object-group',
228 proxy: {
229 type: 'proxmox',
230 url: "/api2/json/config/ruledb/who",
231 },
232 sorters: 'name',
233 },
234 whatobjects: {
235 model: 'pmg-object-group',
236 proxy: {
237 type: 'proxmox',
238 url: "/api2/json/config/ruledb/what",
239 },
240 sorters: 'name',
241 },
242 whenobjects: {
243 model: 'pmg-object-group',
244 proxy: {
245 type: 'proxmox',
246 url: "/api2/json/config/ruledb/when",
247 },
248 sorters: 'name',
249 },
250 },
251 },
252
253
254 defaults: {
255 padding: '5 10 5 10',
256 },
257
258 bodyPadding: '5 0 5 0',
259
260 layout: {
261 type: 'vbox',
262 align: 'stretch',
263 },
264
265 scrollable: true,
266
267 items: [
268 {
269 xtype: 'panel',
270 bodyPadding: '10 10 10 10',
271 data: {
272 name: '',
273 },
274 bind: {
275 data: {
276 name: '{selectedRule.name:htmlEncode}',
277 priority: '{selectedRule.priority}',
278 active: '{selectedRule.active}',
279 direction: '{selectedRule.direction}',
280 selected: '{selectedRule}',
281 },
282 },
283 tpl: [
284 '<tpl if="selected">',
285 '<b>{name}</b><br><br>',
286 gettext('Priority') + ': {priority}<br>',
287 gettext('Direction') + ': {[PMG.Utils.format_rule_direction(values.direction)]}<br>',
288 gettext('Active') + ': {[Proxmox.Utils.format_boolean(values.active)]}<br>',
289 '<tpl else>',
290 gettext('Please select a rule.'),
291 '</tpl>',
292 ],
293 },
294 {
295 xtype: 'treepanel',
296 reference: 'usedobjects',
297 hidden: true,
298 emptyText: gettext('No Objects'),
299
300 title: gettext('Used Objects'),
301 rootVisible: false,
302 useArrows: true,
303 rowLines: true,
304 userCls: 'pmx-rule-tree',
305
306 viewConfig: {
307 getRowClass: record => record.data.type ? 'pmx-type-row' : '',
308 plugins: {
309 ptype: 'gridviewdragdrop',
310 copy: true,
311 dragGroup: 'usedobjects',
312 dropGroup: 'unusedobjects',
313
314 // do not show default grid dragdrop behaviour
315 dropZone: {
316 indicatorHtml: '',
317 indicatorCls: '',
318 handleNodeDrop: Ext.emptyFn,
319 },
320 },
321 },
322
323 columns: [
324 {
325 header: gettext('Name'),
326 dataIndex: 'name',
327 xtype: 'treecolumn',
328 renderer: PMG.Utils.format_oclass,
329 sorter: function(a, b) {
330 if (a.data.type && b.data.type) {
331 return a.data.oclass.localeCompare(b.data.oclass);
332 }
333 return a.data.text.localeCompare(b.data.text);
334 },
335 flex: 1,
336 },
337 {
338 header: gettext('Match if'),
339 xtype: 'widgetcolumn',
340 width: 200,
341 widget: {
342 xtype: 'pmgMatchModeSelector',
343 },
344 onWidgetAttach: function(col, widget, rec) {
345 if (rec.data.type && rec.data.oclass !== 'action') {
346 let mode = rec.data.invert ? 'not' : '';
347 mode += rec.data.and ? 'all' : 'any';
348 widget.suspendEvents();
349 widget.setValue(mode);
350 widget.resumeEvents();
351 widget.setHidden(false);
352 } else {
353 widget.setHidden(true);
354 }
355 },
356 },
357 {
358 text: '',
359 xtype: 'actioncolumn',
360 align: 'center',
361 width: 40,
362 items: [
363 {
364 tooltip: gettext('Remove'),
365 isActionDisabled: (v, rI, cI, i, rec) => rec.data.type,
366 getClass: (v, mD, { data }) => data.type ? 'pmx-hidden' : 'fa fa-fw fa-minus-circle',
367 handler: 'removeIconClick',
368 },
369 ],
370 },
371 ],
372
373 bind: {
374 store: '{objects}',
375 hidden: '{!selectedRule}',
376 },
377 },
378 {
379 xtype: 'tabpanel',
380 title: gettext('Available Objects'),
381 reference: 'availobjects',
382 hidden: true,
383 bind: {
384 hidden: '{!selectedRule}',
385 },
386 defaults: {
387 xtype: 'grid',
388 emptyText: gettext('No Objects'),
389 viewConfig: {
390 plugins: {
391 ptype: 'gridviewdragdrop',
392 dragGroup: 'unusedobjects',
393 dropGroup: 'usedobjects',
394
395 // do not show default grid dragdrop behaviour
396 dropZone: {
397 indicatorHtml: '',
398 indicatorCls: '',
399 handleNodeDrop: Ext.emptyFn,
400 },
401 },
402 },
403 columns: [
404 {
405 header: gettext('Name'),
406 dataIndex: 'name',
407 flex: 1,
408 },
409 {
410 text: '',
411 xtype: 'actioncolumn',
412 align: 'center',
413 width: 40,
414 items: [
415 {
416 iconCls: 'fa fa-fw fa-plus-circle',
417 tooltip: gettext('Add'),
418 handler: 'addIconClick',
419 },
420 ],
421 },
422 ],
423 },
424 items: [
425 {
426 title: gettext('Action'),
427 bind: {
428 store: '{actionobjects}',
429 },
430 type: 'action',
431 iconCls: 'fa fa-flag',
432 },
433 {
434 title: gettext('From'),
435 iconCls: 'fa fa-user-circle',
436 type: 'from',
437 bind: {
438 store: '{fromobjects}',
439 },
440 },
441 {
442 title: gettext('To'),
443 iconCls: 'fa fa-user-circle',
444 type: 'to',
445 bind: {
446 store: '{toobjects}',
447 },
448 },
449 {
450 title: gettext('What'),
451 iconCls: 'fa fa-cube',
452 type: 'what',
453 bind: {
454 store: '{whatobjects}',
455 },
456 },
457 {
458 title: gettext('When'),
459 iconCls: 'fa fa-clock-o',
460 type: 'when',
461 bind: {
462 store: '{whenobjects}',
463 },
464 },
465 ],
466 },
467 ],
468 });