2021-04-03 11:14:15 +00:00
|
|
|
import React from 'react';
|
2021-04-30 08:10:57 +00:00
|
|
|
import { dataqueryService } from '@/_services';
|
2021-12-30 11:57:02 +00:00
|
|
|
import { toast } from 'react-hot-toast';
|
2021-04-26 07:13:20 +00:00
|
|
|
import ReactTooltip from 'react-tooltip';
|
2022-10-27 11:29:43 +00:00
|
|
|
import { allSources, source } from './QueryEditors';
|
2021-04-30 16:15:42 +00:00
|
|
|
import { Transformation } from './Transformation';
|
2022-12-20 13:08:51 +00:00
|
|
|
import { previewQuery } from '@/_helpers/appUtils';
|
2021-09-06 14:40:51 +00:00
|
|
|
import { EventManager } from '../Inspector/EventManager';
|
2021-11-15 06:18:09 +00:00
|
|
|
import { CodeHinter } from '../CodeBuilder/CodeHinter';
|
2021-12-08 08:25:22 +00:00
|
|
|
import { DataSourceTypes } from '../DataSourceManager/SourceComponents';
|
2022-12-27 14:40:33 +00:00
|
|
|
import Preview from './Preview';
|
|
|
|
|
import DataSourceLister from './DataSourceLister';
|
|
|
|
|
import _, { isEmpty, isEqual, capitalize } from 'lodash';
|
|
|
|
|
import { allOperations } from '@tooljet/plugins/client';
|
|
|
|
|
import { withTranslation } from 'react-i18next';
|
|
|
|
|
import cx from 'classnames';
|
|
|
|
|
// eslint-disable-next-line import/no-unresolved
|
|
|
|
|
import { diff } from 'deep-object-diff';
|
2022-12-28 09:31:31 +00:00
|
|
|
import { CustomToggleSwitch } from './CustomToggleSwitch';
|
2022-12-27 14:40:33 +00:00
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
const queryNameRegex = new RegExp('^[A-Za-z0-9_-]*$');
|
2021-04-29 16:39:09 +00:00
|
|
|
|
2021-12-08 07:33:08 +00:00
|
|
|
const staticDataSources = [
|
2023-01-03 07:29:47 +00:00
|
|
|
{ kind: 'restapi', id: 'restapi', name: 'REST API' },
|
2021-12-08 08:25:22 +00:00
|
|
|
{ kind: 'runjs', id: 'runjs', name: 'Run JavaScript code' },
|
2022-12-22 20:39:57 +00:00
|
|
|
{ kind: 'tooljetdb', id: 'null', name: 'Run ToolJetDb query' },
|
2022-12-27 14:40:33 +00:00
|
|
|
{ kind: 'runpy', id: 'runpy', name: 'Run Python code' },
|
2021-12-08 07:33:08 +00:00
|
|
|
];
|
2021-04-04 17:07:03 +00:00
|
|
|
|
2022-09-14 08:04:49 +00:00
|
|
|
class QueryManagerComponent extends React.Component {
|
2021-04-30 06:31:32 +00:00
|
|
|
constructor(props) {
|
|
|
|
|
super(props);
|
|
|
|
|
|
2021-12-02 08:47:48 +00:00
|
|
|
this.state = {
|
|
|
|
|
options: {},
|
|
|
|
|
selectedQuery: null,
|
|
|
|
|
selectedDataSource: null,
|
2021-12-08 08:25:22 +00:00
|
|
|
dataSourceMeta: {},
|
2022-02-02 16:59:57 +00:00
|
|
|
dataQueries: [],
|
2022-03-08 09:27:28 +00:00
|
|
|
theme: {},
|
2022-03-18 04:57:35 +00:00
|
|
|
isSourceSelected: false,
|
2022-05-23 22:32:59 +00:00
|
|
|
isFieldsChanged: false,
|
2022-12-27 14:40:33 +00:00
|
|
|
isNameChanged: false,
|
2022-05-23 22:32:59 +00:00
|
|
|
paneHeightChanged: false,
|
|
|
|
|
showSaveConfirmation: false,
|
|
|
|
|
restArrayValuesChanged: false,
|
|
|
|
|
nextProps: null,
|
2022-06-17 12:23:59 +00:00
|
|
|
buttonText: '',
|
2022-12-20 13:08:51 +00:00
|
|
|
renameQuery: false,
|
2021-12-02 08:47:48 +00:00
|
|
|
};
|
2021-05-22 12:57:36 +00:00
|
|
|
|
2022-12-27 14:40:33 +00:00
|
|
|
this.defaultOptions = React.createRef({});
|
2021-05-22 12:57:36 +00:00
|
|
|
this.previewPanelRef = React.createRef();
|
2021-04-30 06:31:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setStateFromProps = (props) => {
|
|
|
|
|
const selectedQuery = props.selectedQuery;
|
2021-06-17 05:56:53 +00:00
|
|
|
const dataSourceId = selectedQuery?.data_source_id;
|
|
|
|
|
const source = props.dataSources.find((datasource) => datasource.id === dataSourceId);
|
2022-12-27 14:40:33 +00:00
|
|
|
const selectedDataSource =
|
|
|
|
|
paneHeightChanged || queryPaneDragged ? this.state.selectedDataSource : props.selectedDataSource;
|
2022-10-27 11:29:43 +00:00
|
|
|
let dataSourceMeta;
|
|
|
|
|
if (selectedQuery?.pluginId) {
|
|
|
|
|
dataSourceMeta = selectedQuery.manifestFile.data.source;
|
|
|
|
|
} else {
|
|
|
|
|
dataSourceMeta = DataSourceTypes.find((source) => source.kind === selectedQuery?.kind);
|
|
|
|
|
}
|
2022-11-07 09:03:39 +00:00
|
|
|
|
2022-10-27 11:29:43 +00:00
|
|
|
const paneHeightChanged = this.state.queryPaneHeight !== props.queryPaneHeight;
|
2022-02-02 16:59:57 +00:00
|
|
|
const dataQueries = props.dataQueries?.length ? props.dataQueries : this.state.dataQueries;
|
2022-05-23 22:32:59 +00:00
|
|
|
const queryPaneDragged = this.state.isQueryPaneDragging !== props.isQueryPaneDragging;
|
2022-12-13 08:59:41 +00:00
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
this.setState(
|
|
|
|
|
{
|
|
|
|
|
appId: props.appId,
|
|
|
|
|
dataSources: props.dataSources,
|
2022-02-02 16:59:57 +00:00
|
|
|
dataQueries: dataQueries,
|
2022-07-08 13:08:55 +00:00
|
|
|
appDefinition: props.appDefinition,
|
2021-04-30 06:31:32 +00:00
|
|
|
mode: props.mode,
|
|
|
|
|
addingQuery: props.addingQuery,
|
|
|
|
|
editingQuery: props.editingQuery,
|
2022-09-08 13:09:13 +00:00
|
|
|
queryPanelHeight: props.queryPanelHeight,
|
2022-05-23 22:32:59 +00:00
|
|
|
isQueryPaneDragging: props.isQueryPaneDragging,
|
2021-05-22 11:29:27 +00:00
|
|
|
currentState: props.currentState,
|
2021-06-17 05:56:53 +00:00
|
|
|
selectedSource: source,
|
2022-12-27 14:40:33 +00:00
|
|
|
options:
|
|
|
|
|
this.state.isFieldsChanged || props.isUnsavedQueriesAvailable
|
|
|
|
|
? this.state.options
|
|
|
|
|
: selectedQuery?.options ?? {},
|
2021-12-08 08:25:22 +00:00
|
|
|
dataSourceMeta,
|
2022-05-23 22:32:59 +00:00
|
|
|
paneHeightChanged,
|
|
|
|
|
isSourceSelected: paneHeightChanged || queryPaneDragged ? this.state.isSourceSelected : props.isSourceSelected,
|
2022-12-27 14:40:33 +00:00
|
|
|
selectedDataSource,
|
2022-09-27 07:48:04 +00:00
|
|
|
queryPreviewData: this.state.selectedQuery?.id !== props.selectedQuery?.id ? undefined : props.queryPreviewData,
|
2022-12-27 14:40:33 +00:00
|
|
|
selectedQuery: props.mode === 'create' ? selectedQuery : this.state.selectedQuery,
|
|
|
|
|
isFieldsChanged: props.isUnsavedQueriesAvailable,
|
|
|
|
|
isNameChanged: props.isUnsavedQueriesAvailable,
|
2022-03-08 09:27:28 +00:00
|
|
|
theme: {
|
|
|
|
|
scheme: 'bright',
|
|
|
|
|
author: 'chris kempson (http://chriskempson.com)',
|
|
|
|
|
base00: props.darkMode ? '#272822' : '#000000',
|
|
|
|
|
base01: '#303030',
|
|
|
|
|
base02: '#505050',
|
|
|
|
|
base03: '#b0b0b0',
|
|
|
|
|
base04: '#d0d0d0',
|
|
|
|
|
base05: '#e0e0e0',
|
|
|
|
|
base06: '#f5f5f5',
|
|
|
|
|
base07: '#ffffff',
|
|
|
|
|
base08: '#fb0120',
|
|
|
|
|
base09: '#fc6d24',
|
|
|
|
|
base0A: '#fda331',
|
|
|
|
|
base0B: '#a1c659',
|
|
|
|
|
base0C: '#76c7b7',
|
|
|
|
|
base0D: '#6fb3d2',
|
|
|
|
|
base0E: '#d381c3',
|
|
|
|
|
base0F: '#be643c',
|
|
|
|
|
},
|
2022-12-20 13:08:51 +00:00
|
|
|
buttonText: props.mode === 'edit' ? 'Save' : 'Create',
|
|
|
|
|
shouldRunQuery: props.mode === 'edit' ? this.state.isFieldsChanged : this.props.isSourceSelected,
|
2021-04-30 06:31:32 +00:00
|
|
|
},
|
|
|
|
|
() => {
|
2022-12-27 14:40:33 +00:00
|
|
|
let source = props.dataSources.find((datasource) => datasource.id === selectedQuery?.data_source_id);
|
|
|
|
|
if (selectedQuery?.kind === 'restapi') {
|
|
|
|
|
if (!selectedQuery.data_source_id) {
|
|
|
|
|
source = { kind: 'restapi', id: 'null', name: 'REST API' };
|
2021-07-25 17:20:19 +00:00
|
|
|
}
|
2022-12-27 14:40:33 +00:00
|
|
|
}
|
|
|
|
|
if (selectedQuery?.kind === 'runjs') {
|
|
|
|
|
if (!selectedQuery.data_source_id) {
|
|
|
|
|
source = { kind: 'runjs', id: 'runjs', name: 'Run JavaScript code' };
|
2021-12-08 07:33:08 +00:00
|
|
|
}
|
2022-12-28 15:45:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (selectedQuery?.kind === 'tooljetdb') {
|
|
|
|
|
if (!selectedQuery.data_source_id) {
|
|
|
|
|
source = { kind: 'tooljetdb', id: 'null', name: 'Run ToolJetDb query' };
|
2022-12-22 20:39:57 +00:00
|
|
|
}
|
2022-12-27 14:40:33 +00:00
|
|
|
}
|
2022-12-28 15:45:09 +00:00
|
|
|
|
2022-12-27 14:40:33 +00:00
|
|
|
if (selectedQuery?.kind === 'runpy') {
|
|
|
|
|
if (!selectedQuery.data_source_id) {
|
|
|
|
|
source = { kind: 'runpy', id: 'runpy', name: 'Run Python code' };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (this.props.mode === 'edit') {
|
|
|
|
|
this.defaultOptions.current =
|
|
|
|
|
this.state.selectedQuery?.id === selectedQuery?.id ? this.state.options : selectedQuery.options;
|
2021-04-30 06:31:32 +00:00
|
|
|
this.setState({
|
2022-12-27 14:40:33 +00:00
|
|
|
options: paneHeightChanged || props.isUnsavedQueriesAvailable ? this.state.options : selectedQuery.options,
|
2021-04-30 06:31:32 +00:00
|
|
|
selectedQuery,
|
2022-12-27 14:40:33 +00:00
|
|
|
queryName: this.state.isNameChanged ? this.state.queryName : selectedQuery.name,
|
2021-04-30 06:31:32 +00:00
|
|
|
});
|
2021-04-29 16:39:09 +00:00
|
|
|
}
|
2022-12-27 14:40:33 +00:00
|
|
|
// Hack to provide state updated to codehinter suggestion
|
|
|
|
|
this.setState({ selectedDataSource: null }, () =>
|
|
|
|
|
this.setState({ selectedDataSource: this.props.mode === 'edit' ? source : selectedDataSource })
|
|
|
|
|
);
|
2021-04-30 06:31:32 +00:00
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
2022-09-28 09:36:13 +00:00
|
|
|
if (nextProps.loadingDataSources) return;
|
2022-08-03 11:04:37 +00:00
|
|
|
if (this.props.showQueryConfirmation && !nextProps.showQueryConfirmation) {
|
|
|
|
|
if (this.state.isUpdating) {
|
|
|
|
|
this.setState({
|
|
|
|
|
isUpdating: false,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (this.state.isCreating) {
|
|
|
|
|
this.setState({
|
|
|
|
|
isCreating: false,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-16 12:34:07 +00:00
|
|
|
if (!isEmpty(this.state.updatedQuery)) {
|
|
|
|
|
const query = nextProps.dataQueries.find((q) => q.id === this.state.updatedQuery.id);
|
|
|
|
|
if (query) {
|
|
|
|
|
const isLoading = nextProps.currentState?.queries[query.name]
|
|
|
|
|
? nextProps.currentState?.queries[query.name]?.isLoading
|
|
|
|
|
: false;
|
|
|
|
|
const prevLoading = this.state.currentState?.queries[query.name]
|
|
|
|
|
? this.state.currentState?.queries[query.name]?.isLoading
|
|
|
|
|
: false;
|
2022-06-17 12:23:59 +00:00
|
|
|
if (!isEmpty(nextProps.selectedQuery) && !isEqual(this.state.selectedQuery, nextProps.selectedQuery)) {
|
2022-06-16 12:34:07 +00:00
|
|
|
if (query && !isLoading && !prevLoading) {
|
|
|
|
|
this.props.runQuery(query.id, query.name);
|
|
|
|
|
}
|
|
|
|
|
} else if (!isLoading && prevLoading) {
|
|
|
|
|
this.state.updatedQuery.updateQuery
|
|
|
|
|
? this.setState({ updatedQuery: {}, isUpdating: false })
|
|
|
|
|
: this.setState({ updatedQuery: {}, isCreating: false });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-27 14:40:33 +00:00
|
|
|
|
|
|
|
|
const diffProps = diff(this.props, nextProps);
|
|
|
|
|
|
2022-12-28 12:05:19 +00:00
|
|
|
if (
|
|
|
|
|
Object.keys(diffProps).length === 0 ||
|
|
|
|
|
'toggleQueryEditor' in diffProps ||
|
|
|
|
|
'darkMode' in diffProps ||
|
|
|
|
|
(!this.props.isUnsavedQueriesAvailable && nextProps.isUnsavedQueriesAvailable)
|
|
|
|
|
) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-12-27 14:40:33 +00:00
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
this.setStateFromProps(nextProps);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 22:32:59 +00:00
|
|
|
removeRestKey = (options) => {
|
2022-12-27 14:40:33 +00:00
|
|
|
delete options.arrayValuesChanged;
|
2022-05-23 22:32:59 +00:00
|
|
|
return options;
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-18 04:57:35 +00:00
|
|
|
handleBackButton = () => {
|
|
|
|
|
this.setState({
|
|
|
|
|
isSourceSelected: true,
|
2022-11-08 12:48:28 +00:00
|
|
|
queryPreviewData: undefined,
|
2022-03-18 04:57:35 +00:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-27 14:40:33 +00:00
|
|
|
handleBackButtonClick = () => {
|
|
|
|
|
if (this.state.isFieldsChanged) {
|
|
|
|
|
this.props.setSaveConfirmation(true);
|
|
|
|
|
this.props.setCancelData({
|
|
|
|
|
isSourceSelected: false,
|
|
|
|
|
selectedDataSource: null,
|
|
|
|
|
selectedQuery: {},
|
|
|
|
|
draftQuery: null,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({
|
|
|
|
|
isSourceSelected: false,
|
|
|
|
|
selectedDataSource: null,
|
|
|
|
|
options: {},
|
|
|
|
|
});
|
|
|
|
|
this.props.clearDraftQuery();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
changeDataSource = (sourceId) => {
|
2022-12-28 12:05:19 +00:00
|
|
|
const source = [...this.state.dataSources, ...staticDataSources].find((datasource) => datasource.kind === sourceId);
|
2022-12-27 14:40:33 +00:00
|
|
|
|
2022-12-28 09:31:31 +00:00
|
|
|
const isSchemaUnavailable = ['restapi', 'stripe', 'runjs', 'runpy', 'tooljetdb'].includes(source.kind);
|
2021-11-22 08:22:32 +00:00
|
|
|
const schemaUnavailableOptions = {
|
|
|
|
|
restapi: {
|
|
|
|
|
method: 'get',
|
2022-12-27 14:40:33 +00:00
|
|
|
url: '',
|
|
|
|
|
url_params: [['', '']],
|
|
|
|
|
headers: [['', '']],
|
|
|
|
|
body: [['', '']],
|
|
|
|
|
json_body: null,
|
|
|
|
|
body_toggle: false,
|
2021-11-22 08:22:32 +00:00
|
|
|
},
|
|
|
|
|
stripe: {},
|
2022-12-22 20:39:57 +00:00
|
|
|
tooljetdb: {},
|
2022-12-27 14:40:33 +00:00
|
|
|
runjs: {
|
|
|
|
|
code: '',
|
|
|
|
|
},
|
|
|
|
|
runpy: {},
|
2021-11-22 08:22:32 +00:00
|
|
|
};
|
|
|
|
|
|
2022-12-27 14:40:33 +00:00
|
|
|
let newOptions = {};
|
|
|
|
|
|
|
|
|
|
if (isSchemaUnavailable) {
|
|
|
|
|
newOptions = {
|
|
|
|
|
...{ ...schemaUnavailableOptions[source.kind] },
|
|
|
|
|
...(source?.kind != 'runjs' && { transformationLanguage: 'javascript', enableTransformation: false }),
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
const selectedSourceDefault =
|
|
|
|
|
source?.plugin?.operations_file?.data?.defaults ?? allOperations[capitalize(source.kind)]?.defaults;
|
|
|
|
|
if (selectedSourceDefault) {
|
|
|
|
|
newOptions = {
|
|
|
|
|
...{ ...selectedSourceDefault },
|
|
|
|
|
...(source?.kind != 'runjs' && { transformationLanguage: 'javascript', enableTransformation: false }),
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
newOptions = {
|
|
|
|
|
...(source?.kind != 'runjs' && { transformationLanguage: 'javascript', enableTransformation: false }),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const newQueryName = this.computeQueryName(source.kind);
|
|
|
|
|
this.defaultOptions.current = { ...newOptions };
|
|
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
this.setState({
|
|
|
|
|
selectedDataSource: source,
|
2021-06-17 05:56:53 +00:00
|
|
|
selectedSource: source,
|
2022-12-27 14:40:33 +00:00
|
|
|
queryName: newQueryName,
|
|
|
|
|
options: { ...newOptions },
|
2021-04-30 06:31:32 +00:00
|
|
|
});
|
2022-12-27 14:40:33 +00:00
|
|
|
|
|
|
|
|
this.props.createDraftQuery(
|
|
|
|
|
{ ...source, name: newQueryName, id: 'draftQuery', options: { ...newOptions } },
|
|
|
|
|
source
|
|
|
|
|
);
|
2021-04-30 06:31:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
validateQueryName = () => {
|
2022-11-03 11:57:34 +00:00
|
|
|
const { queryName, mode, selectedQuery } = this.state;
|
|
|
|
|
const { dataQueries } = this.props;
|
2021-04-30 06:31:32 +00:00
|
|
|
if (mode === 'create') {
|
|
|
|
|
return dataQueries.find((query) => query.name === queryName) === undefined && queryNameRegex.test(queryName);
|
2021-04-29 16:39:09 +00:00
|
|
|
}
|
2021-04-30 08:10:57 +00:00
|
|
|
const existingQuery = dataQueries.find((query) => query.name === queryName);
|
|
|
|
|
if (existingQuery) {
|
|
|
|
|
return existingQuery.id === selectedQuery.id && queryNameRegex.test(queryName);
|
|
|
|
|
}
|
|
|
|
|
return queryNameRegex.test(queryName);
|
2021-04-30 06:31:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
computeQueryName = (kind) => {
|
2022-11-03 11:57:34 +00:00
|
|
|
const { dataQueries } = this.props;
|
2021-04-30 06:31:32 +00:00
|
|
|
const currentQueriesForKind = dataQueries.filter((query) => query.kind === kind);
|
|
|
|
|
let found = false;
|
2021-04-30 12:43:29 +00:00
|
|
|
let newName = '';
|
2021-04-30 06:31:32 +00:00
|
|
|
let currentNumber = currentQueriesForKind.length + 1;
|
|
|
|
|
|
|
|
|
|
while (!found) {
|
2021-04-30 12:43:29 +00:00
|
|
|
newName = `${kind}${currentNumber}`;
|
|
|
|
|
if (dataQueries.find((query) => query.name === newName) === undefined) {
|
2021-04-30 06:31:32 +00:00
|
|
|
found = true;
|
|
|
|
|
}
|
2021-04-30 08:10:57 +00:00
|
|
|
currentNumber += 1;
|
2021-04-04 06:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-30 12:43:29 +00:00
|
|
|
return newName;
|
2021-04-30 06:31:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
createOrUpdateDataQuery = () => {
|
2022-06-17 12:23:59 +00:00
|
|
|
const { appId, options, selectedDataSource, mode, queryName, shouldRunQuery } = this.state;
|
2022-01-04 08:04:12 +00:00
|
|
|
const appVersionId = this.props.editingVersionId;
|
2021-04-30 06:31:32 +00:00
|
|
|
const kind = selectedDataSource.kind;
|
2021-07-24 06:13:21 +00:00
|
|
|
const dataSourceId = selectedDataSource.id === 'null' ? null : selectedDataSource.id;
|
2022-10-27 11:29:43 +00:00
|
|
|
const pluginId = selectedDataSource.plugin_id;
|
2021-04-30 06:31:32 +00:00
|
|
|
|
|
|
|
|
const isQueryNameValid = this.validateQueryName();
|
|
|
|
|
if (!isQueryNameValid) {
|
2021-12-10 23:11:24 +00:00
|
|
|
toast.error('Invalid query name. Should be unique and only include letters, numbers and underscore.');
|
2021-04-30 06:31:32 +00:00
|
|
|
return;
|
2021-04-03 11:14:15 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
if (mode === 'edit') {
|
|
|
|
|
this.setState({ isUpdating: true });
|
2021-06-17 05:56:53 +00:00
|
|
|
dataqueryService
|
|
|
|
|
.update(this.state.selectedQuery.id, queryName, options)
|
2022-06-16 12:34:07 +00:00
|
|
|
.then((data) => {
|
|
|
|
|
this.setState({
|
2022-06-17 12:23:59 +00:00
|
|
|
isUpdating: shouldRunQuery ? true : false,
|
2022-06-16 12:34:07 +00:00
|
|
|
isFieldsChanged: false,
|
2022-12-27 14:40:33 +00:00
|
|
|
isNameChanged: false,
|
2022-06-16 12:34:07 +00:00
|
|
|
restArrayValuesChanged: false,
|
2022-06-17 12:23:59 +00:00
|
|
|
updatedQuery: shouldRunQuery ? { ...data, updateQuery: true } : {},
|
2022-06-16 12:34:07 +00:00
|
|
|
});
|
2021-06-17 05:56:53 +00:00
|
|
|
this.props.dataQueriesChanged();
|
2022-06-01 12:14:59 +00:00
|
|
|
this.props.setStateOfUnsavedQueries(false);
|
2022-10-31 13:38:26 +00:00
|
|
|
localStorage.removeItem('transformation');
|
2022-12-20 13:08:51 +00:00
|
|
|
toast.success('Query Saved');
|
2021-06-17 05:56:53 +00:00
|
|
|
})
|
|
|
|
|
.catch(({ error }) => {
|
2022-12-27 14:40:33 +00:00
|
|
|
this.setState({
|
|
|
|
|
isUpdating: false,
|
|
|
|
|
isFieldsChanged: false,
|
|
|
|
|
isNameChanged: false,
|
|
|
|
|
restArrayValuesChanged: false,
|
|
|
|
|
});
|
2022-06-01 12:14:59 +00:00
|
|
|
this.props.setStateOfUnsavedQueries(false);
|
2021-12-10 23:11:24 +00:00
|
|
|
toast.error(error);
|
2021-06-17 05:56:53 +00:00
|
|
|
});
|
2021-04-30 06:31:32 +00:00
|
|
|
} else {
|
|
|
|
|
this.setState({ isCreating: true });
|
2021-06-17 05:56:53 +00:00
|
|
|
dataqueryService
|
2022-10-27 11:29:43 +00:00
|
|
|
.create(appId, appVersionId, queryName, kind, options, dataSourceId, pluginId)
|
2022-06-16 12:34:07 +00:00
|
|
|
.then((data) => {
|
2021-12-10 23:11:24 +00:00
|
|
|
toast.success('Query Added');
|
2022-06-16 12:34:07 +00:00
|
|
|
this.setState({
|
2022-06-17 12:23:59 +00:00
|
|
|
isCreating: shouldRunQuery ? true : false,
|
2022-06-16 12:34:07 +00:00
|
|
|
isFieldsChanged: false,
|
2022-12-27 14:40:33 +00:00
|
|
|
isNameChanged: false,
|
2022-06-16 12:34:07 +00:00
|
|
|
restArrayValuesChanged: false,
|
2022-06-17 12:23:59 +00:00
|
|
|
updatedQuery: shouldRunQuery ? { ...data, updateQuery: false } : {},
|
2022-06-16 12:34:07 +00:00
|
|
|
});
|
2022-12-27 14:40:33 +00:00
|
|
|
this.props.clearDraftQuery();
|
2021-06-17 05:56:53 +00:00
|
|
|
this.props.dataQueriesChanged();
|
2022-06-01 12:14:59 +00:00
|
|
|
this.props.setStateOfUnsavedQueries(false);
|
2021-06-17 05:56:53 +00:00
|
|
|
})
|
|
|
|
|
.catch(({ error }) => {
|
2022-12-27 14:40:33 +00:00
|
|
|
this.setState({
|
|
|
|
|
isCreating: false,
|
|
|
|
|
isFieldsChanged: false,
|
|
|
|
|
isNameChanged: false,
|
|
|
|
|
restArrayValuesChanged: false,
|
|
|
|
|
});
|
2022-06-01 12:14:59 +00:00
|
|
|
this.props.setStateOfUnsavedQueries(false);
|
2021-12-10 23:11:24 +00:00
|
|
|
toast.error(error);
|
2021-06-17 05:56:53 +00:00
|
|
|
});
|
2021-04-03 11:14:15 +00:00
|
|
|
}
|
2021-04-30 06:31:32 +00:00
|
|
|
};
|
|
|
|
|
|
2022-12-27 14:40:33 +00:00
|
|
|
// Clear the focus field value from options
|
|
|
|
|
cleanFocusedFields = (newOptions) => {
|
|
|
|
|
const diffFields = diff(newOptions, this.defaultOptions.current);
|
|
|
|
|
const updatedOptions = { ...newOptions };
|
|
|
|
|
Object.keys(diffFields).forEach((key) => {
|
|
|
|
|
if (newOptions[key] === '' && this.defaultOptions.current[key] === undefined) {
|
|
|
|
|
delete updatedOptions[key];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return updatedOptions;
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-01 12:14:59 +00:00
|
|
|
validateNewOptions = (newOptions) => {
|
|
|
|
|
const headersChanged = newOptions.arrayValuesChanged ?? false;
|
2022-12-27 14:40:33 +00:00
|
|
|
const updatedOptions = this.cleanFocusedFields(newOptions);
|
2022-06-01 12:14:59 +00:00
|
|
|
let isFieldsChanged = false;
|
|
|
|
|
if (this.state.selectedQuery) {
|
|
|
|
|
const isQueryChanged = !_.isEqual(
|
2022-12-27 14:40:33 +00:00
|
|
|
this.removeRestKey(updatedOptions),
|
|
|
|
|
this.removeRestKey(this.defaultOptions.current)
|
2022-06-01 12:14:59 +00:00
|
|
|
);
|
|
|
|
|
if (isQueryChanged) {
|
|
|
|
|
isFieldsChanged = true;
|
|
|
|
|
} else if (this.state.selectedQuery.kind === 'restapi' && headersChanged) {
|
|
|
|
|
isFieldsChanged = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-27 14:40:33 +00:00
|
|
|
this.setState(
|
|
|
|
|
{
|
|
|
|
|
options: { ...this.state.options, ...updatedOptions },
|
|
|
|
|
isFieldsChanged,
|
|
|
|
|
restArrayValuesChanged: headersChanged,
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
if (isFieldsChanged !== this.props.isUnsavedQueriesAvailable)
|
|
|
|
|
this.props.setStateOfUnsavedQueries(isFieldsChanged);
|
|
|
|
|
}
|
|
|
|
|
);
|
2022-06-01 12:14:59 +00:00
|
|
|
};
|
|
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
optionchanged = (option, value) => {
|
2022-06-01 12:14:59 +00:00
|
|
|
const newOptions = { ...this.state.options, [option]: value };
|
|
|
|
|
this.validateNewOptions(newOptions);
|
2021-04-30 06:31:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
optionsChanged = (newOptions) => {
|
2022-06-01 12:14:59 +00:00
|
|
|
this.validateNewOptions(newOptions);
|
2021-04-30 06:31:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
toggleOption = (option) => {
|
|
|
|
|
const currentValue = this.state.options[option] ? this.state.options[option] : false;
|
|
|
|
|
this.optionchanged(option, !currentValue);
|
|
|
|
|
};
|
|
|
|
|
|
2021-09-06 14:40:51 +00:00
|
|
|
// Here we have mocked data query in format of a component to be usable by event manager
|
|
|
|
|
// TODO: Refactor EventManager to be generic
|
|
|
|
|
mockDataQueryAsComponent = () => {
|
|
|
|
|
const dataQueryEvents = this.state.options?.events || [];
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
component: { component: { definition: { events: dataQueryEvents } } },
|
|
|
|
|
componentMeta: {
|
|
|
|
|
events: {
|
|
|
|
|
onDataQuerySuccess: { displayName: 'Query Success' },
|
|
|
|
|
onDataQueryFailure: { displayName: 'Query Failure' },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
eventsChanged = (events) => {
|
|
|
|
|
this.optionchanged('events', events);
|
|
|
|
|
};
|
2022-12-20 13:08:51 +00:00
|
|
|
createInputElementToUpdateQueryName = () => {
|
|
|
|
|
this.setState({ renameQuery: true });
|
|
|
|
|
};
|
|
|
|
|
executeQueryNameUpdation = (newName) => {
|
2022-12-22 14:27:52 +00:00
|
|
|
const isNewQueryNameAlreadyExists = this.state.dataQueries.some((query) => query.name === newName);
|
|
|
|
|
if (newName && !isNewQueryNameAlreadyExists) {
|
2022-12-20 13:08:51 +00:00
|
|
|
if (this.state.mode === 'create') {
|
|
|
|
|
this.setState({
|
|
|
|
|
queryName: newName,
|
|
|
|
|
renameQuery: false,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
dataqueryService
|
|
|
|
|
.update(this.state.selectedQuery.id, newName)
|
|
|
|
|
.then(() => {
|
|
|
|
|
this.props.dataQueriesChanged();
|
|
|
|
|
toast.success('Query Name Updated');
|
|
|
|
|
this.setState({
|
|
|
|
|
renameQuery: false,
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(({ error }) => {
|
|
|
|
|
this.setState({ renameQuery: false });
|
|
|
|
|
toast.error(error);
|
|
|
|
|
});
|
|
|
|
|
}
|
2022-06-17 12:23:59 +00:00
|
|
|
} else {
|
2022-12-22 14:27:52 +00:00
|
|
|
if (isNewQueryNameAlreadyExists) toast.error('Query name already exists');
|
2022-12-20 13:08:51 +00:00
|
|
|
this.setState({ renameQuery: false });
|
2022-06-17 12:23:59 +00:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-27 14:40:33 +00:00
|
|
|
updateQueryName = (e) => {
|
|
|
|
|
const { value } = e.target;
|
|
|
|
|
if (value !== this.state.selectedQuery?.name && (!this.state.isNameChanged || !this.state.isNameChanged)) {
|
|
|
|
|
this.setState({ queryName: value, isFieldsChanged: true, isNameChanged: true });
|
|
|
|
|
this.props.setStateOfUnsavedQueries(true);
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({ queryName: value });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-19 09:27:14 +00:00
|
|
|
updateQueryName = (e) => {
|
|
|
|
|
const { value } = e.target;
|
|
|
|
|
if (value !== this.state.selectedQuery?.name && (!this.state.isNameChanged || !this.state.isNameChanged)) {
|
|
|
|
|
this.setState({ queryName: value, isFieldsChanged: true, isNameChanged: true });
|
|
|
|
|
this.props.setStateOfUnsavedQueries(true);
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({ queryName: value });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
render() {
|
|
|
|
|
const {
|
|
|
|
|
dataSources,
|
|
|
|
|
selectedDataSource,
|
|
|
|
|
mode,
|
2021-05-22 11:50:55 +00:00
|
|
|
options,
|
2021-04-30 06:31:32 +00:00
|
|
|
isUpdating,
|
|
|
|
|
isCreating,
|
|
|
|
|
addingQuery,
|
|
|
|
|
editingQuery,
|
|
|
|
|
selectedQuery,
|
2021-05-22 11:29:27 +00:00
|
|
|
queryName,
|
|
|
|
|
previewLoading,
|
2021-06-17 05:56:53 +00:00
|
|
|
queryPreviewData,
|
2021-12-08 08:25:22 +00:00
|
|
|
dataSourceMeta,
|
2021-04-30 06:31:32 +00:00
|
|
|
} = this.state;
|
|
|
|
|
let ElementToRender = '';
|
|
|
|
|
if (selectedDataSource) {
|
|
|
|
|
const sourcecomponentName = selectedDataSource.kind.charAt(0).toUpperCase() + selectedDataSource.kind.slice(1);
|
2022-10-27 11:29:43 +00:00
|
|
|
ElementToRender = allSources[sourcecomponentName] || source;
|
2021-04-04 17:07:03 +00:00
|
|
|
}
|
2021-04-30 06:31:32 +00:00
|
|
|
const buttonDisabled = isUpdating || isCreating;
|
2021-09-06 14:40:51 +00:00
|
|
|
const mockDataQueryComponent = this.mockDataQueryAsComponent();
|
2022-02-01 03:12:57 +00:00
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
return (
|
2022-09-28 09:36:13 +00:00
|
|
|
<div
|
2022-12-20 13:08:51 +00:00
|
|
|
className={cx(`query-manager ${this.props.darkMode ? 'theme-dark' : ''}`, {
|
|
|
|
|
'd-none': this.props.loadingDataSources,
|
|
|
|
|
})}
|
2022-09-28 09:36:13 +00:00
|
|
|
key={selectedQuery ? selectedQuery.id : ''}
|
|
|
|
|
>
|
2021-04-30 06:31:32 +00:00
|
|
|
<ReactTooltip type="dark" effect="solid" delayShow={250} />
|
2022-12-28 09:31:31 +00:00
|
|
|
|
2022-12-20 13:08:51 +00:00
|
|
|
<div className="row header" style={{ padding: '8px 0' }}>
|
|
|
|
|
<div className="col d-flex align-items-center px-3 h-100 font-weight-500 py-1" style={{ gap: '10px' }}>
|
2022-03-15 03:04:32 +00:00
|
|
|
{(addingQuery || editingQuery) && selectedDataSource && (
|
2022-12-20 13:08:51 +00:00
|
|
|
<>
|
|
|
|
|
<span
|
2023-01-03 03:01:47 +00:00
|
|
|
className={`${
|
|
|
|
|
this.props.darkMode ? 'color-light-gray-c3c3c3' : 'color-light-slate-11'
|
|
|
|
|
} cursor-pointer font-weight-400`}
|
2022-12-20 13:08:51 +00:00
|
|
|
onClick={() => {
|
2022-12-22 14:04:46 +00:00
|
|
|
this.props.addNewQueryAndDeselectSelectedQuery();
|
2022-12-20 13:08:51 +00:00
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{mode === 'create' ? 'New Query' : 'Queries'}
|
|
|
|
|
</span>
|
|
|
|
|
<span className="breadcrum">
|
|
|
|
|
<svg width="5.33" height="9.33" viewBox="0 0 8 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
|
|
<path
|
|
|
|
|
fillRule="evenodd"
|
|
|
|
|
clipRule="evenodd"
|
|
|
|
|
d="M0.292893 0.292893C0.683417 -0.0976311 1.31658 -0.0976311 1.70711 0.292893L7.70711 6.29289C8.09763 6.68342 8.09763 7.31658 7.70711 7.70711L1.70711 13.7071C1.31658 14.0976 0.683417 14.0976 0.292893 13.7071C-0.0976311 13.3166 -0.0976311 12.6834 0.292893 12.2929L5.58579 7L0.292893 1.70711C-0.0976311 1.31658 -0.0976311 0.683417 0.292893 0.292893Z"
|
|
|
|
|
fill="#C1C8CD"
|
|
|
|
|
/>
|
|
|
|
|
</svg>
|
|
|
|
|
</span>
|
|
|
|
|
<div className="query-name-breadcrum d-flex align-items-center">
|
|
|
|
|
<span className="query-manager-header-query-name font-weight-400">
|
|
|
|
|
{this.state.renameQuery ? (
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
2023-01-03 03:01:47 +00:00
|
|
|
className={`query-name query-name-input-field border-indigo-09 bg-transparent ${
|
|
|
|
|
this.props.darkMode && 'text-white'
|
|
|
|
|
}`}
|
2022-12-20 13:08:51 +00:00
|
|
|
autoFocus
|
|
|
|
|
defaultValue={queryName}
|
|
|
|
|
onKeyUp={(event) => {
|
|
|
|
|
event.persist();
|
|
|
|
|
if (event.keyCode === 13) {
|
|
|
|
|
this.executeQueryNameUpdation(event.target.value);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
onBlur={({ target }) => this.executeQueryNameUpdation(target.value)}
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
|
|
|
|
queryName
|
|
|
|
|
)}
|
|
|
|
|
</span>
|
|
|
|
|
<span
|
|
|
|
|
className={`breadcrum-rename-query-icon ${this.state.renameQuery && 'd-none'}`}
|
|
|
|
|
onClick={this.createInputElementToUpdateQueryName}
|
|
|
|
|
>
|
|
|
|
|
<svg width="auto" height="auto" viewBox="0 0 19 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
|
|
<path
|
|
|
|
|
fillRule="evenodd"
|
|
|
|
|
clipRule="evenodd"
|
|
|
|
|
d="M13.7087 1.40712C14.29 0.826221 15.0782 0.499893 15.9 0.499893C16.7222 0.499893 17.5107 0.82651 18.0921 1.40789C18.6735 1.98928 19.0001 2.7778 19.0001 3.6C19.0001 4.42197 18.6737 5.21028 18.0926 5.79162C18.0924 5.79178 18.0928 5.79145 18.0926 5.79162L16.8287 7.06006C16.7936 7.11191 16.753 7.16118 16.7071 7.20711C16.6621 7.25215 16.6138 7.292 16.563 7.32665L9.70837 14.2058C9.52073 14.3942 9.26584 14.5 9 14.5H6C5.44772 14.5 5 14.0523 5 13.5V10.5C5 10.2342 5.10585 9.97927 5.29416 9.79163L12.1733 2.93697C12.208 2.88621 12.2478 2.83794 12.2929 2.79289C12.3388 2.74697 12.3881 2.70645 12.4399 2.67132L13.7079 1.40789C13.7082 1.40763 13.7084 1.40738 13.7087 1.40712ZM13.0112 4.92545L7 10.9153V12.5H8.58474L14.5745 6.48876L13.0112 4.92545ZM15.9862 5.07202L14.428 3.51376L15.1221 2.82211C15.3284 2.6158 15.6082 2.49989 15.9 2.49989C16.1918 2.49989 16.4716 2.6158 16.6779 2.82211C16.8842 3.02842 17.0001 3.30823 17.0001 3.6C17.0001 3.89177 16.8842 4.17158 16.6779 4.37789L15.9862 5.07202ZM0.87868 5.37868C1.44129 4.81607 2.20435 4.5 3 4.5H4C4.55228 4.5 5 4.94772 5 5.5C5 6.05228 4.55228 6.5 4 6.5H3C2.73478 6.5 2.48043 6.60536 2.29289 6.79289C2.10536 6.98043 2 7.23478 2 7.5V16.5C2 16.7652 2.10536 17.0196 2.29289 17.2071C2.48043 17.3946 2.73478 17.5 3 17.5H12C12.2652 17.5 12.5196 17.3946 12.7071 17.2071C12.8946 17.0196 13 16.7652 13 16.5V15.5C13 14.9477 13.4477 14.5 14 14.5C14.5523 14.5 15 14.9477 15 15.5V16.5C15 17.2957 14.6839 18.0587 14.1213 18.6213C13.5587 19.1839 12.7957 19.5 12 19.5H3C2.20435 19.5 1.44129 19.1839 0.87868 18.6213C0.31607 18.0587 0 17.2957 0 16.5V7.5C0 6.70435 0.31607 5.94129 0.87868 5.37868Z"
|
|
|
|
|
fill="#11181C"
|
|
|
|
|
/>
|
|
|
|
|
</svg>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
2021-04-30 06:31:32 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
2022-12-20 13:08:51 +00:00
|
|
|
<div className="col-auto d-flex align-items-center h-100 query-header-buttons m-auto">
|
2022-03-18 04:57:35 +00:00
|
|
|
{selectedDataSource && (addingQuery || editingQuery) && (
|
2022-02-02 16:59:57 +00:00
|
|
|
<button
|
2021-06-17 05:56:53 +00:00
|
|
|
onClick={() => {
|
2021-09-06 14:40:51 +00:00
|
|
|
const _options = { ...options };
|
|
|
|
|
|
2021-06-17 05:56:53 +00:00
|
|
|
const query = {
|
2021-09-06 14:40:51 +00:00
|
|
|
data_source_id: selectedDataSource.id === 'null' ? null : selectedDataSource.id,
|
2022-10-27 11:29:43 +00:00
|
|
|
pluginId: selectedDataSource.plugin_id,
|
2021-08-30 11:25:27 +00:00
|
|
|
options: _options,
|
2021-06-17 05:56:53 +00:00
|
|
|
kind: selectedDataSource.kind,
|
|
|
|
|
};
|
2022-12-22 20:39:57 +00:00
|
|
|
|
2022-07-08 13:08:55 +00:00
|
|
|
previewQuery(this, query, this.props.editorState)
|
2021-06-17 05:56:53 +00:00
|
|
|
.then(() => {
|
|
|
|
|
this.previewPanelRef.current.scrollIntoView();
|
|
|
|
|
})
|
|
|
|
|
.catch(({ error, data }) => {
|
2021-09-21 13:48:28 +00:00
|
|
|
console.log(error, data);
|
2021-05-22 12:57:36 +00:00
|
|
|
});
|
|
|
|
|
}}
|
2023-01-03 03:01:47 +00:00
|
|
|
className={`default-tertiary-button float-right1 ${
|
|
|
|
|
previewLoading ? (this.props.darkMode ? 'btn-loading' : 'button-loading') : ''
|
|
|
|
|
} ${this.props.darkMode ? 'theme-dark ' : ''} ${this.state.selectedDataSource ? '' : 'disabled'}`}
|
2022-11-11 05:45:12 +00:00
|
|
|
data-cy={'query-preview-button'}
|
2021-05-22 11:29:27 +00:00
|
|
|
>
|
2022-12-20 13:08:51 +00:00
|
|
|
<span
|
|
|
|
|
className="query-preview-svg d-flex align-items-center query-icon-wrapper"
|
|
|
|
|
style={{ width: '16px', height: '16px', padding: '2.67px 0.67px', margin: '6px 0' }}
|
|
|
|
|
>
|
|
|
|
|
<svg width="auto" height="auto" viewBox="0 0 22 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
|
|
<path
|
|
|
|
|
fillRule="evenodd"
|
|
|
|
|
clipRule="evenodd"
|
|
|
|
|
d="M2.15986 8C4.65779 12.1305 7.61278 14 11 14C14.3872 14 17.3422 12.1305 19.8401 8C17.3422 3.86948 14.3872 2 11 2C7.61278 2 4.65779 3.86948 2.15986 8ZM0.131768 7.50384C2.9072 2.64709 6.51999 0 11 0C15.48 0 19.0928 2.64709 21.8682 7.50384C22.0439 7.81128 22.0439 8.18871 21.8682 8.49616C19.0928 13.3529 15.48 16 11 16C6.51999 16 2.9072 13.3529 0.131768 8.49616C-0.0439228 8.18871 -0.0439228 7.81128 0.131768 7.50384ZM11 7C10.4477 7 10 7.44772 10 8C10 8.55228 10.4477 9 11 9C11.5523 9 12 8.55228 12 8C12 7.44772 11.5523 7 11 7ZM8 8C8 6.34315 9.34315 5 11 5C12.6569 5 14 6.34315 14 8C14 9.65685 12.6569 11 11 11C9.34315 11 8 9.65685 8 8Z"
|
|
|
|
|
fill="#11181C"
|
|
|
|
|
/>
|
|
|
|
|
</svg>
|
|
|
|
|
</span>
|
|
|
|
|
<span>{this.props.t('editor.queryManager.preview', 'Preview')}</span>
|
2022-02-02 16:59:57 +00:00
|
|
|
</button>
|
2021-05-22 11:29:27 +00:00
|
|
|
)}
|
2022-03-18 04:57:35 +00:00
|
|
|
{selectedDataSource && (addingQuery || editingQuery) && (
|
2022-12-20 13:08:51 +00:00
|
|
|
<button
|
2023-01-03 03:01:47 +00:00
|
|
|
className={`default-tertiary-button ${
|
|
|
|
|
isUpdating || isCreating ? (this.props.darkMode ? 'btn-loading' : 'button-loading') : ''
|
|
|
|
|
} ${this.props.darkMode ? 'theme-dark' : ''} ${this.state.selectedDataSource ? '' : 'disabled'} `}
|
2022-12-20 13:08:51 +00:00
|
|
|
onClick={this.createOrUpdateDataQuery}
|
|
|
|
|
disabled={buttonDisabled}
|
|
|
|
|
data-cy={'query-create-and-run-button'}
|
|
|
|
|
>
|
|
|
|
|
<span className="d-flex query-create-run-svg query-icon-wrapper">
|
|
|
|
|
<svg width="auto" height="auto" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
|
|
<path
|
|
|
|
|
fillRule="evenodd"
|
|
|
|
|
clipRule="evenodd"
|
|
|
|
|
d="M3 2.5C2.73478 2.5 2.48043 2.60536 2.29289 2.79289C2.10536 2.98043 2 3.23478 2 3.5V15.5C2 15.7652 2.10536 16.0196 2.29289 16.2071C2.48043 16.3946 2.73478 16.5 3 16.5H15C15.2652 16.5 15.5196 16.3946 15.7071 16.2071C15.8946 16.0196 16 15.7652 16 15.5V5.91421L12.5858 2.5H12V5.5C12 6.05228 11.5523 6.5 11 6.5H5C4.44772 6.5 4 6.05228 4 5.5V2.5H3ZM3 0.5C2.20435 0.5 1.44129 0.81607 0.87868 1.37868C0.31607 1.94129 0 2.70435 0 3.5V15.5C0 16.2956 0.31607 17.0587 0.87868 17.6213C1.44129 18.1839 2.20435 18.5 3 18.5H15C15.7957 18.5 16.5587 18.1839 17.1213 17.6213C17.6839 17.0587 18 16.2957 18 15.5V5.5C18 5.23478 17.8946 4.98043 17.7071 4.79289L13.7071 0.792893C13.5196 0.605357 13.2652 0.5 13 0.5H3ZM6 2.5V4.5H10V2.5H6ZM9 10.5C8.44772 10.5 8 10.9477 8 11.5C8 12.0523 8.44772 12.5 9 12.5C9.55228 12.5 10 12.0523 10 11.5C10 10.9477 9.55229 10.5 9 10.5ZM6 11.5C6 9.84315 7.34315 8.5 9 8.5C10.6569 8.5 12 9.84315 12 11.5C12 13.1569 10.6569 14.5 9 14.5C7.34315 14.5 6 13.1569 6 11.5Z"
|
|
|
|
|
fill="#11181C"
|
|
|
|
|
/>
|
|
|
|
|
</svg>
|
|
|
|
|
</span>
|
|
|
|
|
<span>{this.state.buttonText}</span>
|
|
|
|
|
</button>
|
2021-04-30 06:31:32 +00:00
|
|
|
)}
|
2022-12-20 13:08:51 +00:00
|
|
|
{selectedDataSource && (addingQuery || editingQuery) && (
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => {
|
|
|
|
|
if (this.state.isFieldsChanged || this.state.addingQuery) {
|
|
|
|
|
this.setState({ shouldRunQuery: true }, () => this.createOrUpdateDataQuery());
|
|
|
|
|
} else {
|
|
|
|
|
this.props.runQuery(selectedQuery.id, selectedQuery.name);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
className={`border-0 default-secondary-button float-right1 ${this.props.darkMode ? 'theme-dark' : ''} ${
|
|
|
|
|
this.state.selectedDataSource ? '' : 'disabled'
|
2022-12-30 03:28:17 +00:00
|
|
|
} ${
|
|
|
|
|
this.state.currentState.queries[selectedQuery.name]?.isLoading
|
|
|
|
|
? this.props.darkMode
|
|
|
|
|
? 'btn-loading'
|
|
|
|
|
: 'button-loading'
|
|
|
|
|
: ''
|
2022-12-20 13:08:51 +00:00
|
|
|
}`}
|
|
|
|
|
>
|
2022-12-30 03:28:17 +00:00
|
|
|
<span
|
|
|
|
|
className={`query-manager-btn-svg-wrapper d-flex align-item-center query-icon-wrapper query-run-svg ${
|
|
|
|
|
this.state.currentState.queries[selectedQuery.name]?.isLoading && 'invisible'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
2022-12-20 13:08:51 +00:00
|
|
|
<svg width="auto" height="auto" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
|
|
<path
|
|
|
|
|
fillRule="evenodd"
|
|
|
|
|
clipRule="evenodd"
|
|
|
|
|
d="M0.292893 0.292893C0.683417 -0.0976311 1.31658 -0.0976311 1.70711 0.292893L6.70711 5.29289C7.09763 5.68342 7.09763 6.31658 6.70711 6.70711L1.70711 11.7071C1.31658 12.0976 0.683417 12.0976 0.292893 11.7071C-0.0976311 11.3166 -0.0976311 10.6834 0.292893 10.2929L4.58579 6L0.292893 1.70711C-0.0976311 1.31658 -0.0976311 0.683417 0.292893 0.292893ZM8 11C8 10.4477 8.44772 10 9 10H15C15.5523 10 16 10.4477 16 11C16 11.5523 15.5523 12 15 12H9C8.44772 12 8 11.5523 8 11Z"
|
|
|
|
|
fill="#3A5CCC"
|
|
|
|
|
/>
|
|
|
|
|
</svg>
|
|
|
|
|
</span>
|
2022-12-30 03:28:17 +00:00
|
|
|
<span className="query-manager-btn-name">
|
|
|
|
|
{this.state.currentState.queries[selectedQuery.name]?.isLoading ? ' ' : 'Run'}
|
|
|
|
|
</span>
|
2022-12-20 13:08:51 +00:00
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
<span
|
|
|
|
|
onClick={this.props.toggleQueryEditor}
|
|
|
|
|
className={`cursor-pointer m-3 toggle-query-editor-svg d-flex`}
|
|
|
|
|
data-tip="Hide query editor"
|
|
|
|
|
>
|
|
|
|
|
<svg width="5.58" height="10.25" viewBox="0 0 6 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
|
|
<path
|
|
|
|
|
d="M3.00013 4.18288C2.94457 4.18288 2.88624 4.17177 2.82513 4.14954C2.76402 4.12732 2.70569 4.08843 2.65013 4.03288L0.366797 1.74954C0.266797 1.64954 0.216797 1.52732 0.216797 1.38288C0.216797 1.23843 0.266797 1.11621 0.366797 1.01621C0.466797 0.916211 0.583464 0.866211 0.716797 0.866211C0.85013 0.866211 0.966797 0.916211 1.0668 1.01621L3.00013 2.94954L4.93346 1.01621C5.03346 0.916211 5.15291 0.866211 5.2918 0.866211C5.43069 0.866211 5.55013 0.916211 5.65013 1.01621C5.75013 1.11621 5.80013 1.23566 5.80013 1.37454C5.80013 1.51343 5.75013 1.63288 5.65013 1.73288L3.35013 4.03288C3.29457 4.08843 3.23902 4.12732 3.18346 4.14954C3.12791 4.17177 3.0668 4.18288 3.00013 4.18288ZM0.366797 10.9662C0.266797 10.8662 0.216797 10.7468 0.216797 10.6079C0.216797 10.469 0.266797 10.3495 0.366797 10.2495L2.65013 7.96621C2.70569 7.91065 2.76402 7.87177 2.82513 7.84954C2.88624 7.82732 2.94457 7.81621 3.00013 7.81621C3.0668 7.81621 3.12791 7.82732 3.18346 7.84954C3.23902 7.87177 3.29457 7.91065 3.35013 7.96621L5.65013 10.2662C5.75013 10.3662 5.80013 10.4829 5.80013 10.6162C5.80013 10.7495 5.75013 10.8662 5.65013 10.9662C5.55013 11.0662 5.42791 11.1162 5.28346 11.1162C5.13902 11.1162 5.0168 11.0662 4.9168 10.9662L3.00013 9.04954L1.08346 10.9662C0.983464 11.0662 0.864019 11.1162 0.72513 11.1162C0.586241 11.1162 0.466797 11.0662 0.366797 10.9662Z"
|
|
|
|
|
fill="#576574"
|
|
|
|
|
/>
|
2021-12-20 03:54:11 +00:00
|
|
|
</svg>
|
|
|
|
|
</span>
|
2021-04-30 06:31:32 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{(addingQuery || editingQuery) && (
|
2022-12-20 13:08:51 +00:00
|
|
|
<div>
|
2022-12-22 20:39:57 +00:00
|
|
|
<div
|
2023-01-03 03:01:47 +00:00
|
|
|
className={`row row-deck px-2 mt-0 query-details ${
|
|
|
|
|
selectedDataSource?.kind === 'tooljetdb' && 'tooljetdb-query-details'
|
|
|
|
|
}`}
|
2022-12-22 20:39:57 +00:00
|
|
|
>
|
2022-12-20 13:08:51 +00:00
|
|
|
{dataSources && mode === 'create' && !this.state.isSourceSelected && (
|
|
|
|
|
<div className="datasource-picker">
|
|
|
|
|
{!this.state.isSourceSelected && (
|
|
|
|
|
<label className="form-label col-md-3" data-cy={'label-select-datasource'}>
|
|
|
|
|
{this.props.t('editor.queryManager.selectDatasource', 'Select Datasource')}
|
|
|
|
|
</label>
|
|
|
|
|
)}{' '}
|
|
|
|
|
{!this.state.isSourceSelected && (
|
|
|
|
|
<DataSourceLister
|
|
|
|
|
dataSources={dataSources}
|
|
|
|
|
staticDataSources={staticDataSources}
|
|
|
|
|
changeDataSource={this.changeDataSource}
|
|
|
|
|
handleBackButton={this.handleBackButton}
|
|
|
|
|
darkMode={this.props.darkMode}
|
|
|
|
|
dataSourceModalHandler={this.props.dataSourceModalHandler}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2021-04-30 06:31:32 +00:00
|
|
|
|
2022-12-20 13:08:51 +00:00
|
|
|
{selectedDataSource && (
|
|
|
|
|
<div style={{ padding: '0 32px' }}>
|
2021-04-30 06:31:32 +00:00
|
|
|
<div>
|
2021-06-17 05:56:53 +00:00
|
|
|
<ElementToRender
|
2022-10-27 11:29:43 +00:00
|
|
|
pluginSchema={this.state.selectedDataSource?.plugin?.operations_file?.data}
|
2022-05-12 01:31:20 +00:00
|
|
|
selectedDataSource={selectedDataSource}
|
2021-06-17 05:56:53 +00:00
|
|
|
options={this.state.options}
|
|
|
|
|
optionsChanged={this.optionsChanged}
|
2021-11-17 17:59:00 +00:00
|
|
|
optionchanged={this.optionchanged}
|
2022-12-27 14:40:33 +00:00
|
|
|
currentState={this.props.currentState}
|
2021-07-03 14:17:47 +00:00
|
|
|
darkMode={this.props.darkMode}
|
2022-12-27 14:40:33 +00:00
|
|
|
isEditMode={true} // Made TRUE always to avoid setting default options again
|
2021-12-10 03:09:23 +00:00
|
|
|
queryName={this.state.queryName}
|
2021-06-17 05:56:53 +00:00
|
|
|
/>
|
2022-06-02 09:26:26 +00:00
|
|
|
|
2022-12-27 14:40:33 +00:00
|
|
|
{!dataSourceMeta?.disableTransformations &&
|
|
|
|
|
(selectedDataSource?.kind != 'runjs' || selectedDataSource?.kind != 'runpy') && (
|
|
|
|
|
<div>
|
2022-12-28 09:31:31 +00:00
|
|
|
<Transformation
|
|
|
|
|
changeOption={this.optionchanged}
|
|
|
|
|
options={options ?? {}}
|
|
|
|
|
currentState={this.props.currentState}
|
|
|
|
|
darkMode={this.props.darkMode}
|
|
|
|
|
queryId={selectedQuery?.id}
|
|
|
|
|
/>
|
2022-12-27 14:40:33 +00:00
|
|
|
</div>
|
|
|
|
|
)}
|
2022-03-31 10:30:09 +00:00
|
|
|
<Preview
|
|
|
|
|
previewPanelRef={this.previewPanelRef}
|
|
|
|
|
previewLoading={previewLoading}
|
|
|
|
|
queryPreviewData={queryPreviewData}
|
|
|
|
|
theme={this.state.theme}
|
|
|
|
|
darkMode={this.props.darkMode}
|
|
|
|
|
/>
|
2021-04-30 06:31:32 +00:00
|
|
|
</div>
|
2022-01-12 08:26:48 +00:00
|
|
|
</div>
|
2022-12-20 13:08:51 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
2021-04-30 06:31:32 +00:00
|
|
|
|
2022-12-20 13:08:51 +00:00
|
|
|
{selectedDataSource && (addingQuery || editingQuery) && (
|
|
|
|
|
<div className="advanced-options-container font-weight-400 border-top query-manager-border-color">
|
|
|
|
|
<div className="advance-options-input-form-container">
|
|
|
|
|
<div className="mx-4">
|
|
|
|
|
<CustomToggleSwitch
|
|
|
|
|
isChecked={this.state.options.runOnPageLoad}
|
|
|
|
|
toggleSwitchFunction={this.toggleOption}
|
|
|
|
|
action="runOnPageLoad"
|
|
|
|
|
darkMode={this.props.darkMode}
|
|
|
|
|
label={this.props.t(
|
|
|
|
|
'editor.queryManager.runQueryOnApplicationLoad',
|
|
|
|
|
'Run this query on application load?'
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className=" mx-4 pb-3 pt-3">
|
|
|
|
|
<CustomToggleSwitch
|
|
|
|
|
isChecked={this.state.options.requestConfirmation}
|
|
|
|
|
toggleSwitchFunction={this.toggleOption}
|
|
|
|
|
action="requestConfirmation"
|
|
|
|
|
darkMode={this.props.darkMode}
|
|
|
|
|
label={this.props.t(
|
|
|
|
|
'editor.queryManager.confirmBeforeQueryRun',
|
|
|
|
|
'Request confirmation before running query?'
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className=" mx-4">
|
|
|
|
|
<CustomToggleSwitch
|
|
|
|
|
isChecked={this.state.options.showSuccessNotification}
|
|
|
|
|
toggleSwitchFunction={this.toggleOption}
|
|
|
|
|
action="showSuccessNotification"
|
|
|
|
|
darkMode={this.props.darkMode}
|
|
|
|
|
label={this.props.t('editor.queryManager.notificationOnSuccess', 'Show notification on success?')}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
{this.state.options.showSuccessNotification && (
|
|
|
|
|
<div className="mx-4" style={{ paddingLeft: '100px', paddingTop: '12px' }}>
|
|
|
|
|
<div className="row mt-1">
|
|
|
|
|
<div className="col-auto" style={{ width: '200px' }}>
|
|
|
|
|
<label className="form-label p-2 font-size-12" data-cy={'label-success-message-input'}>
|
|
|
|
|
{this.props.t('editor.queryManager.successMessage', 'Success Message')}
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="col">
|
|
|
|
|
<CodeHinter
|
|
|
|
|
currentState={this.props.currentState}
|
|
|
|
|
initialValue={this.state.options.successMessage}
|
|
|
|
|
height="36px"
|
|
|
|
|
theme={this.props.darkMode ? 'monokai' : 'default'}
|
|
|
|
|
onChange={(value) => this.optionchanged('successMessage', value)}
|
|
|
|
|
placeholder={this.props.t(
|
|
|
|
|
'editor.queryManager.queryRanSuccessfully',
|
|
|
|
|
'Query ran successfully'
|
|
|
|
|
)}
|
|
|
|
|
cyLabel={'success-message'}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2021-09-06 14:40:51 +00:00
|
|
|
</div>
|
2022-12-20 13:08:51 +00:00
|
|
|
<div className="row mt-3">
|
|
|
|
|
<div className="col-auto" style={{ width: '200px' }}>
|
|
|
|
|
<label className="form-label p-2 font-size-12" data-cy={'label-notification-duration-input'}>
|
|
|
|
|
{this.props.t('editor.queryManager.notificationDuration', 'Notification duration (s)')}
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="col query-manager-input-elem">
|
|
|
|
|
<input
|
|
|
|
|
type="number"
|
|
|
|
|
disabled={!this.state.options.showSuccessNotification}
|
|
|
|
|
onChange={(e) => this.optionchanged('notificationDuration', e.target.value)}
|
|
|
|
|
placeholder={5}
|
|
|
|
|
className="form-control"
|
|
|
|
|
value={this.state.options.notificationDuration}
|
|
|
|
|
data-cy={'notification-duration-input-field'}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2021-09-06 14:40:51 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2022-12-20 13:08:51 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
2021-09-06 14:40:51 +00:00
|
|
|
|
2022-12-20 13:08:51 +00:00
|
|
|
<div
|
2023-01-03 03:01:47 +00:00
|
|
|
className={`border-top query-manager-border-color hr-text-left px-4 ${
|
|
|
|
|
this.props.darkMode ? 'color-white' : 'color-light-slate-12'
|
|
|
|
|
}`}
|
2022-12-20 13:08:51 +00:00
|
|
|
style={{ paddingTop: '28px' }}
|
|
|
|
|
>
|
|
|
|
|
{this.props.t('editor.queryManager.eventsHandler', 'Events Handler')}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="query-manager-events px-4 mt-2 pb-4">
|
2021-09-06 14:40:51 +00:00
|
|
|
<EventManager
|
|
|
|
|
eventsChanged={this.eventsChanged}
|
|
|
|
|
component={mockDataQueryComponent.component}
|
|
|
|
|
componentMeta={mockDataQueryComponent.componentMeta}
|
|
|
|
|
currentState={this.props.currentState}
|
|
|
|
|
dataQueries={this.props.dataQueries}
|
|
|
|
|
components={this.props.allComponents}
|
|
|
|
|
apps={this.props.apps}
|
|
|
|
|
popoverPlacement="top"
|
2022-12-13 09:30:46 +00:00
|
|
|
pages={
|
|
|
|
|
this.props.appDefinition?.pages
|
|
|
|
|
? Object.entries(this.props.appDefinition?.pages).map(([id, page]) => ({ ...page, id }))
|
|
|
|
|
: []
|
|
|
|
|
}
|
2021-09-06 14:40:51 +00:00
|
|
|
/>
|
2021-04-26 07:13:20 +00:00
|
|
|
</div>
|
2021-04-30 06:31:32 +00:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-09-14 08:04:49 +00:00
|
|
|
}
|
2021-04-03 11:14:15 +00:00
|
|
|
|
2022-09-14 08:04:49 +00:00
|
|
|
export const QueryManager = withTranslation()(React.memo(QueryManagerComponent));
|