Skip to content

Commit 41df944

Browse files
Merge pull request #8523 from christianbeeznest/fixes-updates465
Document: Improve document editor defaults and option help
2 parents 8ac06d1 + e480ac8 commit 41df944

4 files changed

Lines changed: 333 additions & 53 deletions

File tree

assets/vue/components/documents/FormNewDocument.vue

Lines changed: 109 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
v-model="item.contentFile"
2525
:full-page="isFullPage"
2626
:title="t('Content')"
27+
:editor-config="tinyEditorConfig"
2728
editor-id="item_content"
2829
/>
2930
</div>
@@ -114,16 +115,28 @@
114115

115116
<div
116117
v-if="searchEnabled"
117-
class="mb-2 flex flex-row"
118+
class="mb-3 flex flex-col gap-2 sm:flex-row sm:items-center"
118119
>
119-
<label class="w-40 font-semibold">{{ $t("Options") }}:</label>
120-
121-
<BaseCheckbox
122-
id="indexDocumentContent"
123-
v-model="item.indexDocumentContent"
124-
:label="$t('Index document content?')"
125-
name="indexDocumentContent"
126-
/>
120+
<div class="flex w-40 shrink-0 items-center gap-1 font-semibold">
121+
<span>{{ $t("Options") }}:</span>
122+
</div>
123+
124+
<div class="flex items-center gap-2">
125+
<BaseCheckbox
126+
id="indexDocumentContent"
127+
v-model="item.indexDocumentContent"
128+
:label="$t('Index document content?')"
129+
name="indexDocumentContent"
130+
/>
131+
132+
<span
133+
class="mdi mdi-information-outline cursor-help text-primary"
134+
role="img"
135+
tabindex="0"
136+
:aria-label="t('Information about indexing document content')"
137+
:title="t('When enabled, the document text is indexed by the search engine so users can find it from platform search.')"
138+
/>
139+
</div>
127140
</div>
128141

