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"; | 		throw "no datastore specified"; | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	    this.data_store = Ext.create('Ext.data.Store', { | 	    this.store = Ext.create('Ext.data.Store', { | ||||||
| 		model: 'pbs-data-store-snapshots', | 		model: 'pbs-data-store-snapshots', | ||||||
| 		sorters: 'backup-group', | 		sorters: 'backup-group', | ||||||
| 		groupField: 'backup-group', | 		groupField: 'backup-group', | ||||||
| 	    }); | 	    }); | ||||||
|  | 	    this.store.on('load', this.onLoad, this); | ||||||
|  |  | ||||||
| 	    Proxmox.Utils.monStoreErrors(view, view.store, true); | 	    Proxmox.Utils.monStoreErrors(view, view.store, true); | ||||||
| 	    this.reload(); // initial load | 	    this.reload(); // initial load | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	reload: function() { | 	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`; | 	    let url = `/api2/json/admin/datastore/${view.datastore}/snapshots`; | ||||||
| 	    this.data_store.setProxy({ | 	    this.store.setProxy({ | ||||||
| 		type: 'proxmox', | 		type: 'proxmox', | ||||||
| 		url:  url | 		url:  url | ||||||
| 	    }); | 	    }); | ||||||
|  |  | ||||||
| 	    this.data_store.load(function(records, operation, success) { | 	    this.store.load(); | ||||||
| 		let groups = {}; | 	}, | ||||||
|  |  | ||||||
| 		records.forEach(function(item) { | 	getRecordGroups: function(records) { | ||||||
| 		    var btype = item.data["backup-type"]; | 	    let groups = {}; | ||||||
| 		    let group = btype + "/" + item.data["backup-id"]; |  | ||||||
|  |  | ||||||
| 		    if (groups[group] !== undefined) | 	    for (const item of records) { | ||||||
| 			return; | 		var btype = item.data["backup-type"]; | ||||||
|  | 		let group = btype + "/" + item.data["backup-id"]; | ||||||
|  |  | ||||||
| 		    var cls = ''; | 		if (groups[group] !== undefined) { | ||||||
| 		    if (btype === 'vm') { | 		    continue; | ||||||
| 			cls = 'fa-desktop'; | 		} | ||||||
| 		    } else if (btype === 'ct') { |  | ||||||
| 			cls = 'fa-cube'; |  | ||||||
| 		    } else if (btype === 'host') { |  | ||||||
| 			cls = 'fa-building'; |  | ||||||
| 		    } else { |  | ||||||
| 			return btype + '/' + value; |  | ||||||
| 		    } |  | ||||||
|  |  | ||||||
| 		    groups[group] = { | 		var cls = ''; | ||||||
| 			text: group, | 		if (btype === 'vm') { | ||||||
| 			leaf: false, | 		    cls = 'fa-desktop'; | ||||||
| 			iconCls: "fa " + cls, | 		} else if (btype === 'ct') { | ||||||
| 			expanded: false, | 		    cls = 'fa-cube'; | ||||||
| 			backup_type: item.data["backup-type"], | 		} else if (btype === 'host') { | ||||||
| 			backup_id: item.data["backup-id"], | 		    cls = 'fa-building'; | ||||||
| 			children: [] | 		} else { | ||||||
| 		    }; | 		    console.warn(`got unkown backup-type '${btype}'`); | ||||||
| 		}); | 		    continue; // FIXME: auto render? what do? | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		let backup_time_to_string = function(backup_time) { | 		groups[group] = { | ||||||
| 		    let pad = function(number) { | 		    text: group, | ||||||
| 			if (number < 10) { | 		    leaf: false, | ||||||
| 			    return '0' + number; | 		    iconCls: "fa " + cls, | ||||||
| 			} | 		    expanded: false, | ||||||
| 			return number; | 		    backup_type: item.data["backup-type"], | ||||||
| 		    }; | 		    backup_id: item.data["backup-id"], | ||||||
| 		    return backup_time.getUTCFullYear() + | 		    children: [] | ||||||
| 			'-' + pad(backup_time.getUTCMonth() + 1) + |  | ||||||
| 			'-' + pad(backup_time.getUTCDate()) + |  | ||||||
| 			'T' + pad(backup_time.getUTCHours()) + |  | ||||||
| 			':' + pad(backup_time.getUTCMinutes()) + |  | ||||||
| 			':' + pad(backup_time.getUTCSeconds()) + |  | ||||||
| 			'Z'; |  | ||||||
| 		}; | 		}; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
| 		records.forEach(function(item) { | 	    return groups; | ||||||
| 		    let group = item.data["backup-type"] + "/" + item.data["backup-id"]; | 	}, | ||||||
| 		    let children = groups[group].children; |  | ||||||
|  |  | ||||||
| 		    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'); | 	    if (!success) { | ||||||
| 		    data.text = group + '/' + backup_time_to_string(data["backup-time"]); | 		return; | ||||||
| 		    data.leaf = true; | 	    } | ||||||
| 		    data.cls = 'no-leaf-icons'; |  | ||||||
|  |  | ||||||
| 		    children.push(data); | 	    let groups = this.getRecordGroups(records); | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		let children = []; | 	    let backup_time_to_string = function(backup_time) { | ||||||
| 		Ext.Object.each(groups, function(key, group) { | 		let pad = (number) => number < 10 ? '0' + number : number; | ||||||
| 		    let last_backup = 0; | 		return backup_time.getUTCFullYear() + | ||||||
| 		    group.children.forEach(function(item) { | 		    '-' + pad(backup_time.getUTCMonth() + 1) + | ||||||
| 			if (item["backup-time"] > last_backup) { | 		    '-' + pad(backup_time.getUTCDate()) + | ||||||
| 			    last_backup = item["backup-time"]; | 		    'T' + pad(backup_time.getUTCHours()) + | ||||||
| 			    group["backup-time"] = last_backup; | 		    ':' + pad(backup_time.getUTCMinutes()) + | ||||||
| 			    group.files = item.files; | 		    ':' + pad(backup_time.getUTCSeconds()) + | ||||||
| 			    group.size = item.size; | 		    'Z'; | ||||||
| 			} | 	    }; | ||||||
| 		    }); |  | ||||||
| 		    group.count = group.children.length; |  | ||||||
| 		    children.push(group) |  | ||||||
| 		}) |  | ||||||
|  |  | ||||||
| 		view.setRootNode({ | 	    for (const item of records) { | ||||||
| 		    expanded: true, | 		let group = item.data["backup-type"] + "/" + item.data["backup-id"]; | ||||||
| 		    children: children | 		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() { | 	onPrune: function() { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user