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.
321 lines
9.6 KiB
321 lines
9.6 KiB
<template>
|
|
<q-page class="q-pa-md">
|
|
<q-chip class="float-right text-white" color="secondary">{{item.ref}}</q-chip>
|
|
<q-chip v-if="item.deleted" class="float-right q-mr-md" color="red">Supprimé</q-chip>
|
|
<h2 class="q-ma-none" :class="{'text-faded': !item.name}">{{item.name || '---- -- ----'}}</h2>
|
|
<h4 class="q-ma-none q-pb-md text-grey">{{item.type}}</h4>
|
|
|
|
<div class="q-py-md">
|
|
<q-input v-model="item.name"
|
|
:disable="item.deleted"
|
|
type="text"
|
|
outlined color="secondary"
|
|
stack-label label="Nom" class="q-mb-md"
|
|
@update:model-value="changed = true"/>
|
|
<q-input v-model="item.owner"
|
|
:disable="item.deleted"
|
|
outlined color="secondary" stack-label label="Propriétaire" class="q-mb-md"
|
|
@input="changed = true"/>
|
|
<q-field borderless stack-label label="Etat cosmétique" class="q-mb-md">
|
|
<q-btn-toggle
|
|
no-caps
|
|
:disable="item.deleted"
|
|
v-model="item.state"
|
|
@update:model-value="changed = true"
|
|
toggle-color="secondary"
|
|
text-color="black"
|
|
:options="[
|
|
{label: 'Neuf', value: 'Neuf'},
|
|
{label: 'Excellent', value: 'Excellent'},
|
|
{label: 'Bon', value: 'Bon'},
|
|
{label: 'Moyen', value: 'Moyen'},
|
|
{label: 'Abimé', value: 'Abimé'},
|
|
{label: 'Inutilisable', value: 'Inutilisable'}
|
|
]"
|
|
/>
|
|
</q-field>
|
|
<q-field borderless stack-label label="Fonctionnel" class="q-mb-md">
|
|
<q-btn-toggle
|
|
no-caps
|
|
:disable="item.deleted"
|
|
v-model="item.working"
|
|
:toggle-color="item.working ? 'green' : 'red'"
|
|
text-color="black"
|
|
:options="[
|
|
{label: '✔', value: true},
|
|
{label: '?', value: null},
|
|
{label: '✘', value: false}
|
|
]"
|
|
@input="changed = true"
|
|
/>
|
|
</q-field>
|
|
<q-field borderless stack-label label="En stock" class="q-mb-md">
|
|
<q-btn-toggle
|
|
no-caps
|
|
:disable="item.deleted"
|
|
v-model="item.available"
|
|
:toggle-color="item.available ? 'green' : 'red'"
|
|
text-color="black"
|
|
:options="[
|
|
{label: '✔', value: true},
|
|
{label: '✘', value: false}
|
|
]"
|
|
@input="changed = true"
|
|
/>
|
|
</q-field>
|
|
<q-field borderless stack-label label="Supprimé" class="q-mb-md">
|
|
<q-btn-toggle
|
|
no-caps
|
|
v-model="item.deleted"
|
|
:toggle-color="item.deleted ? 'green' : 'red'"
|
|
text-color="black"
|
|
:options="[
|
|
{label: 'Oui', value: true},
|
|
{label: 'Non', value: false}
|
|
]"
|
|
@input="changed = true"
|
|
/>
|
|
</q-field>
|
|
<q-input
|
|
:disable="item.deleted"
|
|
v-model="item.comment"
|
|
@update:model-value="changed = true"
|
|
type="textarea"
|
|
:max-height="100"
|
|
rows="4"
|
|
outlined color="secondary" stack-label label="Commentaire" class="q-mb-md"
|
|
inverted
|
|
/>
|
|
<q-btn :disabled="!changed || originalItem.deleted"
|
|
@click="updateItem()"
|
|
color="primary"
|
|
:flat="!changed"
|
|
>Enregistrer</q-btn>
|
|
</div>
|
|
|
|
<br/>
|
|
<br/>
|
|
|
|
<h4 class="q-ma-none q-pb-md text-light">Historique</h4>
|
|
<q-timeline color="secondary">
|
|
<!--<q-timeline-entry heading>-->
|
|
<!--Historique-->
|
|
<!--</q-timeline-entry>-->
|
|
<q-timeline-entry
|
|
title="Ajouter une entrée"
|
|
side="left"
|
|
icon="add"
|
|
color="primary"
|
|
@click="openHistoryForm()"
|
|
style="cursor:pointer"
|
|
>
|
|
<q-slide-transition>
|
|
<div v-show="showHistoryForm">
|
|
<q-input
|
|
v-model="pendingHistory"
|
|
type="textarea"
|
|
label="Description"
|
|
:max-height="100"
|
|
rows="3"
|
|
invertedd
|
|
/>
|
|
<q-input label="Date"
|
|
v-model="pendingHistoryDate"
|
|
type="datetime"
|
|
format24h />
|
|
<br/>
|
|
<q-uploader url=""
|
|
:upload-factory="uploadFile"
|
|
@add="hasFile = true"
|
|
ref="uploader"
|
|
:extensions="'.jpg,.png'"
|
|
auto-expand
|
|
hide-upload-button
|
|
stack-label="Uploader une photo"
|
|
/>
|
|
<br/>
|
|
<q-btn flat color="faded" @click.stop="showHistoryForm = false">Annuler</q-btn>
|
|
<q-btn flat color="primary" @click.stop="addHistory()">Ok</q-btn>
|
|
</div>
|
|
</q-slide-transition>
|
|
</q-timeline-entry>
|
|
<q-timeline-entry
|
|
v-for="event in history.slice().reverse()"
|
|
:key="event.created"
|
|
:subtitle="getDate(event.created)"
|
|
:title="event.user"
|
|
side="left"
|
|
>
|
|
<div>
|
|
<q-icon name="format_quote"
|
|
color="light"
|
|
size="2rem"
|
|
/>
|
|
{{ event.text }}
|
|
<q-icon name="format_quote"
|
|
color="light"
|
|
size="2rem"
|
|
/>
|
|
</div>
|
|
<q-img :src="getImageUrl(event, event.image_file)"
|
|
alt="photo"
|
|
v-if="event.image_file"
|
|
class="q-py-md"
|
|
style="max-height:300px;max-width:300px"
|
|
:fit="'contain'"
|
|
/>
|
|
<br/>
|
|
<q-btn flat
|
|
:disable="item.deleted"
|
|
icon="delete"
|
|
label="Supprimer cette entrée"
|
|
@click="removeHistory(event)"
|
|
/>
|
|
</q-timeline-entry>
|
|
</q-timeline>
|
|
</q-page>
|
|
</template>
|
|
|
|
<script>
|
|
import { date } from 'quasar'
|
|
export default {
|
|
name: 'StockItem',
|
|
props: ['itemRef'],
|
|
data () {
|
|
return {
|
|
showHistoryForm: false,
|
|
pendingHistory: null,
|
|
pendingHistoryDate: null,
|
|
changed: false,
|
|
hasFile: false,
|
|
username: null,
|
|
item: {}
|
|
}
|
|
},
|
|
computed: {
|
|
category () {
|
|
return this.item.type || ''
|
|
},
|
|
stock () {
|
|
return this.$store.state.core.firebase.stock || []
|
|
},
|
|
originalItem () {
|
|
return this.stock.find(item => {
|
|
return (item) ? item.ref === this.itemRef : false
|
|
}) || []
|
|
},
|
|
itemId () {
|
|
return this.$store.state.core.firebase.stock.findIndex(item => {
|
|
return (item) ? item.ref === this.itemRef : false
|
|
})
|
|
},
|
|
history () {
|
|
return this.$store.state.core.firebase.history.filter(item => {
|
|
return item.ref === this.itemRef
|
|
}).sort((a, b) => {
|
|
return (a.timestamp > b.timestamp) ? 1 : -1
|
|
}) || []
|
|
}
|
|
},
|
|
created: function () {
|
|
this.loadItem()
|
|
},
|
|
mounted () {
|
|
this.username = this.$q.localStorage.getItem('username')
|
|
},
|
|
methods: {
|
|
getDate (timestamp) {
|
|
return date.formatDate(timestamp, 'DD/MM/YY - HH:mm')
|
|
},
|
|
openHistoryForm () {
|
|
this.showHistoryForm = true
|
|
this.pendingHistoryDate = Date.now()
|
|
},
|
|
async addHistory () {
|
|
this.$q.loading.show()
|
|
let url = null
|
|
if (this.hasFile) {
|
|
let resp = await this.uploadFile(this.$refs.uploader.files[0])
|
|
url = resp
|
|
console.log(resp)
|
|
}
|
|
this.$store.dispatch('core/addToCollection', {
|
|
collection: 'history',
|
|
data: {
|
|
ref: this.itemRef,
|
|
text: this.pendingHistory,
|
|
user: this.$store.state.core.username,
|
|
image: url,
|
|
timestamp: this.pendingHistoryDate
|
|
}
|
|
}).then(response => {
|
|
this.$store.dispatch('core/loadAppData').then(_ => {
|
|
this.loadItem()
|
|
this.showHistoryForm = false
|
|
this.pendingHistory = null
|
|
this.pendingHistoryDate = null
|
|
this.hasFile = false
|
|
this.$refs.uploader.reset()
|
|
this.$q.loading.hide()
|
|
})
|
|
})
|
|
},
|
|
removeHistory (data) {
|
|
this.$q.dialog({
|
|
title: 'Supprimer ?',
|
|
message: "Il est possible que tu sois Meth, nous sommes donc légalement obligés de te demander : es-tu absolument sur d'être certain de vouloir effectuer cette action irréversible ?",
|
|
ok: 'Supprimer',
|
|
cancel: 'Annuler'
|
|
}).onOk(() => {
|
|
this.$store.dispatch('core/removeFromCollection', {
|
|
collection: 'history',
|
|
data
|
|
}).then(_ => {
|
|
this.$store.dispatch('core/loadAppData').then(_ => {
|
|
this.loadItem()
|
|
this.$q.notify('Supprimé !')
|
|
})
|
|
})
|
|
})
|
|
},
|
|
updateItem () {
|
|
this.$q.loading.show()
|
|
this.$store.dispatch('core/updateItem', {
|
|
collection: 'stock',
|
|
itemId: this.itemId,
|
|
data: this.item
|
|
}).then(response => {
|
|
// this.$speech(`sugoï, domo arigato senpai !`)
|
|
this.$q.notify({
|
|
message: 'Enregistré !',
|
|
color: 'secondary',
|
|
avatar: '/gyoza_logo_nobg.png',
|
|
timeout: 2000
|
|
})
|
|
this.changed = false
|
|
this.$store.dispatch('core/loadAppData').then(_ => {
|
|
this.loadItem()
|
|
this.$q.loading.hide()
|
|
})
|
|
})
|
|
},
|
|
uploadFile (file) {
|
|
return this.$store.dispatch('core/uploadFile', file).then(response => {
|
|
return response.ref.getDownloadURL()
|
|
})
|
|
},
|
|
getImageUrl (history, image) {
|
|
return this.$pb.files.getURL(history, image, { thumb: '300x300f' })
|
|
},
|
|
loadItem () {
|
|
let item = this.stock.find(item => {
|
|
return (item) ? item.ref === this.itemRef : false
|
|
}) || []
|
|
this.item = { ...item }
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
</style>
|
|
|