Commit 57d34909 authored by Sascha Herzinger's avatar Sascha Herzinger
Browse files

Implemented data filtering

parent 7a93add7
......@@ -3,6 +3,11 @@
"version": "0.1.0",
"lockfileVersion": 1,
"dependencies": {
"@types/jquery": {
"version": "2.0.48",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-2.0.48.tgz",
"integrity": "sha512-nNLzUrVjaRV/Ds1eHZLYTd7IZxs38cwwLSaqMJj8OTXY8xNUbxSK69bi9cMLvQ7dm/IBeQ1wHwQ0S1uYa0rd2w=="
},
"abbrev": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
......@@ -1630,6 +1635,11 @@
"integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
"dev": true
},
"devbridge-autocomplete": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/devbridge-autocomplete/-/devbridge-autocomplete-1.4.2.tgz",
"integrity": "sha512-GIoxYPOnPIh1W1OKBEYW01smHy8sWTTjPKGSXgxrPByyLCx/aJGNxA2JngS/rxV5srU36BKBhDgU9oRupZO84g=="
},
"di": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
......@@ -6305,9 +6315,9 @@
"dev": true
},
"vuex": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-2.3.1.tgz",
"integrity": "sha1-zejpl8H5lXcZvH3qFU+appHZgaY="
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-2.4.0.tgz",
"integrity": "sha512-Jin6dmhB3rMXrNbOZH15F20idQ4F7YH5lTzkxITnooCkKO22nJlsMmDXI45kEiLZ9x7Z7UYlZt8/CFohQmFaHA=="
},
"watchpack": {
"version": "1.3.1",
......
......@@ -28,7 +28,7 @@
"uuid": "^3.1.0",
"vue": "^2.4.2",
"vue-template-compiler": "^2.4.2",
"vuex": "^2.3.1"
"vuex": "^2.4.0"
},
"devDependencies": {
"babel-core": "7.0.0-alpha.3",
......
// inspired by https://vuejsfeed.com/blog/build-a-reusable-autocomplete-component-with-vue-2-1
<template>
<div class="fjs-autocomplete">
<input placeholder="Add Filter..."
v-model="keyword"
@focus="queryItems"
@input="onInput"
@keydown.enter="select"
@keydown.down="moveDown"
@keydown.up="moveUp"
@keydown.esc="onEsc"/>
<ul class="fjs-suggestions" v-show="showSuggestions">
<li class="fjs-suggestion"
:class="{highlight: i === highlightIdx}"
@mouseenter="highlightIdx = i"
@mousedown="select"
v-for="item, i in suggestedItems">
{{ item }}
</li>
</ul>
<ul class="fjs-selections" v-show="selections.length">
<li class="fjs-selection" v-for="selection in selections">
<span class="fjs-clear-selection"@click="unselect(selection)">&#215;</span>{{ selection }}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'autocomplete',
data () {
return {
keyword: '',
highlightIdx: 0,
items: [],
showSuggestions: false,
selections: []
}
},
props: {
itemGetter: {
type: Function,
required: true
},
maxSuggestions: {
type: Number,
required: false,
default: 5
}
},
computed: {
suggestedItems () {
const re = new RegExp(this.keyword, 'i')
return this.items
.filter(item => !~this.selections.indexOf(item) && item.match(re))
.slice(0, this.maxSuggestions)
}
},
methods: {
onInput () {
this.highlightIdx = 0
this.showSuggestions = !!this.keyword
},
onEsc () {
this.showSuggestions = false
this.highlightIdx = 0
},
queryItems () {
if (this.items.length) {
return
}
Promise.resolve(this.itemGetter()).then(items => {
this.items = items
})
},
moveDown () {
if (!this.showSuggestions) {
return
}
this.highlightIdx = (this.highlightIdx + 1) % this.suggestedItems.length
},
moveUp () {
if (!this.showSuggestions) {
return
}
this.highlightIdx = this.highlightIdx - 1 < 0 ? this.suggestedItems.length - 1 : this.highlightIdx - 1
},
select () {
const selection = this.suggestedItems[this.highlightIdx]
this.selections.push(selection)
this.showSuggestions = false
this.keyword = ''
},
unselect (selection) {
this.selections.splice(this.selections.indexOf(selection), 1)
}
},
watch: {
'selections': {
handler: function () {
this.$emit('select', this.selections)
}
}
}
}
</script>
<style lang="sass" scoped>
.fjs-autocomplete
.fjs-suggestions
list-style-type: none
display: flex
flex-direction: column
width: 100%
padding: 1px
overflow: hidden
.fjs-suggestion
font-size: 0.75em
display: inline-block
margin: -1px 0 0 0
width: 95%
flex-wrap: wrap
color: #fff
padding: 0.25vh
border: 1px dotted #fff
cursor: pointer
&.highlight
background-color: #fff
color: #000
.fjs-selections
list-style-type: none
display: flex
flex-direction: column
width: 100%
overflow: hidden
padding: 0
margin: 0.5vh 0 0 0
.fjs-selection
display: inline-block
margin: 0
font-size: 0.75em
width: 95%
flex-wrap: wrap
color: #fff
padding: 0.25vh
.fjs-clear-selection
cursor: pointer
padding: 0 1vh 0 0
font-size: 1.25em
</style>
......@@ -18,6 +18,10 @@
<span class="fjs-reload-btn" @click="reloadData(item.task_id)">&#8635;</span>
<span class="fjs-delete-btn" @click="deleteData(item.task_id)">&#215;</span>
</div>
<autocomplete class="fjs-autocomplete"
v-on:select="updateFilter($event, item.task_id)"
:itemGetter="featureGetter(item.task_id)">
</autocomplete>
<span>{{ item.etl_message }}</span>
</div>
......@@ -29,11 +33,15 @@
<script>
import store from '../../store/store'
import $ from 'jquery'
import 'devbridge-autocomplete'
import Autocomplete from './Autocomplete.vue'
export default {
components: {Autocomplete},
name: 'data-box',
data () {
return {
selectedIDs: []
selectedIDs: [],
featureFilter: {}
}
},
props: {
......@@ -55,7 +63,7 @@
return store.getters.data.filter(item => ~this.dataType.split(',').map(s => s.trim()).indexOf(item.data_type))
},
transformedIDs () {
return this.selectedIDs.map(d => `$${d}$`)
return this.selectedIDs.map(id => `$${JSON.stringify({id, filters: { feature: this.featureFilter[id] }})}$`)
}
},
watch: {
......@@ -84,6 +92,12 @@
this.selectedIDs.push(taskID)
}
},
featureGetter (taskID) {
return async () => {
const metaData = await store.getters.requestManager.getMetaData({taskID})
return metaData.data.meta['features'] || []
}
},
toggleDataEntryBody (taskID) {
const $body = $(this.$el.querySelector(`.fjs-data-entry-body[data-id="${taskID}"]`))
$body.slideToggle(500)
......@@ -93,6 +107,9 @@
},
deleteData (taskID) {
store.getters.requestManager.deleteData({taskID})
},
updateFilter (filter, taskID) {
this.featureFilter[taskID] = filter
}
}
}
......@@ -130,15 +147,20 @@
color: #00ffff
.fjs-data-entry-body
display: none
padding: 1%
padding: 0.25vh 0.25vh 3vh 0.25vh
> span
color: #ff6565
.fjs-action-btns
display: flex
flex-direction: row
justify-content: space-around
border: 1px solid #fff
border-radius: 3px
margin: 0 0 0.5vh 0
span
cursor: pointer
.fjs-autocomplete
text-align: center
@keyframes loadingColorCycle
0%
opacity: 1
......
......@@ -132,6 +132,16 @@
isArray: false
},
data_set: 'denopa.clinical_baseline'
},
{
dictionary: {
name: 'a_SonoRestharn',
projection: 'a_SonoRestharn',
label: 'SonoRestharn',
fieldType: 'Double',
isArray: true
},
data_set: 'denopa.clinical_baseline'
}
])
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment