Commit 67b936db authored by MARCO Jonathan's avatar MARCO Jonathan
Browse files

馃毀 Can update translation for the rich text

parent cc4caef5
<template>
<v-row class="flex-column">
<v-col v-if="isEditable">
<v-card class="ma-2" flat outlined tile>
<v-card-title class="pa-0">
<editor-menu-bar :editor="editor" v-slot="{ commands, getMarkAttrs, isActive }">
<v-toolbar color="primary" flat dense>
<v-toolbar-items>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.bold()) }"
:color="isActive.bold() ? 'secondary' : 'primary'"
@click="commands.bold"
>
<v-icon small>mdi-format-bold</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.italic()) }"
:color="isActive.italic() ? 'secondary' : 'primary'"
@click="commands.italic"
>
<v-icon small>mdi-format-italic</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.heading({ level: 1 })) }"
:color="isActive.heading({ level: 1 }) ? 'secondary' : 'primary'"
@click="commands.heading({ level: 1 })"
>
<v-icon small>mdi-format-header-1</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.heading({ level: 2 })) }"
:color="isActive.heading({ level: 2 }) ? 'secondary' : 'primary'"
@click="commands.heading({ level: 2 })"
>
<v-icon small>mdi-format-header-2</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.heading({ level: 3 })) }"
:color="isActive.heading({ level: 3 }) ? 'secondary' : 'primary'"
@click="commands.heading({ level: 3 })"
>
<v-icon small>mdi-format-header-3</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.link()) }"
:color="isActive.link() ? 'secondary' : 'primary'"
@click.stop="showLinkDialog(getMarkAttrs('link'))"
>
<v-icon small>mdi-link</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.bullet_list()) }"
:color="isActive.bullet_list() ? 'secondary' : 'primary'"
@click="commands.bullet_list"
>
<v-icon small>mdi-format-list-bulleted</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.ordered_list()) }"
:color="isActive.ordered_list() ? 'secondary' : 'primary'"
@click="commands.ordered_list"
>
<v-icon small>mdi-format-list-numbered</v-icon>
</v-btn>
<section>
<v-row>
<v-col>
<v-select
:label="_uct('builder.tabs.data.localeRichText.label')"
:items="locales"
item-text="locale"
item-value="locale"
:value="localeSelected"
@change="updateLocaleSelected"
/>
</v-col>
</v-row>
<v-row class="flex-column">
<v-col v-if="isEditable">
<v-card class="ma-2" flat outlined tile>
<v-card-title class="pa-0">
<editor-menu-bar :editor="editor" v-slot="{ commands, getMarkAttrs, isActive }">
<v-toolbar color="primary" flat dense>
<v-toolbar-items>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.bold()) }"
:color="isActive.bold() ? 'secondary' : 'primary'"
@click="commands.bold"
>
<v-icon small>mdi-format-bold</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.italic()) }"
:color="isActive.italic() ? 'secondary' : 'primary'"
@click="commands.italic"
>
<v-icon small>mdi-format-italic</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.heading({ level: 1 })) }"
:color="isActive.heading({ level: 1 }) ? 'secondary' : 'primary'"
@click="commands.heading({ level: 1 })"
>
<v-icon small>mdi-format-header-1</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.heading({ level: 2 })) }"
:color="isActive.heading({ level: 2 }) ? 'secondary' : 'primary'"
@click="commands.heading({ level: 2 })"
>
<v-icon small>mdi-format-header-2</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.heading({ level: 3 })) }"
:color="isActive.heading({ level: 3 }) ? 'secondary' : 'primary'"
@click="commands.heading({ level: 3 })"
>
<v-icon small>mdi-format-header-3</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.link()) }"
:color="isActive.link() ? 'secondary' : 'primary'"
@click.stop="showLinkDialog(getMarkAttrs('link'))"
>
<v-icon small>mdi-link</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.bullet_list()) }"
:color="isActive.bullet_list() ? 'secondary' : 'primary'"
@click="commands.bullet_list"
>
<v-icon small>mdi-format-list-bulleted</v-icon>
</v-btn>
<v-btn
tile
elevation="0"
x-small
:class="{ 'light-button': !isLightButton(isActive.ordered_list()) }"
:color="isActive.ordered_list() ? 'secondary' : 'primary'"
@click="commands.ordered_list"
>
<v-icon small>mdi-format-list-numbered</v-icon>
</v-btn>
<!-- dialog to add link -->
<v-dialog
v-model="link.dialog.display"
max-width="300"
>
<v-card>
<v-card-title>
{{ isActive.link() ? 'Update link' : 'Add link' }}
</v-card-title>
<v-divider />
<v-card-text>
<v-text-field
v-model="link.url"
label="URL"
placeholder="https://"
hint="Enter URL"
>
</v-text-field>
</v-card-text>
<v-divider />
<v-card-actions>
<v-spacer />
<v-btn
outlined
tile
elevation="0"
color="primary"
@click="saveLink(commands.link, null)"
>
<strong>Close</strong>
</v-btn>
<v-btn
tile
elevation="0"
color="primary"
@click="saveLink(commands.link, link.url)"
>
<strong>Save</strong>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar-items>
</v-toolbar>
</editor-menu-bar>
</v-card-title>
<v-card-text class="pa-4">
<editor-content class="content-editor" :editor="editor" />
</v-card-text>
</v-card>
</v-col>
</v-row>
<!-- dialog to add link -->
<v-dialog
v-model="link.dialog.display"
max-width="300"
>
<v-card>
<v-card-title>
{{ isActive.link() ? 'Update link' : 'Add link' }}
</v-card-title>
<v-divider/>
<v-card-text>
<v-text-field
v-model="link.url"
label="URL"
placeholder="https://"
hint="Enter URL"
>
</v-text-field>
</v-card-text>
<v-divider/>
<v-card-actions>
<v-spacer/>
<v-btn
outlined
tile
elevation="0"
color="primary"
@click="saveLink(commands.link, null)"
>
<strong>Close</strong>
</v-btn>
<v-btn
tile
elevation="0"
color="primary"
@click="saveLink(commands.link, link.url)"
>
<strong>Save</strong>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar-items>
</v-toolbar>
</editor-menu-bar>
</v-card-title>
<v-card-text class="pa-4">
<editor-content class="content-editor" :editor="editor"/>
</v-card-text>
</v-card>
</v-col>
</v-row>
</section>
</template>
<script lang="ts">
......@@ -155,6 +169,10 @@ import {
} from 'tiptap-extensions';
import { CustomLink } from '@form-plugin/utils';
import Vue from 'vue';
import { Field } from '#form-plugin/models/form';
import { Control } from '#form-plugin/models/control';
import { LocaleNameAndRTLStatus } from '@form-plugin/store/modules/form/messages/getters';
import { mapActions, mapGetters } from 'vuex';
export default Vue.extend({
name: 'UsfTabDataLayout',
......@@ -174,6 +192,7 @@ export default Vue.extend({
},
data: () => ({
localeSelected: '',
editor: null,
savedContent: '',
savedContentJson: '',
......@@ -184,40 +203,25 @@ export default Vue.extend({
}),
computed: {
field() {
...mapGetters('form', [
'fallbackLocale',
'locales',
]),
field(): Field {
return this.$store.getters['form/getFieldById'](this.fieldId);
},
fieldControl() {
fieldControl(): Control {
return this.$store.getters['formBuilder/controls/getControlById'](this.field.component);
},
isEditable() {
isEditable(): boolean {
return this.fieldControl.usfSubtypes.some(subtype => subtype === 'editable');
},
},
created() {
// @ts-ignore
this.editor = new Editor({
onUpdate: ({ getHTML }) => {
this.updateField('content', getHTML());
},
content: this.field.content || this._uct('builder.tabs.data.richTextDefaultValue'),
extensions: [
// @ts-ignore
new Bold(),
// @ts-ignore
new Italic(),
// @ts-ignore
new Heading({ levels: [1, 2, 3] }),
// @ts-ignore
new BulletList(),
// @ts-ignore
new OrderedList(),
// @ts-ignore
new ListItem(),
new CustomLink(),
],
});
this.localeSelected = this.$store.getters['form/fallbackLocale'] || 'fr';
this.editor?.destroy();
this.initEditor();
},
beforeDestroy() {
......@@ -225,6 +229,9 @@ export default Vue.extend({
},
methods: {
...mapActions('form', [
'updateTranslation',
]),
/**
* Update the color of the button text
*
......@@ -234,8 +241,22 @@ export default Vue.extend({
isLightButton(action: boolean): boolean {
return action ? this.secondaryIsDark : this.primaryIsDark;
},
updateField(attribute, value) {
this.$store.dispatch('form/updateField', { id: this.field.id, attribute, value });
updateField(attribute: 'content', value: string) {
if (this.localeSelected === this.fallbackLocale) {
this.$store.dispatch('form/updateField', { id: this.field.id, attribute, value });
}
this.updateTranslation({
id: this.fieldId,
locale: this.localeSelected,
attribute: 'content',
translation: value,
});
},
updateLocaleSelected(newLocaleSelected: string): void {
this.localeSelected = newLocaleSelected;
this.editor?.destroy();
this.initEditor();
},
showLinkDialog(attrs) {
this.link.url = attrs.href;
......@@ -251,6 +272,43 @@ export default Vue.extend({
});
this.closeLinkDialog();
},
initEditor(): void {
let content = this._uct('builder.tabs.data.richTextDefaultValue');
const contentTranslated = this.$store.getters['form/translation'](
this.fieldId,
this.localeSelected,
'content',
);
if (contentTranslated !== '') {
content = contentTranslated;
} else if (this.localeSelected === this.fallbackLocale && this.field.content !== '') {
content = this.field.content;
}
// @ts-ignore
this.editor = new Editor({
onUpdate: ({ getHTML }) => {
this.updateField('content', getHTML());
},
content,
extensions: [
// @ts-ignore
new Bold(),
// @ts-ignore
new Italic(),
// @ts-ignore
new Heading({ levels: [1, 2, 3] }),
// @ts-ignore
new BulletList(),
// @ts-ignore
new OrderedList(),
// @ts-ignore
new ListItem(),
new CustomLink(),
],
});
},
},
});
</script>
......
import {AppMessages} from '#form-plugin/index';
import { AppMessages } from '#form-plugin/index';
export const fr: AppMessages = {
builder: {
......@@ -117,6 +117,9 @@ export const fr: AppMessages = {
value: 'Valeur',
},
displayedBy: 'Afficher par...',
localeRichText: {
label: 'Langue',
},
multiple: 'Multiple',
options: {
dependsOn: 'D茅pend de...',
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment