sozsoft-platform/ui/src/views/report/shared/reportShell.ts

149 lines
4.7 KiB
TypeScript
Raw Normal View History

import { useEffect, useMemo, useState } from 'react'
import { ajaxSetup } from '@devexpress/analytics-core/analytics-utils-native'
import { MODE_DARK } from '@/constants/theme.constant'
import { useStoreState } from '@/store'
import {
createReportQueryString,
createReportUrl,
type ReportRouteParams,
} from '../reportRouteParams'
const REPORT_THEME_LINK_ID = 'devexpress-report-viewer-theme'
const REPORT_DESIGNER_CSS_ID = 'devexpress-report-designer-css'
const COMMON_STYLE_HREFS = [
new URL('@devexpress/analytics-core/dist/css/dx-analytics.common.css', import.meta.url).href,
new URL('devexpress-reporting/dist/css/dx-webdocumentviewer.css', import.meta.url).href,
]
const DARK_THEME_HREF = new URL(
'@devexpress/analytics-core/dist/css/dx-analytics.dark.css',
import.meta.url,
).href
const LIGHT_THEME_HREF = new URL(
'@devexpress/analytics-core/dist/css/dx-analytics.light.css',
import.meta.url,
).href
const DESIGNER_STYLE_HREF = new URL(
'devexpress-reporting/dist/css/dx-reportdesigner.css',
import.meta.url,
).href
const appendStylesheet = (href: string, id?: string) => {
if (id ? document.getElementById(id) : document.querySelector(`link[href="${href}"]`)) return
const link = document.createElement('link')
if (id) link.id = id
link.rel = 'stylesheet'
link.href = href
document.head.appendChild(link)
}
const applyThemeStylesheet = (isDarkMode: boolean) => {
const themeHref = isDarkMode ? DARK_THEME_HREF : LIGHT_THEME_HREF
let themeLink = document.getElementById(REPORT_THEME_LINK_ID) as HTMLLinkElement | null
if (!themeLink) {
themeLink = document.createElement('link')
themeLink.id = REPORT_THEME_LINK_ID
themeLink.rel = 'stylesheet'
document.head.appendChild(themeLink)
}
if (themeLink.href !== themeHref) {
themeLink.href = themeHref
}
}
export const getReportShellClassName = (isDarkMode: boolean) =>
[
'dx-viewport',
'dx-device-desktop',
'dx-device-generic',
'dx-theme-generic',
'dx-theme-generic-typography',
isDarkMode ? 'dx-color-scheme-dark' : 'dx-color-scheme-light',
'report-viewer-shell',
isDarkMode ? 'report-viewer-shell-dark' : '',
]
.filter(Boolean)
.join(' ')
/**
* DevExpress rapor bileşenlerinin stillerini yükler ve aktif temaya göre kabuk sınıfını döner.
*/
export const useReportShellTheme = (includeDesignerStyles = false) => {
const themeMode = useStoreState((state) => state.theme.mode)
const isDarkMode = themeMode === MODE_DARK
useEffect(() => {
COMMON_STYLE_HREFS.forEach((href) => appendStylesheet(href))
applyThemeStylesheet(isDarkMode)
if (includeDesignerStyles) {
appendStylesheet(DESIGNER_STYLE_HREF, REPORT_DESIGNER_CSS_ID)
}
}, [isDarkMode, includeDesignerStyles])
return { isDarkMode, shellClassName: getReportShellClassName(isDarkMode) }
}
export const useReportCultureName = () => {
const cultureName = useStoreState((state) => state.locale.currentLang)
const configCultureName = useStoreState(
(state) => state.abpConfig.config?.localization.currentCulture.cultureName,
)
return cultureName || configCultureName
}
/**
* DevExpress istekleri global ajax ayarları üzerinden gittiği için oturum ve dil
* başlıkları bileşen render edilmeden önce yazılır. `isRequestConfigured` false iken
* rapor bileşeni render edilmemelidir, aksi hâlde ilk istek yetkisiz gider.
*/
export const useReportRequestSetup = () => {
const token = useStoreState((state) => state.auth.session.token)
const cultureName = useReportCultureName()
const requestConfigKey = `${token ?? ''}|${cultureName ?? ''}`
const [configuredRequestKey, setConfiguredRequestKey] = useState<string>()
useEffect(() => {
const nextHeaders = { ...(ajaxSetup.ajaxSettings.headers ?? {}) }
delete nextHeaders.Authorization
delete nextHeaders['Accept-Language']
ajaxSetup.ajaxSettings.headers = {
...nextHeaders,
...(token ? { Authorization: `Bearer ${token}` } : {}),
...(cultureName ? { 'Accept-Language': cultureName } : {}),
}
setConfiguredRequestKey(requestConfigKey)
}, [token, cultureName, requestConfigKey])
return {
cultureName,
isRequestConfigured: configuredRequestKey === requestConfigKey,
}
}
export const useReportUrl = (
params: ReportRouteParams,
search: string,
cultureName?: string,
action?: string,
) => {
const { report, id, listFormCode } = params
return useMemo(() => {
const searchParams = new URLSearchParams(search)
if (cultureName) {
searchParams.set('cultureName', cultureName)
}
const queryString = createReportQueryString(searchParams)
return createReportUrl(
{ report, id, listFormCode },
queryString ? `?${queryString}` : '',
action,
)
}, [report, id, listFormCode, search, cultureName, action])
}