q42-cms-components
Version:
Front-end package that provides a UI on top of the QMS back-end
217 lines (177 loc) • 6.35 kB
JavaScript
import { ServerStore } from './server-store.js';
import store from './../stores';
import Vue from 'vue';
export class PageStore extends ServerStore {
constructor() {
super({
initial: {
pages: [],
publishedPages: [],
isLoadingPublishedPages: true,
schema: { properties: {}, oneOf: [] }
},
loaders: {
pages: () => this.fetch('/pages/all').then(pageStore.setupPublishedPages).catch(error => {
if (error.message) {
store.dispatch('alerts/addError', error.message);
}
// fallback for not getting an undefined as value
return [];
}),
schema: () => this.fetch('/versions/schema')
},
computed: {
pageTree: () => PageStore.sortPages(PageStore.parsePageTree(this.pages)),
types: () => {
var result = {};
this.schema.oneOf.forEach(s => {
result[s.properties.$type.enum[0]] = s;
});
return result;
}
},
watch: {
publishedPages: {
handler: () => pageStore.setIsPublishedState(),
deep: true
}
}
});
}
/**
* Parses the given flat pagelist and creates a nested structure of pages
* using the parent property of pages.
*/
static parsePageTree(pageList) {
pageList.forEach(page => Vue.set(page, 'path', page.parentId ? '/' + page.name : ''));
let getSubPagesById = id => pageList.filter(page => page.parentId === id);
pageList.forEach((page) => {
page.children = getSubPagesById(page.id);
page.children.forEach(subPage => {
subPage.path = page.path + subPage.path;
// Mark subpages as child so we can remove them later.
subPage.isChild = true;
});
page.path = page.path || '/';
});
return pageList.filter(page => !page.isChild);
}
getPublishedPages() {
super.fetch('/pages/published').then(this.mapResponseToPublishedPages);
}
getFolders() {
super.fetch('/pages/folders').then(this.mapResponseToPublishedPages);
}
getRecurrentSchedulesForId(id) {
return super.fetch(`/versions/schedules/${id}`);
}
mapResponseToPublishedPages(response) {
pageStore.state.publishedPages = pageStore.state.publishedPages.concat(response.map(p => p.pageId));
}
setupPublishedPages(response) {
pageStore.state.isLoadingPublishedPages = true;
// this is needed because isPublished need to be reactive from the begin
response.forEach(page => page.isPublished = false);
// start fetching data
pageStore.state.publishedPages = []; // empty published pages, because we're getting a new set of values from teh server
pageStore.getPublishedPages();
pageStore.getFolders();
return response;
}
setIsPublishedState() {
pageStore.state.pages.forEach(page => {
page.isPublished = pageStore.state.publishedPages.indexOf(page.id) > -1;
});
// remove loading state after the first time this function called, the rest of possible updates is done on the background, updated on the fly, without loading state
pageStore.state.isLoadingPublishedPages = false;
}
/**
* Sorts the given array so that it can be displayed in the page tree.
* @param pageTree nested list of pages.
* @returns sorted pageTree
*/
static sortPages(pageTree) {
let sortByName = (a, b) => {
if(a.name < b.name) {
return -1;
}
if(a.name > b.name) {
return 1;
}
return 0;
};
let pageSorter = (a, b) => {
if(a.children && a.children.length && b.children && b.children.length) {
// Both have child pages.
return sortByName(a, b);
}
if(a.children && a.children.length) {
return -1;
}
if(b.children && b.children.length) {
return 1;
}
// Both pages do not have child pages, only use name to sort.
return sortByName(a, b);
};
pageTree = pageTree.sort(pageSorter);
// Apply recursive sorting on sub arrays.
pageTree.forEach(page => {
if(page.children && page.children.length) {
page.children = PageStore.sortPages(page.children);
}
});
return pageTree;
}
getPageById(id) {
return this.fetch(`/pages/${id}`).then(page => {
return this.fetch(`/pages/${id}/versions`).then(versions => {
page.versions = versions;
return page;
});
});
}
create(version, name, parentId) {
return this.postJson('/versions/create', version, { name, parentId }).then(this.updaters.pages);
}
createFromCopy(sourceVersionId, name, parentId) {
return this.postJson('/versions/create-from-copy', null, { sourceVersionId, name, parentId }).then(this.updaters.pages);
}
updateVersion(version) {
return this.putJson(`/versions/update/${version.id}`, version).then(this.updaters.pages);
}
publishVersion(version) {
return this.post(`/versions/publish/${version.id}`).then(this.updaters.pages);
}
depublishVersion(version) {
return this.post(`/versions/depublish/${version.id}`).then(this.updaters.pages);
}
copyVersion(version) {
return this.post(`/versions/copy/${version.id}`);
}
deleteVersion(version) {
return this.del(`/versions/${version.id}`).then(this.updaters.pages);
}
previewUrl(version, versionCounter) {
return version.id ? this.url(`/versions/preview/${version.id}?counter=${versionCounter}`) : null;
}
move(page, newParentId) {
return this.post(`/pages/${page.id}/move`, { newParentId }).then(this.updaters.pages);
}
rename(page, name) {
return this.post(`/pages/${page.id}/rename`, { name }).then(this.updaters.pages);
}
deletePage(page) {
return this.del(`/pages/${page.id}`).then(this.updaters.pages);
}
scheduledVersionIds(pageId) {
return this.fetch(`/pages/schedules/${pageId}`);
}
scheduleDaily(schedule) {
return this.postJson(`/versions/schedule`, schedule);
}
deleteSchedule(id) {
return super.fetch(`/versions/schedules/delete/${id}`);
}
}
export const pageStore = new PageStore();