1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-11 07:51:20 +00:00

000 📚: Fix rendering diffs in grid view for the rich text field

This commit is contained in:
Davide Silvestri 2024-03-25 11:13:01 +00:00
parent 3fd4b604fb
commit 4bfe3ae299
8 changed files with 145 additions and 200 deletions
premium/web-frontend/modules/baserow_premium/assets/scss/components
web-frontend/modules
core
assets/scss/components
components/editor
editor
database/components

View file

@ -20,60 +20,11 @@
}
}
.rich-text-editor__content--scaled {
overflow: hidden;
h1, h2, h3, p, a, ul, ol, li, blockquote, pre, code {
@include fixed-height(32px, 13px);
padding: 0;
margin-top: 0;
margin-bottom: 0;
color: revert;
}
h1, h2, h3, p, a, blockquote, pre, code {
@extend %ellipsis;
}
ul {
list-style-type: disc;
margin-left: 0;
padding-left: 0;
}
li {
margin-left: 20px;
}
ul[data-type='taskList'] li {
margin-left: 0;
}
pre {
display: flex;
align-items: center;
height: 22px;
padding: 0 2px;
width: fit-content;
margin-top: 5px;
max-width: 100%;
}
blockquote {
margin-left: 0;
display: flex;
align-items: center;
height: 22px;
padding-left: 6px;
width: fit-content;
margin-top: 5px;
max-width: 100%;
}
}
.rich-text-editor__content-blockquote {
padding-left: 1rem;
color: $color-neutral-700;
border-left: 4px solid $color-neutral-300;
}
.rich-text-editor__content {
width: 100%;
@ -112,10 +63,9 @@
}
blockquote {
@extend .rich-text-editor__content-blockquote;
margin: 1rem;
padding-left: 1rem;
color: $color-neutral-700;
border-left: 4px solid $color-neutral-300;
}
pre {
@ -144,63 +94,6 @@
}
}
.rich-text-editor__content.rich-text-editor__content--scaled {
overflow: hidden;
height: 100%;
/* stylelint-disable-next-line no-descending-specificity */
h1, h2, h3, p, a, ul, ol, li, blockquote, pre, code {
@include fixed-height(32px, 13px);
padding: 0;
margin-top: 0;
margin-bottom: 0;
color: revert;
}
h1, h2, h3, p, a, blockquote, pre, code {
@extend %ellipsis;
}
ul {
list-style-type: disc;
margin-left: 0;
padding-left: 0;
}
/* stylelint-disable-next-line no-descending-specificity */
li {
margin-left: 20px;
}
ul[data-type='taskList'] li {
margin-left: 0;
}
pre {
display: flex;
align-items: center;
height: 22px;
padding: 0 2px;
width: fit-content;
margin-top: 5px;
max-width: 100%;
}
blockquote {
margin-left: 0;
display: flex;
align-items: center;
height: 22px;
padding-left: 6px;
width: fit-content;
margin-top: 5px;
max-width: 100%;
}
}
.rich-text-editor__content--comment {
max-height: 50vh;
overflow: auto;

View file

@ -11,3 +11,89 @@
background-color: $palette-neutral-700;
}
}
.field-rich-text--preview {
overflow: hidden;
h1,
h2,
h3,
p,
a,
ul,
ol,
li,
blockquote,
pre,
code {
@include fixed-height(32px, 13px);
padding: 0;
margin-top: 0;
margin-bottom: 0;
color: revert;
}
h1,
h2,
h3,
p,
a,
blockquote,
pre,
code {
@extend %ellipsis;
}
ul {
list-style-type: disc;
margin-left: 0;
padding-left: 0;
}
li {
margin-left: 20px;
}
blockquote {
@extend .rich-text-editor__content-blockquote;
margin: 5px 0 0 0;
display: flex;
align-items: center;
height: 22px;
padding-left: 6px;
width: fit-content;
max-width: 100%;
}
pre {
background-color: $color-neutral-100;
border-radius: $rounded;
display: flex;
align-items: center;
height: 22px;
padding: 0 2px;
width: fit-content;
margin-top: 5px;
max-width: 100%;
}
ul.contains-task-list {
list-style-type: none;
li {
margin-left: 0;
label {
@extend %ellipsis;
@include fixed-height(32px, 13px);
display: flex;
align-items: center;
gap: 8px;
pointer-events: none;
}
}
}
}

View file

