adding a few fixes and new logic for tags

release-neutralino
HerrHase 2 years ago
parent 5d24497a5d
commit 24be1e9f6a

@ -72,6 +72,7 @@ class Connector {
// if event is in handlers-object mapped call it // if event is in handlers-object mapped call it
if (this.handlers.hasOwnProperty(message.event)) { if (this.handlers.hasOwnProperty(message.event)) {
console.log(event.data)
this.handlers[message.event].call(null, this, message.data) this.handlers[message.event].call(null, this, message.data)
} }
} }

@ -38,7 +38,25 @@ class AppsHandler {
appsStore.update(data) appsStore.update(data)
.then((data) => { .then((data) => {
connector.send('pouchdb.apps.success', data) connector.send('pouchdb.apps.readyOne', data)
})
}
/**
* use update in appStore and send event with result to app
*
* @param {object} data
* @return {object}
*
*/
findOne(connector, data) {
const appsStore = new AppsStore()
appsStore.findOneById(data.id)
.then((data) => {
if (data) {
connector.send('pouchdb.apps.readyOne', data)
}
}) })
} }

@ -9,6 +9,8 @@ const appsHandler = new AppsHandler
// create connector and add handlers for events // create connector and add handlers for events
const connector = new Connector({ const connector = new Connector({
'pouchdb.apps.create': appsHandler.create, 'pouchdb.apps.create': appsHandler.create,
'pouchdb.apps.update': appsHandler.update,
'pouchdb.apps.findOne': appsHandler.findOne,
'pouchdb.apps.find': appsHandler.find 'pouchdb.apps.find': appsHandler.find
}) })

@ -1,5 +1,5 @@
{ {
"name": "database", "private": true,
"version": "1.0.0", "version": "1.0.0",
"main": "index.js", "main": "index.js",
"license": "MIT", "license": "MIT",

@ -8,7 +8,18 @@ import PouchdbHandler from './pouchdbHandler.js'
* @link https://gitea.node001.net/HerrHase/tellme-bot.git * @link https://gitea.node001.net/HerrHase/tellme-bot.git
* *
*/ */
class AppsDatabase extends PouchdbHandler { class AppsStore extends PouchdbHandler {
constructor() {
super()
// add index for apps
this.createIndex([
'name',
'description',
'tags'
])
}
/** /**
* *
@ -17,12 +28,11 @@ class AppsDatabase extends PouchdbHandler {
* *
*/ */
create(data) { create(data) {
data['type'] = 'apps'
return this.db.post(data) return this.db.post(data)
.then((response) => { .then((response) => {
console.log(response)
return response return response
}).catch((error) => {
console.log(error)
}) })
} }
@ -35,8 +45,15 @@ class AppsDatabase extends PouchdbHandler {
*/ */
findOneById(id) { findOneById(id) {
const query = { const query = {
'fields': [
'_id',
'name',
'command',
'description',
'thumbnail',
'tags'
],
'selector': { 'selector': {
'type': 'apps',
'_id' : id '_id' : id
} }
} }
@ -47,6 +64,8 @@ class AppsDatabase extends PouchdbHandler {
} else { } else {
return documents.docs[0] return documents.docs[0]
} }
}).catch((error) => {
console.log(error)
}) })
} }
@ -58,16 +77,33 @@ class AppsDatabase extends PouchdbHandler {
*/ */
find() { find() {
const query = { const query = {
'fields': [
'_id',
'name',
'command',
'description',
'thumbnail',
'tags',
'started_date'
],
'selector': { 'selector': {
'type': 'apps' 'name': {
'$exists': true
}
} }
} }
return this.db.find(query).then((documents) => { return this.db.find(query).then((documents) => {
if (documents.warning) {
console.log(documents.warning)
}
return documents.docs return documents.docs
}).catch((error) => {
console.log(error)
}) })
} }
} }
export default AppsDatabase export default AppsStore

