]> git.proxmox.com Git - proxmox-backup.git/blame - www/MainView.js
ui: datastore: used fixed-width icons for summary
[proxmox-backup.git] / www / MainView.js
CommitLineData
5c7a1b15
DM
1Ext.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 {
239 reference: 'logoutButton',
240 iconCls: 'fa fa-sign-out',
241 text: gettext('Logout'),
242 },
243 ],
244 },
8acd4d9a 245 ],
5c7a1b15
DM
246 },
247 {
248 xtype: 'panel',
249 scrollable: 'y',
250 border: false,
251 region: 'west',
252 layout: {
253 type: 'vbox',
8acd4d9a 254 align: 'stretch',
5c7a1b15 255 },
b0ee976f
DM
256 items: [{
257 xtype: 'navigationtree',
258 minWidth: 180,
259 reference: 'navtree',
260 // we have to define it here until extjs 6.2
261 // because of a bug where a viewcontroller does not detect
262 // the selectionchange event of a treelist
263 listeners: {
8acd4d9a
TL
264 selectionchange: 'navigate',
265 },
b0ee976f
DM
266 }, {
267 xtype: 'box',
268 cls: 'x-treelist-nav',
8acd4d9a
TL
269 flex: 1,
270 }],
5c7a1b15
DM
271 },
272 {
273 xtype: 'panel',
274 layout: { type: 'card' },
275 region: 'center',
276 border: false,
8acd4d9a
TL
277 reference: 'contentpanel',
278 },
279 ],
5c7a1b15 280});