adding tags handle

main
HerrHase 2 years ago
parent e380f34c21
commit 6770faf4fe

@ -1,5 +1,5 @@
<potato-close-button>
<button class="button button--icon button--danger button--hover-icon-contrast m-left-4 m-bottom-0" onclick={ (event) => { handleClose(event) } }>
<button class="button button--full button--icon button--danger m-bottom-0" onclick={ (event) => { handleClose(event) } }>
<svg class="icon icon--big" aria-hidden="true">
<use xlink:href="symbol-defs.svg#icon-log-out"></use>
</svg>

@ -1,24 +1,45 @@
<potato-filter>
<div class="filter">
<button class="button button--icon button--hover-icon-contrast m-bottom-0">
<svg class="icon icon--big">
<use xlink:href="symbol-defs.svg#icon-filter" />
</svg>
</button>
<div class="">
<div class="">
</div>
<div class="">
<div class="{ getCssClasses('filter') }">
<div class="display-flex">
<button class="button button--open button--icon button--hover-icon-contrast m-bottom-0" onclick={ (event) => { handleOpen(event) }}>
<svg class="icon icon--big">
<use xlink:href="symbol-defs.svg#icon-filter" />
</svg>
</button>
<button class="button button--close button--icon button--hover-icon-contrast m-bottom-0" onclick={ (event) => { handleOpen(event) }}>
<svg class="icon icon--big">
<use xlink:href="symbol-defs.svg#icon-close" />
</svg>
</button>
<div class="filter__selected m-left-3" if={ state.tags.length > 0 }>
<button if={ tag.selected === true } class="button m-bottom-0 m-right-3" each={ (tag, index) in state.tags } onclick={ (event) => { handleToggle(event, index) }}>
{ tag.name }
<svg class="icon">
<use xlink:href="symbol-defs.svg#icon-close" />
</svg>
</button>
</div>
</div>
<div class="filter__tags">
<button class="button" each={ (tag, index) in state.tags } onclick={ (event) => { handleToggle(event, index) }}>
{ tag.name }
<svg class="icon { tag.selected ? 'hidden' : '' }">
<use xlink:href="symbol-defs.svg#icon-checkbox" />
</svg>
<svg class="icon { tag.selected === undefined ? 'hidden' : '' }">
<use xlink:href="symbol-defs.svg#icon-checkbox-checked" />
</svg>
</button>
</div>
</div>
<script>
import tagsStore from './../stores/tags.js'
import appsStore from './../stores/apps.js'
/**
* close app
*
*
* @author Björn Hase
* @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3
@ -27,7 +48,78 @@
*/
export default {
state: {
tags: [],
selected: [],
isOpen: false
},
/**
*
*
*/
getCssClasses(defaultCssClass) {
const classes = [
defaultCssClass
]
if (this.state.isOpen === true) {
classes.push('filter--open')
}
return classes.join(' ')
},
/**
*
*
*/
onMounted() {
tagsStore.on('ready', (data) => {
this.state.tags = data
this.update()
})
tagsStore.get()
},
/**
* toggle
*
* @param {object} event
* @param {integer} index
*
*/
handleToggle(event, index) {
if (this.state.tags[index].selected === undefined) {
this.state.tags[index].selected = true
this.state.selected.push(this.state.tags[index].name)
} else {
const selectedIndex = this.state.selected.indexOf(this.state.tags[index].name)
// delete selected from tags
delete this.state.tags[index].selected
if (selectedIndex !== -1) {
this.state.selected.splice(selectedIndex, 1)
}
}
appsStore.filter(this.state.selected)
this.update()
},
handleOpen(event) {
if (this.state.isOpen === true) {
this.state.isOpen = false
} else {
this.state.isOpen = true
}
this.update()
}
}
</script>

