]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/grid/ObjectGrid.js
cleanly separate sources from package build, move to own folder
[proxmox-widget-toolkit.git] / src / grid / ObjectGrid.js
1 /* Renders a list of key values objets
2
3 mandatory config parameters:
4 rows: an object container where each propery is a key-value object we want to render
5 let rows = {
6 keyboard: {
7 header: gettext('Keyboard Layout'),
8 editor: 'Your.KeyboardEdit',
9 required: true
10 },
11
12 optional:
13 disabled: setting this parameter to true will disable selection and focus on the
14 proxmoxObjectGrid as well as greying out input elements.
15 Useful for a readonly tabular display
16
17 */
18
19 Ext.define('Proxmox.grid.ObjectGrid', {
20 extend: 'Ext.grid.GridPanel',
21 alias: ['widget.proxmoxObjectGrid'],
22 disabled: false,
23 hideHeaders: true,
24
25 monStoreErrors: false,
26
27 add_combobox_row: function(name, text, opts) {
28 let me = this;
29
30 opts = opts || {};
31 me.rows = me.rows || {};
32
33 me.rows[name] = {
34 required: true,
35 defaultValue: opts.defaultValue,
36 header: text,
37 renderer: opts.renderer,
38 editor: {
39 xtype: 'proxmoxWindowEdit',
40 subject: text,
41 onlineHelp: opts.onlineHelp,
42 fieldDefaults: {
43 labelWidth: opts.labelWidth || 100,
44 },
45 items: {
46 xtype: 'proxmoxKVComboBox',
47 name: name,
48 comboItems: opts.comboItems,
49 value: opts.defaultValue,
50 deleteEmpty: !!opts.deleteEmpty,
51 emptyText: opts.defaultValue,
52 labelWidth: Proxmox.Utils.compute_min_label_width(
53 text, opts.labelWidth),
54 fieldLabel: text,
55 },
56 },
57 };
58 },
59
60 add_text_row: function(name, text, opts) {
61 let me = this;
62
63 opts = opts || {};
64 me.rows = me.rows || {};
65
66 me.rows[name] = {
67 required: true,
68 defaultValue: opts.defaultValue,
69 header: text,
70 renderer: opts.renderer,
71 editor: {
72 xtype: 'proxmoxWindowEdit',
73 subject: text,
74 onlineHelp: opts.onlineHelp,
75 fieldDefaults: {
76 labelWidth: opts.labelWidth || 100,
77 },
78 items: {
79 xtype: 'proxmoxtextfield',
80 name: name,
81 deleteEmpty: !!opts.deleteEmpty,
82 emptyText: opts.defaultValue,
83 labelWidth: Proxmox.Utils.compute_min_label_width(
84 text, opts.labelWidth),
85 vtype: opts.vtype,
86 fieldLabel: text,
87 },
88 },
89 };
90 },
91
92 add_boolean_row: function(name, text, opts) {
93 let me = this;
94
95 opts = opts || {};
96 me.rows = me.rows || {};
97
98 me.rows[name] = {
99 required: true,
100 defaultValue: opts.defaultValue || 0,
101 header: text,
102 renderer: opts.renderer || Proxmox.Utils.format_boolean,
103 editor: {
104 xtype: 'proxmoxWindowEdit',
105 subject: text,
106 onlineHelp: opts.onlineHelp,
107 fieldDefaults: {
108 labelWidth: opts.labelWidth || 100,
109 },
110 items: {
111 xtype: 'proxmoxcheckbox',
112 name: name,
113 uncheckedValue: 0,
114 defaultValue: opts.defaultValue || 0,
115 checked: !!opts.defaultValue,
116 deleteDefaultValue: !!opts.deleteDefaultValue,
117 labelWidth: Proxmox.Utils.compute_min_label_width(
118 text, opts.labelWidth),
119 fieldLabel: text,
120 },
121 },
122 };
123 },
124
125 add_integer_row: function(name, text, opts) {
126 let me = this;
127
128 opts = opts || {};
129 me.rows = me.rows || {};
130
131 me.rows[name] = {
132 required: true,
133 defaultValue: opts.defaultValue,
134 header: text,
135 renderer: opts.renderer,
136 editor: {
137 xtype: 'proxmoxWindowEdit',
138 subject: text,
139 onlineHelp: opts.onlineHelp,
140 fieldDefaults: {
141 labelWidth: opts.labelWidth || 100,
142 },
143 items: {
144 xtype: 'proxmoxintegerfield',
145 name: name,
146 minValue: opts.minValue,
147 maxValue: opts.maxValue,
148 emptyText: gettext('Default'),
149 deleteEmpty: !!opts.deleteEmpty,
150 value: opts.defaultValue,
151 labelWidth: Proxmox.Utils.compute_min_label_width(
152 text, opts.labelWidth),
153 fieldLabel: text,
154 },
155 },
156 };
157 },
158
159 editorConfig: {}, // default config passed to editor
160
161 run_editor: function() {
162 let me = this;
163
164 let sm = me.getSelectionModel();
165 let rec = sm.getSelection()[0];
166 if (!rec) {
167 return;
168 }
169
170 let rows = me.rows;
171 let rowdef = rows[rec.data.key];
172 if (!rowdef.editor) {
173 return;
174 }
175
176 let win;
177 let config;
178 if (Ext.isString(rowdef.editor)) {
179 config = Ext.apply({
180 confid: rec.data.key,
181 }, me.editorConfig);
182 win = Ext.create(rowdef.editor, config);
183 } else {
184 config = Ext.apply({
185 confid: rec.data.key,
186 }, me.editorConfig);
187 Ext.apply(config, rowdef.editor);
188 win = Ext.createWidget(rowdef.editor.xtype, config);
189 win.load();
190 }
191
192 win.show();
193 win.on('destroy', me.reload, me);
194 },
195
196 reload: function() {
197 let me = this;
198 me.rstore.load();
199 },
200
201 getObjectValue: function(key, defaultValue) {
202 let me = this;
203 let rec = me.store.getById(key);
204 if (rec) {
205 return rec.data.value;
206 }
207 return defaultValue;
208 },
209
210 renderKey: function(key, metaData, record, rowIndex, colIndex, store) {
211 let me = this;
212 let rows = me.rows;
213 let rowdef = rows && rows[key] ? rows[key] : {};
214 return rowdef.header || key;
215 },
216
217 renderValue: function(value, metaData, record, rowIndex, colIndex, store) {
218 let me = this;
219 let rows = me.rows;
220 let key = record.data.key;
221 let rowdef = rows && rows[key] ? rows[key] : {};
222
223 let renderer = rowdef.renderer;
224 if (renderer) {
225 return renderer(value, metaData, record, rowIndex, colIndex, store);
226 }
227
228 return value;
229 },
230
231 listeners: {
232 itemkeydown: function(view, record, item, index, e) {
233 if (e.getKey() === e.ENTER) {
234 this.pressedIndex = index;
235 }
236 },
237 itemkeyup: function(view, record, item, index, e) {
238 if (e.getKey() === e.ENTER && index === this.pressedIndex) {
239 this.run_editor();
240 }
241
242 this.pressedIndex = undefined;
243 },
244 },
245
246 initComponent: function() {
247 let me = this;
248
249 let rows = me.rows;
250
251 if (!me.rstore) {
252 if (!me.url) {
253 throw "no url specified";
254 }
255
256 me.rstore = Ext.create('Proxmox.data.ObjectStore', {
257 url: me.url,
258 interval: me.interval,
259 extraParams: me.extraParams,
260 rows: me.rows,
261 });
262 }
263
264 let rstore = me.rstore;
265 let store = Ext.create('Proxmox.data.DiffStore', {
266 rstore: rstore,
267 sorters: [],
268 filters: [],
269 });
270
271 if (rows) {
272 Ext.Object.each(rows, function(key, rowdef) {
273 if (Ext.isDefined(rowdef.defaultValue)) {
274 store.add({ key: key, value: rowdef.defaultValue });
275 } else if (rowdef.required) {
276 store.add({ key: key, value: undefined });
277 }
278 });
279 }
280
281 if (me.sorterFn) {
282 store.sorters.add(Ext.create('Ext.util.Sorter', {
283 sorterFn: me.sorterFn,
284 }));
285 }
286
287 store.filters.add(Ext.create('Ext.util.Filter', {
288 filterFn: function(item) {
289 if (rows) {
290 let rowdef = rows[item.data.key];
291 if (!rowdef || rowdef.visible === false) {
292 return false;
293 }
294 }
295 return true;
296 },
297 }));
298
299 Proxmox.Utils.monStoreErrors(me, rstore);
300
301 Ext.applyIf(me, {
302 store: store,
303 stateful: false,
304 columns: [
305 {
306 header: gettext('Name'),
307 width: me.cwidth1 || 200,
308 dataIndex: 'key',
309 renderer: me.renderKey,
310 },
311 {
312 flex: 1,
313 header: gettext('Value'),
314 dataIndex: 'value',
315 renderer: me.renderValue,
316 },
317 ],
318 });
319
320 me.callParent();
321
322 if (me.monStoreErrors) {
323 Proxmox.Utils.monStoreErrors(me, me.store);
324 }
325 },
326 });