]>
Commit | Line | Data |
---|---|---|
5c7a1b15 DM |
1 | Ext.define('PBS.MainView', { |
2 | extend: 'Ext.container.Container', | |
3 | xtype: 'mainview', | |
4 | ||
5 | title: 'Proxmox Backup Server', | |
6 | ||
7 | controller: { | |
8 | xclass: 'Ext.app.ViewController', | |
9 | routes: { | |
10 | ':path:subpath': { | |
11 | action: 'changePath', | |
12 | before: 'beforeChangePath', | |
8acd4d9a TL |
13 | conditions: { |
14 | ':path': '(?:([%a-zA-Z0-9\\-\\_\\s,.]+))', | |
15 | ':subpath': '(?:(?::)([%a-zA-Z0-9\\-\\_\\s,]+))?', | |
16 | }, | |
17 | }, | |
5c7a1b15 | 18 | }, |
2e75b6d8 | 19 | |
5c7a1b15 DM |
20 | beforeChangePath: function(path, subpath, action) { |
21 | var me = this; | |
22 | ||
c0ac2074 DC |
23 | let xtype = path; |
24 | let datastore; | |
25 | let isDataStore = PBS.Utils.isDataStorePath(path); | |
26 | if (isDataStore) { | |
27 | xtype = 'pbsDataStorePanel'; | |
28 | datastore = PBS.Utils.getDataStoreFromPath(path); | |
29 | } | |
30 | ||
31 | if (!Ext.ClassManager.getByAlias(`widget.${xtype}`)) { | |
32 | console.warn(`xtype ${xtype} not found`); | |
b0ee976f DM |
33 | action.stop(); |
34 | return; | |
35 | } | |
36 | ||
37 | var lastpanel = me.lookupReference('contentpanel').getLayout().getActiveItem(); | |
c0ac2074 DC |
38 | if (lastpanel && lastpanel.xtype === xtype) { |
39 | if (isDataStore) { | |
40 | if (datastore === lastpanel.datastore) { | |
ca23a97f DM |
41 | action.stop(); |
42 | return; | |
43 | } | |
44 | } else { | |
45 | // we have the right component already, | |
46 | // we just need to select the correct tab | |
47 | // default to the first | |
48 | subpath = subpath || 0; | |
49 | if (lastpanel.getActiveTab) { | |
50 | // we assume lastpanel is a tabpanel | |
51 | if (lastpanel.getActiveTab().getItemId() !== subpath) { | |
52 | // set the active tab | |
53 | lastpanel.setActiveTab(subpath); | |
54 | } | |
55 | // else we are already there | |
b0ee976f | 56 | } |
ca23a97f DM |
57 | action.stop(); |
58 | return; | |
b0ee976f | 59 | } |
b0ee976f DM |
60 | } |
61 | ||
5c7a1b15 DM |
62 | action.resume(); |
63 | }, | |
2e75b6d8 | 64 | |
ca23a97f | 65 | changePath: function(path, subpath) { |
5c7a1b15 DM |
66 | var me = this; |
67 | var contentpanel = me.lookupReference('contentpanel'); | |
68 | var lastpanel = contentpanel.getLayout().getActiveItem(); | |
69 | ||
2565fdd0 DC |
70 | let tabChangeListener = function(tp, newc, oldc) { |
71 | let newpath = path; | |
b0ee976f | 72 | |
2565fdd0 DC |
73 | // only add the subpath part for the |
74 | // non-default tabs | |
75 | if (tp.items.findIndex('id', newc.id) !== 0) { | |
76 | newpath += `:${newc.getItemId()}`; | |
77 | } | |
b0ee976f | 78 | |
2565fdd0 DC |
79 | me.redirectTo(newpath); |
80 | }; | |
b0ee976f | 81 | |
2565fdd0 DC |
82 | let xtype = path; |
83 | var obj; | |
84 | let datastore; | |
85 | if (PBS.Utils.isDataStorePath(path)) { | |
86 | datastore = PBS.Utils.getDataStoreFromPath(path); | |
87 | if (lastpanel && lastpanel.xtype === 'pbsDataStorePanel' && !subpath) { | |
88 | let activeTab = lastpanel.getActiveTab(); | |
89 | let newpath = path; | |
90 | if (lastpanel.items.indexOf(activeTab) !== 0) { | |
91 | subpath = activeTab.getItemId(); | |
92 | newpath += `:${subpath}`; | |
b0ee976f | 93 | } |
b0ee976f | 94 | me.redirectTo(newpath); |
2565fdd0 DC |
95 | } |
96 | xtype = 'pbsDataStorePanel'; | |
b0ee976f | 97 | } |
2565fdd0 DC |
98 | obj = contentpanel.add({ |
99 | xtype, | |
100 | datastore, | |
101 | nodename: 'localhost', | |
102 | border: false, | |
103 | activeTab: subpath || 0, | |
104 | listeners: { | |
105 | tabchange: tabChangeListener, | |
106 | }, | |
107 | }); | |
108 | ||
109 | var treelist = me.lookupReference('navtree'); | |
110 | ||
111 | treelist.select(path, true); | |
b0ee976f DM |
112 | |
113 | contentpanel.setActiveItem(obj); | |
114 | ||
115 | if (lastpanel) { | |
116 | contentpanel.remove(lastpanel, { destroy: true }); | |
117 | } | |
b0ee976f DM |
118 | }, |
119 | ||
34f956bc DM |
120 | logout: function() { |
121 | PBS.app.logout(); | |
122 | }, | |
123 | ||
b0ee976f DM |
124 | navigate: function(treelist, item) { |
125 | this.redirectTo(item.get('path')); | |
5c7a1b15 DM |
126 | }, |
127 | ||
34f956bc | 128 | control: { |
f6e964b9 | 129 | '[reference=logoutButton]': { |
8acd4d9a TL |
130 | click: 'logout', |
131 | }, | |
34f956bc DM |
132 | }, |
133 | ||
5c7a1b15 DM |
134 | init: function(view) { |
135 | var me = this; | |
5c7a1b15 | 136 | |
cc83c136 | 137 | PBS.data.RunningTasksStore.startUpdate(); |
f6e964b9 | 138 | me.lookupReference('usernameinfo').setText(Proxmox.UserName); |
a602faeb | 139 | |
8af272fd TL |
140 | // show login on requestexception |
141 | // fixme: what about other errors | |
142 | Ext.Ajax.on('requestexception', function(conn, response, options) { | |
8acd4d9a | 143 | if (response.status === 401 || response.status === '401') { // auth failure |
8af272fd TL |
144 | me.logout(); |
145 | } | |
146 | }); | |
147 | ||
a602faeb TL |
148 | // get ticket periodically |
149 | Ext.TaskManager.start({ | |
150 | run: function() { | |
151 | var ticket = Proxmox.Utils.authOK(); | |
152 | if (!ticket || !Proxmox.UserName) { | |
153 | return; | |
154 | } | |
155 | ||
156 | Ext.Ajax.request({ | |
157 | params: { | |
158 | username: Proxmox.UserName, | |
8acd4d9a | 159 | password: ticket, |
a602faeb TL |
160 | }, |
161 | url: '/api2/json/access/ticket', | |
162 | method: 'POST', | |
163 | failure: function() { | |
164 | me.logout(); | |
165 | }, | |
166 | success: function(response, opts) { | |
167 | var obj = Ext.decode(response.responseText); | |
323515c2 | 168 | PBS.Utils.updateLoginData(obj.data); |
8acd4d9a | 169 | }, |
a602faeb TL |
170 | }); |
171 | }, | |
8acd4d9a | 172 | interval: 15*60*1000, |
a602faeb | 173 | }); |
9710e5d0 TL |
174 | |
175 | ||
176 | // select treeitem and load page from url fragment, if set | |
177 | let token = Ext.util.History.getToken() || 'pbsDashboard'; | |
178 | this.redirectTo(token, true); | |
8acd4d9a | 179 | }, |
5c7a1b15 DM |
180 | }, |
181 | ||
182 | plugins: 'viewport', | |
183 | ||
184 | layout: { type: 'border' }, | |
185 | ||
186 | items: [ | |
187 | { | |
188 | region: 'north', | |
189 | xtype: 'container', | |
190 | layout: { | |
191 | type: 'hbox', | |
8acd4d9a | 192 | align: 'middle', |
5c7a1b15 | 193 | }, |
86443141 | 194 | margin: '2 0 2 5', |
5c7a1b15 DM |
195 | height: 38, |
196 | items: [ | |
197 | { | |
1d8ef0dc DC |
198 | xtype: 'proxmoxlogo', |
199 | prefix: '', | |
5c7a1b15 DM |
200 | }, |
201 | { | |
86443141 TL |
202 | padding: '0 0 0 5', |
203 | xtype: 'versioninfo', | |
5c7a1b15 | 204 | }, |
36cb4b30 DC |
205 | { |
206 | padding: 5, | |
207 | html: '<a href="https://bugzilla.proxmox.com" target="_blank">BETA</a>', | |
208 | baseCls: 'x-plain', | |
209 | }, | |
5c7a1b15 | 210 | { |
bd260569 DC |
211 | flex: 1, |
212 | baseCls: 'x-plain', | |
5c7a1b15 | 213 | }, |
9c01e73c TL |
214 | { |
215 | xtype: 'button', | |
216 | baseCls: 'x-btn', | |
217 | cls: 'x-btn-default-toolbar-small proxmox-inline-button', | |
218 | iconCls: 'fa fa-book x-btn-icon-el-default-toolbar-small ', | |
219 | text: gettext('Documentation'), | |
220 | href: '/docs/index.html', | |
221 | margin: '0 5 0 0', | |
222 | }, | |
a3970d6c DC |
223 | { |
224 | xtype: 'pbsTaskButton', | |
225 | margin: '0 5 0 0', | |
226 | }, | |
5c7a1b15 | 227 | { |
5c7a1b15 | 228 | xtype: 'button', |
f6e964b9 TL |
229 | reference: 'usernameinfo', |
230 | style: { | |
231 | // proxmox dark grey p light grey as border | |
232 | backgroundColor: '#464d4d', | |
8acd4d9a | 233 | borderColor: '#ABBABA', |
f6e964b9 TL |
234 | }, |
235 | margin: '0 5 0 0', | |
236 | iconCls: 'fa fa-user', | |
237 | menu: [ | |
238 | { | |
f8a682a8 TL |
239 | iconCls: 'fa fa-language', |
240 | text: gettext('Language'), | |
241 | reference: 'languageButton', | |
242 | handler: () => Ext.create('Proxmox.window.LanguageEditWindow', { | |
243 | cookieName: 'PBSLangCookie', | |
244 | autoShow: true, | |
245 | }), | |
246 | }, | |
247 | '-', | |
248 | { | |
f6e964b9 TL |
249 | iconCls: 'fa fa-sign-out', |
250 | text: gettext('Logout'), | |
f8a682a8 | 251 | reference: 'logoutButton', |
f6e964b9 TL |
252 | }, |
253 | ], | |
254 | }, | |
8acd4d9a | 255 | ], |
5c7a1b15 DM |
256 | }, |
257 | { | |
258 | xtype: 'panel', | |
259 | scrollable: 'y', | |
260 | border: false, | |
261 | region: 'west', | |
262 | layout: { | |
263 | type: 'vbox', | |
8acd4d9a | 264 | align: 'stretch', |
5c7a1b15 | 265 | }, |
b0ee976f DM |
266 | items: [{ |
267 | xtype: 'navigationtree', | |
268 | minWidth: 180, | |
269 | reference: 'navtree', | |
270 | // we have to define it here until extjs 6.2 | |
271 | // because of a bug where a viewcontroller does not detect | |
272 | // the selectionchange event of a treelist | |
273 | listeners: { | |
8acd4d9a TL |
274 | selectionchange: 'navigate', |
275 | }, | |
b0ee976f DM |
276 | }, { |
277 | xtype: 'box', | |
278 | cls: 'x-treelist-nav', | |
8acd4d9a TL |
279 | flex: 1, |
280 | }], | |
5c7a1b15 DM |
281 | }, |
282 | { | |
283 | xtype: 'panel', | |
284 | layout: { type: 'card' }, | |
285 | region: 'center', | |
286 | border: false, | |
8acd4d9a TL |
287 | reference: 'contentpanel', |
288 | }, | |
289 | ], | |
5c7a1b15 | 290 | }); |