@ -1,11 +1,11 @@
<potato-sorting>
<div class="filter">
<button class="button button--icon button--hover-icon-contrast m-bottom-0" if={ state.orderBy === 'name' } onclick={ (event) => { handleToggle(event) }}>
<button class="button button--icon button--hover-icon-contrast m-bottom-0" if={ state.column === 'name' } onclick={ (event) => { handleToggle(event) }}>
<svg class="icon icon--big">
<use xlink:href="symbol-defs.svg#icon-text" />
</svg>
</button>
<button class="button button--icon button--hover-icon-contrast m-bottom-0" if={ state.orderBy === 'date_started' } onclick={ (event) => { handleToggle(event) }}>
<button class="button button--icon button--hover-icon-contrast m-bottom-0" if={ state.column === 'date_started' } onclick={ (event) => { handleToggle(event) }}>
<svg class="icon icon--big">
<use xlink:href="symbol-defs.svg#icon-clock" />
</svg>
@ -14,6 +14,8 @@
<script>
import appsStore from './../stores/apps.js'
/**
* sorting of apps
*
@ -24,19 +26,29 @@
*/
export default {
state: {
orderBy: 'name'
column: 'name'
},
/**
* toggle sorting
*
*
* @param {[type]} event
*
*/
handleToggle(event) {
event.preventDefault()
if (this.state.orderBy === 'name') {
this.state.orderBy = 'date_started'
} else if (this.state.orderBy = 'date_started') {
this.state.orderBy = 'name'
if (this.state.column === 'name') {
this.state.column = 'date_started'
} else if (this.state.column === 'date_started') {
this.state.column = 'name'
}
appsStore.sort(this.state.column)
this.update()
}
}

@ -1,4 +1,5 @@
import DatabaseHandler from './databaseHandler.js'
import TagsDatabase from './tags.js'
/**
* apps
@ -11,14 +12,17 @@ import DatabaseHandler from './databaseHandler.js'
class AppsDatabase extends DatabaseHandler {
constructor() {
super()
super('apps')
// add index for apps
// add index for apps to sort by name
this.createIndex([
'name',
'description',
'tags'
])
'name'
], 'name-sort')
// add index for apps to sort by name
this.createIndex([
'date_started'
], 'date-started-sort')
}
/**
@ -28,8 +32,17 @@ class AppsDatabase extends DatabaseHandler {
*
*/
create(data) {
data.date_started = 0
return this.db.post(data)
.then((response) => {
if (data.tags) {
const tagsDatabase = new TagsDatabase()
tagsDatabase.update(data.tags)
}
return this.findOneById(response._id)
}).catch((error) => {
console.error(error)
@ -67,7 +80,8 @@ class AppsDatabase extends DatabaseHandler {
'command',
'description',
'thumbnail',
'tags'
'tags',
'date_started'
],
'selector': {
'_id' : id
@ -91,7 +105,8 @@ class AppsDatabase extends DatabaseHandler {
* @return {mixed}
*
*/
find(sorting = 'name', tags = []) {
find(parameters) {
const query = {
'fields': [
'_id',
@ -102,13 +117,36 @@ class AppsDatabase extends DatabaseHandler {
'thumbnail',
'tags',
'date_started'
],
'selector': {
'name': {
'$exists': true
]
}
// adding sort from parameters
if (parameters.sort) {
query.sort = []
query.sort.push(parameters.sort)
if (parameters.sort === 'date_started') {
query.use_index = '_design/date-started-sort'
query.selector = {
'date_started': {
'$regex': ''
}
}
},
'sort': [ sorting ]
} else {
query.use_index = '_design/name-sort'
query.selector = {
'name': {
'$regex': ''
}
}
}
}
// adding tags from parameters
if (parameters.tags.length > 0) {
query.selector.tags = {
$in: parameters.tags
}
}
return this.db.find(query).then((documents) => {
@ -116,6 +154,10 @@ class AppsDatabase extends DatabaseHandler {
console.warning(documents.warning)
}
if (documents.docs.length > 0 && parameters.tags.length > 0) {
}
return documents.docs
}).catch((error) => {
console.error(error)

@ -16,10 +16,10 @@ class DatabaseHandler {
*
*
*/
constructor() {
constructor(name) {
PouchDB.plugin(PouchDBfind)
this.db = new PouchDB('apps', {
this.db = new PouchDB(name, {
revs_limit: 0
})
}
@ -30,17 +30,22 @@ class DatabaseHandler {
* @param {array} fields
*
*/
createIndex(fields) {
createIndex(fields, name = null) {
// adding index
try {
this.db.createIndex({
const query = {
index: {
fields: fields
}
}).then(() => {
}
if (name) {
query.index.ddoc = name
}
})
this.db.createIndex(query)
} catch (error) {
console.log(error)
}

@ -11,12 +11,12 @@ import DatabaseHandler from './databaseHandler.js'
class TagsDatabase extends DatabaseHandler {
constructor() {
super()
super('tags')
// add index for apps
this.createIndex([
'name'
])
], 'tags')
}
/**
@ -25,7 +25,7 @@ class TagsDatabase extends DatabaseHandler {
* @param {object} data
*
*/
async create(tags) {
async update(tags) {
const query = {
'selector': {
@ -40,9 +40,10 @@ class TagsDatabase extends DatabaseHandler {
// check for existings tags and remove
// adding tags that are not removed
this.db.find(query).then((documents) => {
if (documents.docs && documents.docs.length > 0) {
documents.docs.forEach(data, () => {
if (documents.docs.length > 0) {
documents.docs.forEach((data) => {
// getting
const index = tags.indexOf(data.name)
if (index >= 0) {
@ -53,7 +54,7 @@ class TagsDatabase extends DatabaseHandler {
if (tags.length > 0) {
tags.forEach((tag) => {
await this.db.post({
this.db.post({
'name': tag
})
})
@ -62,61 +63,32 @@ class TagsDatabase extends DatabaseHandler {
}
/**
* find apps
*
*
* @param {object} data
* @return
*
*/
async remove(tags) {
find() {
const query = {
'fields': [
'name'
],
'selector': {
'name': {
'$in': tags
'$exists': true
}
}, 'fields': [
},
'sort': [
'name'
]
}
// check for existings tags and remove
// adding tags that are not removed
this.db.find(query).then((documents) => {
if (documents.docs && documents.docs.length > 0) {
documents.docs.forEach(data, () => {
const index = tags.indexOf(data.name)
if (index >= 0) {
tags.splice(index, 1)
}
})
}
if (tags.length > 0) {
tags.forEach((tag) => {
await this.db.post({
'name': tag
})
})
return this.db.find(query).then((documents) => {
if (documents.warning) {
console.warning(documents.warning)
}
})
}
/**
* find apps
*
* @return {mixed}
*
*/
find() {
const query = {
'fields': [
'name'
]
}
return this.db.find(query).then((documents) => {
return documents.docs
})
}

@ -12,14 +12,29 @@ import observable from '@riotjs/observable'
export default observable({
parameters: {
sort: 'name',
tags: []
},
/**
* getting all apps
*
*/
get() {
const appsDatabase = new AppsDatabase()
appsDatabase.find().then((data) => {
appsDatabase.find(this.parameters).then((data) => {
this.trigger('ready', data)
})
},
/**
* getting single apps
*
* @param {uuid} id
*
*/
getOne(id) {
const appsDatabase = new AppsDatabase()
@ -28,6 +43,12 @@ export default observable({
})
},
/**
* create new app
*
* @param {object} data
*
*/
post(data) {
const appsDatabase = new AppsDatabase()
@ -36,12 +57,40 @@ export default observable({
})
},
/**
* update app
*
* @param {object} data
*
*/
put(data) {
const appsDatabase = new AppsDatabase()
appsDatabase.update(data).then((data) => {
this.trigger('success', data)
})
},
/**
* orderBy and run get
*
* @param {string} orderBy
*
*/
sort(column) {
this.parameters.sort = column
this.get()
},
/**
* filter and run get
*
* @param {array} tags
*
*/
filter(tags) {
this.parameters.tags = tags
this.get()
}
})

@ -1,5 +1,5 @@
/**
* Store for apps
*
*
* @author Björn Hase
* @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3
@ -7,8 +7,20 @@
*
*/
import observable from '@riotjs/observable'
import TagsDatabase from './../database/tags.js'
import observable from '@riotjs/observable'
export default observable({
export default observable({
/**
* getting all apps
*
*/
get() {
const tagsDatabase = new TagsDatabase()
})
tagsDatabase.find().then((data) => {
this.trigger('ready', data)
})
}
})

@ -8,7 +8,7 @@
<potato-filter></potata-filter>
</div>
<div>
<potato-apps-form-button></potato-apps-form-button>
<potato-apps-form-button class="m-right-3"></potato-apps-form-button>
<potato-close-button></potato-close-button>
</div>
</div>

@ -1,3 +1,7 @@
.justify-content-space-between {
justify-content: space-between;
}
.hidden {
display: none;
}

@ -0,0 +1,67 @@
.filter {
&__tags {
visibility: hidden;
position: absolute;
z-index: 100;
margin: 1em 0 0;
.button {
display: block;
margin-right: 1em;
.icon {
vertical-align: sub;
margin: 0 -0.25em 0 0.25em;
}
}
}
&:after {
content: '';
position: fixed;
left: 0;
top:0;
z-index: 99;
visibility: hidden;
width: 100%;
height: 100%;
background-color: #04040480;
}
.button--close {
display: none;
}
&__selected {
.button {
color: white;
padding: 0.8em 1.2em;
background: #878787;
.icon {
fill: white;
margin: 0 -0.25em 0 0.25em
}
}
}
&--open {
&:after {
visibility: visible;
}
.filter__tags {
visibility: visible;
}
.button--close {
display: inline-flex;
z-index: 101;
}
.button--open {
display: none;
}
}
}

@ -10,5 +10,6 @@
'components/field-tags',
'components/loading',
'components/buttons',
'components/filter',
'components/icons';

Loading…
Cancel
Save