]>
git.proxmox.com Git - proxmox-backup.git/blob - www/NavigationTree.js
1 Ext
.define('pbs-datastore-list', {
2 extend
: 'Ext.data.Model',
3 fields
: ['name', 'comment', 'maintenance'],
6 url
: "/api2/json/admin/datastore",
11 Ext
.define('pbs-tape-drive-list', {
12 extend
: 'Ext.data.Model',
13 fields
: ['name', 'changer'],
16 url
: "/api2/json/tape/drive",
21 Ext
.define('PBS.store.NavigationStore', {
22 extend
: 'Ext.data.TreeStore',
24 storeId
: 'NavigationStore',
30 text
: gettext('Dashboard'),
31 iconCls
: 'fa fa-tachometer',
36 text
: gettext('Notes'),
37 iconCls
: 'fa fa-sticky-note-o',
42 text
: gettext('Configuration'),
43 iconCls
: 'fa fa-gears',
44 path
: 'pbsSystemConfiguration',
48 text
: gettext('Access Control'),
50 path
: 'pbsAccessControlPanel',
54 text
: gettext('Remotes'),
55 iconCls
: 'fa fa-server',
56 path
: 'pbsRemoteView',
60 text
: gettext('Traffic Control'),
61 iconCls
: 'fa fa-signal fa-rotate-90',
62 path
: 'pbsTrafficControlView',
66 text
: gettext('Certificates'),
67 iconCls
: 'fa fa-certificate',
68 path
: 'pbsCertificateConfiguration',
72 text
: gettext('Subscription'),
73 iconCls
: 'fa fa-support',
74 path
: 'pbsSubscription',
80 text
: gettext('Administration'),
81 iconCls
: 'fa fa-wrench',
82 path
: 'pbsServerAdministration',
87 text
: gettext('Shell'),
88 iconCls
: 'fa fa-terminal',
89 path
: 'pbsXtermJsConsole',
93 text
: gettext('Storage / Disks'),
94 iconCls
: 'fa fa-hdd-o',
95 path
: 'pbsStorageAndDiskPanel',
102 iconCls
: 'pbs-icon-tape',
103 id
: 'tape_management',
104 path
: 'pbsTapeManagement',
109 text
: gettext('Datastore'),
110 iconCls
: 'fa fa-archive',
112 path
: 'pbsDataStores',
118 text
: gettext('Add Datastore'),
119 iconCls
: 'fa fa-plus-circle',
130 Ext
.define('CustomTreeListItem', {
131 extend
: 'Ext.list.TreeItem',
132 xtype
: 'qtiptreelistitem',
134 nodeUpdate: function(node
, modifiedFieldNames
) {
135 this.callParent(arguments
);
136 const qtip
= node
? node
.get('qtip') : null;
138 this.element
.dom
.setAttribute('data-qtip', qtip
);
140 this.element
.dom
.removeAttribute('data-qtip');
145 Ext
.define('PBS.view.main.NavigationTree', {
146 extend
: 'Ext.list.Tree',
147 xtype
: 'navigationtree',
151 expanderFirst
: false,
152 store
: 'NavigationStore',
156 xtype
: 'qtiptreelistitem',
160 xclass
: 'Ext.app.ViewController',
162 init: function(view
) {
163 view
.rstore
= Ext
.create('Proxmox.data.UpdateStore', {
166 storeId
: 'pbs-datastore-list', // NOTE: this is queried by selectors, avoid change!
167 model
: 'pbs-datastore-list',
170 view
.rstore
.on('load', this.onLoad
, this);
171 view
.on('destroy', view
.rstore
.stopUpdate
);
173 if (view
.tapeStore
=== undefined) {
174 view
.tapeStore
= Ext
.create('Proxmox.data.UpdateStore', {
177 storeid
: 'pbs-tape-drive-list',
178 model
: 'pbs-tape-drive-list',
180 view
.tapeStore
.on('load', this.onTapeDriveLoad
, this);
181 view
.on('destroy', view
.tapeStore
.stopUpdate
);
185 onTapeDriveLoad: function(store
, records
, success
) {
186 if (!success
) return;
188 let view
= this.getView();
189 let root
= view
.getStore().getRoot();
191 records
.sort((a
, b
) => a
.data
.name
.localeCompare(b
.data
.name
));
193 let list
= root
.findChild('id', 'tape_management', false);
194 let existingChildren
= {};
195 for (const drive
of records
) {
196 let path
, text
, iconCls
;
197 if (drive
.data
.changer
!== undefined) {
198 text
= drive
.data
.changer
;
199 path
= `Changer-${text}`;
200 iconCls
= 'fa fa-exchange';
202 text
= drive
.data
.name
;
203 path
= `Drive-${text}`;
204 iconCls
= 'pbs-icon-tape-drive';
206 existingChildren
[path
] = {
214 let paths
= Object
.keys(existingChildren
).sort();
217 for (let newIdx
= 0; newIdx
< paths
.length
; newIdx
++) {
218 let newPath
= paths
[newIdx
];
219 // find index to insert
220 while (oldIdx
< list
.childNodes
.length
&& newPath
> list
.getChildAt(oldIdx
).data
.path
) {
224 if (oldIdx
>= list
.childNodes
.length
|| list
.getChildAt(oldIdx
).data
.path
!== newPath
) {
225 list
.insertChild(oldIdx
, existingChildren
[newPath
]);
230 list
.eachChild((child
) => {
231 if (!existingChildren
[child
.data
.path
]) {
232 toRemove
.push(child
);
235 toRemove
.forEach((child
) => list
.removeChild(child
, true));
237 if (view
.pathToSelect
!== undefined) {
238 let path
= view
.pathToSelect
;
239 delete view
.pathToSelect
;
240 view
.select(path
, true);
244 onLoad: function(store
, records
, success
) {
248 let view
= this.getView();
249 let root
= view
.getStore().getRoot();
251 records
.sort((a
, b
) => a
.id
.localeCompare(b
.id
));
253 let list
= root
.findChild('id', 'datastores', false);
254 let getChildTextAt
= i
=> list
.getChildAt(i
).data
.text
;
255 let existingChildren
= {};
256 for (let i
= 0, j
= 0, length
= records
.length
; i
< length
; i
++) {
257 let name
= records
[i
].id
;
258 existingChildren
[name
] = true;
260 while (name
.localeCompare(getChildTextAt(j
)) > 0 && (j
+1) < list
.childNodes
.length
) {
264 let [qtip
, iconCls
] = ['', 'fa fa-database'];
265 const maintenance
= records
[i
].data
.maintenance
;
267 const [type
, message
] = PBS
.Utils
.parseMaintenanceMode(maintenance
);
268 qtip
= `${type}${message ? ': ' + message : ''}`;
269 let mainenanceTypeCls
= type
=== 'delete' ? 'destroying' : 'maintenance';
270 iconCls
= `fa fa-database pmx-tree-icon-custom ${mainenanceTypeCls}`;
273 if (getChildTextAt(j
).localeCompare(name
) !== 0) {
274 list
.insertChild(j
, {
277 path
: `DataStore-${name}`,
282 let oldChild
= list
.getChildAt(j
);
283 oldChild
.set('qtip', qtip
);
284 oldChild
.set('iconCls', iconCls
);
288 // remove entries which are not existing anymore
290 list
.eachChild(child
=> {
291 if (!existingChildren
[child
.data
.text
] && !child
.data
.virtualEntry
) {
292 toRemove
.push(child
);
295 toRemove
.forEach(child
=> list
.removeChild(child
, true));
297 if (view
.pathToSelect
!== undefined) {
298 let path
= view
.pathToSelect
;
299 delete view
.pathToSelect
;
300 view
.select(path
, true);
306 itemclick: function(tl
, info
) {
307 if (info
.node
.data
.id
=== 'addbutton') {
309 Ext
.create('PBS.DataStoreEdit', {
311 destroy
: () => me
.rstore
.reload(),
320 reloadTapeStore: function() {
325 select: function(path
, silent
) {
327 if (me
.rstore
.isLoaded() && me
.tapeStore
.isLoaded()) {
329 me
.suspendEvents(false);
331 var item
= me
.getStore().findRecord('path', path
, 0, false, true, true);
332 me
.setSelection(item
);
334 me
.resumeEvents(true);
337 me
.pathToSelect
= path
;