mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 18:11:40 -05:00
decorate categories with active and expanded properties; adapt Categories.getParents to work with store; add category parent resolver; improve mongo-redux; remove duplicate unflatten; add level property to items in unflatten
This commit is contained in:
parent
8bc6aacf85
commit
435cc3555d
7 changed files with 52 additions and 66 deletions
|
@ -5,19 +5,37 @@ import { Button, DropdownButton, MenuItem } from 'react-bootstrap';
|
|||
import { withRouter } from 'react-router'
|
||||
import { LinkContainer } from 'react-router-bootstrap';
|
||||
import Categories from 'meteor/nova:categories';
|
||||
import { withApollo } from 'react-apollo';
|
||||
|
||||
class CategoriesList extends Component {
|
||||
|
||||
render() {
|
||||
|
||||
getNestedCategories() {
|
||||
const categories = this.props.results;
|
||||
|
||||
const currentQuery = _.clone(this.props.router.location.query);
|
||||
delete currentQuery.cat;
|
||||
// check if a category is currently active in the route
|
||||
const currentCategorySlug = this.props.router.location.query && this.props.router.location.query.cat;
|
||||
const currentCategory = Categories.findOneInStore(this.props.client.store, {slug: currentCategorySlug});
|
||||
const parentCategories = Categories.getParents(currentCategory, this.props.client.store);
|
||||
|
||||
// decorate categories with active and expanded properties
|
||||
const categoriesClone = _.map(categories, category => {
|
||||
return {
|
||||
...category, // we don't want to modify the objects we got from props
|
||||
active: currentCategory && category.slug === currentCategory.slug,
|
||||
expanded: parentCategories && _.contains(_.pluck(parentCategories, 'slug'), category.slug)
|
||||
};
|
||||
});
|
||||
|
||||
const categoriesClone = _.map(categories, _.clone); // we don't want to modify the objects we got from props
|
||||
const nestedCategories = Utils.unflatten(categoriesClone, '_id', 'parentId');
|
||||
|
||||
return nestedCategories;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const currentQuery = _.clone(this.props.router.location.query);
|
||||
const nestedCategories = this.getNestedCategories();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DropdownButton
|
||||
|
@ -26,8 +44,8 @@ class CategoriesList extends Component {
|
|||
title={<FormattedMessage id="categories"/>}
|
||||
id="categories-dropdown"
|
||||
>
|
||||
<div className="category-menu-item dropdown-item">
|
||||
<LinkContainer to={{pathname:"/", query: currentQuery}}>
|
||||
<div className="category-menu-item category-menu-item-all dropdown-item">
|
||||
<LinkContainer className="category-menu-item-title" to={{pathname:"/", query: currentQuery}}>
|
||||
<MenuItem eventKey={0}>
|
||||
<FormattedMessage id="categories.all"/>
|
||||
</MenuItem>
|
||||
|
@ -72,4 +90,4 @@ const options = {
|
|||
pollInterval: 0,
|
||||
};
|
||||
|
||||
registerComponent('CategoriesList', CategoriesList, withRouter, [withList, options]);
|
||||
registerComponent('CategoriesList', CategoriesList, withRouter, withApollo, [withList, options]);
|
||||
|
|
|
@ -47,9 +47,9 @@ function categoriesNewGenerateSlug (category) {
|
|||
}
|
||||
addCallback("categories.new.sync", categoriesNewGenerateSlug);
|
||||
|
||||
function categoriesEditGenerateSlug (modifier) {
|
||||
function categoriesEditGenerateSlug (modifier, document) {
|
||||
// if slug is changing
|
||||
if (modifier.$set && modifier.$set.slug) {
|
||||
if (modifier.$set && modifier.$set.slug && modifier.$set.slug !== document.slug) {
|
||||
const slug = modifier.$set.slug;
|
||||
modifier.$set.slug = Utils.getUnusedSlug(Categories, slug);
|
||||
}
|
||||
|
|
|
@ -6,14 +6,15 @@ import { Utils } from 'meteor/nova:core';
|
|||
* @summary Get all of a category's parents
|
||||
* @param {Object} category
|
||||
*/
|
||||
Categories.getParents = function (category) {
|
||||
Categories.getParents = function (category, store) {
|
||||
const categoriesArray = [];
|
||||
|
||||
const getParents = function recurse (category) {
|
||||
const parent = Categories.findOne(category.parentId);
|
||||
if (parent) {
|
||||
categoriesArray.push(parent);
|
||||
recurse(parent);
|
||||
if (category && category.parentId) {
|
||||
const parent = store ? Categories.findOneInStore(store, category.parentId) : Categories.findOne(category.parentId);
|
||||
if (parent) {
|
||||
categoriesArray.push(parent);
|
||||
recurse(parent);
|
||||
}
|
||||
}
|
||||
};
|
||||
getParents(category);
|
||||
|
|
|
@ -7,12 +7,11 @@ const specificResolvers = {
|
|||
return post.categories ? context.Categories.find({_id: {$in: post.categories}}, { fields: context.getViewableFields(context.currentUser, context.Categories) }).fetch() : [];
|
||||
},
|
||||
},
|
||||
// TODO: fix this
|
||||
// Category: {
|
||||
// parent(category, args, context) {
|
||||
// return category.parent ? context.Categories.findOne({_id: category.parent }, { fields: context.getViewableFields(context.currentUser, context.Categories) }) : null;
|
||||
// }
|
||||
// },
|
||||
Category: {
|
||||
parent(category, args, context) {
|
||||
return category.parentId ? context.Categories.findOne({_id: category.parentId }, { fields: context.getViewableFields(context.currentUser, context.Categories) }) : null;
|
||||
}
|
||||
},
|
||||
};
|
||||
GraphQLSchema.addResolvers(specificResolvers);
|
||||
|
||||
|
|
|
@ -5,6 +5,6 @@ Mongo.Collection.prototype.findRedux = function (selector = {}, options = {}) {
|
|||
return this.findInStore(store, selector, options);
|
||||
}
|
||||
|
||||
Mongo.Collection.prototype.findOneRedux = function (_id) {
|
||||
return this.findRedux({_id});
|
||||
Mongo.Collection.prototype.findOneRedux = function (_idOrObject) {
|
||||
return this.findOneInStore(store, _idOrObject);
|
||||
}
|
|
@ -20,6 +20,7 @@ Mongo.Collection.prototype.findInStore = function (store, selector = {}, options
|
|||
return {fetch: () => sortedDocs};
|
||||
}
|
||||
|
||||
Mongo.Collection.prototype.findOneInStore = function (store, _id) {
|
||||
return this.findInStore(store, {_id}).fetch();
|
||||
Mongo.Collection.prototype.findOneInStore = function (store, _idOrObject) {
|
||||
const docs = typeof _idOrObject === 'string' ? this.findInStore(store, {_id: _idOrObject}).fetch() : this.findInStore(store, _idOrObject).fetch();
|
||||
return docs.length === 0 ? undefined: docs[0];
|
||||
}
|
|
@ -266,42 +266,6 @@ _.mixin({
|
|||
}
|
||||
});
|
||||
|
||||
// adapted from http://stackoverflow.com/a/22072374/649299
|
||||
Utils.unflatten = function( array, idProperty, parentIdProperty, parent, tree ){
|
||||
|
||||
tree = typeof tree !== "undefined" ? tree : [];
|
||||
|
||||
let children = [];
|
||||
|
||||
if (typeof parent === "undefined") {
|
||||
// if there is no parent, we're at the root level
|
||||
// so we return all root nodes (i.e. nodes with no parent)
|
||||
children = _.filter( array, node => !node[parentIdProperty]);
|
||||
} else {
|
||||
// if there *is* a parent, we return all its child nodes
|
||||
// (i.e. nodes whose parentId is equal to the parent's id.)
|
||||
children = _.filter( array, node => node[parentIdProperty] === parent[idProperty]);
|
||||
}
|
||||
|
||||
// if we found children, we keep on iterating
|
||||
if (!!children.length) {
|
||||
|
||||
if (typeof parent === "undefined") {
|
||||
// if we're at the root, then the tree consist of all root nodes
|
||||
tree = children;
|
||||
} else {
|
||||
// else, we add the children to the parent as the "childrenResults" property
|
||||
parent.childrenResults = children;
|
||||
}
|
||||
|
||||
// we call the function on each child
|
||||
children.forEach(child => {
|
||||
Utils.unflatten(array, idProperty, parentIdProperty, child);
|
||||
});
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
Utils.getFieldLabel = (fieldName, collection) => {
|
||||
const label = collection.simpleSchema()._schema[fieldName].label;
|
||||
|
@ -344,7 +308,9 @@ Utils.findIndex = (array, predicate) => {
|
|||
}
|
||||
|
||||
// adapted from http://stackoverflow.com/a/22072374/649299
|
||||
Utils.unflatten = function( array, idProperty, parentIdProperty, parent, tree ){
|
||||
Utils.unflatten = function(array, idProperty, parentIdProperty, parent, level=0, tree){
|
||||
|
||||
level++;
|
||||
|
||||
tree = typeof tree !== "undefined" ? tree : [];
|
||||
|
||||
|
@ -353,11 +319,11 @@ Utils.unflatten = function( array, idProperty, parentIdProperty, parent, tree ){
|
|||
if (typeof parent === "undefined") {
|
||||
// if there is no parent, we're at the root level
|
||||
// so we return all root nodes (i.e. nodes with no parent)
|
||||
children = _.filter( array, node => !node[parentIdProperty]);
|
||||
children = _.filter(array, node => !node[parentIdProperty]);
|
||||
} else {
|
||||
// if there *is* a parent, we return all its child nodes
|
||||
// (i.e. nodes whose parentId is equal to the parent's id.)
|
||||
children = _.filter( array, node => node[parentIdProperty] === parent[idProperty]);
|
||||
children = _.filter(array, node => node[parentIdProperty] === parent[idProperty]);
|
||||
}
|
||||
|
||||
// if we found children, we keep on iterating
|
||||
|
@ -373,7 +339,8 @@ Utils.unflatten = function( array, idProperty, parentIdProperty, parent, tree ){
|
|||
|
||||
// we call the function on each child
|
||||
children.forEach(child => {
|
||||
Utils.unflatten(array, idProperty, parentIdProperty, child);
|
||||
child.level = level;
|
||||
Utils.unflatten(array, idProperty, parentIdProperty, child, level);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue