]>
Commit | Line | Data |
---|---|---|
3fd52fba | 1 | /* |
8b93a29e TL |
2 | * Base class for all the multitab config panels. |
3 | * Usage: You'd create a subclass of this, and then define your wanted tabs as items like this: | |
3fd52fba DM |
4 | * |
5 | * items: [{ | |
6 | * title: "myTitle", | |
7 | * xytpe: "somextype", | |
8 | * iconCls: 'fa fa-icon', | |
9 | * groups: ['somegroup'], | |
10 | * expandedOnInit: true, | |
11 | * itemId: 'someId' | |
12 | * }] | |
13 | * | |
8b93a29e TL |
14 | * this has to be in the declarative syntax, else we cannot save them for later (so no Ext.create |
15 | * or Ext.apply of an item in the subclass) | |
3fd52fba | 16 | * |
8b93a29e TL |
17 | * the groups array expects the itemids of the items which are the parents, which have to come |
18 | * before they are used. | |
3fd52fba | 19 | * |
8b93a29e TL |
20 | * If you want following the tree: |
21 | * Option1 | |
22 | * Option2 | |
23 | * -> SubOption1 | |
24 | * -> SubSubOption1 | |
3fd52fba | 25 | * |
8b93a29e TL |
26 | * then the suboption1 group array has to look like this: |
27 | * groups: ['itemid-of-option2'] | |
3fd52fba | 28 | * |
8b93a29e TL |
29 | * and the subsuboption1 one: |
30 | * groups: ['itemid-of-option2', 'itemid-of-suboption1'] | |
3fd52fba | 31 | * |
8b93a29e | 32 | * setting the expandedOnInit determines if the item/group is expanded initially (false by default) |
3fd52fba DM |
33 | */ |
34 | Ext.define('PMG.panel.Config', { | |
35 | extend: 'Ext.panel.Panel', | |
36 | alias: 'widget.pmgPanelConfig', | |
37 | ||
38 | viewFilter: undefined, // a filter to pass to that ressource grid | |
39 | ||
40 | dockedItems: [{ | |
41 | // this is needed for the overflow handler | |
42 | xtype: 'toolbar', | |
43 | overflowHandler: 'scroller', | |
44 | dock: 'left', | |
45 | style: { | |
46 | backgroundColor: '#f5f5f5', | |
47 | padding: 0, | |
c87d46fb | 48 | margin: 0, |
3fd52fba DM |
49 | }, |
50 | items: { | |
51 | xtype: 'treelist', | |
52 | itemId: 'menu', | |
9d87a333 | 53 | ui: 'pve-nav', |
3fd52fba DM |
54 | expanderOnly: true, |
55 | expanderFirst: false, | |
56 | animation: false, | |
57 | singleExpand: false, | |
58 | listeners: { | |
59 | selectionchange: function(treeList, selection) { | |
28eb60c0 TL |
60 | let view = this.up('panel'); |
61 | view.suspendLayout = true; | |
62 | view.activateCard(selection.data.id); | |
63 | view.suspendLayout = false; | |
64 | view.updateLayout(); | |
3fd52fba DM |
65 | }, |
66 | itemclick: function(treelist, info) { | |
67 | var olditem = treelist.getSelection(); | |
68 | var newitem = info.node; | |
69 | ||
8b93a29e | 70 | // don't select when clicking on the expand arrow, but still want the original behavior |
3fd52fba DM |
71 | if (info.select === false) { |
72 | return; | |
73 | } | |
74 | ||
8b93a29e | 75 | // if a different open item is clicked, leave it open, else toggle the clicked item |
3fd52fba DM |
76 | if (olditem.data.id !== newitem.data.id && |
77 | newitem.data.expanded === true) { | |
78 | info.toggle = false; | |
79 | } else { | |
80 | info.toggle = true; | |
81 | } | |
c87d46fb TL |
82 | }, |
83 | }, | |
84 | }, | |
3fd52fba DM |
85 | }], |
86 | ||
87 | firstItem: '', | |
88 | layout: 'card', | |
89 | border: 0, | |
90 | ||
91 | // used for automated test | |
92 | selectById: function(cardid) { | |
93 | var me = this; | |
94 | ||
95 | var root = me.store.getRoot(); | |
96 | var selection = root.findChild('id', cardid, true); | |
97 | ||
98 | if (selection) { | |
99 | selection.expand(); | |
100 | var menu = me.down('#menu'); | |
101 | menu.setSelection(selection); | |
102 | return cardid; | |
103 | } | |
28eb60c0 | 104 | return null; |
3fd52fba DM |
105 | }, |
106 | ||
107 | activateCard: function(cardid) { | |
108 | var me = this; | |
109 | if (me.savedItems[cardid]) { | |
110 | var curcard = me.getLayout().getActiveItem(); | |
28eb60c0 | 111 | me.add(me.savedItems[cardid]); |
3fd52fba DM |
112 | if (curcard) { |
113 | me.setActiveItem(cardid); | |
114 | me.remove(curcard, true); | |
115 | ||
116 | // trigger state change | |
117 | ||
118 | var ncard = cardid; | |
8b93a29e | 119 | // Note: '' is alias for first tab. First tab can be 'search' or something else |
3fd52fba DM |
120 | if (cardid === me.firstItem) { |
121 | ncard = ''; | |
122 | } | |
123 | if (me.hstateid) { | |
124 | me.sp.set(me.hstateid, { value: ncard }); | |
125 | } | |
126 | } | |
127 | } | |
128 | }, | |
129 | ||
130 | initComponent: function() { | |
131 | var me = this; | |
132 | ||
133 | var stateid = me.hstateid; | |
134 | ||
135 | me.sp = Ext.state.Manager.getProvider(); | |
136 | ||
137 | var activeTab; // leaving this undefined means items[0] will be the default tab | |
138 | ||
139 | if (stateid) { | |
140 | var state = me.sp.get(stateid); | |
141 | if (state && state.value) { | |
142 | // if this tab does not exists, it chooses the first | |
143 | activeTab = state.value; | |
144 | } | |
145 | } | |
146 | ||
3fd52fba DM |
147 | // include search tab |
148 | me.items = me.items || []; | |
149 | ||
150 | me.savedItems = {}; | |
3fd52fba DM |
151 | if (me.items[0]) { |
152 | me.firstItem = me.items[0].itemId; | |
153 | } | |
3fd52fba DM |
154 | |
155 | me.store = Ext.create('Ext.data.TreeStore', { | |
156 | root: { | |
c87d46fb TL |
157 | expanded: true, |
158 | }, | |
3fd52fba DM |
159 | }); |
160 | var root = me.store.getRoot(); | |
c87d46fb TL |
161 | me.items.forEach(function(item) { |
162 | var treeitem = Ext.create('Ext.data.TreeModel', { | |
3fd52fba DM |
163 | id: item.itemId, |
164 | text: item.title, | |
165 | iconCls: item.iconCls, | |
166 | leaf: true, | |
c87d46fb | 167 | expanded: item.expandedOnInit, |
3fd52fba DM |
168 | }); |
169 | item.header = false; | |
170 | if (me.savedItems[item.itemId] !== undefined) { | |
3fd52fba DM |
171 | throw "itemId already exists, please use another"; |
172 | } | |
173 | me.savedItems[item.itemId] = item; | |
174 | ||
175 | var group; | |
176 | var curnode = root; | |
177 | ||
178 | // get/create the group items | |
179 | while (Ext.isArray(item.groups) && item.groups.length > 0) { | |
180 | group = item.groups.shift(); | |
181 | ||
182 | var child = curnode.findChild('id', group); | |
183 | if (child === null) { | |
8b93a29e | 184 | // did not find the group item so add it where we are |
3fd52fba DM |
185 | break; |
186 | } | |
187 | curnode = child; | |
188 | } | |
189 | ||
3fd52fba DM |
190 | // lets see if it already exists |
191 | var node = curnode.findChild('id', item.itemId); | |
192 | ||
193 | if (node === null) { | |
8b93a29e | 194 | curnode.appendChild(treeitem); // insert the item |
3fd52fba DM |
195 | } else { |
196 | // should not happen! | |
197 | throw "id already exists"; | |
198 | } | |
199 | }); | |
200 | ||
201 | delete me.items; | |
202 | me.defaults = me.defaults || {}; | |
203 | Ext.apply(me.defaults, { | |
204 | viewFilter: me.viewFilter, | |
c87d46fb | 205 | border: 0, |
3fd52fba DM |
206 | }); |
207 | ||
208 | me.callParent(); | |
209 | ||
210 | var menu = me.down('#menu'); | |
211 | var selection = root.findChild('id', activeTab, true) || root.firstChild; | |
212 | var node = selection; | |
213 | while (node !== root) { | |
214 | node.expand(); | |
215 | node = node.parentNode; | |
216 | } | |
217 | menu.setStore(me.store); | |
218 | menu.setSelection(selection); | |
219 | ||
8b93a29e | 220 | // on a state change select the new item |
28eb60c0 | 221 | const statechange = function(sp, key, newState) { |
3fd52fba | 222 | // it the state change is for this panel |
28eb60c0 | 223 | if (stateid && (key === stateid) && newState) { |
3fd52fba DM |
224 | // get active item |
225 | var acard = me.getLayout().getActiveItem().itemId; | |
226 | // get the itemid of the new value | |
28eb60c0 TL |
227 | var ncard = newState.value || me.firstItem; |
228 | if (ncard && (acard !== ncard)) { | |
3fd52fba DM |
229 | // select the chosen item |
230 | menu.setSelection(root.findChild('id', ncard, true) || root.firstChild); | |
231 | } | |
232 | } | |
233 | }; | |
234 | ||
235 | if (stateid) { | |
236 | me.mon(me.sp, 'statechange', statechange); | |
237 | } | |
c87d46fb | 238 | }, |
3fd52fba | 239 | }); |