]>
Commit | Line | Data |
---|---|---|
017a6376 | 1 | /** Renders a list of key values objects |
52d3f3b0 TL |
2 | |
3 | Mandatory Config Parameters: | |
06694509 | 4 | |
017a6376 | 5 | rows: an object container where each property is a key-value object we want to render |
06694509 | 6 | |
52d3f3b0 TL |
7 | rows: { |
8 | keyboard: { | |
9 | header: gettext('Keyboard Layout'), | |
10 | editor: 'Your.KeyboardEdit', | |
11 | required: true | |
12 | }, | |
13 | // ... | |
14 | }, | |
15 | ||
16 | Convenience Helper: | |
17 | ||
18 | As alternative you can use the common add-row helper like `add_text_row`, but you need to | |
19 | call it in an overridden initComponent before `me.callParent(arguments)` gets executed. | |
20 | ||
21 | For a declarative approach you can use the `gridRows` configuration to pass an array of | |
22 | objects with each having at least a `xtype` to match `add_XTYPE_row` and a field-name | |
23 | property, for example: | |
06694509 | 24 | |
52d3f3b0 TL |
25 | gridRows: [ |
26 | { | |
27 | xtype: 'text', | |
28 | name: 'http-proxy', | |
29 | text: gettext('HTTP proxy'), | |
30 | defaultValue: Proxmox.Utils.noneText, | |
31 | vtype: 'HttpProxy', | |
32 | deleteEmpty: true, | |
33 | }, | |
34 | ], | |
35 | ||
36 | Optional Configs: | |
37 | ||
38 | disabled:: setting this parameter to true will disable selection and focus on | |
39 | the proxmoxObjectGrid as well as greying out input elements. Useful for a | |
40 | readonly tabular display | |
41 | ||
42 | */ | |
06694509 DM |
43 | Ext.define('Proxmox.grid.ObjectGrid', { |
44 | extend: 'Ext.grid.GridPanel', | |
45 | alias: ['widget.proxmoxObjectGrid'], | |
bc9ae602 TL |
46 | |
47 | // can be used as declarative replacement over manually calling the add_XYZ_row helpers, | |
48 | // see top-level doc-comment above for details/example | |
49 | gridRows: [], | |
50 | ||
06694509 DM |
51 | disabled: false, |
52 | hideHeaders: true, | |
53 | ||
4297e795 DM |
54 | monStoreErrors: false, |
55 | ||
8f7370ee | 56 | add_combobox_row: function(name, text, opts) { |
05a977a2 | 57 | let me = this; |
8f7370ee DM |
58 | |
59 | opts = opts || {}; | |
60 | me.rows = me.rows || {}; | |
61 | ||
62 | me.rows[name] = { | |
63 | required: true, | |
64 | defaultValue: opts.defaultValue, | |
65 | header: text, | |
66 | renderer: opts.renderer, | |
67 | editor: { | |
68 | xtype: 'proxmoxWindowEdit', | |
69 | subject: text, | |
7d16f8b3 | 70 | onlineHelp: opts.onlineHelp, |
37d8d602 | 71 | fieldDefaults: { |
01031528 | 72 | labelWidth: opts.labelWidth || 100, |
37d8d602 | 73 | }, |
8f7370ee DM |
74 | items: { |
75 | xtype: 'proxmoxKVComboBox', | |
76 | name: name, | |
77 | comboItems: opts.comboItems, | |
78 | value: opts.defaultValue, | |
01031528 | 79 | deleteEmpty: !!opts.deleteEmpty, |
8f7370ee DM |
80 | emptyText: opts.defaultValue, |
81 | labelWidth: Proxmox.Utils.compute_min_label_width( | |
82 | text, opts.labelWidth), | |
01031528 TL |
83 | fieldLabel: text, |
84 | }, | |
85 | }, | |
8f7370ee DM |
86 | }; |
87 | }, | |
88 | ||
5dea30d0 | 89 | add_text_row: function(name, text, opts) { |
05a977a2 | 90 | let me = this; |
5dea30d0 DM |
91 | |
92 | opts = opts || {}; | |
c2ea0137 | 93 | me.rows = me.rows || {}; |
5dea30d0 DM |
94 | |
95 | me.rows[name] = { | |
96 | required: true, | |
97 | defaultValue: opts.defaultValue, | |
98 | header: text, | |
99 | renderer: opts.renderer, | |
100 | editor: { | |
101 | xtype: 'proxmoxWindowEdit', | |
102 | subject: text, | |
7d16f8b3 | 103 | onlineHelp: opts.onlineHelp, |
37d8d602 | 104 | fieldDefaults: { |
01031528 | 105 | labelWidth: opts.labelWidth || 100, |
37d8d602 | 106 | }, |
5dea30d0 DM |
107 | items: { |
108 | xtype: 'proxmoxtextfield', | |
109 | name: name, | |
01031528 | 110 | deleteEmpty: !!opts.deleteEmpty, |
5dea30d0 | 111 | emptyText: opts.defaultValue, |
d00e8b94 | 112 | labelWidth: Proxmox.Utils.compute_min_label_width(text, opts.labelWidth), |
85d85d15 | 113 | vtype: opts.vtype, |
01031528 TL |
114 | fieldLabel: text, |
115 | }, | |
116 | }, | |
5dea30d0 DM |
117 | }; |
118 | }, | |
119 | ||
0e49da6d | 120 | add_boolean_row: function(name, text, opts) { |
05a977a2 | 121 | let me = this; |
0e49da6d DM |
122 | |
123 | opts = opts || {}; | |
c2ea0137 | 124 | me.rows = me.rows || {}; |
0e49da6d | 125 | |
0e49da6d DM |
126 | me.rows[name] = { |
127 | required: true, | |
128 | defaultValue: opts.defaultValue || 0, | |
129 | header: text, | |
130 | renderer: opts.renderer || Proxmox.Utils.format_boolean, | |
131 | editor: { | |
132 | xtype: 'proxmoxWindowEdit', | |
133 | subject: text, | |
7d16f8b3 | 134 | onlineHelp: opts.onlineHelp, |
37d8d602 | 135 | fieldDefaults: { |
01031528 | 136 | labelWidth: opts.labelWidth || 100, |
37d8d602 | 137 | }, |
0e49da6d DM |
138 | items: { |
139 | xtype: 'proxmoxcheckbox', | |
140 | name: name, | |
141 | uncheckedValue: 0, | |
01031528 TL |
142 | defaultValue: opts.defaultValue || 0, |
143 | checked: !!opts.defaultValue, | |
144 | deleteDefaultValue: !!opts.deleteDefaultValue, | |
d00e8b94 | 145 | labelWidth: Proxmox.Utils.compute_min_label_width(text, opts.labelWidth), |
01031528 TL |
146 | fieldLabel: text, |
147 | }, | |
148 | }, | |
0e49da6d DM |
149 | }; |
150 | }, | |
151 | ||
152 | add_integer_row: function(name, text, opts) { | |
05a977a2 | 153 | let me = this; |
0e49da6d | 154 | |
01031528 | 155 | opts = opts || {}; |
c2ea0137 | 156 | me.rows = me.rows || {}; |
0e49da6d | 157 | |
0e49da6d DM |
158 | me.rows[name] = { |
159 | required: true, | |
160 | defaultValue: opts.defaultValue, | |
161 | header: text, | |
0d5c5e14 | 162 | renderer: opts.renderer, |
0e49da6d DM |
163 | editor: { |
164 | xtype: 'proxmoxWindowEdit', | |
165 | subject: text, | |
7d16f8b3 | 166 | onlineHelp: opts.onlineHelp, |
37d8d602 | 167 | fieldDefaults: { |
01031528 | 168 | labelWidth: opts.labelWidth || 100, |
37d8d602 | 169 | }, |
0e49da6d DM |
170 | items: { |
171 | xtype: 'proxmoxintegerfield', | |
172 | name: name, | |
173 | minValue: opts.minValue, | |
174 | maxValue: opts.maxValue, | |
175 | emptyText: gettext('Default'), | |
01031528 | 176 | deleteEmpty: !!opts.deleteEmpty, |
0e49da6d | 177 | value: opts.defaultValue, |
d00e8b94 | 178 | labelWidth: Proxmox.Utils.compute_min_label_width(text, opts.labelWidth), |
01031528 TL |
179 | fieldLabel: text, |
180 | }, | |
181 | }, | |
0e49da6d DM |
182 | }; |
183 | }, | |
184 | ||
7ec6cd9e DM |
185 | editorConfig: {}, // default config passed to editor |
186 | ||
187 | run_editor: function() { | |
05a977a2 | 188 | let me = this; |
7ec6cd9e | 189 | |
05a977a2 TL |
190 | let sm = me.getSelectionModel(); |
191 | let rec = sm.getSelection()[0]; | |
7ec6cd9e DM |
192 | if (!rec) { |
193 | return; | |
194 | } | |
195 | ||
05a977a2 TL |
196 | let rows = me.rows; |
197 | let rowdef = rows[rec.data.key]; | |
7ec6cd9e DM |
198 | if (!rowdef.editor) { |
199 | return; | |
200 | } | |
201 | ||
05a977a2 TL |
202 | let win; |
203 | let config; | |
7ec6cd9e DM |
204 | if (Ext.isString(rowdef.editor)) { |
205 | config = Ext.apply({ | |
206 | confid: rec.data.key, | |
01031528 | 207 | }, me.editorConfig); |
7ec6cd9e DM |
208 | win = Ext.create(rowdef.editor, config); |
209 | } else { | |
210 | config = Ext.apply({ | |
211 | confid: rec.data.key, | |
01031528 | 212 | }, me.editorConfig); |
7ec6cd9e DM |
213 | Ext.apply(config, rowdef.editor); |
214 | win = Ext.createWidget(rowdef.editor.xtype, config); | |
215 | win.load(); | |
216 | } | |
217 | ||
218 | win.show(); | |
219 | win.on('destroy', me.reload, me); | |
220 | }, | |
221 | ||
222 | reload: function() { | |
05a977a2 | 223 | let me = this; |
7ec6cd9e DM |
224 | me.rstore.load(); |
225 | }, | |
226 | ||
06694509 | 227 | getObjectValue: function(key, defaultValue) { |
05a977a2 TL |
228 | let me = this; |
229 | let rec = me.store.getById(key); | |
06694509 DM |
230 | if (rec) { |
231 | return rec.data.value; | |
232 | } | |
233 | return defaultValue; | |
234 | }, | |
235 | ||
236 | renderKey: function(key, metaData, record, rowIndex, colIndex, store) { | |
05a977a2 TL |
237 | let me = this; |
238 | let rows = me.rows; | |
239 | let rowdef = rows && rows[key] ? rows[key] : {}; | |
06694509 DM |
240 | return rowdef.header || key; |
241 | }, | |
242 | ||
243 | renderValue: function(value, metaData, record, rowIndex, colIndex, store) { | |
05a977a2 TL |
244 | let me = this; |
245 | let rows = me.rows; | |
246 | let key = record.data.key; | |
247 | let rowdef = rows && rows[key] ? rows[key] : {}; | |
06694509 | 248 | |
05a977a2 | 249 | let renderer = rowdef.renderer; |
06694509 DM |
250 | if (renderer) { |
251 | return renderer(value, metaData, record, rowIndex, colIndex, store); | |
252 | } | |
253 | ||
254 | return value; | |
255 | }, | |
256 | ||
9307eda4 | 257 | listeners: { |
ce9a0f27 | 258 | itemkeydown: function(view, record, item, index, e) { |
9307eda4 | 259 | if (e.getKey() === e.ENTER) { |
ce9a0f27 DC |
260 | this.pressedIndex = index; |
261 | } | |
262 | }, | |
263 | itemkeyup: function(view, record, item, index, e) { | |
05a977a2 | 264 | if (e.getKey() === e.ENTER && index === this.pressedIndex) { |
9307eda4 DC |
265 | this.run_editor(); |
266 | } | |
ce9a0f27 DC |
267 | |
268 | this.pressedIndex = undefined; | |
01031528 | 269 | }, |
9307eda4 DC |
270 | }, |
271 | ||
01031528 | 272 | initComponent: function() { |
05a977a2 | 273 | let me = this; |
06694509 | 274 | |
bc9ae602 TL |
275 | for (const rowdef of me.gridRows || []) { |
276 | let addFn = me[`add_${rowdef.xtype}_row`]; | |
277 | if (typeof addFn !== 'function') { | |
278 | throw `unknown object-grid row xtype '${rowdef.xtype}'`; | |
279 | } else if (typeof rowdef.name !== 'string') { | |
280 | throw `object-grid row need a valid name string-property!`; | |
281 | } else { | |
282 | addFn.call(me, rowdef.name, rowdef.text || rowdef.name, rowdef); | |
283 | } | |
284 | } | |
285 | ||
05a977a2 | 286 | let rows = me.rows; |
06694509 DM |
287 | |
288 | if (!me.rstore) { | |
289 | if (!me.url) { | |
290 | throw "no url specified"; | |
291 | } | |
292 | ||
293 | me.rstore = Ext.create('Proxmox.data.ObjectStore', { | |
294 | url: me.url, | |
295 | interval: me.interval, | |
296 | extraParams: me.extraParams, | |
01031528 | 297 | rows: me.rows, |
06694509 DM |
298 | }); |
299 | } | |
300 | ||
4f1b9b8c TL |
301 | let rstore = me.rstore; |
302 | let store = Ext.create('Proxmox.data.DiffStore', { | |
303 | rstore: rstore, | |
06694509 | 304 | sorters: [], |
01031528 | 305 | filters: [], |
06694509 DM |
306 | }); |
307 | ||
308 | if (rows) { | |
f0f898d2 | 309 | for (const [key, rowdef] of Object.entries(rows)) { |
06694509 DM |
310 | if (Ext.isDefined(rowdef.defaultValue)) { |
311 | store.add({ key: key, value: rowdef.defaultValue }); | |
312 | } else if (rowdef.required) { | |
313 | store.add({ key: key, value: undefined }); | |
314 | } | |
f0f898d2 | 315 | } |
06694509 DM |
316 | } |
317 | ||
318 | if (me.sorterFn) { | |
319 | store.sorters.add(Ext.create('Ext.util.Sorter', { | |
01031528 | 320 | sorterFn: me.sorterFn, |
06694509 DM |
321 | })); |
322 | } | |
323 | ||
324 | store.filters.add(Ext.create('Ext.util.Filter', { | |
325 | filterFn: function(item) { | |
326 | if (rows) { | |
05a977a2 | 327 | let rowdef = rows[item.data.key]; |
01031528 | 328 | if (!rowdef || rowdef.visible === false) { |
06694509 DM |
329 | return false; |
330 | } | |
331 | } | |
332 | return true; | |
01031528 | 333 | }, |
06694509 DM |
334 | })); |
335 | ||
336 | Proxmox.Utils.monStoreErrors(me, rstore); | |
337 | ||
338 | Ext.applyIf(me, { | |
339 | store: store, | |
340 | stateful: false, | |
341 | columns: [ | |
342 | { | |
343 | header: gettext('Name'), | |
344 | width: me.cwidth1 || 200, | |
345 | dataIndex: 'key', | |
01031528 | 346 | renderer: me.renderKey, |
06694509 DM |
347 | }, |
348 | { | |
349 | flex: 1, | |
350 | header: gettext('Value'), | |
351 | dataIndex: 'value', | |
01031528 TL |
352 | renderer: me.renderValue, |
353 | }, | |
354 | ], | |
06694509 DM |
355 | }); |
356 | ||
357 | me.callParent(); | |
4297e795 DM |
358 | |
359 | if (me.monStoreErrors) { | |
360 | Proxmox.Utils.monStoreErrors(me, me.store); | |
361 | } | |
01031528 | 362 | }, |
06694509 | 363 | }); |