@ -2,11 +2,11 @@ import PouchDB from 'pouchdb'
import PouchDBfind from 'pouchdb-find' import PouchDBfind from 'pouchdb-find'
/** /**
* PouchdbHandler * PouchdbHandler, for create
* *
* @author Björn Hase, me@herr-hase.wtf * @author Björn Hase
* @license http://opensource.org/licenses/MIT The MIT License * @license https://www.gnu.org/licenses/gpl-3.0.en.html GPL-3
* @link https://gitea.node001.net/HerrHase/super-hog * @link https://gitea.node001.net/HerrHase/potato-launcher.git
* *
*/ */
@ -22,14 +22,15 @@ class PouchdbHandler {
this.db = new PouchDB('.storage/pouchdb/apps', { this.db = new PouchDB('.storage/pouchdb/apps', {
revs_limit: 0 revs_limit: 0
}) })
}
// create fields for index /**
const fields = [ * adding index for current class
'type', *
'name', * @param {array} fields
'description', *
'tags' */
] createIndex(fields) {
// adding index // adding index
try { try {
@ -41,8 +42,9 @@ class PouchdbHandler {
}) })
} catch (error) { } catch (error) {
console.log(error); console.log(error)
} }
} }
} }

@ -0,0 +1,126 @@
import PouchdbHandler from './pouchdbHandler.js'
/**
* apps
*
* @author Björn Hase
* @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3
* @link https://gitea.node001.net/HerrHase/tellme-bot.git
*
*/
class TagsDatabase extends PouchdbHandler {
constructor() {
super()
// add index for apps
this.createIndex([
'name'
])
}
/**
*
*
* @param {object} data
*
*/
async create(tags) {
const query = {
'selector': {
'name': {
'$in': tags
}
}, 'fields': [
'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
})
})
}
})
}
/**
*
*
* @param {object} data
*
*/
async remove(tags) {
const query = {
'selector': {
'name': {
'$in': tags
}
}, 'fields': [
'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
})
})
}
})
}
/**
* find apps
*
* @return {mixed}
*
*/
find() {
const query = {
'fields': [
'name'
]
}
return this.db.find(query).then((documents) => {
return documents.docs
})
}
}
export default AppsDatabase

@ -24,7 +24,7 @@
], ],
"modes": { "modes": {
"window": { "window": {
"title": "shiny-dashboard", "title": "Potato Launcher",
"fullScreen": false, "fullScreen": false,
"alwaysOnTop": false, "alwaysOnTop": false,
"icon": "/resources/icons/appIcon.png", "icon": "/resources/icons/appIcon.png",
@ -37,7 +37,7 @@
} }
}, },
"cli": { "cli": {
"binaryName": "shiny-dashboard", "binaryName": "potato-launcher",
"resourcesPath": "/build/", "resourcesPath": "/build/",
"extensionsPath": "/extensions/", "extensionsPath": "/extensions/",
"clientLibrary": "/resources/js/neutralino.js", "clientLibrary": "/resources/js/neutralino.js",
@ -46,7 +46,7 @@
}, },
"extensions": [ "extensions": [
{ {
"id": "js.neutralino.database", "id": "js.neutralino.pouchdb",
"command": "node ${NL_PATH}/extensions/pouchdb/index.js" "command": "node ${NL_PATH}/extensions/pouchdb/index.js"
} }
] ]

@ -9,6 +9,7 @@
<div class="potato-main"> <div class="potato-main">
<div class="container-full p-top-4"> <div class="container-full p-top-4">
<potato-apps-view></potato-apps-view> <potato-apps-view></potato-apps-view>
<tiny-notification></tiny-notification>
</div> </div>
</div> </div>

