UNPKG

devexpress-reporting-react

Version:

DevExpress Reporting React provides the capability to develop a reporting application to create and customize reports.

102 lines (101 loc) 5.32 kB
import React from 'react'; import PropTypes from 'prop-types'; import Callbacks from './options/Callbacks'; import ExportSettings from './options/ExportSettings'; import MobileModeSettings from './options/MobileModeSettings'; import ProgressBarSettings from './options/ProgressBarSettings'; import RemoteSettings from './options/RemoteSettings'; import RequestOptions from './options/RequestOptions'; import SearchSettings from './options/SearchSettings'; import TabPanelSettings from './options/TabPanelSettings'; import OptionsManager from '../core/options-manager'; import { TemplateEngine } from './core/template-engine'; import { JSReportViewerBinding } from 'devexpress-reporting/viewer/binding/jsReportViewerBinding'; import AccessibilitySettingsProvider from './components/core/AccessibilitySettingsProvider'; import TemplateEngineProvider from './components/core/TemplateEngineProvider'; import Template from './components/core/Template'; import { ViewModelChangedEvent, viewModelGeneratorSettings } from '@devexpress/analytics-core/serializer/native/viewModels/viewModelGenerator'; import '@devexpress/analytics-core/dx-dev-analytics-core-svg-templates.generated'; import 'devexpress-reporting/dx-dev-reporting-svg-templates.generated'; import AISettings, { validChildComponents as aiValidChildComponents } from './options/aiSettings/AISettings'; const validChildComponents = { 'callbacks': { component: Callbacks }, 'exportSettings': { component: ExportSettings }, 'mobileModeSettings': { component: MobileModeSettings }, 'progressBarSettings': { component: ProgressBarSettings }, 'remoteSettings': { component: RemoteSettings }, 'requestOptions': { component: RequestOptions }, 'searchSettings': { component: SearchSettings }, 'tabPanelSettings': { component: TabPanelSettings }, 'aiSettings': { component: AISettings, children: aiValidChildComponents } }; const DxReportViewer = React.forwardRef(({ reportUrl, ...props }, ref) => { const viewerRef = React.useRef(null); const [viewModel, setViewModel] = React.useState(null); const [viewerBinding, setViewerBinding] = React.useState(null); React.useImperativeHandle(ref, () => ({ instance() { return viewerBinding?.sender; } }), [viewerBinding]); viewModelGeneratorSettings.ensureChangesImmutable = false; React.useEffect(() => { if (viewerBinding && viewModel) { viewerBinding.sender.OpenReport(reportUrl); setViewModel({ ...viewModel }); } }, [reportUrl]); React.useEffect(() => { let disposeViewModelSubscription; const updateViewModel = (model) => { const viewModel = model.GetPreviewModel()?.getViewModel(); setViewModel({ ...viewModel }); disposeViewModelSubscription && disposeViewModelSubscription(); disposeViewModelSubscription = viewModel?._viewModelEvents?.on(ViewModelChangedEvent, () => setViewModel({ ...viewModel })); }; const controlOptions = OptionsManager.getControlOptions({ ...props, reportUrl }, DxReportViewer.propTypes, DxReportViewerDefaultProps, validChildComponents); const binding = new JSReportViewerBinding({ ...controlOptions, callbacks: {} }, OptionsManager.getEventRaiser(controlOptions.callbacks, () => binding?.sender), false); binding.applyBindings(viewerRef.current); setViewerBinding(binding); const model = binding.sender; updateViewModel(model); const disposeModelSubscription = model.events.on('propertyChanged', (args) => { if (args.propertyName === 'previewModel') { updateViewModel(model); } }); return () => { disposeModelSubscription && disposeModelSubscription(); disposeViewModelSubscription && disposeViewModelSubscription(); setViewModel(null); setViewerBinding(null); setTimeout(() => { binding && binding.dispose(); }); }; }, []); return (React.createElement(TemplateEngineProvider, { templateEngine: props.templateEngine ?? new TemplateEngine() }, React.createElement(AccessibilitySettingsProvider, { value: { accessibilityCompliant: !!viewModel?.accessibilityCompliant } }, React.createElement("div", { ref: viewerRef, className: props.cssClass, style: { width: props.width || DxReportViewerDefaultProps.width, height: props.height || DxReportViewerDefaultProps.height } }, React.createElement("div", { className: "dx-designer" }, !!viewModel && React.createElement(Template, { template: "dx-designer", data: viewModel })))))); }); DxReportViewer.displayName = 'DxReportViewer'; DxReportViewer.propTypes = { height: PropTypes.string, width: PropTypes.string, cssClass: PropTypes.string, templateEngine: PropTypes.instanceOf(TemplateEngine), isMobile: PropTypes.bool, accessibilityCompliant: PropTypes.bool, keepReportOnComponentDisposal: PropTypes.bool, reportUrl: PropTypes.string, rtl: PropTypes.bool, developmentMode: PropTypes.bool, children: PropTypes.node, }; const DxReportViewerDefaultProps = { height: '800px', width: '100%', cssClass: '', }; export default DxReportViewer;