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
JavaScript
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;