@ -3,6 +3,7 @@ import * as riot from 'riot'
import TinyLoading from '@tiny-components/loading/src/loading.riot' import TinyLoading from '@tiny-components/loading/src/loading.riot'
import TinySidebarFormHeader from './forms/header.riot' import TinySidebarFormHeader from './forms/header.riot'
import TinySidebarFormFooter from './forms/footer.riot' import TinySidebarFormFooter from './forms/footer.riot'
import TinyNotification from '@tiny-components/notification/src/notification.riot'
import FieldError from '@tiny-components/validator/src/fieldError.riot' import FieldError from '@tiny-components/validator/src/fieldError.riot'
@ -16,18 +17,46 @@ riot.register('field-error', FieldError)
riot.register('tiny-loading', TinyLoading) riot.register('tiny-loading', TinyLoading)
riot.register('tiny-sidebar-form-header', TinySidebarFormHeader) riot.register('tiny-sidebar-form-header', TinySidebarFormHeader)
riot.register('tiny-sidebar-form-footer', TinySidebarFormFooter) riot.register('tiny-sidebar-form-footer', TinySidebarFormFooter)
riot.register('tiny-notification', TinyNotification)
riot.register('potato-field-tags', potatoFieldTags) riot.register('potato-field-tags', potatoFieldTags)
riot.register('potato-apps-view', potatoAppsView) riot.register('potato-apps-view', potatoAppsView)
riot.register('potato-close-button', potatoCloseButton) riot.register('potato-close-button', potatoCloseButton)
// adding events for Neutralino // adding events for Neutralino
Neutralino.events.on('ready', () => { Neutralino.events.on('ready', async () => {
// @TODO thats mad, it is only a workaround, don't judge me, i will do better
// its no possible to create a hole path, solving this with array and a recursive function
try {
const result = await Neutralino.filesystem.getStats('./.storage')
if (result) {
try {
await Neutralino.filesystem.createDirectory('./.storage/pouchdb')
} catch(error) {
}
}
} catch(error) {
if (error.code === 'NE_FS_NOPATHE') {
try {
await Neutralino.filesystem.createDirectory('./.storage')
await Neutralino.filesystem.createDirectory('./.storage/pouchdb')
} catch(error) {
}
}
}
riot.mount('potato-apps-view') riot.mount('potato-apps-view')
riot.mount('tiny-notification')
}) })
// let it rain // let it rain
Neutralino.init() Neutralino.init()
// workaround to prevent a stack overflow
window._arrayBufferToBase64 = function _arrayBufferToBase64(buffer) { window._arrayBufferToBase64 = function _arrayBufferToBase64(buffer) {
var binary = ''; var binary = '';

@ -1,5 +1,5 @@
<potato-apps-form-button> <potato-apps-form-button>
<button class="button button--icon m-bottom-0" onclick={ (event) => { handleClick(event) } }> <button class="button button--icon button--hover-icon-contrast m-bottom-0" onclick={ (event) => { handleClick(event) } }>
<svg class="icon icon--big" aria-hidden="true"> <svg class="icon icon--big" aria-hidden="true">
<use xlink:href="symbol-defs.svg#icon-add"></use> <use xlink:href="symbol-defs.svg#icon-add"></use>
</svg> </svg>
@ -11,7 +11,7 @@
import formStore from './../stores/form.js' import formStore from './../stores/form.js'
/** /**
* open sidebar form * open sidebar form
* *
* @author Björn Hase * @author Björn Hase
* @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3 * @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3

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

@ -1,35 +1,40 @@
<potato-field-tags> <potato-field-tags>
<div class="field-tags"> <div class="field-tags">
<select name="{ state.options.name }[]" multiple style="display: none;"> <select name="{ state.options.name }[]" multiple style="display: none;">
<option each={ tag in state.tags } value={ tag }></option> <option each={ tag in state.tags } value={ tag }></option>
</select> </select>
<ul class="field-tags__list">
<label class="field-label">
<div class="field-input-group">
<input class="field-text" type="text" onkeypress={ handleKeyup } />
<button class="button button--add m-bottom-0 button--hover-icon-contrast" type="button" onclick={ () => { handleAdd() }}>
<svg class="icon"><use xlink:href="symbol-defs.svg#icon-add" /></svg>
</button>
</div>
</label>
<ul class="field-tags__list m-top-4 m-bottom-0" if={ state.tags.length > 0 }>
<li class="badge field-tags__item field-tags__item--active" each={ tag in state.tags }> <li class="badge field-tags__item field-tags__item--active" each={ tag in state.tags }>
<span class="field-tags__label">{ tag }</span> <span class="field-tags__label">{ tag }</span>
<button class="button m-bottom-0" type="button" onclick={ () => { handleRemove(tag) } }> <button class="button m-bottom-0 button--hover-icon-contrast" type="button" onclick={ () => { handleRemove(tag) } }>
<svg class="icon"><use xlink:href="symbol-defs.svg#icon-remove" /></svg> <svg class="icon"><use xlink:href="symbol-defs.svg#icon-remove" /></svg>
</button> </button>
</li> </li>
<li class="field-tags__item field-tags__item--add">
<div class="field-input-group">
<input class="field-text" type="text" onkeypress={ handleKeyup } />
<button class="button m-bottom-0" type="button" onclick={ handleAdd }>
<svg class="icon"><use xlink:href="symbol-defs.svg#icon-add" /></svg>
</button>
</div>
<div if={ state.errors && state.errors.length > 0 } class="field-error">
<ul>
<li each={ error in state.errors }>
{ error }
</li>
</ul>
</div>
</li>
</ul> </ul>
<div if={ state.errors && state.errors.length > 0 } class="field-error">
<ul>
<li each={ error in state.errors }>
{ error }
</li>
</ul>
</div>
</div> </div>
<script> <script>
import * as riot from 'riot' import * as riot from 'riot'
import tagsStore from './../../stores/tags.js'
/** /**
* component field adding / remove tags for a form * component field adding / remove tags for a form
@ -46,7 +51,6 @@
{ {
options: { options: {
name: 'tags', name: 'tags',
separator: ','
}, },
tags: [ ], tags: [ ],
errors: [ ] errors: [ ]
@ -58,23 +62,26 @@
*/ */
onBeforeMount() onBeforeMount()
{ {
if (this.props.options) {
this.state.options = Object.assign(this.state.options, this.props.options)
}
},
// if props.tags is set and it is not a array, split it with a /**
// separator and add to tags *
if (this.props.tags) { *
*/
let tags = this.props.tags onMounted() {
tagsStore.on('update', (data) => {
if (!Array.isArray(tags)) { // if no data is send, reset array
tags = tags.split(this.state.options.separator) if (!data) {
data = []
} }
this.state.tags = tags; this.state.tags = data
} this.update()
})
if (this.props.options) {
this.state.options = Object.assign(this.state.options, this.props.options)
}
}, },
/** /**
@ -90,7 +97,7 @@
event.preventDefault() event.preventDefault()
// trigger to add tag // trigger to add tag
this.$('.field-tags__item--add .button').click() this.$('.button--add').click()
} }
}, },

@ -5,6 +5,8 @@
<!-- header --> <!-- header -->
<tiny-sidebar-form-header title="New" close={ (event) => { handleClose(event) }}></tiny-sidebar-form-header> <tiny-sidebar-form-header title="New" close={ (event) => { handleClose(event) }}></tiny-sidebar-form-header>
<div class="sidebar__form">
<!-- body --> <!-- body -->
<form class="form" novalidate method="post" onsubmit={ (event) => ( state.validator.submit(event) ) }> <form class="form" novalidate method="post" onsubmit={ (event) => ( state.validator.submit(event) ) }>
<div class="sidebar__body"> <div class="sidebar__body">
@ -23,7 +25,7 @@
command* command*
<div class="field-input-group"> <div class="field-input-group">
<input class="field-text" type="text" name="command" value="{ state.current.command ? state.current.command : '' }" /> <input class="field-text" type="text" name="command" value="{ state.current.command ? state.current.command : '' }" />
<button class="button m-bottom-0" type="button" onclick={ handleSelectProgram }> <button class="button button--hover-icon-contrast m-bottom-0" type="button" onclick={ handleSelectProgram }>
<svg class="icon"> <svg class="icon">
<use xlink:href="symbol-defs.svg#icon-folder" /> <use xlink:href="symbol-defs.svg#icon-folder" />
</svg> </svg>
@ -38,7 +40,7 @@
<div class="field-group"> <div class="field-group">
<label class="field-label"> <label class="field-label">
tags tags
<potato-field-tags name="tags" value={ state.current.tags ? state.current.tags : '' }></potato-field-tags> <potato-field-tags name="tags"></potato-field-tags>
</label> </label>
<field-error name="tags[]"></field-error> <field-error name="tags[]"></field-error>
</div> </div>
@ -54,24 +56,24 @@
<!-- media --> <!-- media -->
<div class="field-group"> <div class="field-group">
<label class="field-label"> <label class="field-label">
<button class="button button--upload m-top-3 w-100" type="button" onclick={ (event) => { handleSelectMedia(event) }}> Thumbnail<br />
Add Image <button class="button button--hover-icon-contrast m-top-3" type="button" onclick={ (event) => { handleSelectThumbnail(event) }}>
<svg class="icon m-left-3"> <svg class="icon">
<use xlink:href="symbol-defs.svg#icon-image" /> <use xlink:href="symbol-defs.svg#icon-image" />
</svg> </svg>
</button> </button>
</label> </label>
<div class="field-media" if={ state.current.media }> <div class="field-media" if={ state.current.thumbnail }>
<button class="button button--small" type="button" onclick={ (event) => { handleRemoveMedia(event) }}>
<svg class="icon">
<use xlink:href="symbol-defs.svg#icon-delete" />
</svg>
</button>
<div class="field-media__img"> <div class="field-media__img">
<img src={ toImage(state.current.media) } /> <button class="button button--hover-icon-contrast" type="button" onclick={ (event) => { handleRemoveThumbnail(event) }}>
<svg class="icon">
<use xlink:href="symbol-defs.svg#icon-delete" />
</svg>
</button>
<img class="w-100" src={ toImage(state.current.thumbnail) } />
</div> </div>
</div> </div>
<field-error name="media"></field-error> <field-error name="thumbnail"></field-error>
</div> </div>
<tiny-loading active={ state.loading }></tiny-loading> <tiny-loading active={ state.loading }></tiny-loading>
@ -80,6 +82,7 @@
<!-- footer --> <!-- footer -->
<tiny-sidebar-form-footer id={ state.current.id ? state.current.id : false } loading={ state.loading }></tiny-sidebar-form-footer> <tiny-sidebar-form-footer id={ state.current.id ? state.current.id : false } loading={ state.loading }></tiny-sidebar-form-footer>
</form> </form>
</div>
</div> </div>
</div> </div>
@ -97,6 +100,9 @@
// store for sidebar // store for sidebar
import appsStore from './../stores/apps.js' import appsStore from './../stores/apps.js'
// store for tags
import tagsStore from './../stores/tags.js'
// validator // validator
import FormValidator from '@tiny-components/validator/src/formValidator.js' import FormValidator from '@tiny-components/validator/src/formValidator.js'
@ -118,12 +124,20 @@
* *
* *
*/ */
async onMounted() { onMounted() {
// adding event for open sidebar // adding event for open sidebar
formStore.on('open', () => { formStore.on('open', (id) => {
this.state.open = true
this.update() // if id is send, load apps from pouchdb
if (id) {
Neutralino.extensions.dispatch('js.neutralino.pouchdb', 'pouchdb.apps.findOne', {
'id': id
})
}
this.state.open = true
this.update()
}) })
// creating formValidator // creating formValidator
@ -144,6 +158,27 @@
this.handleSuccess(event, data) this.handleSuccess(event, data)
}) })
// receive from extensions database
Neutralino.events.on('pouchdb.apps.success', (event) => {
appsStore.trigger('updated')
// stop loading
this.state.loading = false
this.update()
})
// receive from extensions database
Neutralino.events.on('pouchdb.apps.readyOne', (event) => {
this.state.current = event.detail
tagsStore.trigger('update', this.state.current.tags)
// stop loading
this.state.loading = false
this.update()
})
}, },
@ -160,7 +195,19 @@
'defaultPath': '/home/' 'defaultPath': '/home/'
}) })
this.current.command = entry this.state.current.command = entry
this.update()
},
/**
*
*
*
*/
handleRemoveThumbnail(event) {
event.preventDefault()
this.state.current.thumbnail = null
this.update() this.update()
}, },
@ -176,20 +223,11 @@
this.state.loading = true this.state.loading = true
this.update() this.update()
// receive from extensions database // adding thumbnail
Neutralino.events.on('pouchdb.apps.success', (event) => { data.thumbnail = this.state.current.thumbnail
appsStore.trigger('updated')
// stop loading
this.state.loading = false
this.update()
})
data.media = this.state.current.media
// send to extensions database // send to extensions database
Neutralino.extensions.dispatch('js.neutralino.database', 'pouchdb.apps.create', data) Neutralino.extensions.dispatch('js.neutralino.pouchdb', 'pouchdb.apps.create', data)
}, },
/** /**
@ -218,16 +256,20 @@
this.update() this.update()
}, },
toImage(media) {
return 'data:image/png;base64,' + media
},
/** /**
* *
* *
* @param {object} media
*
*/ */
toImage(media) {
return 'data:image/png;base64,' + media
},
reset() { reset() {
this.state.current = {
}
} }
} }
} }

