UNPKG

devexpress-reporting

Version:

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

361 lines (360 loc) 17.8 kB
/** * DevExpress HTML/JS Reporting (viewer\parameters\parametersPanelModelBase.js) * Version: 24.2.6 * Build date: Mar 18, 2025 * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * License: https://www.devexpress.com/Support/EULAs/universal.xml */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { DxDeferred, PropertyGridKeyboardHelper, sendRequest } from '@devexpress/analytics-core/analytics-internal-native'; import { getLocalization, PrepareRequestArgs, TabInfoWithPropertyGrid } from '@devexpress/analytics-core/analytics-utils-native'; import { HandlerUri } from '../settings'; import { ParameterPanelItemBase } from './parameterPanelItemBase'; import { PreviewParameter } from './previewParameter'; import { mutable, subscribableProperty, nativeMultiPlatformEngine, BaseEmptyModel, mutableArray } from '@devexpress/analytics-core/analytics-serializer-native'; import { createPreviewParametersViewModel, updateViewModel } from './previewParametersViewModel.viewmodel'; export class ParametersPanelModelBase extends ParameterPanelItemBase { get parameters() { return this._parameters; } createViewModel() { return createPreviewParametersViewModel.call(this, super.createViewModel()); } updateViewModel(args) { updateViewModel.call(this, args); } get _visibleParameters() { return this._parameters.filter((p) => { return p.visible; }); } _shouldProcessParameter(param) { return this.processInvisibleParameters || (param && (param.visible || param.hasVisibleExpression || param.isFilteredLookUpSettings)); } subscribeParameter(parameter) { const needToUpdateParameter = this._needToUpdateParameter || (this._shouldProcessParameter(parameter)) && (parameter.isFilteredLookUpSettings || parameter.hasBindedExpressions); this._needToUpdateParameter = needToUpdateParameter; if (this._shouldProcessParameter(parameter)) { this.addDisposable(parameter.events.on(`${parameter.isMultiValueWithLookUp ? '_value' : 'value'}Changed`, (newValue) => { if (this._needToUpdateParameter) { this.updateParameters(parameter); } })); } } _setLookUpValues(parameter, lookUpValues) { if (!lookUpValues) { parameter.lookUpValues = []; return; } parameter.lookUpValues = this.parameterHelper.mapLookUpValues(parameter.type, lookUpValues); const _parameterValuesContainedInLookUps = this._getParameterValuesContainedInLookups(lookUpValues, parameter); if (parameter.isMultiValue) { parameter.initialize(_parameterValuesContainedInLookUps.length > 0 ? _parameterValuesContainedInLookUps : [], this.parameterHelper); } else { parameter.initialize(_parameterValuesContainedInLookUps[0] && _parameterValuesContainedInLookUps[0].Value || (lookUpValues.length > 0 ? lookUpValues[0].Value : null), this.parameterHelper); } } _getParameterValuesContainedInLookups(parameterLookUpValues, parameter) { if (parameterLookUpValues) { if (parameter.isMultiValue) { const selectedItems = parameter.value.value; return selectedItems.filter((item) => this._filterParameterValuesContainsInLookups(parameterLookUpValues, parameter.type, item).length > 0); } else { return this._filterParameterValuesContainsInLookups(parameterLookUpValues, parameter.type, parameter.value); } } return []; } _filterParameterValuesContainsInLookups(parameterLookUpValues, parameterType, value) { return parameterLookUpValues.filter((x) => PreviewParameter._compareValues(this.parameterHelper.getValueConverter(parameterType)(x.Value), value)); } _setParameterValue(parameter, value) { const descriptor = parameter.getParameterDescriptor(); if (descriptor.multiValue) { if (value && !Array.isArray(value)) throw new Error(`The '${parameter.path}' parameter must be an array.`); if (descriptor.hasLookUpValues) { parameter.value.value = value; } else { const parameterValues = this.parameterHelper.createMultiValueArray(value, parameter); parameter.value = parameterValues; } } else { parameter.validateAndAssignValue(value); } } setParameterValue(parameterName, value) { const parameter = this._parameters.filter(x => x.path === parameterName)[0]; if (!parameter) throw new Error(`The '${parameterName}' parameter is not found.`); this._setParameterValue(parameter, value); } onPropertyChanged(args) { if (args.propertyName === 'isEmpty') { this.tabInfo.visible = !this.isEmpty; if (this._popupInfo) this._popupInfo.notEmpty = !this.isEmpty; } if (args.propertyName === '_popupVisible') { this._popupVisibleSwitch = this._popupVisible; if (this._popupInfo) this._popupInfo.visible = this._popupVisible; } if (args.propertyName == '_popupVisibleSwitch' || args.propertyName === 'isEmpty') { this._popupVisible = !this.isEmpty && this._popupVisibleSwitch; } if (args.propertyName == '_getInfo') { this.tabInfo && this.tabInfo.propertyGrid.updateEditorsInfo(this, this.getInfo()); } } constructor(parametersHolder, parameterHelper, enableKeyboardSupport, getRootElement) { super(parameterHelper); this._getParametersStateRequest = (argsObject) => { return sendRequest(HandlerUri(), 'getParametersState', PrepareRequestArgs(argsObject), (message, jqXHR, textStatus) => this._parametersHolder._processError(getLocalization('Cannot supply filtered lookup values to a report parameter editor', 'ASPxReportsStringId.WebDocumentViewer_GetLookUpValuesError'), jqXHR)); }; this._getDoneGetParametersStateHandler = (changedParameter) => { const parametersViewModel = this; return (response) => { try { if (!response || !response.parameters) { return; } response.parameters.forEach((parametersInfoCollection) => { const matchedParameter = parametersViewModel._parameters.filter((p) => { return p.path === parametersInfoCollection.Key; })[0]; if (!parametersViewModel._shouldProcessParameter(matchedParameter)) return; matchedParameter.visible = parametersInfoCollection.Value.visible; matchedParameter.enabled = parametersInfoCollection.Value.enabled; if (parametersViewModel._parameters.indexOf(changedParameter) < parametersViewModel._parameters.indexOf(matchedParameter) && parametersInfoCollection.Value.lookUpValues != null) { parametersViewModel._setLookUpValues(matchedParameter, parametersInfoCollection.Value.lookUpValues); } }); } finally { parametersViewModel.parametersLoading = false; } }; }; this._getFailGetParametersStateHandler = () => { const parametersViewModel = this; return (jqXHRError) => { parametersViewModel.parametersLoading = false; }; }; this.restore = () => { if (this.parametersLoading) { return; } try { this.parametersLoading = true; this._parameters.forEach((parameter) => { if (!this._shouldProcessParameter(parameter)) return; parameter.lookUpValues = parameter._originalLookUpValues; parameter.initialize(parameter._originalValue, this.parameterHelper); }); } finally { this.parameterHelper.callbacks && this.parameterHelper.callbacks.parametersReset && this.parameterHelper.callbacks.parametersReset(this, this._parameters); this.parametersLoading = false; } }; this.submit = () => { }; this.processInvisibleParameters = false; this._parametersHolder = parametersHolder; this.addDisposable(parametersHolder.events.on('originalParametersInfoChanged', (args) => { this.initialize(args.newValue); })); this.initialize(parametersHolder.originalParametersInfo); this._popupVisible = !this.isEmpty && this._popupVisibleSwitch; this._popupInfo = { visible: this._popupVisible, notEmpty: !this.isEmpty }; const keyboardHelperViewModelAccessor = () => this.tabInfo.getViewModel().propertyGrid.editors; const keyboardHelper = enableKeyboardSupport ? new PropertyGridKeyboardHelper(keyboardHelperViewModelAccessor) : undefined; this._disposables.push(keyboardHelper); this.tabInfo = new TabInfoWithPropertyGrid({ text: 'Parameters', template: 'dxrd-preview-parameters', model: this.getViewModel(), propertyGridModel: this, keyboardHelper, localizationId: 'PreviewStringId.RibbonPreview_Parameters_Caption', imageClassName: 'parameters', imageTemplateName: 'dxrd-svg-tabs-parameters', visible: !this.isEmpty, engineType: 'native' }); this._disposables.push({ dispose: () => { clearTimeout(this._updateParametersTimeOut); this.prevParametersStateRequest?.reject(); this.lastValidationRequest?.reject(); } }); this.buttons = [{ text: getLocalization('Reset', 'ASPxReportsStringId.ParametersPanel_Reset'), onClick: (e) => this.restore() }]; } initialize(originalParametersInfo) { originalParametersInfo && this.parameterHelper.initialize(originalParametersInfo.knownEnums); super.initialize(originalParametersInfo); if (!originalParametersInfo) return; const layout = originalParametersInfo.parameterPanelLayout; if ((!layout || layout.layoutItems.length === 0) && originalParametersInfo.parameters) { this._parameters.forEach(x => this._add(x, {})); } this.isEmpty = this._visibleParameters.length === 0; const actualParametersInfo = []; this._parameters.forEach(x => { this.subscribeParameter(x); const model = new BaseEmptyModel(); this.addDisposable(nativeMultiPlatformEngine.createComputedProperty(model, 'value', { read: () => { return x.serialize().Value; }, write: (newVal) => { this._setParameterValue(x, newVal); } }, [ subscribableProperty(x, '*') ])); this.addDisposable(nativeMultiPlatformEngine.createComputedProperty(model, 'selectAll', { read: () => { const value = x.value; return value?.isSelectedAll; }, write: (newVal) => { const value = x.value; if (value?.isSelectedAll) { value.isSelectedAll = newVal; } } }, [ subscribableProperty(x, [{ propertyName: 'value', subscribables: ['isSelectedAll'] } ]) ])); model['parameterDescriptor'] = x.getParameterDescriptor(), this.addDisposable(nativeMultiPlatformEngine.createComputedProperty(model, 'lookUpValues', { read: () => x.lookUpValues, write: (newVal) => x.lookUpValues = newVal }, [subscribableProperty(x, ['lookUpValues'])])); actualParametersInfo.push(model); }); if (this.parameterHelper.callbacks && this.parameterHelper.callbacks.parametersInitialized) { this.parameterHelper.callbacks.parametersInitialized(this, actualParametersInfo, this.submit, originalParametersInfo.shouldRequestParameters); } } getPathsAfterPath(parameterPath) { let startIndex = 0; for (let index = 0; index < this._parameters.length; index++) { if (this._parameters[index].path === parameterPath) { startIndex = index + 1; break; } } const paths = this._parameters .filter((param, index) => { return this._shouldProcessParameter(param) && (param.hasBindedExpressions || param.isFilteredLookUpSettings && index >= startIndex); }) .map((x) => x.path); return paths || []; } serializeParameters() { return this._parameters.map(x => x.serialize()); } updateParameters(changedParameter) { const requiredParameterPaths = this.getPathsAfterPath(changedParameter.path); if (!requiredParameterPaths || requiredParameterPaths.length === 0) { return; } const changedParameterIndex = this._parameters.indexOf(changedParameter); const updateTopChangedParameter = (index, changedParameter, requiredParameterPaths) => { this._topChangedParameter = { index: index, changedParameter: changedParameter, requiredParameterPaths: requiredParameterPaths }; }; if (this._topChangedParameter && changedParameterIndex !== -1) { if (this._topChangedParameter.index > changedParameterIndex) updateTopChangedParameter(changedParameterIndex, changedParameter, requiredParameterPaths); return; } updateTopChangedParameter(changedParameterIndex, changedParameter, requiredParameterPaths); this.prevParametersStateRequest?.reject(); clearTimeout(this._updateParametersTimeOut); const deferred = new DxDeferred(); this._updateParametersTimeOut = setTimeout(() => { this.parametersLoading = true; const argsObject = { reportId: this._parametersHolder.reportId, reportUrl: this._parametersHolder.reportUrl, requiredParameterPaths: this._topChangedParameter.requiredParameterPaths, changedParameterPath: this._topChangedParameter.changedParameter.path, parameters: this.serializeParameters(), timeZoneOffset: 0 - new Date().getTimezoneOffset() }; this._getParametersStateRequest(argsObject) .done((result) => deferred.resolve(result)) .fail(() => deferred.resolve()); deferred.done(this._getDoneGetParametersStateHandler(this._topChangedParameter.changedParameter)); deferred.fail(this._getFailGetParametersStateHandler()); this.prevParametersStateRequest = deferred; this._topChangedParameter = null; }, 20); } _handleValidationResult(validationResult) { if (!validationResult || validationResult.isValid) this.submit(); } _validateAndSubmit(params) { if (this.lastValidationRequest?._state === 'pending') return; const result = params?.validationGroup?.validate?.(); if (result && result.status === 'pending' && result.complete.then) { this.lastValidationRequest?.reject(); const validationRequest = new DxDeferred(); result.complete.then(asyncResult => { validationRequest.resolve(asyncResult); }, () => { validationRequest.resolve({ isValid: false }); }); validationRequest.done(asyncResult => { this._handleValidationResult(asyncResult); }); this.lastValidationRequest = validationRequest; } else { this._handleValidationResult(result); } } } __decorate([ mutable(false) ], ParametersPanelModelBase.prototype, "_needToUpdateParameter", void 0); __decorate([ mutable(true) ], ParametersPanelModelBase.prototype, "showButtons", void 0); __decorate([ mutable(true) ], ParametersPanelModelBase.prototype, "_showHeader", void 0); __decorate([ mutableArray(() => []) ], ParametersPanelModelBase.prototype, "buttons", void 0); __decorate([ mutable(false) ], ParametersPanelModelBase.prototype, "parametersLoading", void 0); __decorate([ mutable(true) ], ParametersPanelModelBase.prototype, "_popupVisible", void 0); __decorate([ mutable(true) ], ParametersPanelModelBase.prototype, "_popupVisibleSwitch", void 0);