Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandermendes committed Jul 20, 2018
2 parents c495b30 + 38d19cd commit 6c68366
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 6 deletions.
86 changes: 82 additions & 4 deletions components/infiniteload/Annotations.vue
Expand Up @@ -15,7 +15,16 @@
</template>

<script>
import uniqBy from 'lodash/uniqBy'
import Fuse from 'fuse.js'
export default {
data () {
return {
items: []
}
},
props: {
value: {
type: Array,
Expand All @@ -32,6 +41,14 @@ export default {
noMoreResults: {
type: String,
default: 'No more results'
},
searchString: {
type: String,
default: ''
},
searchKeys: {
type: Array,
default: () => ([])
}
},
Expand All @@ -43,26 +60,50 @@ export default {
*/
async infiniteLoadAnnotations ($state) {
let response = null
const limit = 20
try {
response = await this.$explicates.search({
collection: this.containerIri,
limit: 20,
offset: this.value.length
limit: limit,
offset: this.items.length
})
} catch (err) {
this.$nuxt.error(err)
}
if (!response.data.hasOwnProperty('first')) {
if (response.data.hasOwnProperty('first')) {
this.items = uniqBy(this.items.concat(response.data.first.items), 'id')
}
if (
!response.data.hasOwnProperty('first') ||
response.data.first.items.length < limit
) {
$state.complete()
this.$emit('complete')
return
}
this.$emit('input', this.value.concat(response.data.first.items))
$state.loaded()
},
/**
* Apply fuzzy search.
* @param {Array} items
* The items to search.
*/
search (items) {
if (
this.searchKeys &&
this.searchString &&
this.searchKeys.length &&
this.searchString.length
) {
return this.fuse.search(this.searchString)
}
return items
},
/**
* Reset the loaded items.
*/
Expand All @@ -83,6 +124,43 @@ export default {
this.$refs.infiniteload.attemptLoad()
}
})
},
/**
* Emit the loaded and possibly filtered items.
*/
emitItems () {
const filteredItems = this.search(this.items)
this.$emit('input', filteredItems)
}
},
computed: {
fuse () {
return new Fuse(this.items, {
shouldSort: true,
tokenize: true,
matchAllTokens: true,
findAllMatches: true,
threshold: 0,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: this.searchKeys
})
}
},
watch: {
searchKeys () {
this.emitItems()
},
searchString () {
this.emitItems()
},
items () {
this.emitItems()
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions layouts/admin-collection-dashboard.vue
Expand Up @@ -100,6 +100,15 @@ export default {
}
}
},
{
label: 'Item Tags',
link: {
name: 'admin-collection-short_name-tags',
params: {
short_name: this.currentCollection.short_name
}
}
},
{
label: 'Project Filters',
link: {
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "libcrowds",
"version": "1.0.0",
"version": "1.1.0",
"description": "A Vue.js frontend for PYBOSSA.",
"author": "Alex Mendes <alexanderhmendes@gmail.com>",
"private": true,
Expand Down
140 changes: 140 additions & 0 deletions pages/admin/collection/_short_name/tags.vue
@@ -0,0 +1,140 @@
<template>
<card-base
:title="title"
:description="description"
docs="/collections/tags/">

<p slot="guidance">
Use the table below to delete tags. Note that the same word may be used
to tag multiple items and therefore could appear multiple times in the
table below, you can use the search button above to filter the
table.
</p>

<b-form slot="controls" :class="darkMode ? 'form-dark' : null">
<b-form-input
v-model="searchString"
class="search-control"
size="sm"
placeholder="Type to search">
</b-form-input>
</b-form>

<b-table
responsive
striped
hover
show-empty
:dark="darkMode"
:items="tagAnnotations"
:fields="tableFields">
<template slot="action" slot-scope="row">
<b-btn
variant="warning"
size="sm"
@click="deleteTag(row.item)">
Delete
</b-btn>
</template>
</b-table>

<infinite-load-annotations
ref="infiniteload"
v-if="hasTagAnnotations"
v-model="tagAnnotations"
:search-keys="searchKeys"
:search-string="searchString"
:container-iri="currentCollection.info.annotations.tags"
no-results="It looks like nothing has been tagged yet!"
no-more-results="">
</infinite-load-annotations>

</card-base>
</template>

<script>
import { fetchCollectionByName } from '@/mixins/fetchCollectionByName'
import { metaTags } from '@/mixins/metaTags'
import InfiniteLoadAnnotations from '@/components/infiniteload/Annotations'
import CardBase from '@/components/cards/Base'
export default {
layout: 'admin-collection-dashboard',
mixins: [ fetchCollectionByName, metaTags ],
data () {
return {
title: 'Item Tags',
description: 'Manage item tags for the collection microsite.',
tagAnnotations: [],
tableFields: {
'body.value': {
label: 'Name'
},
action: {
label: 'Action',
class: 'text-center'
}
},
searchKeys: [
'body.value'
],
searchString: ''
}
},
components: {
CardBase,
InfiniteLoadAnnotations
},
computed: {
currentCollection () {
return this.$store.state.currentCollection
},
hasTagAnnotations () {
return this.currentCollection.info.annotations.hasOwnProperty('tags')
}
},
methods: {
/**
* Delete a tag.
* @param {Object}
* The tag.
*/
deleteTag (tag) {
this.$swal({
title: `Confirm`,
html: `This tag will be removed permanently.<br><br>
Are you sure you want to continue?`,
type: 'question',
showCancelButton: true,
reverseButtons: true,
showLoaderOnConfirm: true,
preConfirm: () => {
return this.$axios.$delete(tag.id)
}
}).then(r => {
this.reset()
this.$notifications.success({
message: 'Tag deleted'
})
}).catch(err => {
if (typeof err === 'object' && err.hasOwnProperty('dismiss')) {
this.$notifications.error({ message: err.message })
}
})
},
/**
* Reset the loaded items.
*/
reset () {
this.$refs.infiniteload.reset()
}
}
}
</script>

0 comments on commit 6c68366

Please sign in to comment.