@ -1,33 +1,7 @@
.grid-field-rich-text__cell {
@extend .grid-field-long-text__cell;
&.grid-field-rich-text__cell--preview {
@extend .rich-text-editor__content.rich-text-editor__content--scaled;
padding: 0 10px;
pre {
background-color: $color-neutral-100;
border-radius: $rounded;
}
ul.contains-task-list {
list-style-type: none;
li {
margin-left: 0;
label {
@extend %ellipsis;
@include fixed-height(32px, 13px);
display: flex;
align-items: center;
gap: 8px;
}
}
}
}
padding: 0 10px;
}
.grid-field-rich-text {

View file

@ -24,12 +24,7 @@
</div>
<EditorContent
class="rich-text-editor__content"
:class="[
{
'rich-text-editor__content--scaled': contentScaled,
},
editorClass,
]"
:class="editorClass"
:editor="editor"
/>
</div>
@ -120,10 +115,6 @@ export default {
type: String,
default: '',
},
contentScaled: {
type: Boolean,
default: false,
},
enableMentions: {
type: Boolean,
default: false,

View file

@ -0,0 +1,8 @@
import Markdown from 'markdown-it'
import taskLists from 'markdown-it-task-lists'
const md = new Markdown({ html: false })
md.use(taskLists, { label: true, enabled: true })
export const defaultMarkdownParser = md
export const parseMarkdown = (markdown) => md.render(markdown)

View file

@ -1,19 +1,15 @@
<template>
<div class="card-rich-text">
<RichTextEditor
:content-scaled="true"
:editable="false"
:enable-rich-text-formatting="true"
:value="value"
></RichTextEditor>
</div>
<!-- eslint-disable-next-line vue/no-v-html -->
<div
class="card-rich-text field-rich-text--preview"
v-html="formattedValue"
></div>
</template>
<script>
import RichTextEditor from '@baserow/modules/core/components/editor/RichTextEditor.vue'
import { parseMarkdown } from '@baserow/modules/core/editor/markdown'
export default {
components: { RichTextEditor },
props: {
value: {
type: String,
@ -22,8 +18,8 @@ export default {
},
height: 32,
computed: {
richValue() {
return this.value || ''
formattedValue() {
return parseMarkdown(this.value || '')
},
},
}

View file

@ -1,34 +1,29 @@
<!-- eslint-disable vue/no-v-html -->
<template functional>
<div
class="field-rich-text--preview grid-view__cell grid-field-rich-text__cell"
v-html="$options.methods.renderFormattedValue(props.value)"
></div>
</template>
<script>
import Markdown from 'markdown-it'
import taskLists from 'markdown-it-task-lists'
import { parseMarkdown } from '@baserow/modules/core/editor/markdown'
export default {
functional: true,
render(createElement, context) {
const { props } = context
const md = new Markdown({ html: false })
function parseMarkdown(value) {
return md.use(taskLists, { label: true, enabled: true }).render(value)
}
// Take only a part of the text as a preview to avoid rendering a huge amount of
// HTML that could slow down the page and won't be visible anyway
let preview = ''
if (props.value) {
preview = props.value.substring(0, 200)
if (props.value.length > 200) {
preview += '...'
name: 'FunctionalGridViewFieldRichText',
methods: {
renderFormattedValue(value) {
// Take only a part of the text as a preview to avoid rendering a huge amount of
// HTML that could slow down the page and won't be visible anyway
let preview = ''
if (value) {
preview = value.substring(0, 200)
if (value.length > 200) {
preview += '...'
}
}
}
return createElement('div', {
class:
'grid-view__cell grid-field-rich-text__cell grid-field-rich-text__cell--preview',
domProps: {
innerHTML: parseMarkdown(preview),
},
})
return parseMarkdown(preview)
},
},
}
</script>

View file

@ -2,14 +2,21 @@
<div
ref="cell"
class="grid-view__cell grid-field-rich-text__cell active"
:class="{ editing: opened && !isModalOpen() }"
:class="{
editing: opened && !isModalOpen(),
'field-rich-text--preview': !opened || isModalOpen(),
}"
@contextmenu="stopContextIfEditing($event)"
>
<!-- eslint-disable-next-line vue/no-v-html -->
<div v-if="!opened || isModalOpen()" v-html="formattedValue"></div>
<RichTextEditor
v-else
ref="input"
v-model="richCopy"
v-prevent-parent-scroll="editing"
:class="classNames"
class="grid-field-rich-text__textarea"
:class="{ 'grid-field-rich-text__textarea--resizable': editing }"
:editable="editing && !isModalOpen()"
:content-scaled="!opened || isModalOpen()"
:enable-rich-text-formatting="true"
@ -37,6 +44,7 @@ import RichTextEditor from '@baserow/modules/core/components/editor/RichTextEdit
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 },
@ -48,14 +56,8 @@ export default {
}
},
computed: {
classNames() {
if (!this.opened || this.isModalOpen()) {
return 'grid-field-rich-text'
} else if (this.editing) {
return 'grid-field-rich-text__textarea grid-field-rich-text__textarea--resizable'
} else {
return 'grid-field-rich-text__textarea'
}
formattedValue() {
return parseMarkdown(this.value)
},
},
watch: {