130 lines
3.1 KiB
Vue
130 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
import {
|
|
ref,
|
|
watch
|
|
} from 'vue'
|
|
import Button from 'primevue/button'
|
|
import Checkbox from 'primevue/checkbox'
|
|
import Dialog from 'primevue/dialog'
|
|
import ImageComponent from 'primevue/image'
|
|
import InputGroup from 'primevue/inputgroup'
|
|
import InputGroupAddon from 'primevue/inputgroupaddon'
|
|
import InputText from 'primevue/inputtext'
|
|
import MultiSelect from 'primevue/multiselect'
|
|
import Select from 'primevue/select'
|
|
|
|
import { useAppStore } from 'src/store'
|
|
import type { EditingRow } from 'src/types/editing'
|
|
import type { Row as DataRow, Column as DataColumn } from 'src/types/data'
|
|
import InputImage from 'src/components/InputImage.vue'
|
|
|
|
const store = useAppStore()
|
|
|
|
const props = defineProps<{
|
|
fields: DataColumn[],
|
|
row: EditingRow,
|
|
}>()
|
|
const visible = defineModel<boolean>('visible', { default: false })
|
|
const emit = defineEmits<{
|
|
(e: 'saved', val: DataRow, editingRow: EditingRow): void
|
|
}>()
|
|
const editing = ref<DataRow>({} as any)
|
|
watch(() => props.row, async (newRow, oldRow) => {
|
|
editing.value = JSON.parse(JSON.stringify(props.row.data || {}))
|
|
})
|
|
|
|
const onCancel = (e: Event) => {
|
|
e.preventDefault()
|
|
visible.value = false
|
|
}
|
|
|
|
const onSave = async (e: Event) => {
|
|
e.preventDefault()
|
|
emit('saved', JSON.parse(JSON.stringify(editing.value || {})), props.row)
|
|
visible.value = false
|
|
}
|
|
|
|
const onImageChanged = (field: string, image: string) => {
|
|
editing.value[field] = {
|
|
...editing.value[field],
|
|
src: image,
|
|
}
|
|
}
|
|
|
|
const onImageRemoved = (field: string) => {
|
|
editing.value[field] = null
|
|
}
|
|
</script>
|
|
|
|
<template lang="pug">
|
|
Dialog(
|
|
v-model:visible='visible'
|
|
modal
|
|
header='Edit Data'
|
|
)
|
|
.content
|
|
InputGroup(
|
|
v-for='field in fields'
|
|
)
|
|
InputGroupAddon
|
|
label
|
|
span {{ field.name }}
|
|
InputGroupAddon(
|
|
v-if='field.type === "image"'
|
|
)
|
|
InputImage(
|
|
:src='editing[field.name]?.src'
|
|
@changed='(e) => onImageChanged(field.name, e)'
|
|
@removed='(e) => onImageRemoved(field.name)'
|
|
)
|
|
InputGroupAddon(
|
|
v-else-if='field.type === "toggle"'
|
|
)
|
|
Checkbox(
|
|
v-model='editing[field.name]'
|
|
:name='`toggle for ${editing.name || editing._id} ${field.name}`'
|
|
binary
|
|
)
|
|
InputGroupAddon(
|
|
v-else-if='field.type === "dropdown"'
|
|
)
|
|
Select(
|
|
v-model='editing[field.name]'
|
|
:options='field.options'
|
|
placeholder='Select from Options'
|
|
filter
|
|
showClear
|
|
fluid
|
|
)
|
|
InputGroupAddon(
|
|
v-else-if='field.type === "multiselect"'
|
|
)
|
|
MultiSelect(
|
|
v-model='editing[field.name]'
|
|
:options='field.options'
|
|
placeholder='Select from Options'
|
|
filter
|
|
showClear
|
|
fluid
|
|
display='chip'
|
|
)
|
|
InputGroupAddon(
|
|
v-else
|
|
)
|
|
InputText(
|
|
v-model='editing[field.name]'
|
|
)
|
|
template(#footer)
|
|
Button(
|
|
label='Save'
|
|
@click='onSave'
|
|
)
|
|
Button(
|
|
label='Cancel'
|
|
@click='onCancel'
|
|
)
|
|
</template>
|
|
|
|
<style scoped lang="sass">
|
|
|
|
</style>
|