public/src/js/models/config/collection.js (171 lines of code) (raw):

import ko from 'knockout'; import _ from 'underscore'; import DropTarget from 'models/drop-target'; import persistence from 'models/config/persistence'; import * as vars from 'modules/vars'; import alert from 'utils/alert'; import asObservableProps from 'utils/as-observable-props'; import observableNumeric from 'utils/observable-numeric'; import deepGet from 'utils/deep-get'; import fullTrim from 'utils/full-trim'; import populateObservables from 'utils/populate-observables'; import urlAbsPath from 'utils/url-abs-path'; import isPlatformSpecificCollection from 'utils/platform'; import CONST from 'constants/defaults'; export default class ConfigCollection extends DropTarget { constructor(opts = {}) { super(); this.id = opts.id; const defaults = vars.model.state().defaults; this.parents = ko.observableArray(findParents(opts.id)); this.userVisibilities = CONST.userVisibilities; this.availableTerritories = (defaults && defaults.availableTerritories) ? defaults.availableTerritories : []; this.meta = Object.assign( asObservableProps([ 'displayName', 'href', 'groups', 'type', 'uneditable', 'showTags', 'showSections', 'hideKickers', 'showDateHeader', 'showLatestUpdate', 'showTimestamps', 'excludeFromRss', 'hideShowMore', 'backfill', 'description', 'metadata', 'platform', 'frontsToolSettings', 'userVisibility', 'targetedTerritory' ]), { displayHints: asObservableProps([ 'maxItemsToDisplay', 'suppressImages' ], observableNumeric) }, { frontsToolSettings: asObservableProps([ 'displayEditWarning' ]) }, { groupsConfig: ko.observableArray( opts.groupsConfig !== undefined && Array.isArray(opts.groupsConfig) ? opts.groupsConfig.map((groupConfig) => { return { name: groupConfig.name, maxItems: observableNumeric(groupConfig.maxItems) }; }) : [] )} ); populateObservables(this.meta, opts); this.state = asObservableProps([ 'isOpen', 'isOpenTypePicker', 'underDrag', 'underControlDrag' ]); this.containerThumbnail = ko.pureComputed(() => { var containerId = this.meta.type(); if (/^(fixed|dynamic|flexible|scrollable|static)\//.test(containerId)) { return '/thumbnails/' + containerId + '.svg'; } else { return null; } }); this.subscribeOn(this.meta.type, type => { this.meta.groups(vars.model.typesGroups[type]); const groupsConfig = vars.model.typesGroupsConfig[type]; this.meta.groupsConfig(groupsConfig !== undefined ? groupsConfig() : undefined); }); this.typePicker = this._typePicker.bind(this); this.thisIsPlatformSpecificCollection = isPlatformSpecificCollection(this.meta.platform()); this.thisIsBetaCollection = ko.pureComputed(() => { return isBetaCollection(this.meta.type()); }); } getPlatform() { switch (this.meta.platform()) { case vars.CONST.platforms.app: return 'app only'; case vars.CONST.platforms.web: return 'web only'; default: return 'any'; } } getDisplayName() { const platform = isPlatformSpecificCollection(this.meta.platform()) ? ` (${this.meta.platform()} only)` : ''; return this.meta.displayName() + platform || '(no title)'; } toggleOpen() { this.state.isOpen(!this.state.isOpen()); } toggleOpenTypePicker() { this.state.isOpenTypePicker(!this.state.isOpenTypePicker()); } _typePicker(type) { this.meta.type(type); this.state.isOpenTypePicker(false); } close() { this.state.isOpen(false); } /** IDs of fronts to which the collection belongs */ frontIds() { return _.chain(this.parents()) .map(front => _.result(front, 'id')) .filter(_.identity) .value(); } save(frontEdited) { const potentialErrors = [ {key: 'displayName', errMsg: 'enter a title'}, {key: 'type', errMsg: 'choose a layout'} ]; const errs = _.chain(potentialErrors) .filter(test => !fullTrim(_.result(this.meta, test.key))) .pluck('errMsg') .value(); const priority = vars.getPriority(frontEdited.getPriority()); if (priority.hasGroups && !frontEdited.props.group()) { errs.push('choose a group'); } if (errs.length) { const lastError = errs[errs.length - 1]; const lastErrorJoiner = errs.length > 1 ? ', and ' : ''; errs.splice(errs.length - 1); alert('Oops! You must ' + errs.join(', ') + lastErrorJoiner + lastError + '...'); return; } this.meta.href(urlAbsPath(this.meta.href())); this.state.isOpen(false); persistence.collection.save(this); } updateConfig(opts) { populateObservables(this.meta, opts); this.parents(findParents(this.id)); } get() { return { id: this.id, type: vars.CONST.draggableTypes.configCollection }; } } function findParents (collectionId) { const frontsMap = vars.model.frontsMap(); const state = vars.model.state(); return _.chain(deepGet(state, '.config.fronts')) .map((front, frontId) => { return _.contains(front.collections, collectionId) ? frontsMap[frontId] : null; }) .filter(Boolean) .value(); } function isBetaCollection (collectionId) { return vars.CONST.betaCollectionTypes.includes(collectionId); }