You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
8.6 KiB
239 lines
8.6 KiB
2 years ago
|
<shiny-apps-form>
|
||
|
<div class={ getCssClasses() }>
|
||
|
<div class="sidebar__inner">
|
||
|
|
||
|
<!-- header -->
|
||
|
<tiny-sidebar-form-header title="New" close={ (event) => { handleClose(event) }}></tiny-sidebar-form-header>
|
||
|
|
||
|
<!-- body -->
|
||
|
<form class="form" novalidate method="post" onsubmit={ (event) => ( state.validator.submit(event) ) }>
|
||
|
<div class="sidebar__body">
|
||
|
|
||
|
<!-- name -->
|
||
|
<div class="field-group">
|
||
|
<label class="field-label">
|
||
|
name*
|
||
|
<input type="text" class="field-text" name="name" value="{ state.current.name ? state.current.name : '' }" />
|
||
|
</label>
|
||
|
</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 ? state.current.command : '' }" />
|
||
|
<button class="button m-bottom-0" type="button" onclick={ handleSelectProgram }>
|
||
|
<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
|
||
|
<shiny-field-tags name="tags" value={ state.current.tags ? state.current.tags : '' }></shiny-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">{ state.current.description ? state.current.description : '' }</textarea>
|
||
|
</label>
|
||
|
</div>
|
||
|
|
||
|
<!-- media -->
|
||
|
<div class="field-group">
|
||
|
<label class="field-label">
|
||
|
<button class="button button--upload m-top-3 w-100" type="button" onclick={ (event) => { handleSelectMedia(event) }}>
|
||
|
Add Image
|
||
|
<svg class="icon m-left-3">
|
||
|
<use xlink:href="symbol-defs.svg#icon-image" />
|
||
|
</svg>
|
||
|
</button>
|
||
|
</label>
|
||
|
<div class="field-media" if={ state.current.media }>
|
||
|
<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">
|
||
|
<img src={ toImage(state.current.media) } />
|
||
|
</div>
|
||
|
</div>
|
||
|
<field-error name="media"></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 }></tiny-sidebar-form-footer>
|
||
|
</form>
|
||
|
|
||
|
</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'
|
||
|
|
||
|
// validator
|
||
|
import FormValidator from '@tiny-components/validator/src/formValidator.js'
|
||
|
|
||
|
/**
|
||
|
* Sidebar Form has slot:title and slot:form
|
||
|
*
|
||
|
* Button need props.formId to trigger submit in slot:form
|
||
|
*
|
||
|
*
|
||
|
* @author Björn Hase
|
||
|
* @license http://opensource.org/licenses/MIT The MIT License
|
||
|
* @link https://gitea.node001.net/tiny-components/sidebar-form
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
export default () => {
|
||
|
return {
|
||
|
|
||
|
...sidebarMixin, // adding basic funtion for sidebar
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*
|
||
|
*/
|
||
|
async onMounted() {
|
||
|
|
||
|
// adding event for open sidebar
|
||
|
formStore.on('open', () => {
|
||
|
this.state.open = true
|
||
|
this.update()
|
||
|
})
|
||
|
|
||
|
// creating formValidator
|
||
|
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)
|
||
|
})
|
||
|
|
||
|
},
|
||
|
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*/
|
||
|
async handleSelectProgram(event) {
|
||
|
event.preventDefault()
|
||
|
|
||
|
let entry = await Neutralino.os.showOpenDialog('', {
|
||
|
'multiSelections': false,
|
||
|
'defaultPath': '/home/'
|
||
|
})
|
||
|
|
||
|
this.current.command = entry
|
||
|
this.update()
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*
|
||
|
* @param {object} event
|
||
|
*
|
||
|
*/
|
||
|
handleSuccess(event, data) {
|
||
|
event.preventDefault()
|
||
|
|
||
|
this.state.loading = true
|
||
|
this.update()
|
||
|
|
||
|
// receive from extensions database
|
||
|
Neutralino.events.on('pouchdb.apps.success', (event) => {
|
||
|
|
||
|
appsStore.trigger('updated')
|
||
|
|
||
|
// stop loading
|
||
|
this.state.loading = false
|
||
|
this.update()
|
||
|
})
|
||
|
|
||
|
data.media = this.state.current.media
|
||
|
|
||
|
// send to extensions database
|
||
|
Neutralino.extensions.dispatch('js.neutralino.database', 'pouchdb.apps.create', data)
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*
|
||
|
* @param object event
|
||
|
*
|
||
|
*/
|
||
|
async handleSelectMedia(event)
|
||
|
{
|
||
|
const entry = await Neutralino.os.showOpenDialog('', {
|
||
|
'multiSelections': false,
|
||
|
'defaultPath': '/home/',
|
||
|
'filters': [{
|
||
|
'name': 'Images',
|
||
|
'extensions': ['jpg', 'png', 'jpeg', 'webp', 'gif', 'md']
|
||
|
}]
|
||
|
})
|
||
|
|
||
|
// getting data
|
||
|
const data = await Neutralino.filesystem.readBinaryFile(entry[0])
|
||
|
|
||
|
// adding as blob
|
||
|
this.state.current.media = _arrayBufferToBase64(data)
|
||
|
|
||
|
this.update()
|
||
|
},
|
||
|
|
||
|
toImage(media) {
|
||
|
return 'data:image/png;base64,' + media
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*
|
||
|
*/
|
||
|
reset() {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
</script>
|
||
|
</shiny-apps-form>
|