Change logic to allow as many comment vue apps to be charged on same page as needed

This commit is contained in:
Julie Lenaerts 2025-02-06 15:10:49 +01:00
parent 321d569ee9
commit c32c18b0e2
7 changed files with 84 additions and 83 deletions

View File

@ -84,8 +84,15 @@
{# {{ form_row(form.comment) }}#} {# {{ form_row(form.comment) }}#}
{#{% endif %}#} {#{% endif %}#}
<div id="comment-widget" data-comment-mode="{{ 'both' }}"></div> <div class="comment-container">
<label class="col-form-label col-sm-4" for="comment-widget-1">{{ 'comment_public'|trans }}</label>
<div id="comment-widget-1" data-comment-mode="rich"></div>
</div>
<div class="comment-container">
<label class="col-form-label col-sm-4" for="comment-widget-2">{{ 'comment_private'|trans }}</label>
<div id="comment-widget-2" data-comment-mode="rich"></div>
</div>
{#{%- if form.privateComment is defined -%}#} {#{%- if form.privateComment is defined -%}#}
{# {{ form_row(form.privateComment) }}#} {# {{ form_row(form.privateComment) }}#}
{#{% endif %}#} {#{% endif %}#}

View File

@ -2,6 +2,20 @@
margin-top: 1.5rem; margin-top: 1.5rem;
} }
.toggle-button {
position: absolute;
bottom: -10px;
left: 10px;
padding: 2px 6px;
cursor: pointer;
z-index: 10;
}
.editor-wrapper textarea {
resize: vertical;
min-height: 100px;
}
.editor-container { .editor-container {
position: relative; position: relative;
display: flex; display: flex;

View File

@ -1,36 +1,29 @@
<template> <template>
<div> <div>
<div class="comment-container" v-if="shouldRenderPublic"> <div>
<label class="col-form-label" for="content">{{ <comment-editor :isSimple="globalState.isSimple" @toggle="toggleEditorMode"></comment-editor>
$t("comment.label_public")
}}</label>
<comment-editor type="public"></comment-editor>
</div>
<div class="comment-container" v-if="shouldRenderPrivate">
<label class="col-form-label" for="content">{{
$t("comment.label_private")
}}</label>
<comment-editor type="private"></comment-editor>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { defineComponent, inject } from 'vue';
import CommentEditor from "../CommentEditor/component/CommentEditor.vue"; import CommentEditor from "../CommentEditor/component/CommentEditor.vue";
export default { export default defineComponent({
name: "App", name: "App",
components: { CommentEditor }, components: { CommentEditor },
props: { setup() {
commentMode: String, const globalState = inject('globalState');
}, const toggleEditorMode = () => {
computed: { globalState.isSimple = !globalState.isSimple;
shouldRenderPublic() { localStorage.setItem('editorMode', globalState.isSimple ? 'simple' : 'rich');
return this.commentMode === "public" || this.commentMode === "both"; };
},
shouldRenderPrivate() { return {
return this.commentMode === "private" || this.commentMode === "both"; globalState,
}, toggleEditorMode
}, };
}; }
});
</script> </script>

View File

@ -16,74 +16,46 @@
class="form-control" class="form-control"
></textarea> ></textarea>
</div> </div>
<a @click="toggleSimpleEditor" class="toggle-button">{{ buttonText }}</a> <a @click="toggleSimpleEditor" class="toggle-button btn btn-misc">{{ isSimple ? $t("mode.rich") : $t("mode.simple") }}</a>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import {Ckeditor} from "@ckeditor/ckeditor5-vue"; import { defineComponent, ref, watch, toRefs } from 'vue';
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config" import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import {ClassicEditor} from "ckeditor5"; import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import {onMounted, ref} from "vue" import { ClassicEditor } from "ckeditor5";
export default { export default defineComponent({
name: "CommentEditor", name: "CommentEditor",
components: { components: {
ckeditor: Ckeditor, ckeditor: Ckeditor,
}, },
setup() { props: {
const isSimple = ref(false); type: String,
isSimple: Boolean,
},
setup(props, { emit }) {
const { isSimple } = toRefs(props);
const content = ref(""); const content = ref("");
const classicEditor = ClassicEditor; const classicEditor = ClassicEditor;
const editorConfig = classicEditorConfig; const editorConfig = classicEditorConfig;
const buttonText = "Simple editor"
const initializeEditorPreference = () => {
const storedValue = localStorage.getItem("isSimpleEditor");
if (storedValue !== null) {
isSimple.value = storedValue === "true";
} else {
localStorage.setItem("isSimpleEditor", "false");
}
};
const toggleSimpleEditor = () => { const toggleSimpleEditor = () => {
isSimple.value = !isSimple.value; emit("toggle");
localStorage.setItem("isSimpleEditor", String(isSimple.value));
}; };
onMounted(() => initializeEditorPreference())
return { return {
isSimple, isSimple,
toggleSimpleEditor, content,
content: "",
classicEditor, classicEditor,
editorConfig, editorConfig,
buttonText toggleSimpleEditor
}; };
}, }
}; });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.toggle-button {
position: absolute;
bottom: -10px;
left: 10px;
background: white;
padding: 2px 6px;
font-size: 14px;
text-decoration: none;
border-radius: 4px;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
cursor: pointer;
z-index: 10;
}
.editor-wrapper textarea {
resize: vertical;
min-height: 100px;
}
</style> </style>

View File

@ -4,9 +4,9 @@ import {activityMessages} from "ChillActivityAssets/vuejs/Activity/i18n";
const appMessages = { const appMessages = {
fr: { fr: {
comment:{ mode: {
label_public: "Note", simple: "Editeur simple",
label_private: "Note privée", rich: "Editeur riche"
} }
}, },
}; };

View File

@ -1,16 +1,29 @@
import { createApp } from "vue"; import { createApp, reactive } from "vue";
import App from "./App.vue"; import App from "./App.vue";
import {_createI18n} from "ChillMainAssets/vuejs/_js/i18n"; import {_createI18n} from "ChillMainAssets/vuejs/_js/i18n";
import {appMessages} from "ChillMainAssets/vuejs/CommentEditor/i18n"; import { appMessages } from "ChillMainAssets/vuejs/CommentEditor/i18n";
const i18n = _createI18n(appMessages); const i18n = _createI18n(appMessages);
const commentContainer = document.getElementById('comment-widget');
const commentMode = commentContainer.dataset.commentMode; // Global reactive state to handle editorMode
const globalState = reactive({
isSimple: localStorage.getItem('editorMode') === 'simple'
});
const app = createApp({ // Watch for changes to `localStorage` and update the state
template: `<app></app>`, window.addEventListener('storage', () => {
}, { commentMode }) globalState.isSimple = localStorage.getItem('editorMode') === 'simple';
.use(i18n) });
.component("app", App)
.mount("#comment-widget"); const commentWidgets = document.querySelectorAll('[id^="comment-widget"]');
commentWidgets.forEach((commentContainer) => {
const app = createApp({
template: `<app></app>`
});
// Pass the global state to each app instance
app.use(i18n)
.provide('globalState', globalState) // Provide global state to components
.component("app", App)
.mount(commentContainer);
});

View File

@ -109,6 +109,8 @@ Any comment: Aucun commentaire
# comment embeddable # comment embeddable
No comment associated: Aucun commentaire No comment associated: Aucun commentaire
private comment: Notes privées private comment: Notes privées
comment_public: Note
comment_private: Note privée
#pagination #pagination
Previous: Précédent Previous: Précédent