]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/panel/ConfigPanel.js
drop jslint lines
[pve-manager.git] / www / manager6 / panel / ConfigPanel.js
1 /*
2 * Base class for all the multitab config panels
3 *
4 * How to use this:
5 *
6 * You create a subclass of this, and then define your wanted tabs
7 * as items like this:
8 *
9 * items: [{
10 * title: "myTitle",
11 * xytpe: "somextype",
12 * iconCls: 'fa fa-icon',
13 * groups: ['somegroup'],
14 * expandedOnInit: true,
15 * itemId: 'someId'
16 * }]
17 *
18 * this has to be in the declarative syntax, else we
19 * cannot save them for later
20 * (so no Ext.create or Ext.apply of an item in the subclass)
21 *
22 * the groups array expects the itemids of the items
23 * which are the parents, which have to come before they
24 * are used
25 *
26 * if you want following the tree:
27 *
28 * Option1
29 * Option2
30 * -> SubOption1
31 * -> SubSubOption1
32 *
33 * the suboption1 group array has to look like this:
34 * groups: ['itemid-of-option2']
35 *
36 * and of subsuboption1:
37 * groups: ['itemid-of-option2', 'itemid-of-suboption1']
38 *
39 * setting the expandedOnInit determines if the item/group is expanded
40 * initially (false by default)
41 */
42 Ext.define('PVE.panel.Config', {
43 extend: 'Ext.panel.Panel',
44 alias: 'widget.pvePanelConfig',
45
46 showSearch: true, // add a resource grid with a search button as first tab
47 viewFilter: undefined, // a filter to pass to that resource grid
48
49 tbarSpacing: true, // if true, adds a spacer after the title in tbar
50
51 dockedItems: [{
52 // this is needed for the overflow handler
53 xtype: 'toolbar',
54 overflowHandler: 'scroller',
55 dock: 'left',
56 style: {
57 backgroundColor: '#f5f5f5',
58 padding: 0,
59 margin: 0
60 },
61 items: {
62 xtype: 'treelist',
63 itemId: 'menu',
64 ui: 'nav',
65 expanderOnly: true,
66 expanderFirst: false,
67 animation: false,
68 singleExpand: false,
69 listeners: {
70 selectionchange: function(treeList, selection) {
71 var me = this.up('panel');
72 me.suspendLayout = true;
73 me.activateCard(selection.data.id);
74 me.suspendLayout = false;
75 me.updateLayout();
76 },
77 itemclick: function(treelist, info) {
78 var olditem = treelist.getSelection();
79 var newitem = info.node;
80
81 // when clicking on the expand arrow,
82 // we don't select items, but still want
83 // the original behaviour
84 if (info.select === false) {
85 return;
86 }
87
88 // if you click on a different item which is open,
89 // leave it open
90 // else toggle the clicked item
91 if (olditem.data.id !== newitem.data.id &&
92 newitem.data.expanded === true) {
93 info.toggle = false;
94 } else {
95 info.toggle = true;
96 }
97 }
98 }
99 }
100 },
101 {
102 xtype: 'toolbar',
103 itemId: 'toolbar',
104 dock: 'top',
105 height: 36,
106 overflowHandler: 'scroller'
107 }],
108
109 firstItem: '',
110 layout: 'card',
111 border: 0,
112
113 // used for automated test
114 selectById: function(cardid) {
115 var me = this;
116
117 var root = me.store.getRoot();
118 var selection = root.findChild('id', cardid, true);
119
120 if (selection) {
121 selection.expand();
122 var menu = me.down('#menu');
123 menu.setSelection(selection);
124 return cardid;
125 }
126 },
127
128 activateCard: function(cardid) {
129 var me = this;
130 if (me.savedItems[cardid]) {
131 var curcard = me.getLayout().getActiveItem();
132 var newcard = me.add(me.savedItems[cardid]);
133 me.helpButton.setOnlineHelp(newcard.onlineHelp || me.onlineHelp);
134 if (curcard) {
135 me.setActiveItem(cardid);
136 me.remove(curcard, true);
137
138 // trigger state change
139
140 var ncard = cardid;
141 // Note: '' is alias for first tab.
142 // First tab can be 'search' or something else
143 if (cardid === me.firstItem) {
144 ncard = '';
145 }
146 if (me.hstateid) {
147 me.sp.set(me.hstateid, { value: ncard });
148 }
149 }
150 }
151 },
152
153 initComponent: function() {
154 var me = this;
155
156 var stateid = me.hstateid;
157
158 me.sp = Ext.state.Manager.getProvider();
159
160 var activeTab; // leaving this undefined means items[0] will be the default tab
161
162 if (stateid) {
163 var state = me.sp.get(stateid);
164 if (state && state.value) {
165 // if this tab does not exist, it chooses the first
166 activeTab = state.value;
167 }
168 }
169
170 // get title
171 var title = me.title || me.pveSelNode.data.text;
172 me.title = undefined;
173
174 // create toolbar
175 var tbar = me.tbar || [];
176 me.tbar = undefined;
177
178 if (!me.onlineHelp) {
179 switch(me.pveSelNode.data.id) {
180 case 'type/storage':me.onlineHelp = 'chapter-pvesm.html'; break;
181 case 'type/qemu':me.onlineHelp = 'chapter-qm.html'; break;
182 case 'type/lxc':me.onlineHelp = 'chapter-pct.html'; break;
183 case 'type/pool':me.onlineHelp = 'chapter-pveum.html#_pools'; break;
184 case 'type/node':me.onlineHelp = 'chapter-sysadmin.html'; break;
185 }
186 }
187
188 if (me.tbarSpacing) {
189 tbar.unshift('->');
190 }
191 tbar.unshift({
192 xtype: 'tbtext',
193 text: title,
194 baseCls: 'x-panel-header-text'
195 });
196
197 me.helpButton = Ext.create('Proxmox.button.Help', {
198 hidden: false,
199 listenToGlobalEvent: false,
200 onlineHelp: me.onlineHelp || undefined
201 });
202
203 tbar.push(me.helpButton);
204
205 me.dockedItems[1].items = tbar;
206
207 // include search tab
208 me.items = me.items || [];
209 if (me.showSearch) {
210 me.items.unshift({
211 itemId: 'search',
212 title: gettext('Search'),
213 iconCls: 'fa fa-search',
214 xtype: 'pveResourceGrid',
215 pveSelNode: me.pveSelNode
216 });
217 }
218
219 me.savedItems = {};
220 if (me.items[0]) {
221 me.firstItem = me.items[0].itemId;
222 }
223
224 me.store = Ext.create('Ext.data.TreeStore', {
225 root: {
226 expanded: true
227 }
228 });
229 var root = me.store.getRoot();
230 me.items.forEach(function(item){
231 var treeitem = Ext.create('Ext.data.TreeModel',{
232 id: item.itemId,
233 text: item.title,
234 iconCls: item.iconCls,
235 leaf: true,
236 expanded: item.expandedOnInit
237 });
238 item.header = false;
239 if (me.savedItems[item.itemId] !== undefined) {
240 throw "itemId already exists, please use another";
241 }
242 me.savedItems[item.itemId] = item;
243
244 var group;
245 var curnode = root;
246
247 // get/create the group items
248 while (Ext.isArray(item.groups) && item.groups.length > 0) {
249 group = item.groups.shift();
250
251 var child = curnode.findChild('id', group);
252 if (child === null) {
253 // did not find the group item
254 // so add it where we are
255 break;
256 }
257 curnode = child;
258 }
259
260 // insert the item
261
262 // lets see if it already exists
263 var node = curnode.findChild('id', item.itemId);
264
265 if (node === null) {
266 curnode.appendChild(treeitem);
267 } else {
268 // should not happen!
269 throw "id already exists";
270 }
271 });
272
273 delete me.items;
274 me.defaults = me.defaults || {};
275 Ext.apply(me.defaults, {
276 pveSelNode: me.pveSelNode,
277 viewFilter: me.viewFilter,
278 workspace: me.workspace,
279 border: 0
280 });
281
282 me.callParent();
283
284 var menu = me.down('#menu');
285 var selection = root.findChild('id', activeTab, true) || root.firstChild;
286 var node = selection;
287 while (node !== root) {
288 node.expand();
289 node = node.parentNode;
290 }
291 menu.setStore(me.store);
292 menu.setSelection(selection);
293
294 // on a state change,
295 // select the new item
296 var statechange = function(sp, key, state) {
297 // it the state change is for this panel
298 if (stateid && (key === stateid) && state) {
299 // get active item
300 var acard = me.getLayout().getActiveItem().itemId;
301 // get the itemid of the new value
302 var ncard = state.value || me.firstItem;
303 if (ncard && (acard != ncard)) {
304 // select the chosen item
305 menu.setSelection(root.findChild('id', ncard, true) || root.firstChild);
306 }
307 }
308 };
309
310 if (stateid) {
311 me.mon(me.sp, 'statechange', statechange);
312 }
313 }
314 });