Skip to content

Commit 34df767

Browse files
Merge pull request #7389 from christianbeeznest/GH-7355-2
Internal: Fix doc picker mode switch and document move after resource_link changes - refs #7355
2 parents b1f0e79 + 2924783 commit 34df767

7 files changed

Lines changed: 579 additions & 126 deletions

File tree

assets/vue/App.vue

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
/>
2828
<ConfirmDialog />
2929
<AccessUrlChooser v-if="!showAccessUrlChosserLayout" />
30+
31+
<!-- Do not show docked chat in embedded contexts (iframes/pickers/dialogs) -->
3032
<DockedChat v-if="showGlobalChat" />
3133
</component>
3234

@@ -101,13 +103,43 @@ const showAccessUrlChosserLayout = computed(
101103
() => securityStore.isAuthenticated && !securityStore.isAdmin && accessUrlChooserVisible.value,
102104
)
103105
106+
// ---- Embedded context detection (iframe/dialog/picker) ----
107+
const queryParams = computed(() => new URLSearchParams(window.location.search))
108+
109+
const isPickerContext = computed(() => {
110+
const picker = String(queryParams.value.get("picker") || "").toLowerCase()
111+
return picker === "tinymce" || picker === "ckeditor"
112+
})
113+
114+
const isIframeContext = computed(() => {
115+
// Safe checks: if cross-origin, accessing window.top can throw.
116+
try {
117+
return window.self !== window.top
118+
} catch (e) {
119+
// If we cannot access window.top, we assume we are inside an iframe.
120+
return true
121+
}
122+
})
123+
124+
const isDialogContext = computed(() => {
125+
// allow explicit opt-out via query param.
126+
// Example: ?hideChat=1
127+
const hideChat = String(queryParams.value.get("hideChat") || "").toLowerCase()
128+
return hideChat === "1" || hideChat === "true"
129+
})
130+
131+
const isEmbeddedContext = computed(() => {
132+
// In embedded contexts, we must not render global docked chat to avoid duplicated UI.
133+
return isPickerContext.value || isIframeContext.value || isDialogContext.value
134+
})
135+
104136
const layout = computed(() => {
105137
if (showAccessUrlChosserLayout.value) {
106138
return AccessUrlChooserLayout
107139
}
108140
109-
const queryParams = new URLSearchParams(window.location.search)
110-
const picker = String(queryParams.get("picker") || "").toLowerCase()
141+
const qp = queryParams.value
142+
const picker = String(qp.get("picker") || "").toLowerCase()
111143
112144
// Force EmptyLayout for embedded editor pickers (TinyMCE/CKEditor)
113145
if (picker === "tinymce" || picker === "ckeditor") {
@@ -119,8 +151,8 @@ const layout = computed(() => {
119151
}
120152
121153
if (
122-
(queryParams.has("lp_id") && "view" === queryParams.get("action")) ||
123-
(queryParams.has("origin") && "learnpath" === queryParams.get("origin"))
154+
(qp.has("lp_id") && "view" === qp.get("action")) ||
155+
(qp.has("origin") && "learnpath" === qp.get("origin"))
124156
) {
125157
return EmptyLayout
126158
}
@@ -244,7 +276,8 @@ const allowGlobalChat = computed(() => {
244276
})
245277
246278
const showGlobalChat = computed(() => {
247-
return securityStore.isAuthenticated && allowGlobalChat.value
279+
// Do not render global chat when the app is embedded (iframe/dialog/picker).
280+
return securityStore.isAuthenticated && allowGlobalChat.value && !isEmbeddedContext.value
248281
})
249282
250283
watch(forbiddenMsg, (msg) => {

0 commit comments

Comments
 (0)