Skip to content
This repository has been archived by the owner on Jan 20, 2023. It is now read-only.

Commit

Permalink
#1: added ml-facet-tree
Browse files Browse the repository at this point in the history
  • Loading branch information
grtjn committed Feb 3, 2020
1 parent 1d78827 commit 29b541a
Show file tree
Hide file tree
Showing 9 changed files with 8,451 additions and 5,233 deletions.
1,048 changes: 838 additions & 210 deletions dist/grove-vue-core-components.esm.js

Large diffs are not rendered by default.

1,050 changes: 839 additions & 211 deletions dist/grove-vue-core-components.min.js

Large diffs are not rendered by default.

1,056 changes: 842 additions & 214 deletions dist/grove-vue-core-components.umd.js

Large diffs are not rendered by default.

10,148 changes: 5,569 additions & 4,579 deletions package-lock.json

Large diffs are not rendered by default.

41 changes: 23 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@marklogic-community/grove-vue-core-components",
"version": "0.1.0",
"version": "0.2.0",
"description": "Grove Vue UI core components",
"main": "dist/grove-vue-core-components.umd.js",
"module": "dist/grove-vue-core-components.esm.js",
Expand Down Expand Up @@ -35,30 +35,35 @@
"url": "https://github.com/marklogic-community/grove-vue-core-components/issues"
},
"devDependencies": {
"@babel/core": "^7.3.4",
"@vue/cli-plugin-eslint": "^3.4.1",
"@vue/cli-plugin-pwa": "^3.4.1",
"@vue/cli-plugin-unit-jest": "^3.5.3",
"@vue/cli-service": "^3.5.3",
"@vue/eslint-config-prettier": "^4.0.1",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-jest": "^24.1.0",
"@babel/core": "^7.8.4",
"@vue/cli-plugin-eslint": "^4.1.2",
"@vue/cli-plugin-pwa": "^4.1.2",
"@vue/cli-plugin-unit-jest": "^4.1.2",
"@vue/cli-service": "^4.1.2",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "^1.0.0-beta.31",
"babel-jest": "^25.1.0",
"babel-preset-env": "^1.7.0",
"canvas": "^2.3.1",
"canvas": "^2.6.1",
"eslint": "^6.8.0",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-vue": "^6.1.2",
"jest-environment-jsdom-thirteen": "^1.0.0",
"jsdom": "^13.2.0",
"less": "^3.9.0",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"rollup": "^1.4.0",
"rollup-plugin-buble": "^0.19.6",
"rollup-plugin-commonjs": "^10.0.0",
"rollup-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.6.7"
"prettier": "^1.19.1",
"rollup": "^1.31.0",
"rollup-plugin-buble": "^0.19.8",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-vue": "^5.1.6",
"vue-multiselect": "^2.1.6",
"vue-template-compiler": "^2.6.11"
},
"peerDependencies": {},
"dependencies": {
"es6-promise": "^4.2.6",
"es6-promise": "^4.2.8",
"isomorphic-fetch": "^2.2.1",
"vue": "^2.6.7"
"vue": "^2.6.11"
}
}
9 changes: 9 additions & 0 deletions src/components/ml-tree-facet/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

import mlTreeFacet from './ml-tree-facet.vue';
import mlSubTree from './ml-sub-tree.vue';

export default {
mlTreeFacet,
mlSubTree
};
98 changes: 98 additions & 0 deletions src/components/ml-tree-facet/ml-sub-tree.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<template>
<ul class="ml-sub-tree">
<li v-for="(id, $index) in nonEmptystartIds" :key="$index" :id="id">
<div :class="nodes[id].highlight ? 'ml-tree-highlight' : ''">
<a
href
v-if="
nodes[id].children.length &&
(showEmpty || nodes[id].sum > (nodes[id].value || 0))
"
v-on:click.prevent="toggle(id)"
>
<i class="fa fa-chevron-right" v-show="collapsed[id]"></i>
<i class="fa fa-chevron-down" v-show="!collapsed[id]"></i>
</a>
<a href v-on:click.prevent="onClick(nodes[id])">{{
nodes[id].label
}}</a>
<a href v-on:click.prevent="onClick(nodes[id], true)"
><i class="fa fa-remove"></i
></a>
<span v-show="nodes[id].value"> ({{ nodes[id].value }})</span>
<span v-show="nodes[id].sum > (nodes[id].value || 0)">
[{{ nodes[id].sum }}]</span
>
</div>
<div v-if="!collapsed[id] && nodes[id].children.length">
<ml-sub-tree
:nodes="nodes"
:start-ids="nodes[id].children"
:on-click="onClick"
:show-empty="showEmpty"
></ml-sub-tree>
</div>
</li>
</ul>
</template>

<script>
export default {
name: 'ml-sub-tree',
components: {},
data() {
return {
collapsed: {},
console: console
};
},
props: {
nodes: {
type: Object,
required: true
},
startIds: {
type: Array,
required: true
},
onClick: {
type: Function,
default: function() {}
},
showEmpty: {
type: Boolean,
default: false
}
},
computed: {
nonEmptystartIds() {
if (this.showEmpty) {
return this.startIds.filter(id => {
const node = this.nodes[id];
return node !== undefined;
});
} else {
return this.startIds.filter(id => {
const node = this.nodes[id];
return node && node.sum > 0;
});
}
}
},
methods: {
toggle(id) {
this.$set(this.collapsed, id, !this.collapsed[id]);
}
}
};
</script>