@ -9,7 +9,7 @@
<button class="button m-bottom-0" type="submit" disabled={ props.loading } close> <button class="button m-bottom-0" type="submit" disabled={ props.loading } close>
Save Save
<svg class="icon fill-success p-left-3" aria-hidden="true"> <svg class="icon fill-success p-left-3" aria-hidden="true">
<use xlink:href="symbol-defs.svg#icon-arrow-right"></use> <use xlink:href="symbol-defs.svg#icon-check"></use>
</svg> </svg>
</button> </button>
</div> </div>

@ -4,8 +4,8 @@
{ props.title } { props.title }
</div> </div>
<div class="bar__end"> <div class="bar__end">
<button class="button button--transparent" type="button" onclick={ props.close }> <button class="button button--icon button--hover-icon-contrast m-top-3 m-bottom-3" type="button" onclick={ props.close }>
<svg class="icon fill-danger fill-text-hover" aria-hidden="true"> <svg class="icon fill-danger" aria-hidden="true">
<use xlink:href="/symbol-defs.svg#icon-close"></use> <use xlink:href="/symbol-defs.svg#icon-close"></use>
</svg> </svg>
</button> </button>

@ -7,6 +7,8 @@
* *
*/ */
import * as riot from 'riot'
export default { export default {
state: { state: {
@ -22,9 +24,9 @@ export default {
* *
*/ */
handleClose() { handleClose() {
this.state.open = false
this.reset() this.reset()
this.state.open = false
this.update() this.update()
}, },

@ -7,16 +7,17 @@
* *
*/ */
import observable from '@riotjs/observable' import observable from '@riotjs/observable'
export default observable({ export default observable({
/** /**
* *
* @param {object} data * @param {object} data
* *
*/ */
open() { open(id = null) {
this.trigger('open') this.trigger('open', id)
} }
})
})

@ -0,0 +1,14 @@
/**
* Store for apps
*
* @author Björn Hase
* @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3
* @link https://gitea.node001.net/HerrHase/potato-launcher.git
*
*/
import observable from '@riotjs/observable'
export default observable({
})

@ -4,7 +4,7 @@
<header class="header m-bottom-3"> <header class="header m-bottom-3">
<div class="display-flex justify-content-space-between m-top-3"> <div class="display-flex justify-content-space-between m-top-3">
<div> <div>
<button class="button button--icon m-bottom-0"> <button class="button button--icon button--hover-icon-contrast m-bottom-0">
<svg class="icon icon--big"> <svg class="icon icon--big">
<use xlink:href="symbol-defs.svg#icon-filter" /> <use xlink:href="symbol-defs.svg#icon-filter" />
</svg> </svg>
@ -22,7 +22,7 @@
<div class="col-12 col-md-3 col-lg-2" each={ app in state.apps }> <div class="col-12 col-md-3 col-lg-2" each={ app in state.apps }>
<div class="apps__item" onclick={ (event) => { handleClick(event, app) }} style="{ addBackgroundStyles(app) }"> <div class="apps__item" onclick={ (event) => { handleClick(event, app) }} style="{ addBackgroundStyles(app) }">
<div class="apps__header p-4 right"> <div class="apps__header p-4 right">
<button class="button button--transparent p-2" onclick={ (event) => { handleEdit(event, app) }}> <button class="button button--icon button--hover-icon-contrast" onclick={ (event) => { handleEdit(event, app) }}>
<svg class="icon"> <svg class="icon">
<use xlink:href="symbol-defs.svg#icon-settings" /> <use xlink:href="symbol-defs.svg#icon-settings" />
</svg> </svg>
@ -53,6 +53,9 @@
import potatoAppsForm from './../forms/apps.riot' import potatoAppsForm from './../forms/apps.riot'
import potatoAppsFormButton from './../components/appsFormButton.riot' import potatoAppsFormButton from './../components/appsFormButton.riot'
import appsStore from './../stores/apps.js' import appsStore from './../stores/apps.js'
import formStore from './../stores/form.js'
import notificationStore from '@tiny-components/notification/src/notificationStore.js'
// let it rain // let it rain
riot.register('potato-apps-form', potatoAppsForm) riot.register('potato-apps-form', potatoAppsForm)
@ -62,7 +65,7 @@
riot.mount('potato-apps-form-buttons') riot.mount('potato-apps-form-buttons')
/** /**
* *
* *
* @author Björn Hase * @author Björn Hase
* @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3 * @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3
@ -94,7 +97,7 @@
// send event to get all after // send event to get all after
appsStore.on('updated', () => { appsStore.on('updated', () => {
Neutralino.extensions.dispatch('js.neutralino.database', 'pouchdb.apps.find') Neutralino.extensions.dispatch('js.neutralino.pouchdb', 'pouchdb.apps.find')
}) })
// trigger event to get all apps // trigger event to get all apps
@ -109,10 +112,17 @@
* @param {object} app * @param {object} app
* *
*/ */
handleClick(event, app) { async handleClick(event, app) {
Neutralino.os.execCommand(app.command).catch((error) => { try {
const state = await Neutralino.os.execCommand(app.command)
// if there is a error message display send a notification
if (state.stdErr) {
notificationStore.danger(state.stdErr)
}
} catch(error) {
console.log(error) console.log(error)
}) }
}, },
/** /**
@ -123,15 +133,20 @@
* *
*/ */
handleEdit(event, app) { handleEdit(event, app) {
console.log(app) event.stopPropagation()
formStore.open(app._id)
}, },
/**
*
*
*/
addBackgroundStyles(app) { addBackgroundStyles(app) {
let styles = '' let styles = false
if (app.media) { if (app.media) {
styles = "background-image: url('data:image/jpg;base64," + app.media + "')" styles = "background-image: url('data:image/jpg;base64," + app.thumbnail + "')"
} }
return styles return styles

@ -0,0 +1,3 @@
.justify-content-space-between {
justify-content: space-between;
}

@ -0,0 +1,9 @@
/**
* modifications for badge
*
*
*/
.badge {
padding: .5rem .6rem;
}

@ -0,0 +1,6 @@
/**
* modifications for bar
*
*
*
*/

@ -7,4 +7,12 @@
&--icon { &--icon {
padding: 0.5rem 0.6rem; padding: 0.5rem 0.6rem;
} }
&--hover-icon-contrast {
&:hover {
.icon {
fill: white;
}
}
}
} }

@ -9,7 +9,6 @@
&__list { &__list {
list-style: none; list-style: none;
padding: 0; padding: 0;
margin: 0;
} }
&__item { &__item {
@ -34,4 +33,8 @@
} }
} }
} }
&__label {
vertical-align: bottom;
}
} }