129142
<div
@@ -251,6 +264,7 @@ export default {
251264
editorDraftIntervalId: null,
252265
lastEditorDraftContent: "",
253266
maxEditorDrafts: 5,
267+
editorDraftIntervalMs: 60000,
254268
showEditorDrafts: false,
255269
}
256270
},
@@ -308,11 +322,16 @@ export default {
308322
return aiHelpersEnabled && (imageGeneratorEnabled || videoGeneratorEnabled)
309323
},
310324
tinyEditorConfig() {
325+
const config = {
326+
content_style: this.getDocumentEditorContentStyle(),
327+
}
328+
311329
if (!this.showAiMediaButton) {
312-
return {}
330+
return config
313331
}
314332
315333
return {
334+
...config,
316335
appendToolbar: "chamiloAiMedia",
317336
setup: (editor) => {
318337
editor.ui.registry.addIcon(
@@ -365,10 +384,10 @@ export default {
365384
this.item.indexDocumentContent = true
366385
}
367386
368-
this.ensureResourceLanguage()
369-
370387
await this.loadCourseContext()
371388
389+
this.ensureResourceLanguage()
390+
372391
if (!this.searchEnabled) {
373392
return
374393
}
@@ -379,7 +398,7 @@ export default {
379398
mounted() {
380399
this.refreshEditorDrafts()
381400
this.lastEditorDraftContent = this.normalizeEditorDraftContent(this.item.contentFile)
382-
this.editorDraftIntervalId = window.setInterval(this.saveEditorDraft, 30000)
401+
this.editorDraftIntervalId = window.setInterval(this.saveEditorDraft, this.editorDraftIntervalMs)
383402
window.addEventListener("beforeunload", this.saveEditorDraftOnUnload)
384403
},
385404
beforeUnmount() {
@@ -399,35 +418,88 @@ export default {
399418
},
400419
},
401420
methods: {
421+
getDocumentEditorContentStyle() {
422+
const baseStyle =
423+
typeof window !== "undefined" ? String(window.CHAMILO_TINYMCE_BASE_CONFIG?.content_style || "") : ""
424+
425+
return `${baseStyle}
426+
body {
427+
box-sizing: border-box;
428+
padding-left: 0.5rem;
429+
padding-right: 0.5rem;
430+
}
431+
`
432+
},
433+
normalizeLanguageIso(value) {
434+
const raw = String(value || "").trim()
435+
if (!raw) {
436+
return ""
437+
}
438+
439+
const languages = Array.isArray(window.languages) ? window.languages : []
440+
const iriMatch = raw.match(/\/api\/languages\/(\d+)/)
441+
if (iriMatch) {
442+
const byId = languages.find((language) => String(language?.id || "") === iriMatch[1])
443+
return String(byId?.isocode || byId?.isoCode || "")
444+
}
445+
446+
const normalizedRaw = raw.replace("-", "_").toLowerCase()
447+
const exact = languages.find((language) => {
448+
const code = String(language?.isocode || language?.isoCode || "")
449+
.replace("-", "_")
450+
.toLowerCase()
451+
452+
return code === normalizedRaw
453+
})
454+
455+
if (exact) {
456+
return String(exact.isocode || exact.isoCode || "")
457+
}
458+
459+
const shortCode = normalizedRaw.split("_")[0]
460+
const byShortCode = languages.find((language) => {
461+
const code = String(language?.isocode || language?.isoCode || "")
462+
.replace("-", "_")
463+
.toLowerCase()
464+
465+
return code === shortCode || code.startsWith(`${shortCode}_`)
466+
})
467+
468+
return String(byShortCode?.isocode || byShortCode?.isoCode || raw)
469+
},
402470
extractResourceLanguageIso(language) {
403471
if (!language) {
404472
return ""
405473
}
406474
407475
if ("string" === typeof language) {
408-
const iriMatch = language.match(/\/api\/languages\/(\d+)/)
409-
if (!iriMatch) {
410-
return language
411-
}
412-
413-
const languages = Array.isArray(window.languages) ? window.languages : []
414-
const found = languages.find((item) => String(item?.id || "") === iriMatch[1])
415-
416-
return String(found?.isocode || "")
476+
return this.normalizeLanguageIso(language)
417477
}
418478
419-
return String(language.isocode || language.isoCode || "")
479+
return this.normalizeLanguageIso(language.isocode || language.isoCode || language["@id"] || "")
420480
},
421481
ensureResourceLanguage() {
422-
if (!this.item || undefined !== this.item.language) {
482+
if (!this.item) {
423483
return
424484
}
425485
426-
this.item.language = this.extractResourceLanguageIso(
486+
const currentLanguage = this.extractResourceLanguageIso(this.item.language)
487+
if (currentLanguage) {
488+
if (currentLanguage !== this.item.language) {
489+
this.item.language = currentLanguage
490+
}
491+
492+
return
493+
}
494+
495+
const fallbackLanguage = this.extractResourceLanguageIso(
427496
this.item?.resourceNode?.language ||
428497
this.item?.resourceNode?.firstResourceFile?.language ||
429498
this.item?.firstResourceFile?.language,
430499
)
500+
501+
const courseLanguage = this.extractResourceLanguageIso(this.courseContextLanguage)
502+
this.item.language = fallbackLanguage || courseLanguage || ""
431503
},
432504
getEditorDraftUserId() {
433505
const user = this.securityStore?.user || {}
@@ -550,9 +622,15 @@ export default {
550622
return
551623
}
552624
553-
const drafts = this.readEditorDrafts().filter(
554-
(draft) => this.normalizeEditorDraftContent(draft.content) !== content,
555-
)
625+
const storedDrafts = this.readEditorDrafts()
626+
const latestStoredDraft = storedDrafts[0] || null
627+
628+
if (latestStoredDraft && this.normalizeEditorDraftContent(latestStoredDraft.content) === content) {
629+
this.lastEditorDraftContent = content
630+
return
631+
}
632+
633+
const drafts = storedDrafts.filter((draft) => this.normalizeEditorDraftContent(draft.content) !== content)
556634
const draft = {
557635
id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
558636
title: String(this.item.title || "").trim(),
@@ -660,7 +738,7 @@ export default {
660738
async loadCourseContext() {
661739
const cid = Number(this.$route?.query?.cid || 0)
662740
this.courseContextTitle = String(this.$route?.query?.course_title || "").trim()
663-
this.courseContextLanguage = String(this.$route?.query?.course_language || this.locale || "en").trim()
741+
this.courseContextLanguage = String(this.$route?.query?.course_language || "").trim()
664742
665743
if (!cid) {
666744
return
@@ -671,14 +749,15 @@ export default {
671749
const data = response?.data || {}
672750
673751
const apiTitle = String(data?.title || data?.name || "").trim()
674-
const apiLanguage = String(data?.language || "").trim()
752+
const apiLanguage = String(data?.courseLanguage || data?.course_language || data?.language || "").trim()
675753
676754
if (apiTitle) {
677755
this.courseContextTitle = apiTitle
678756
}
679757
680758
if (apiLanguage) {
681759
this.courseContextLanguage = apiLanguage
760+
this.ensureResourceLanguage()
682761
}
683762
} catch (error) {
684763
console.warn("[DocumentsForm] Failed to load course context.", error)

0 commit comments

Comments
 (0)