<style lang="less" scoped>
ul.ml-sub-tree {
list-style: none;
.ml-tree-highlight {
background-color: lightyellow;
}
}
</style>
229 changes: 229 additions & 0 deletions src/components/ml-tree-facet/ml-tree-facet.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
<template>
<div
class="ml-facet ml-tree-facet"
v-if="startIds.length"
v-show="!facet.hide"
>
<h3 v-on:click.prevent="showHideFacet()">
{{ facet.name | capitalize }}
<div class="pull-right">
<i class="fa fa-caret-right" v-if="!facetOpen"></i>
<i class="fa fa-caret-down" v-if="!!facetOpen"></i>
</div>
</h3>
<div v-if="facetOpen">
<form v-if="showSearch" v-on:submit.prevent="highlightNodes()">
<span>
Search:
<!--input v-model="searchNode" autocomplete="off" uib-typeahead="suggestion for suggestion in suggestionsList | filter:$viewValue | limitTo:20" placeholder="in the tree below"-->
<multiselect
:value="searchNode"
:options="suggestionsList"
:multiple="false"
:searchable="true"
:clear-on-select="false"
placeholder="in the tree below"
open-direction="bottom"
v-on:select="highlightNodes"
>
</multiselect>
</span>
<div>
Show empty nodes
<input type="checkbox" v-model="showEmpty_" />
</div>
</form>

<ml-sub-tree
:nodes="nodes_"
:start-ids="startIds"
:on-click="onClick"
:show-empty="showEmpty_"
></ml-sub-tree>
</div>
</div>
</template>

<script>
import Multiselect from 'vue-multiselect';
import mlSubTree from './ml-sub-tree.vue';
import 'vue-multiselect/dist/vue-multiselect.min.css';
export default {
name: 'ml-tree-facet',
components: {
Multiselect,
mlSubTree
},
props: {
facet: {
type: Object,
required: true
},
nodes: {
type: Object,
required: true
},
startIds: {
type: Array,
required: true
},
toggle: {
type: Function,
default: function() {}
},
negate: {
type: Function,
default: function() {}
},
showSearch: {
type: Boolean,
default: true
},
showEmpty: {
type: Boolean,
default: false
}
},
data() {
return {
searchNode: '',
suggestionsList: [],
showEmpty_: false,
nodes_: {},
facetOpen: true
};
},
methods: {
showHideFacet() {
this.facetOpen = !this.facetOpen;
},
onClick(node, negate) {
if (negate) {
this.negate(this.facet.name, this.facet.type, node.id, node.label);
} else {
this.toggle(this.facet.name, this.facet.type, node.id, node.label);
}
},
calculateSums(nodes, startIds) {
var self = this;
var totalSum = 0;
startIds.forEach(function(id) {
var node = nodes[id];
var sum = node.children ? self.calculateSums(nodes, node.children) : 0;
sum = sum + (node.value || 0);
node.sum = sum;
totalSum += sum;
});
return totalSum;
},
updateSuggestions(nodes) {
var self = this;
self.suggestionsList = [];
Object.keys(nodes).forEach(id => {
const node = nodes[id];
if (node.sum > 0) {
if (node.label) {
self.suggestionsList.push(node.label);
}
if (node.altLabels) {
node.altLabels.forEach(function(label) {
self.suggestionsList.push(label);
});
}
}
});
self.suggestionsList.sort();
},
highlightNodes(selected) {
var self = this;
this.searchNode = selected !== undefined ? selected : this.searchNode;
var noMatch = {
test: function() {
return false;
}
};
var _highlightNodes = function(match, startIds) {
var totalHit = false;
startIds.forEach(function(id) {
var node = self.nodes_[id];
var hit = node.children
? _highlightNodes(match, node.children)
: false;
if (!hit) {
hit = node.label && match.test(node.label);
}
if (!hit) {
hit =
node.altLabels &&
node.altLabels.filter(function(label) {
return match.test(label);
}).length;
}
if (hit) {
self.$set(node, 'highlight', true);
totalHit = true;
} else {
self.$set(node, 'highlight', false);
}
});
return totalHit;
};
if (this.searchNode) {
var match = new RegExp('' + this.searchNode, 'i');
_highlightNodes(match, this.startIds);
} else {
_highlightNodes(noMatch, this.startIds);
}
},
init() {
if (this.facet !== undefined && Object.keys(this.nodes).length) {
var nodes = JSON.parse(JSON.stringify(this.nodes));
this.facet.facetValues.forEach(facetValue => {
nodes[facetValue.value].value = facetValue.count;
});
this.calculateSums(nodes, this.startIds);
this.updateSuggestions(nodes);
this.nodes_ = nodes;
}
}
},
created() {
this.init();
},
watch: {
showEmpty(newEmpty) {
if (newEmpty !== undefined) {
this.showEmpty_ = newEmpty;
}
},
facet() {
this.init();
},
nodes() {
this.init();
}
}
};
</script>

<style lang="less" scoped>
.ml-facet {
.facet-add-pos,
.facet-add-neg {
visibility: hidden;
}
span:hover > .facet-add-pos,
div:hover > .facet-add-neg {
visibility: visible !important;
}
form {
padding-bottom: 0;
}
}
</style>
Loading

0 comments on commit 29b541a

Please sign in to comment.