mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
* remove unused elements from tasks page * remove components * client: tasks: wip * tasks: order, start styling them * more tasks works * habits controls * more work * tasks icons * split columns in their own component * implement tags for tasks * wip * add columns description
49 lines
2.0 KiB
JavaScript
49 lines
2.0 KiB
JavaScript
import get from 'lodash/get';
|
|
import axios from 'axios';
|
|
|
|
// Return an object used to describe, in the app state, an
|
|
// async resource loaded from the server with its data and status.
|
|
export function asyncResourceFactory () {
|
|
return {
|
|
loadingStatus: 'NOT_LOADED', // NOT_LOADED, LOADING, LOADED
|
|
data: null,
|
|
};
|
|
}
|
|
|
|
export function loadAsyncResource ({store, path, url, deserialize, forceLoad = false}) {
|
|
if (!store) throw new Error('"store" is required and must be the application store.');
|
|
if (!path) throw new Error('The path to the resource in the application state is required.');
|
|
if (!url) throw new Error('The resource\'s url on the server is required.');
|
|
if (!deserialize) throw new Error('A response deserialization function named must be passed as "deserialize".');
|
|
|
|
const resource = get(store.state, path);
|
|
if (!resource) throw new Error(`No resouce found at path "${path}".`);
|
|
const loadingStatus = resource.loadingStatus;
|
|
|
|
if (loadingStatus === 'LOADED' && !forceLoad) {
|
|
return Promise.resolve(resource);
|
|
} else if (loadingStatus === 'LOADING') {
|
|
return new Promise((resolve, reject) => {
|
|
const resourceWatcher = store.watch(state => get(state, `${path}.loadingStatus`), (newLoadingStatus) => {
|
|
resourceWatcher(); // remove the watcher
|
|
if (newLoadingStatus === 'LOADED') {
|
|
return resolve(resource);
|
|
} else {
|
|
return reject(); // TODO add reason?
|
|
}
|
|
});
|
|
});
|
|
} else if (loadingStatus === 'NOT_LOADED' || loadingStatus === 'LOADED' && forceLoad) {
|
|
return axios.get(url).then(response => { // TODO support more params
|
|
resource.loadingStatus = 'LOADED';
|
|
// deserialize can be a promise
|
|
return Promise.resolve(deserialize(response)).then(deserializedData => {
|
|
resource.data = deserializedData;
|
|
return resource;
|
|
});
|
|
});
|
|
} else {
|
|
return Promise.reject(new Error(`Invalid loading status "${loadingStatus} for resource at "${path}".`));
|
|
}
|
|
}
|