Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Added SessionGuard component to manage session expiration and online status. - Updated AuthProvider to streamline session fetching and handling. - Introduced IdentityProvidersSection for managing OAuth, SAML, and LDAP identity providers. - Implemented identity provider guides for easier configuration. - Enhanced mail settings with infinite scroll option for improved user experience. - Updated global styles and layout components for better consistency across the application.
118 lines
3.2 KiB
TypeScript
118 lines
3.2 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useRef } from "react"
|
|
|
|
type DocEditorInstance = { destroyEditor: () => void }
|
|
|
|
declare global {
|
|
interface Window {
|
|
DocsAPI?: {
|
|
DocEditor: new (id: string, config: Record<string, unknown>) => DocEditorInstance
|
|
}
|
|
DocEditor?: { instances: Record<string, DocEditorInstance | undefined> }
|
|
}
|
|
}
|
|
|
|
let docsApiLoad: Promise<void> | null = null
|
|
|
|
function loadDocsApi(documentServerUrl: string, scriptId: string): Promise<void> {
|
|
if (window.DocsAPI) return Promise.resolve()
|
|
if (docsApiLoad) return docsApiLoad
|
|
|
|
const base = documentServerUrl.replace(/\/$/, "") + "/"
|
|
docsApiLoad = new Promise((resolve, reject) => {
|
|
const script = document.createElement("script")
|
|
script.id = scriptId
|
|
script.src = `${base}web-apps/apps/api/documents/api.js`
|
|
script.async = true
|
|
script.onload = () => resolve()
|
|
script.onerror = () => {
|
|
docsApiLoad = null
|
|
reject(new Error(`Error load DocsAPI from ${base}`))
|
|
}
|
|
document.body.appendChild(script)
|
|
})
|
|
|
|
return docsApiLoad
|
|
}
|
|
|
|
function destroyDocEditor(id: string) {
|
|
const inst = window.DocEditor?.instances?.[id]
|
|
if (inst) {
|
|
try {
|
|
inst.destroyEditor()
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
delete window.DocEditor!.instances[id]
|
|
}
|
|
document.getElementById(id)?.replaceChildren()
|
|
}
|
|
|
|
export function OnlyOfficeMount({
|
|
editorId,
|
|
documentServerUrl,
|
|
config,
|
|
onError,
|
|
scriptId = "onlyoffice-docs-api",
|
|
}: {
|
|
editorId: string
|
|
documentServerUrl: string
|
|
config: Record<string, unknown>
|
|
onError: (message: string) => void
|
|
scriptId?: string
|
|
}) {
|
|
const configJson = JSON.stringify(config)
|
|
const onErrorRef = useRef(onError)
|
|
onErrorRef.current = onError
|
|
|
|
useEffect(() => {
|
|
let cancelled = false
|
|
const id = editorId
|
|
const parsed = JSON.parse(configJson) as Record<string, unknown>
|
|
const editorConfig: Record<string, unknown> = {
|
|
type: "desktop",
|
|
width: "100%",
|
|
height: "100%",
|
|
events: {
|
|
onDocumentReady: () => {
|
|
/* loaded */
|
|
},
|
|
onError: (event: { data?: { errorCode?: number; errorDescription?: string } }) => {
|
|
const code = event?.data?.errorCode
|
|
const desc = event?.data?.errorDescription
|
|
const msg =
|
|
desc ||
|
|
(code != null ? `OnlyOffice error ${code}` : "Erreur OnlyOffice.")
|
|
onErrorRef.current(msg)
|
|
},
|
|
},
|
|
...parsed,
|
|
}
|
|
|
|
void loadDocsApi(documentServerUrl, scriptId)
|
|
.then(() => {
|
|
if (cancelled) return
|
|
if (!window.DocsAPI) throw new Error("DocsAPI is not defined")
|
|
destroyDocEditor(id)
|
|
if (!window.DocEditor) window.DocEditor = { instances: {} }
|
|
const editor = new window.DocsAPI.DocEditor(id, editorConfig)
|
|
window.DocEditor.instances[id] = editor
|
|
})
|
|
.catch((err: unknown) => {
|
|
if (!cancelled) {
|
|
onErrorRef.current(
|
|
err instanceof Error ? err.message : "Impossible de charger OnlyOffice.",
|
|
)
|
|
}
|
|
})
|
|
|
|
return () => {
|
|
cancelled = true
|
|
destroyDocEditor(id)
|
|
}
|
|
}, [editorId, documentServerUrl, configJson, scriptId])
|
|
|
|
return <div id={editorId} className="h-full w-full min-h-0" />
|
|
}
|