]> git.proxmox.com Git - pmg-gui.git/blame - js/ConfigPanel.js
attachment grid: move all-parts controls to tbar, transform back to collapsible title
[pmg-gui.git] / js / ConfigPanel.js
CommitLineData
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 */
34Ext.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});