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() 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]) }