add editor modal + fix image not sending dirty
This commit is contained in:
parent
acaa9a18ae
commit
1eee6c0b4b
2 changed files with 150 additions and 1 deletions
src/views/Editor
|
@ -22,6 +22,7 @@ import {
|
|||
type Row as DataRow,
|
||||
type Column as DataColumn,
|
||||
} from 'src/types/data'
|
||||
import DataEditorModal from './DataEditorModal.vue'
|
||||
import ImageEditor from './ImageEditor.vue'
|
||||
import { type EditingRow } from './types'
|
||||
|
||||
|
@ -37,6 +38,8 @@ const editingRows = ref<DataRow[]>([])
|
|||
const expandedRows = ref<DataRow[]>([])
|
||||
const editingImage = ref(false)
|
||||
const editingImageRow = ref(null as EditingRow | null)
|
||||
const editingRow = ref(false)
|
||||
const editingRowData = ref(null as EditingRow | null)
|
||||
const columnsByKey = computed(() => Object.assign({}, ...props.columns.map(c => ({[c.name]: c}))))
|
||||
const columnsPrimary = computed(() => props.columns.filter(column => !column.secondary))
|
||||
const selectedTemplate = ref(null as DataRow | null) // simply used to reset dropdown when selected
|
||||
|
@ -86,6 +89,12 @@ const onEditImage = (event: Event, slotProps: EditingRow) => {
|
|||
editingImageRow.value = slotProps
|
||||
}
|
||||
|
||||
const onEditRow = (event: Event, slotProps: EditingRow) => {
|
||||
event.preventDefault()
|
||||
editingRow.value = true
|
||||
editingRowData.value = slotProps
|
||||
}
|
||||
|
||||
const onRemoveImage = (event: Event, slotProps: EditingRow) => {
|
||||
event.preventDefault()
|
||||
const row = { ...model.value[slotProps.index] } as any
|
||||
|
@ -96,6 +105,7 @@ const onRemoveImage = (event: Event, slotProps: EditingRow) => {
|
|||
let rows = editingRows.value
|
||||
rows.splice(indexOfEditing, 1)
|
||||
editingRows.value = rows
|
||||
emits('dirty')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,8 +120,14 @@ const onSaveImage = (image: string) => {
|
|||
let rows = editingRows.value
|
||||
rows.splice(indexOfEditing, 1)
|
||||
editingRows.value = rows
|
||||
emits('dirty')
|
||||
}
|
||||
}
|
||||
|
||||
const onSaveRow = (row: DataRow, editingRow: EditingRow) => {
|
||||
model.value[editingRow.index] = row
|
||||
emits('dirty')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
|
@ -120,6 +136,12 @@ ImageEditor(
|
|||
v-model:row='editingImageRow'
|
||||
@saved='onSaveImage'
|
||||
)
|
||||
DataEditorModal(
|
||||
v-model:visible='editingRow'
|
||||
:row='editingRowData'
|
||||
:fields='columns'
|
||||
@saved='onSaveRow'
|
||||
)
|
||||
DataTable.data-editor(
|
||||
@row-edit-save='onRowEditSave'
|
||||
v-model:editingRows='editingRows'
|
||||
|
@ -258,6 +280,14 @@ DataTable.data-editor(
|
|||
variant='text'
|
||||
@click='slotProps.editorInitCallback'
|
||||
)
|
||||
Button.edit(
|
||||
icon='pi pi-pen-to-square'
|
||||
aria-label='Row Edit Details'
|
||||
rounded
|
||||
severity='secondary'
|
||||
variant='text'
|
||||
@click='(e) => onEditRow(e, slotProps)'
|
||||
)
|
||||
Button(
|
||||
icon='pi pi-trash'
|
||||
aria-label='Delete'
|
||||
|
@ -283,7 +313,7 @@ DataTable.data-editor(
|
|||
rounded
|
||||
severity='secondary'
|
||||
variant='text'
|
||||
@click'slotProps.editorCancelCallback(e)'
|
||||
@click='slotProps.editorCancelCallback(e)'
|
||||
)
|
||||
template(
|
||||
#expansion='slotProps'
|
||||
|
|
119
src/views/Editor/DataEditorModal.vue
Normal file
119
src/views/Editor/DataEditorModal.vue
Normal file
|
@ -0,0 +1,119 @@
|
|||
<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 './types'
|
||||
import type { Row as DataRow, Column as DataColumn } from 'src/types/data'
|
||||
|
||||
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
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
ImageEditor(
|
||||
v-model:visible='editingImage'
|
||||
v-model:row='editingImageRow'
|
||||
@saved='onSaveImage'
|
||||
)
|
||||
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"'
|
||||
)
|
||||
p Image editing in data modal not yet supported
|
||||
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>
|
Loading…
Add table
Reference in a new issue