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) }}#}
{#{% 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 -%}#}
{# {{ form_row(form.privateComment) }}#}
{#{% endif %}#}

View File

@ -2,6 +2,20 @@
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 {
position: relative;
display: flex;

View File

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

View File

@ -16,74 +16,46 @@
class="form-control"
></textarea>
</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>
</template>
<script lang="ts">
import {Ckeditor} from "@ckeditor/ckeditor5-vue";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config"
import {ClassicEditor} from "ckeditor5";
import {onMounted, ref} from "vue"
import { defineComponent, ref, watch, toRefs } from 'vue';
import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { ClassicEditor } from "ckeditor5";
export default {
export default defineComponent({
name: "CommentEditor",
components: {
ckeditor: Ckeditor,
},
setup() {
const isSimple = ref(false);
props: {
type: String,
isSimple: Boolean,
},
setup(props, { emit }) {
const { isSimple } = toRefs(props);
const content = ref("");
const classicEditor = ClassicEditor;
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 = () => {
isSimple.value = !isSimple.value;
localStorage.setItem("isSimpleEditor", String(isSimple.value));
emit("toggle");
};
onMounted(() => initializeEditorPreference())
return {
isSimple,
toggleSimpleEditor,
content: "",
content,
classicEditor,
editorConfig,
buttonText
toggleSimpleEditor
};
},
};
}
});
</script>
<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>

View File

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

View File

@ -1,16 +1,29 @@
import { createApp } from "vue";
import { createApp, reactive } from "vue";
import App from "./App.vue";
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 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({
template: `<app></app>`,
}, { commentMode })
.use(i18n)
.component("app", App)
.mount("#comment-widget");
// Watch for changes to `localStorage` and update the state
window.addEventListener('storage', () => {
globalState.isSimple = localStorage.getItem('editorMode') === 'simple';
});
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
No comment associated: Aucun commentaire
private comment: Notes privées
comment_public: Note
comment_private: Note privée
#pagination
Previous: Précédent