]> git.proxmox.com Git - pmg-gui.git/blob - js/ConfigPanel.js
add minigraph component
[pmg-gui.git] / js / 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('PMG.panel.Config', {
43 extend: 'Ext.panel.Panel',
44 alias: 'widget.pmgPanelConfig',
45
46 viewFilter: undefined, // a filter to pass to that ressource grid
47
48 dockedItems: [{
49 // this is needed for the overflow handler
50 xtype: 'toolbar',
51 overflowHandler: 'scroller',
52 dock: 'left',
53 style: {
54 backgroundColor: '#f5f5f5',
55 padding: 0,
56 margin: 0
57 },
58 items: {
59 xtype: 'treelist',
60 itemId: 'menu',
61 ui: 'nav',
62 expanderOnly: true,
63 expanderFirst: false,
64 animation: false,
65 singleExpand: false,
66 listeners: {
67 selectionchange: function(treeList, selection) {
68 var me = this.up('panel');
69 me.suspendLayout = true;
70 me.activateCard(selection.data.id);
71 me.suspendLayout = false;
72 me.updateLayout();
73 },
74 itemclick: function(treelist, info) {
75 var olditem = treelist.getSelection();
76 var newitem = info.node;
77
78 // when clicking on the expand arrow,
79 // we dont select items, but still want
80 // the original behaviour
81 if (info.select === false) {
82 return;
83 }
84
85 // if you click on a different item which is open,
86 // leave it open
87 // else toggle the clicked item
88 if (olditem.data.id !== newitem.data.id &&
89 newitem.data.expanded === true) {
90 info.toggle = false;
91 } else {
92 info.toggle = true;
93 }
94 }
95 }
96 }
97 }],
98
99 firstItem: '',
100 layout: 'card',
101 border: 0,
102
103 // used for automated test
104 selectById: function(cardid) {
105 var me = this;
106
107 var root = me.store.getRoot();
108 var selection = root.findChild('id', cardid, true);
109
110 if (selection) {
111 selection.expand();
112 var menu = me.down('#menu');
113 menu.setSelection(selection);
114 return cardid;
115 }
116 },
117
118 activateCard: function(cardid) {
119 var me = this;
120 if (me.savedItems[cardid]) {
121 var curcard = me.getLayout().getActiveItem();
122 var newcard = me.add(me.savedItems[cardid]);
123 if (curcard) {
124 me.setActiveItem(cardid);
125 me.remove(curcard, true);
126
127 // trigger state change
128
129 var ncard = cardid;
130 // Note: '' is alias for first tab.
131 // First tab can be 'search' or something else
132 if (cardid === me.firstItem) {
133 ncard = '';
134 }
135 if (me.hstateid) {
136 me.sp.set(me.hstateid, { value: ncard });
137 }
138 }
139 }
140 },
141
142 initComponent: function() {
143 var me = this;
144
145 var stateid = me.hstateid;
146
147 me.sp = Ext.state.Manager.getProvider();
148
149 var activeTab; // leaving this undefined means items[0] will be the default tab
150
151 if (stateid) {
152 var state = me.sp.get(stateid);
153 if (state && state.value) {
154 // if this tab does not exists, it chooses the first
155 activeTab = state.value;
156 }
157 }
158
159 // get title
160 var title = me.title;
161 me.title = undefined;
162
163 // create toolbar
164 //var tbar = me.tbar || [];
165 //me.tbar = undefined;
166
167 //tbar.unshift('->');
168 //tbar.unshift({
169 // xtype: 'tbtext',
170 // text: title,
171 // baseCls: 'x-panel-header-text'
172 //});
173
174 //me.dockedItems[1].items = tbar;
175
176 // include search tab
177 me.items = me.items || [];
178
179 me.savedItems = {};
180 /*jslint confusion:true*/
181 if (me.items[0]) {
182 me.firstItem = me.items[0].itemId;
183 }
184 /*jslint confusion:false*/
185
186 me.store = Ext.create('Ext.data.TreeStore', {
187 root: {
188 expanded: true
189 }
190 });
191 var root = me.store.getRoot();
192 me.items.forEach(function(item){
193 var treeitem = Ext.create('Ext.data.TreeModel',{
194 id: item.itemId,
195 text: item.title,
196 iconCls: item.iconCls,
197 leaf: true,
198 expanded: item.expandedOnInit
199 });
200 item.header = false;
201 if (me.savedItems[item.itemId] !== undefined) {
202 console.log("TEST: " + item.itemId);
203 throw "itemId already exists, please use another";
204 }
205 me.savedItems[item.itemId] = item;
206
207 var group;
208 var curnode = root;
209
210 // get/create the group items
211 while (Ext.isArray(item.groups) && item.groups.length > 0) {
212 group = item.groups.shift();
213
214 var child = curnode.findChild('id', group);
215 if (child === null) {
216 // did not find the group item
217 // so add it where we are
218 break;
219 }
220 curnode = child;
221 }
222
223 // insert the item
224
225 // lets see if it already exists
226 var node = curnode.findChild('id', item.itemId);
227
228 if (node === null) {
229 curnode.appendChild(treeitem);
230 } else {
231 // should not happen!
232 throw "id already exists";
233 }
234 });
235
236 delete me.items;
237 me.defaults = me.defaults || {};
238 Ext.apply(me.defaults, {
239 viewFilter: me.viewFilter,
240 border: 0
241 });
242
243 me.callParent();
244
245 var menu = me.down('#menu');
246 var selection = root.findChild('id', activeTab, true) || root.firstChild;
247 var node = selection;
248 while (node !== root) {
249 node.expand();
250 node = node.parentNode;
251 }
252 menu.setStore(me.store);
253 menu.setSelection(selection);
254
255 // on a state change,
256 // select the new item
257 var statechange = function(sp, key, state) {
258 // it the state change is for this panel
259 if (stateid && (key === stateid) && state) {
260 // get active item
261 var acard = me.getLayout().getActiveItem().itemId;
262 // get the itemid of the new value
263 var ncard = state.value || me.firstItem;
264 if (ncard && (acard != ncard)) {
265 // select the chosen item
266 menu.setSelection(root.findChild('id', ncard, true) || root.firstChild);
267 }
268 }
269 };
270
271 if (stateid) {
272 me.mon(me.sp, 'statechange', statechange);
273 }
274 }
275 });