|
|
|
<potato-apps-form>
|
|
|
|
<div class={ getCssClasses() }>
|
|
|
|
<div class="sidebar__inner">
|
|
|
|
|
|
|
|
<!-- header -->
|
|
|
|
<tiny-sidebar-form-header title="New" close={ (event) => { handleClose(event) }}></tiny-sidebar-form-header>
|
|
|
|
|
|
|
|
<div class="sidebar__form">
|
|
|
|
|
|
|
|
<!-- body -->
|
|
|
|
<form class="form" novalidate method="post" onsubmit={ (event) => ( state.validator.submit(event) ) }>
|
|
|
|
<div class="sidebar__body">
|
|
|
|
|
|
|
|
<input type="hidden" if={ state.current._id } name="_id" value="{ state.current._id }" />
|
|
|
|
<input type="hidden" if={ state.current._rev } name="_rev" value="{ state.current._rev }" />
|
|
|
|
|
|
|
|
<!-- name -->
|
|
|
|
<div class="field-group">
|
|
|
|
<label class="field-label">
|
|
|
|
name*
|
|
|
|
<input type="text" class="field-text" name="name" value={ state.current.name } />
|
|
|
|
</label>
|
|
|
|
<field-error name="name"></field-error>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- command -->
|
|
|
|
<div class="field-group">
|
|
|
|
<label class="field-label">
|
|
|
|
command*
|
|
|
|
<div class="field-input-group">
|
|
|
|
<input class="field-text" type="text" name="command" value="{ state.current.command }" />
|
|
|
|
<button class="button button--hover-icon-contrast m-bottom-0" type="button" onclick={ (event) => { handleOpenCommand(event) }}>
|
|
|
|
<svg class="icon">
|
|
|
|
<use xlink:href="symbol-defs.svg#icon-folder" />
|
|
|
|
</svg>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</label>
|
|
|
|
<input id="apps-form-select-program" class="hidden-xxs hidden-xs-up" type="file" onchange={ (event) => { handleSelectCommand(event) }} />
|
|
|
|
<field-error name="command"></field-error>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- tags -->
|
|
|
|
<div class="field-group">
|
|
|
|
<label class="field-label">
|
|
|
|
tags
|
|
|
|
<potato-field-tags name="tags"></potato-field-tags>
|
|
|
|
</label>
|
|
|
|
<field-error name="tags[]"></field-error>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- description -->
|
|
|
|
<div class="field-group">
|
|
|
|
<label class="field-label">
|
|
|
|
description
|
|
|
|
<textarea class="field-text" name="description" value="{ state.current.description }"></textarea>
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- media -->
|
|
|
|
<div class="field-group">
|
|
|
|
<label class="field-label">
|
|
|
|
Thumbnail<br />
|
|
|
|
<input id="apps-form-select-thumbnail" class="hidden-xxs hidden-xs-up" type="file" accept="image/png, image/jpeg, image/gif, image/webm, image/webp" onchange={ (event) => { handleSelectThumbnail(event) }} />
|
|
|
|
<button class="button button--hover-icon-contrast m-top-3" type="button" onclick={ (event) => { handleOpenThumbnail(event) }}>
|
|
|
|
<svg class="icon">
|
|
|
|
<use xlink:href="symbol-defs.svg#icon-image" />
|
|
|
|
</svg>
|
|
|
|
</button>
|
|
|
|
</label>
|
|
|
|
<div class="field-media" if={ state.current.thumbnail }>
|
|
|
|
<div class="field-media__img">
|
|
|
|
<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>
|
|
|
|
<field-error name="thumbnail"></field-error>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<tiny-loading active={ state.loading }></tiny-loading>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- footer -->
|
|
|
|
<tiny-sidebar-form-footer
|
|
|
|
id={ state.current._id ? state.current._id : false }
|
|
|
|
loading={ state.loading }
|
|
|
|
handle-delete={ handleDelete }>
|
|
|
|
</tiny-sidebar-form-footer>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
import * as riot from 'riot'
|
|
|
|
|
|
|
|
// mixins
|
|
|
|
import sidebarMixin from './../mixins/sidebarForm.js'
|
|
|
|
|
|
|
|
// store for sidebar
|
|
|
|
import formStore from './../stores/form.js'
|
|
|
|
|
|
|
|
// store for sidebar
|
|
|
|
import appsStore from './../stores/apps.js'
|
|
|
|
|
|
|
|
// store for tags
|
|
|
|
import tagsStore from './../stores/tags.js'
|
|
|
|
|
|
|
|
// validator
|
|
|
|
import FormValidator from '@tiny-components/validator/src/formValidator.js'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* handler 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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
export default () => {
|
|
|
|
return {
|
|
|
|
|
|
|
|
...sidebarMixin, // adding basic funtion for sidebar
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
onMounted() {
|
|
|
|
|
|
|
|
// adding event for open sidebar
|
|
|
|
formStore.on('open', (id) => {
|
|
|
|
|
|
|
|
this.state.current = false
|
|
|
|
this.state.open = true
|
|
|
|
|
|
|
|
// reset tags
|
|
|
|
tagsStore.trigger('update', [])
|
|
|
|
|
|
|
|
// if id is not undefined, get data from pouchdb
|
|
|
|
if (id !== undefined) {
|
|
|
|
appsStore.getOne(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
this.update()
|
|
|
|
})
|
|
|
|
|
|
|
|
this.createValidator()
|
|
|
|
|
|
|
|
// receive from extensions database
|
|
|
|
appsStore.on('success', (data) => {
|
|
|
|
|
|
|
|
appsStore.trigger('update')
|
|
|
|
|
|
|
|
this.state.current._id = data._id
|
|
|
|
this.state.current._rev = data._rev
|
|
|
|
|
|
|
|
// stop loading
|
|
|
|
this.state.loading = false
|
|
|
|
this.update()
|
|
|
|
})
|
|
|
|
|
|
|
|
// receive from extensions database
|
|
|
|
appsStore.on('close', (data) => {
|
|
|
|
|
|
|
|
appsStore.trigger('update')
|
|
|
|
|
|
|
|
this.state.open = false
|
|
|
|
|
|
|
|
// stop loading
|
|
|
|
this.state.loading = false
|
|
|
|
this.update()
|
|
|
|
})
|
|
|
|
|
|
|
|
appsStore.on('readyOne', (data) => {
|
|
|
|
|
|
|
|
this.state.current = data
|
|
|
|
|
|
|
|
if (!this.state.current.tags) {
|
|
|
|
this.state.current.tags = []
|
|
|
|
}
|
|
|
|
|
|
|
|
tagsStore.trigger('update', this.state.current.tags)
|
|
|
|
|
|
|
|
// stop loading
|
|
|
|
this.state.loading = false
|
|
|
|
this.update()
|
|
|
|
})
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* creating Validator for form
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
createValidator() {
|
|
|
|
this.state.validator = new FormValidator(this.$('.form'), {
|
|
|
|
'name': {
|
|
|
|
'presence': true
|
|
|
|
},
|
|
|
|
'command': {
|
|
|
|
'presence': true
|
|
|
|
},
|
|
|
|
'tags': {
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// adding on success
|
|
|
|
this.state.validator.onSuccess((event, data) => {
|
|
|
|
this.handleSuccess(event, data)
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* choose a file for command
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {object} event
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
handleOpenCommand(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
this.$('#apps-form-select-program').click()
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
handleSelectCommand(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
|
|
|
|
if (event.target.files[0]) {
|
|
|
|
if (!this.state.current) {
|
|
|
|
this.state.current = {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.state.current.command = event.target.files[0].path
|
|
|
|
this.update()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {object} event
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
handleSuccess(event, data) {
|
|
|
|
event.preventDefault()
|
|
|
|
|
|
|
|
this.state.current = data
|
|
|
|
this.state.loading = true
|
|
|
|
this.update()
|
|
|
|
|
|
|
|
// adding thumbnail
|
|
|
|
data.thumbnail = this.state.current.thumbnail
|
|
|
|
|
|
|
|
// send to extensions database
|
|
|
|
if (data._id && data._rev) {
|
|
|
|
appsStore.put(data)
|
|
|
|
} else {
|
|
|
|
appsStore.post(data)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* open dialog for choosing thumbnail
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {object} event
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
handleOpenThumbnail(event)
|
|
|
|
{
|
|
|
|
event.preventDefault()
|
|
|
|
this.$('#apps-form-select-thumbnail').click()
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param object event
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
handleSelectThumbnail(event)
|
|
|
|
{
|
|
|
|
if (event.target.files[0]) {
|
|
|
|
const fileReader = new FileReader()
|
|
|
|
const data = fileReader.readAsArrayBuffer(event.target.files[0])
|
|
|
|
|
|
|
|
fileReader.onload = () => {
|
|
|
|
this.state.current.thumbnail = _arrayBufferToBase64(fileReader.result)
|
|
|
|
this.update()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* remove current thumbnail for App
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {object} event
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
handleRemoveThumbnail(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
|
|
|
|
this.state.current.thumbnail = null
|
|
|
|
this.update()
|
|
|
|
},
|
|
|
|
|
|
|
|
handleDelete() {
|
|
|
|
appsStore.remove(this.state.current)
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {object} media
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
toImage(media) {
|
|
|
|
return 'data:image/png;base64,' + media
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
</script>
|
|
|
|
</potato-apps-form>
|