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