1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-25 00:46:46 +00:00
bramw_baserow/web-frontend/modules/database/components/view/grid/fields/GridViewFieldRichText.vue
2024-04-08 19:11:52 +00:00

140 lines
4.0 KiB
Vue

<!-- eslint-disable vue/no-v-html -->
<template>
<div
ref="cell"
class="grid-view__cell grid-field-rich-text__cell active"
:class="{
editing: opened && !isModalOpen(),
'field-rich-text--preview': !opened || isModalOpen(),
}"
@contextmenu="stopContextIfEditing($event)"
>
<div
v-if="!opened || isModalOpen()"
class="grid-field-rich-text__cell-content"
v-html="formattedValue"
></div>
<RichTextEditor
v-else
ref="input"
v-model="richCopy"
v-prevent-parent-scroll="editing"
class="grid-field-rich-text__textarea"
:class="{ 'grid-field-rich-text__textarea--resizable': editing }"
:editable="editing && !isModalOpen()"
:enable-rich-text-formatting="true"
:mentionable-users="workspace ? workspace.users : null"
:thin-scrollbar="true"
></RichTextEditor>
<i
v-if="editing && !isModalOpen()"
class="baserow-icon-enlarge grid-field-rich-text__textarea-expand-icon"
@click="
$refs.expandedModal.toggle()
resetCellSize()
"
></i>
<FieldRichTextModal
ref="expandedModal"
v-model="richCopy"
:field="field"
:mentionable-users="workspace ? workspace.users : null"
@hidden="onExpandedModalHidden"
></FieldRichTextModal>
</div>
</template>
<script>
import RichTextEditor from '@baserow/modules/core/components/editor/RichTextEditor.vue'
import gridField from '@baserow/modules/database/mixins/gridField'
import gridFieldInput from '@baserow/modules/database/mixins/gridFieldInput'
import FieldRichTextModal from '@baserow/modules/database/components/view/FieldRichTextModal'
import { parseMarkdown } from '@baserow/modules/core/editor/markdown'
export default {
components: { RichTextEditor, FieldRichTextModal },
mixins: [gridField, gridFieldInput],
data() {
return {
// local copy of the value storing the JSON representation of the rich text editor
richCopy: '',
}
},
computed: {
formattedValue() {
return parseMarkdown(this.value, {
openLinkOnClick: true,
workspaceUsers: this.workspace ? this.workspace.users : null,
loggedUserId: this.$store.getters['auth/getUserId'],
})
},
workspace() {
return this.$store.getters['workspace/get'](this.workspaceId)
},
},
watch: {
value: {
handler(value) {
this.richCopy = value || ''
},
immediate: true,
},
editing(editing) {
if (!editing) {
this.richCopy = this.value || ''
}
},
},
methods: {
isModalOpen() {
return this.$refs.expandedModal?.isOpen()
},
scrollHeight() {
return {
sh: this.$refs.container.scrollHeight,
st: this.$refs.container.scrollTop,
}
},
cancel() {
return this.save()
},
beforeSave() {
const ref = this.isModalOpen() ? 'expandedModal' : 'input'
return this.$refs[ref].serializeToMarkdown()
},
afterEdit() {
this.$nextTick(() => {
this.$refs.input.focus()
})
},
onExpandedModalHidden() {
this.preventNextUnselect = true
this.save()
},
canSaveByPressingEnter() {
return false
},
resetCellSize() {
// remove any custom width and height set by the user resizing the cell
this.$refs.input.$el.style.width = ''
this.$refs.input.$el.style.height = ''
},
canUnselectByClickingOutside(event) {
// The RichTextEditorBubbleMenuContext component is a context menu and so it's not
// a direct child of the RichTextEditorBubbleMenu component. This means that the
// when you click on an item, we have to prevent the next unselect event from
// happening otherwise the cell will lose focus and the editor will close.
if (this.preventNextUnselect) {
this.preventNextUnselect = false
return false
}
return (
!this.editing ||
(!this.$refs.input?.isEventTargetInside(event) && !this.isModalOpen())
)
},
},
}
</script>