ui: rework datastore content panel controller
Mostly refactoring, but actually fixes an issue where one seldom run into a undefined dereference due to the store onLoad callback getting triggered after some of the componet was destroyed - on quick switching through the datastores. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
		| @ -29,109 +29,124 @@ Ext.define('PBS.DataStoreContent', { | ||||
| 		throw "no datastore specified"; | ||||
| 	    } | ||||
|  | ||||
| 	    this.data_store = Ext.create('Ext.data.Store', { | ||||
| 	    this.store = Ext.create('Ext.data.Store', { | ||||
| 		model: 'pbs-data-store-snapshots', | ||||
| 		sorters: 'backup-group', | ||||
| 		groupField: 'backup-group', | ||||
| 	    }); | ||||
| 	    this.store.on('load', this.onLoad, this); | ||||
|  | ||||
| 	    Proxmox.Utils.monStoreErrors(view, view.store, true); | ||||
| 	    this.reload(); // initial load | ||||
| 	}, | ||||
|  | ||||
| 	reload: function() { | ||||
| 	    var view = this.getView(); | ||||
| 	    let view = this.getView(); | ||||
|  | ||||
| 	    if (!view.store || !this.store) { | ||||
| 		console.warn('cannot reload, no store(s)'); | ||||
| 		return; | ||||
| 	    } | ||||
|  | ||||
| 	    let url = `/api2/json/admin/datastore/${view.datastore}/snapshots`; | ||||
| 	    this.data_store.setProxy({ | ||||
| 	    this.store.setProxy({ | ||||
| 		type: 'proxmox', | ||||
| 		url:  url | ||||
| 	    }); | ||||
|  | ||||
| 	    this.data_store.load(function(records, operation, success) { | ||||
| 		let groups = {}; | ||||
| 	    this.store.load(); | ||||
| 	}, | ||||
|  | ||||
| 		records.forEach(function(item) { | ||||
| 		    var btype = item.data["backup-type"]; | ||||
| 		    let group = btype + "/" + item.data["backup-id"]; | ||||
| 	getRecordGroups: function(records) { | ||||
| 	    let groups = {}; | ||||
|  | ||||
| 		    if (groups[group] !== undefined) | ||||
| 			return; | ||||
| 	    for (const item of records) { | ||||
| 		var btype = item.data["backup-type"]; | ||||
| 		let group = btype + "/" + item.data["backup-id"]; | ||||
|  | ||||
| 		    var cls = ''; | ||||
| 		    if (btype === 'vm') { | ||||
| 			cls = 'fa-desktop'; | ||||
| 		    } else if (btype === 'ct') { | ||||
| 			cls = 'fa-cube'; | ||||
| 		    } else if (btype === 'host') { | ||||
| 			cls = 'fa-building'; | ||||
| 		    } else { | ||||
| 			return btype + '/' + value; | ||||
| 		    } | ||||
| 		if (groups[group] !== undefined) { | ||||
| 		    continue; | ||||
| 		} | ||||
|  | ||||
| 		    groups[group] = { | ||||
| 			text: group, | ||||
| 			leaf: false, | ||||
| 			iconCls: "fa " + cls, | ||||
| 			expanded: false, | ||||
| 			backup_type: item.data["backup-type"], | ||||
| 			backup_id: item.data["backup-id"], | ||||
| 			children: [] | ||||
| 		    }; | ||||
| 		}); | ||||
| 		var cls = ''; | ||||
| 		if (btype === 'vm') { | ||||
| 		    cls = 'fa-desktop'; | ||||
| 		} else if (btype === 'ct') { | ||||
| 		    cls = 'fa-cube'; | ||||
| 		} else if (btype === 'host') { | ||||
| 		    cls = 'fa-building'; | ||||
| 		} else { | ||||
| 		    console.warn(`got unkown backup-type '${btype}'`); | ||||
| 		    continue; // FIXME: auto render? what do? | ||||
| 		} | ||||
|  | ||||
| 		let backup_time_to_string = function(backup_time) { | ||||
| 		    let pad = function(number) { | ||||
| 			if (number < 10) { | ||||
| 			    return '0' + number; | ||||
| 			} | ||||
| 			return number; | ||||
| 		    }; | ||||
| 		    return backup_time.getUTCFullYear() + | ||||
| 			'-' + pad(backup_time.getUTCMonth() + 1) + | ||||
| 			'-' + pad(backup_time.getUTCDate()) + | ||||
| 			'T' + pad(backup_time.getUTCHours()) + | ||||
| 			':' + pad(backup_time.getUTCMinutes()) + | ||||
| 			':' + pad(backup_time.getUTCSeconds()) + | ||||
| 			'Z'; | ||||
| 		groups[group] = { | ||||
| 		    text: group, | ||||
| 		    leaf: false, | ||||
| 		    iconCls: "fa " + cls, | ||||
| 		    expanded: false, | ||||
| 		    backup_type: item.data["backup-type"], | ||||
| 		    backup_id: item.data["backup-id"], | ||||
| 		    children: [] | ||||
| 		}; | ||||
| 	    } | ||||
|  | ||||
| 		records.forEach(function(item) { | ||||
| 		    let group = item.data["backup-type"] + "/" + item.data["backup-id"]; | ||||
| 		    let children = groups[group].children; | ||||
| 	    return groups; | ||||
| 	}, | ||||
|  | ||||
| 		    let data = item.data; | ||||
| 	onLoad: function(store, records, success) { | ||||
| 	    let view = this.getView(); | ||||
|  | ||||
| 		    data.text = Ext.Date.format(data["backup-time"], 'Y-m-d H:i:s'); | ||||
| 		    data.text = group + '/' + backup_time_to_string(data["backup-time"]); | ||||
| 		    data.leaf = true; | ||||
| 		    data.cls = 'no-leaf-icons'; | ||||
| 	    if (!success) { | ||||
| 		return; | ||||
| 	    } | ||||
|  | ||||
| 		    children.push(data); | ||||
| 		}); | ||||
| 	    let groups = this.getRecordGroups(records); | ||||
|  | ||||
| 		let children = []; | ||||
| 		Ext.Object.each(groups, function(key, group) { | ||||
| 		    let last_backup = 0; | ||||
| 		    group.children.forEach(function(item) { | ||||
| 			if (item["backup-time"] > last_backup) { | ||||
| 			    last_backup = item["backup-time"]; | ||||
| 			    group["backup-time"] = last_backup; | ||||
| 			    group.files = item.files; | ||||
| 			    group.size = item.size; | ||||
| 			} | ||||
| 		    }); | ||||
| 		    group.count = group.children.length; | ||||
| 		    children.push(group) | ||||
| 		}) | ||||
| 	    let backup_time_to_string = function(backup_time) { | ||||
| 		let pad = (number) => number < 10 ? '0' + number : number; | ||||
| 		return backup_time.getUTCFullYear() + | ||||
| 		    '-' + pad(backup_time.getUTCMonth() + 1) + | ||||
| 		    '-' + pad(backup_time.getUTCDate()) + | ||||
| 		    'T' + pad(backup_time.getUTCHours()) + | ||||
| 		    ':' + pad(backup_time.getUTCMinutes()) + | ||||
| 		    ':' + pad(backup_time.getUTCSeconds()) + | ||||
| 		    'Z'; | ||||
| 	    }; | ||||
|  | ||||
| 		view.setRootNode({ | ||||
| 		    expanded: true, | ||||
| 		    children: children | ||||
| 		}); | ||||
| 	    for (const item of records) { | ||||
| 		let group = item.data["backup-type"] + "/" + item.data["backup-id"]; | ||||
| 		let children = groups[group].children; | ||||
|  | ||||
| 		let data = item.data; | ||||
|  | ||||
| 		data.text = Ext.Date.format(data["backup-time"], 'Y-m-d H:i:s'); | ||||
| 		data.text = group + '/' + backup_time_to_string(data["backup-time"]); | ||||
| 		data.leaf = true; | ||||
| 		data.cls = 'no-leaf-icons'; | ||||
|  | ||||
| 		children.push(data); | ||||
| 	    } | ||||
|  | ||||
| 	    let children = []; | ||||
| 	    for (const [_key, group] of Object.entries(groups)) { | ||||
| 		let last_backup = 0; | ||||
| 		for (const item of group.children) { | ||||
| 		    if (item["backup-time"] > last_backup) { | ||||
| 			last_backup = item["backup-time"]; | ||||
| 			group["backup-time"] = last_backup; | ||||
| 			group.files = item.files; | ||||
| 			group.size = item.size; | ||||
| 		    } | ||||
| 		} | ||||
| 		group.count = group.children.length; | ||||
| 		children.push(group); | ||||
| 	    } | ||||
|  | ||||
| 	    view.setRootNode({ | ||||
| 		expanded: true, | ||||
| 		children: children | ||||
| 	    }); | ||||
|  | ||||
| 	}, | ||||
|  | ||||
| 	onPrune: function() { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user