@ -1,7 +1,14 @@
/**
* modifications for sidebar
*
*
*/
.field { .field {
&-error { &-error {
ul { ul {
list-style: square; list-style: square;
margin: 0;
padding-left: 1.25em; padding-left: 1.25em;
} }
} }
@ -14,4 +21,17 @@
margin-top: 0.7em; margin-top: 0.7em;
} }
} }
&-media {
&__img {
position: relative;
button {
position: absolute;
right: 0;
top: 0;
margin: 1em;
}
}
}
} }

@ -0,0 +1,23 @@
/**
* modifications for sidebar
*
*
*/
.sidebar {
&__form {
height: 100%;
overflow-y: scroll;
padding-bottom: calc(72px + 1.5em); // 72px is the minium height for footer
}
&__footer {
bottom: -1px;
}
.bar {
// alpha in neutrolino.js not working
border-radius: 0;
}
}

@ -1,12 +1,13 @@
@import @import
'~@tiny-components/plain-ui/src/scss/plain-ui', '~@tiny-components/plain-ui/src/scss/plain-ui',
'helpers',
'components/apps', 'components/apps',
'components/badge',
'components/sidebar',
'components/field', 'components/field',
'components/field-tags', 'components/field-tags',
'components/buttons', 'components/buttons',
'components/icons'; 'components/icons';
.justify-content-space-between {
justify-content: space-between;
}
Loading…
Cancel
Save