]> git.proxmox.com Git - pmg-gui.git/blame - js/ObjectGroup.js
object groups: consistent add/edit/remove button
[pmg-gui.git] / js / ObjectGroup.js
CommitLineData
3eba771a 1Ext.define('PMG.ObjectGroup', {
56b0691b 2 extend: 'Ext.grid.GridPanel',
049a531b 3 alias: 'widget.pmgObjectGroup',
56b0691b
DM
4
5 baseurl: undefined,
049a531b 6
56b0691b
DM
7 otype_list: [],
8
049a531b
DM
9 hideGroupInfo: false,
10 showDirection: false, // only important for SMTP Whitelist
56b0691b 11
cc1c5008 12 ogdata: undefined,
e3c8d4fd 13 objectClass: undefined,
cc1c5008 14
84185bf4
DM
15 emptyText: gettext('Please select an object.'),
16
56b0691b 17 setBaseUrl: function(baseurl) {
28eb60c0 18 let me = this;
56b0691b
DM
19
20 me.baseurl = baseurl;
21
84185bf4 22 if (me.baseurl === undefined) {
69bc007c 23 me.store.proxy.setUrl(undefined);
84185bf4 24 me.store.setData([]);
7d4f02a3 25 me.setButtonState(me.store, [], false);
84185bf4 26 } else {
28eb60c0 27 let url = '/api2/json' + me.baseurl + '/objects';
69bc007c 28 me.store.proxy.setUrl(url);
7d4f02a3 29 me.store.load();
84185bf4 30 }
56b0691b
DM
31 },
32
cc1c5008 33 setObjectInfo: function(ogdata) {
28eb60c0 34 let me = this;
56b0691b 35
e3c8d4fd
DC
36 let mode = ogdata?.invert ? 'not' : '';
37 mode += ogdata?.and ? 'all' : 'any';
38
cc1c5008
DM
39 me.ogdata = ogdata;
40
84185bf4 41 if (me.ogdata === undefined) {
84185bf4 42 me.down('#oginfo').update(me.emptyText);
758ddf06 43 me.down('#separator').setHidden(true);
e3c8d4fd
DC
44 me.down('#modeBox').setHidden(true);
45 me.down('#whatWarning').setHidden(true);
84185bf4 46 } else {
10784417 47 let html = '<b style="font-weight: bold;">' + Ext.String.htmlEncode(me.ogdata.name) + '</b>';
84185bf4
DM
48 html += "<br><br>";
49 html += Ext.String.htmlEncode(Ext.String.trim(me.ogdata.info));
50
51 me.down('#oginfo').update(html);
52 me.down('#ogdata').setHidden(false);
758ddf06 53 me.down('#separator').setHidden(false);
e3c8d4fd
DC
54 let modeSelector = me.down('#modeSelector');
55 modeSelector.suspendEvents();
56 me.down('#modeSelector').setValue(mode);
57 modeSelector.resumeEvents();
58 me.down('#modeBox').setHidden(false);
59 me.down('#whatWarning').setHidden(me.objectClass !== 'what' || mode === 'any');
84185bf4 60 }
56b0691b 61 },
049a531b 62
7d4f02a3 63 setButtonState: function(store, records, success) {
28eb60c0 64 let me = this;
7d4f02a3
DC
65 if (!success || !me.baseurl) {
66 me.down('#addMenuButton').setDisabled(true);
67 return;
68 }
69 me.down('#addMenuButton').setDisabled(false);
70 },
71
c87d46fb 72 initComponent: function() {
28eb60c0 73 let me = this;
56b0691b
DM
74
75 me.store = new Ext.data.Store({
76 model: 'pmg-object-list',
69bc007c 77 proxy: {
c87d46fb 78 type: 'proxmox',
69bc007c 79 },
56b0691b 80 sorters: [
049a531b 81 {
c87d46fb 82 property: 'receivertest',
049a531b 83 },
56b0691b 84 {
c87d46fb
TL
85 property: 'otype',
86 direction: 'ASC',
87 },
88 ],
56b0691b
DM
89 });
90
049a531b
DM
91 me.columns = [{
92 header: gettext('Type'),
93 dataIndex: 'otype',
94 renderer: PMG.Utils.format_otype,
c87d46fb 95 width: 200,
049a531b
DM
96 }];
97
98 if (me.showDirection) {
99 me.columns.push({
100 header: gettext('Direction'),
101 dataIndex: 'receivertest',
102 renderer: function(value) {
103 return value ? PMG.Utils.receiverText : PMG.Utils.senderText;
c87d46fb 104 },
049a531b
DM
105 });
106 }
107
108 me.columns.push({
109 header: gettext('Value'),
110 dataIndex: 'descr',
111 renderer: Ext.String.htmlEncode,
c87d46fb 112 flex: 1,
7a3b5e2d 113 });
049a531b 114
28eb60c0 115 let reload = function() {
56b0691b
DM
116 me.store.load();
117 };
118
119 me.selModel = Ext.create('Ext.selection.RowModel', {});
120
28eb60c0 121 let remove_btn = Ext.createWidget('proxmoxStdRemoveButton', {
56b0691b 122 selModel: me.selModel,
b357057e
DM
123 getUrl: function(rec) {
124 return me.baseurl + '/objects/' + rec.data.id;
56b0691b 125 },
b357057e
DM
126 callback: reload,
127 getRecordName: function(rec) {
128 return PMG.Utils.format_otype(rec.data.otype) +
129 ': ' + rec.data.descr;
130 },
c87d46fb 131 waitMsgTarget: me,
56b0691b
DM
132 });
133
28eb60c0 134 let full_subject = function(subject, receivertest) {
049a531b 135 if (me.showDirection) {
28eb60c0 136 let direction = receivertest
c87d46fb 137 ? PMG.Utils.receiverText : PMG.Utils.senderText;
049a531b
DM
138
139 return subject + ' (' + direction + ')';
140 } else {
141 return subject;
142 }
143 };
144
28eb60c0
TL
145 let run_editor = function() {
146 let rec = me.selModel.getSelection()[0];
56b0691b
DM
147 if (!rec) {
148 return;
149 }
150
28eb60c0 151 let editor = PMG.Utils.object_editors[rec.data.otype];
8ddd9c44 152 if (!editor || editor.uneditable) {
56b0691b
DM
153 return;
154 }
155
28eb60c0 156 let config = Ext.apply({ method: 'PUT' }, editor);
049a531b 157 config.subject = full_subject(editor.subject, rec.data.receivertest);
56b0691b
DM
158 config.url = me.baseurl + '/' + editor.subdir + '/' + rec.data.id;
159
28eb60c0 160 let win = Ext.createWidget(config);
56b0691b
DM
161
162 win.load();
163 win.on('destroy', reload);
164 win.show();
165 };
166
28eb60c0 167 let menu_items = [];
56b0691b
DM
168
169 Ext.Array.each(me.otype_list, function(otype) {
28eb60c0 170 let editor = PMG.Utils.object_editors[otype];
56b0691b 171
28eb60c0 172 let config = Ext.apply({ method: 'POST' }, editor);
049a531b 173 config.subject = full_subject(editor.subject, editor.receivertest);
56b0691b
DM
174
175 menu_items.push({
176 text: config.subject,
ea4f2a79 177 iconCls: config.iconCls || 'fa fa-question-circle',
56b0691b 178 handler: function() {
28eb60c0 179 if (me.baseurl === undefined) {
56b0691b
DM
180 return;
181 }
182 config.url = me.baseurl + '/' + editor.subdir;
28eb60c0 183 let win = Ext.create(config);
56b0691b
DM
184 win.on('destroy', reload);
185 win.show();
c87d46fb 186 },
56b0691b
DM
187 });
188 });
189
190 me.dockedItems = [];
049a531b 191
56b0691b
DM
192 me.dockedItems.push({
193 xtype: 'toolbar',
194 dock: 'top',
195 items: [
196 {
197 text: gettext('Add'),
198 disabled: true,
199 itemId: 'addMenuButton',
793ac2e4 200 menu: {
c87d46fb
TL
201 items: menu_items,
202 },
56b0691b 203 },
ce33f608 204 '-',
56b0691b
DM
205 {
206 xtype: 'proxmoxButton',
207 text: gettext('Edit'),
208 disabled: true,
209 selModel: me.selModel,
8ddd9c44 210 enableFn: function(rec) {
28eb60c0 211 let editor = PMG.Utils.object_editors[rec.data.otype];
c87d46fb 212 return editor && !editor.uneditable;
8ddd9c44 213 },
c87d46fb 214 handler: run_editor,
56b0691b 215 },
c87d46fb 216 remove_btn,
4703989a
DC
217 '->',
218 {
219 xtype: 'pmgFilterField',
220 filteredFields: [
221 {
222 name: 'otype',
223 renderer: (otype) => PMG.Utils.object_editors[otype].subject,
224 },
225 'descr',
226 ],
227 },
c87d46fb 228 ],
56b0691b 229 });
049a531b 230
56b0691b
DM
231 me.dockedItems.push({
232 dock: 'top',
233 border: 1,
758ddf06
DC
234 layout: {
235 type: 'hbox',
236 align: 'stretch',
237 },
c87d46fb 238 hidden: !!me.hideGroupInfo,
56b0691b 239 itemId: 'ogdata',
758ddf06 240 xtype: 'toolbar',
56b0691b 241 items: [
e3c8d4fd
DC
242 {
243 xtype: 'container',
244 itemId: 'modeBox',
245 hidden: true,
246 width: 220,
247 padding: 10,
248 layout: {
249 type: 'vbox',
250 align: 'stretch',
251 },
252 items: [
253 {
254 xtype: 'box',
10784417 255 html: `<b style="font-weight: bold;">${gettext("Match if")}</b>`,
e3c8d4fd
DC
256 },
257 {
258 xtype: 'pmgMatchModeSelector',
259 itemId: 'modeSelector',
260 padding: '10 0 0 0',
261 listeners: {
262 change: function(_field, value) {
263 let invert = value.startsWith('not') ? 1 : 0;
264 let and = value.endsWith('all') ? 1 : 0;
265
266 Proxmox.Utils.API2Request({
267 url: `${me.baseurl}/config`,
268 method: 'PUT',
269 params: {
270 and,
271 invert,
272 },
1f839721
DC
273 success: () => {
274 me.fireEvent('modeUpdate', me, !!and, !!invert);
275 me.down('#whatWarning')
276 .setHidden(me.objectClass !== 'what' || value === 'any');
277 },
e3c8d4fd
DC
278 });
279 },
280 },
281 },
282 ],
283 },
758ddf06
DC
284 {
285 xtype: 'tbseparator',
286 itemId: 'separator',
287 hidden: true,
288 },
56b0691b
DM
289 {
290 xtype: 'component',
e3c8d4fd 291 flex: 1,
56b0691b 292 itemId: 'oginfo',
de3a7ef5 293 style: { 'white-space': 'pre' },
56b0691b 294 padding: 10,
84185bf4 295 html: me.emptyText,
cc1c5008
DM
296 listeners: {
297 dblclick: {
298 fn: function(e, t) {
299 if (me.ogdata === undefined) { return; }
300 me.fireEvent('dblclickOGInfo', me, e, t, me.ogdata);
301 },
302 element: 'el',
c87d46fb
TL
303 scope: this,
304 },
305 },
306 },
307 ],
56b0691b 308 });
049a531b 309
e3c8d4fd
DC
310 me.dockedItems.push({
311 dock: 'top',
312 border: 1,
313 hidden: true,
314 itemId: 'whatWarning',
315 bodyPadding: 5,
316 items: {
317 xtype: 'displayfield',
318 margin: 0,
319 value: gettext("Caution: 'What Objects' match each mail part separately, so be careful with any option besides 'Any matches'."),
320 userCls: 'pmx-hint',
321 },
322 });
323
69bc007c
DM
324 Proxmox.Utils.monStoreErrors(me, me.store, true);
325
56b0691b 326 Ext.apply(me, {
01e0e5e5 327 run_editor: run_editor,
56b0691b
DM
328 listeners: {
329 itemdblclick: run_editor,
c87d46fb
TL
330 activate: reload,
331 },
56b0691b
DM
332 });
333
334 me.callParent();
049a531b 335
7d4f02a3
DC
336 me.mon(me.store, 'load', me.setButtonState, me);
337
049a531b
DM
338 if (me.baseurl) {
339 me.setBaseUrl(me.baseurl); // configure store, load()
340 }
c87d46fb 341 },
56b0691b 342});