devexpress-reporting
Version:
DevExpress Reporting provides the capability to develop a reporting application to create and customize reports.
226 lines (225 loc) • 11.2 kB
JavaScript
/**
* DevExpress HTML/JS Reporting (designer\actions\_sqlDataSourceEditor.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
*/
import { ResultSet, SqlDataSource } from '@devexpress/analytics-core/analytics-data';
import { sendRequest, getErrorMessage, ShowMessage, DxDeferred } from '@devexpress/analytics-core/analytics-internal';
import { getLocalization, ModelSerializer, PathRequest } from '@devexpress/analytics-core/analytics-utils';
import { DataSourceType, DataSourceWizardPageIterator, SqlDataSourceWizardPageId, _restoreSqlDataSourceFromState } from '@devexpress/analytics-core/analytics-wizard';
import { MasterDetailEditor } from '@devexpress/analytics-core/queryBuilder-widgets-internal';
import * as ko from 'knockout';
import { DataSourceHelper } from '../helpers/_dataSourceHelper';
import { addDataSourceToReport } from '../internal/_dataUtils';
import { ReportDataSourceService } from '../services/_reportDataSourceService';
import { QBRequestWrapper } from '../tools/generator/_qBRequestWrapper';
import { HandlerUri } from '../utils/settings';
export class DataSourceEditorBase {
constructor(_dsHelper, _wizard, _reportViewModel, _undoEngine, _itemsProvider, _callbacks, _rtl) {
this._dsHelper = _dsHelper;
this._wizard = _wizard;
this._reportViewModel = _reportViewModel;
this._undoEngine = _undoEngine;
this._itemsProvider = _itemsProvider;
this._callbacks = _callbacks;
this._rtl = _rtl;
}
_findDataSource(dataSourceID) {
return this._dsHelper().usedDataSources().filter((item) => {
return item.id === dataSourceID || item.ref === dataSourceID;
})[0];
}
static _onFail(result, deferred) {
if (getErrorMessage(result))
ShowMessage(getErrorMessage(result));
deferred.reject(result);
}
}
export class CreateQueryIterator extends DataSourceWizardPageIterator {
getNextPageId(pageId) {
if (!pageId) {
return SqlDataSourceWizardPageId.ConfigureQueryPage;
}
return super.getNextPageId(pageId);
}
}
export class SqlDataSourceEditor extends DataSourceEditorBase {
constructor() {
super(...arguments);
this.relationsEditor = ko.observable();
this.addAction = {
clickAction: (item) => {
this.addSqlQuery(item.data.name);
},
imageClassName: 'dxrd-image-add-query',
imageTemplateName: 'dxrd-svg-operations-add_query',
text: getLocalization('Add query', 'AnalyticsCoreStringId.SqlDSWizard_AddQuery')
};
this.editAction = {
clickAction: (item) => {
this.editSqlQuery(new PathRequest(item.path).id, item.name);
},
position: 0,
imageClassName: 'dx-image-edit',
imageTemplateName: 'dxrd-svg-operations-edit',
text: getLocalization('Edit query', 'AnalyticsCoreStringId.SqlDSWizard_EditQuery')
};
this.removeAction = {
clickAction: (item) => {
this.removeSqlQuery(new PathRequest(item.path).id, item.name);
},
position: 50,
imageClassName: 'dxrd-image-recycle-bin',
imageTemplateName: 'dxrd-svg-operations-recycle_bin',
text: getLocalization('Remove query', 'AnalyticsCoreStringId.SqlDSWizard_RemoveQuery')
};
this.editRelationsAction = {
clickAction: (item) => {
this.editMasterDetailRelations(item.data.name);
},
position: 0,
imageClassName: 'dx-image-edit',
imageTemplateName: 'dxrd-svg-operations-edit',
text: getLocalization('Edit Master-Detail Relations', 'ASPxReportsStringId.ReportDesigner_FieldListActions_EditMasterDetailRelations')
};
}
_applyWizardChanges(dataSource, sqlDataSource, queryName, relationsEditing) {
return this._applyDataSourceChange(sqlDataSource, dataSource, queryName, relationsEditing);
}
_createOrEditSqlDataSource(requestJson, dataSource, requestName) {
return sendRequest(HandlerUri(), requestName, requestJson)
.done((result) => {
result.dataSource.data = JSON.parse(result.dataSource.data);
result.dataSource.isSqlDataSource = true;
if (dataSource) {
dataSource.data['base64'](result.dataSource.data['@Base64']);
}
else {
addDataSourceToReport(this._dsHelper(), this._reportViewModel(), this._undoEngine(), this._itemsProvider(), result.dataSource);
}
})
.fail((result) => {
if (getErrorMessage(result))
ShowMessage(getErrorMessage(result));
});
}
_applyDataSourceChange(source, dest, queryName, relationsEditing) {
const reportExtensions = this._reportViewModel && this._reportViewModel() && this._reportViewModel().extensions;
return SqlDataSourceEditor.createSqlDataSourceInfo(source, queryName, relationsEditing, this._callbacks?.getParameters && this._callbacks?.getParameters(), reportExtensions)
.done((result) => {
if (dest) {
dest.data['base64'](result.base64());
}
else {
addDataSourceToReport(this._dsHelper(), this._reportViewModel(), this._undoEngine(), this._itemsProvider(), result);
}
});
}
editSqlQuery(dataSourceID, queryName) {
const dataSourceInfo = this._findDataSource(dataSourceID);
ReportDataSourceService.sqlDataSourceFromBase64(dataSourceInfo.data['base64']()).done((result) => {
const sqlDataSource = new SqlDataSource(JSON.parse(result.sqlDataSourceJSON), undefined, QBRequestWrapper());
sqlDataSource.name(dataSourceInfo.name);
this._wizard.initialize({
dataSourceType: DataSourceType.Sql,
sqlDataSourceWizard: {
name: sqlDataSource.connection.name(),
queryName: queryName,
sqlDataSourceJSON: JSON.stringify(new ModelSerializer().serialize(sqlDataSource))
}
}, (factory, stateManager) => new CreateQueryIterator(factory, stateManager, this._wizard['_wizardOptions']));
this._wizard.start();
this._wizard.isVisible(true);
});
}
addSqlQuery(dataSourceID) {
this.editSqlQuery(dataSourceID, null);
}
removeSqlQuery(dataSourceID, queryName) {
const dataSourceInfo = this._findDataSource(dataSourceID);
ReportDataSourceService.sqlDataSourceFromBase64(dataSourceInfo.data['base64']()).done((result) => {
const sqlDataSource = new SqlDataSource(JSON.parse(result.sqlDataSourceJSON));
sqlDataSource.queries.remove(x => { return x.name() === queryName; });
this._applyWizardChanges(dataSourceInfo, sqlDataSource, queryName);
});
}
editMasterDetailRelations(dataSourceID) {
const dataSourceInfo = this._findDataSource(dataSourceID);
ReportDataSourceService.sqlDataSourceFromBase64(dataSourceInfo.data['base64']()).done((result) => {
const sqlDataSource = new SqlDataSource(JSON.parse(result.sqlDataSourceJSON));
if (sqlDataSource.queries().length < 2) {
ShowMessage(getLocalization('At least two queries are required to create a master-detail relation.', 'DataAccessUIStringId.MessageLessThanTwoQueries'), 'warning', 10000);
return;
}
this.relationsEditor(new MasterDetailEditor(sqlDataSource.relations, sqlDataSource.resultSet, () => {
return this._applyWizardChanges(dataSourceInfo, sqlDataSource, '', true);
}));
this.relationsEditor().popupVisible(true);
});
}
applySqlDataSourceWizardChanges(dataSourceWizardModel) {
const dataSourceWrapped = _restoreSqlDataSourceFromState(dataSourceWizardModel.sqlDataSourceWizard, QBRequestWrapper(), dataSourceWizardModel.dataSourceId);
const dataSource = this._dsHelper().findDataSourceInfoByName(dataSourceWrapped.sqlDataSource.name());
return this._applyDataSourceChange(dataSourceWrapped.sqlDataSource, dataSource, dataSourceWrapped.sqlQuery && dataSourceWrapped.sqlQuery.name());
}
static rebuildResultSchema(source, queryName, relationsEditing, parameters, dataSerializationExtension) {
return QBRequestWrapper().rebuildResultSchema(source, queryName, relationsEditing, parameters, dataSerializationExtension)
.done((result) => {
const model = JSON.parse(result.resultSchemaJSON);
source.resultSet = !!model ? new ResultSet(model) : null;
if (!!result.connectionParameters) {
source.connection.parameteres((x => { try {
return JSON.parse(x)['Parameters'] || x;
}
catch (_) {
return x;
} })(result.connectionParameters));
source.connection.fromAppConfig(false);
}
});
}
static createSqlDataSourceInfo(source, queryName, relationsEditing, parameters, extensions) {
const deferred = new DxDeferred();
let dataSerializationExtension;
if (extensions && extensions()) {
const extensionModel = extensions().find(extension => extension.key() === DataSourceHelper.defaultReportExtensionKey);
if (extensionModel?.value)
dataSerializationExtension = extensionModel.value();
}
SqlDataSourceEditor.rebuildResultSchema(source, queryName, relationsEditing, parameters, dataSerializationExtension).done((_) => {
ReportDataSourceService.getSqlDataSourceBase64(source)
.done((result) => {
deferred.resolve({
name: 'sqlDataSource',
id: source.id,
data: {
'@ObjectType': 'DevExpress.DataAccess.Sql.SqlDataSource',
'@Base64': result
},
isListType: false,
isSupportQueries: true,
isSqlDataSource: true,
base64: () => result
});
})
.fail(result => { SqlDataSourceEditor._onFail(result, deferred); });
}).fail(result => { SqlDataSourceEditor._onFail(result, deferred); });
return deferred.promise();
}
getActions(context) {
const result = [];
if (!context.data)
return result;
if (context.data['canAddSqlQuery'] === true) {
result.push(this.addAction);
result.push(this.editRelationsAction);
}
if (context.data['canEditQuery'] === true) {
result.push(this.editAction);
result.push(this.removeAction);
}
return result;
}
}