forked from rc/aircox
		
	
		
			
				
	
	
		
			120 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import Vue from 'vue';
 | 
						|
 | 
						|
function getCookie(name) {
 | 
						|
    if(document.cookie && document.cookie !== '') {
 | 
						|
        const cookie = document.cookie.split(';')
 | 
						|
                               .find(c => c.trim().startsWith(name + '='))
 | 
						|
        return cookie ? decodeURIComponent(cookie.split('=')[1]) : null;
 | 
						|
    }
 | 
						|
    return null;
 | 
						|
}
 | 
						|
 | 
						|
var csrfToken = null;
 | 
						|
 | 
						|
export function getCsrf() {
 | 
						|
    if(csrfToken === null)
 | 
						|
        csrfToken = getCookie('csrftoken')
 | 
						|
    return csrfToken;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// TODO: move in another module for reuse
 | 
						|
// TODO: prevent duplicate simple fetch
 | 
						|
export default class Model {
 | 
						|
    constructor(data, {url=null}={}) {
 | 
						|
        this.commit(data);
 | 
						|
    }
 | 
						|
 | 
						|
    static getId(data) {
 | 
						|
        return data.id;
 | 
						|
    }
 | 
						|
 | 
						|
    static getOptions(options) {
 | 
						|
        return {
 | 
						|
            headers: {
 | 
						|
                'Content-Type': 'application/json',
 | 
						|
                'Accept': 'application/json',
 | 
						|
                'X-CSRFToken': getCsrf(),
 | 
						|
            },
 | 
						|
            ...options,
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    static fetch(url, options=null, initArgs=null) {
 | 
						|
        options = this.getOptions(options)
 | 
						|
        return fetch(url, options)
 | 
						|
            .then(response => response.json())
 | 
						|
            .then(data => new this(d, {url: url, ...initArgs}));
 | 
						|
    }
 | 
						|
 | 
						|
    static fetchAll(url, options=null, initArgs=null) {
 | 
						|
        options = this.getOptions(options)
 | 
						|
        return fetch(url, options)
 | 
						|
            .then(response => response.json())
 | 
						|
            .then(data => {
 | 
						|
                if(!(data instanceof Array))
 | 
						|
                    data = data.results;
 | 
						|
                data = data.map(d => new this(d, {baseUrl: url, ...initArgs}));
 | 
						|
                return data
 | 
						|
            })
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Fetch data from server.
 | 
						|
     */
 | 
						|
    fetch(options) {
 | 
						|
        options = this.constructor.getOptions(options)
 | 
						|
        return fetch(this.url, options)
 | 
						|
            .then(response => response.json())
 | 
						|
            .then(data => this.commit(data));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Call API action on object.
 | 
						|
     */
 | 
						|
    action(path, options, commit=false) {
 | 
						|
        options = this.constructor.getOptions(options)
 | 
						|
        const promise = fetch(this.url + path, options);
 | 
						|
        return commit ? promise.then(data => data.json())
 | 
						|
                               .then(data => { this.commit(data); this.data })
 | 
						|
                      : promise;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Update instance's data with provided data. Return None
 | 
						|
     */
 | 
						|
    commit(data) {
 | 
						|
        this.id = this.constructor.getId(data);
 | 
						|
        this.url = data.url_;
 | 
						|
        Vue.set(this, 'data', data);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return data as model with url prepent by `this.url`.
 | 
						|
     */
 | 
						|
    asChild(model, data, prefix='') {
 | 
						|
        return new model(data, {baseUrl: `${this.url}${prefix}/`})
 | 
						|
    }
 | 
						|
 | 
						|
    getChildOf(attr, id) {
 | 
						|
        const index = this.data[attr].findIndex(o => o.id = id)
 | 
						|
        return index == -1 ? null : this.data[attr][index];
 | 
						|
    }
 | 
						|
 | 
						|
    static updateList(list=[], old=[], ...initArgs) {
 | 
						|
         return list.reduce((items, data) => {
 | 
						|
            const id = this.getId(data);
 | 
						|
            let [index, obj] = [old.findIndex(o => o.id == id), null];
 | 
						|
            if(index != -1) {
 | 
						|
                old[index].commit(data)
 | 
						|
                items.push(old[index]);
 | 
						|
            }
 | 
						|
            else
 | 
						|
                items.push(new this(data, ...initArgs))
 | 
						|
            return items;
 | 
						|
        }, [])
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 |