Add widget cta in query pane (#1157)

This commit is contained in:
akash-codemonk 2020-10-15 12:51:00 +05:30 committed by GitHub
parent 05380a9c43
commit 47847cbc7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 173 additions and 9 deletions

View File

@ -0,0 +1,37 @@
const queryLocators = require("../../../locators/QueryEditor.json");
const queryEditor = require("../../../locators/QueryEditor.json");
let datasourceName;
describe("Add widget", function() {
beforeEach(() => {
cy.createPostgresDatasource();
cy.get("@createDatasource").then(httpResponse => {
datasourceName = httpResponse.response.body.data.name;
});
});
it("Add widget", () => {
cy.NavigateToQueryEditor();
cy.get(".t--datasource-name")
.contains(datasourceName)
.click();
cy.get(queryLocators.templateMenu).click();
cy.get(".CodeMirror textarea")
.first()
.focus()
.type("select * from configs");
cy.get(queryEditor.runQuery).click();
cy.wait("@postExecute").should(
"have.nested.property",
"response.body.responseMeta.status",
200,
);
cy.get(".t--add-widget").click();
cy.SearchEntityandOpen("Table1");
});
});

View File

@ -127,3 +127,10 @@ export const cutWidget = () => {
type: ReduxActionTypes.CUT_SELECTED_WIDGET,
};
};
export const addTableWidgetFromQuery = (queryName: string) => {
return {
type: ReduxActionTypes.ADD_TABLE_WIDGET_FROM_QUERY,
payload: queryName,
};
};

View File

@ -168,6 +168,7 @@ export const ReduxActionTypes: { [key: string]: string } = {
FOCUS_WIDGET: "FOCUS_WIDGET",
SET_WIDGET_DRAGGING: "SET_WIDGET_DRAGGING",
SET_WIDGET_RESIZING: "SET_WIDGET_RESIZING",
ADD_TABLE_WIDGET_FROM_QUERY: "ADD_TABLE_WIDGET_FROM_QUERY",
SEARCH_APPLICATIONS: "SEARCH_APPLICATIONS",
UPDATE_PAGE_INIT: "UPDATE_PAGE_INIT",
UPDATE_PAGE_SUCCESS: "UPDATE_PAGE_SUCCESS",

View File

@ -80,6 +80,7 @@ export const QueryTemplates = (props: QueryTemplatesProps) => {
currentPageId,
params.applicationId,
props.datasourceId,
dataSource,
],
);

View File

@ -28,7 +28,7 @@ export type WidgetTree = WidgetProps & { children?: WidgetTree[] };
const UNREGISTERED_WIDGETS: WidgetType[] = [WidgetTypes.ICON_WIDGET];
const navigateToCanvas = (
export const navigateToCanvas = (
params: ExplorerURLParams,
currentPath: string,
widgetPageId: string,

View File

@ -23,7 +23,7 @@ import { Colors } from "constants/Colors";
import JSONViewer from "./JSONViewer";
import Table from "./Table";
import { RestAction } from "entities/Action";
import { connect } from "react-redux";
import { connect, useDispatch } from "react-redux";
import { AppState } from "reducers";
import ActionNameEditor from "components/editorComponents/ActionNameEditor";
import CollapsibleHelp from "components/designSystems/appsmith/help/CollapsibleHelp";
@ -37,6 +37,7 @@ import { ControlProps } from "components/formControls/BaseControl";
import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";
import ActionSettings from "pages/Editor/ActionSettings";
import { queryActionSettingsConfig } from "mockResponses/ActionSettings";
import { addTableWidgetFromQuery } from "actions/widgetActions";
const QueryFormContainer = styled.div`
padding: 20px 32px;
@ -230,6 +231,21 @@ const SettingsWrapper = styled.div`
padding-bottom: 8px;
`;
const AddWidgetButton = styled(BaseButton)`
&&&& {
max-width: 125px;
border: 1px solid ${Colors.GEYSER_LIGHT};
}
`;
const OutputHeader = styled.div`
flex-direction: row;
justify-content: space-between;
display: flex;
margin-bottom: 10px;
align-items: center;
`;
type QueryFormProps = {
onDeleteClick: () => void;
onRunClick: () => void;
@ -279,6 +295,7 @@ const QueryEditorForm: React.FC<Props> = (props: Props) => {
documentationLink,
loadingFormConfigs,
editorConfig,
actionName,
} = props;
let error = runErrorMessage;
@ -294,6 +311,11 @@ const QueryEditorForm: React.FC<Props> = (props: Props) => {
const isSQL = responseType === "TABLE";
const dispatch = useDispatch();
const onAddWidget = () => {
dispatch(addTableWidgetFromQuery(actionName));
};
const MenuList = (props: MenuListComponentProps<{ children: Node }>) => {
return (
<>
@ -523,9 +545,19 @@ const QueryEditorForm: React.FC<Props> = (props: Props) => {
{!error && output && dataSources.length && (
<>
<p className="statementTextArea">
{output.length ? "Query response" : "No data records to display"}
</p>
<OutputHeader>
<p className="statementTextArea">
{output.length ? "Query response" : "No data records to display"}
</p>
{!!output.length && (
<AddWidgetButton
className="t--add-widget"
icon={"plus"}
text="Add Widget"
onClick={onAddWidget}
/>
)}
</OutputHeader>
{isSQL ? <Table data={output} /> : <JSONViewer src={output} />}
</>
)}

View File

@ -127,9 +127,8 @@ type QueryHomeScreenProps = {
class QueryHomeScreen extends React.Component<QueryHomeScreenProps> {
handleCreateNewQuery = (dataSource: Datasource, params: string) => {
const { actions, pages } = this.props;
const { actions } = this.props;
const pageId = new URLSearchParams(params).get("importTo");
const page = pages.find(page => page.pageId === pageId);
if (pageId) {
const newQueryName = createNewQueryName(actions, pageId);

View File

@ -1,4 +1,3 @@
import React from "react";
import { createReducer } from "utils/AppsmithUtils";
import { ReduxActionTypes, ReduxAction } from "constants/ReduxActionConstants";
import { Datasource } from "api/DatasourcesApi";

View File

@ -29,7 +29,6 @@ import {
selectPlugin,
createDatasource,
changeDatasource,
testDatasource,
setDatsourceEditorMode,
expandDatasourceEntity,
fetchDatasourceStructure,

View File

@ -37,6 +37,7 @@ import { convertToString, getNextEntityName } from "utils/AppsmithUtils";
import {
SetWidgetDynamicPropertyPayload,
updateWidgetProperty,
updateWidgetPropertyRequest,
UpdateWidgetPropertyRequestPayload,
} from "actions/controlActions";
import { isDynamicValue } from "utils/DynamicBindingUtils";
@ -71,6 +72,12 @@ import { flashElementById } from "utils/helpers";
import AnalyticsUtil from "utils/AnalyticsUtil";
import { cloneDeep } from "lodash";
import log from "loglevel";
import { navigateToCanvas } from "pages/Editor/Explorer/Widgets/WidgetEntity";
import {
getCurrentApplicationId,
getCurrentPageId,
} from "selectors/editorSelectors";
import { forceOpenPropertyPane } from "actions/widgetActions";
function getChildWidgetProps(
parent: FlattenedWidgetProps,
@ -946,8 +953,90 @@ function* cutWidgetSaga() {
});
}
function* addTableWidgetFromQuerySaga(action: ReduxAction<string>) {
try {
const columns = 8;
const rows = 7;
const queryName = action.payload;
const widgets = yield select(getWidgets);
const widgetName = getNextWidgetName(widgets, "TABLE_WIDGET");
let newWidget = {
type: WidgetTypes.TABLE_WIDGET,
newWidgetId: generateReactKey(),
widgetId: "0",
topRow: 0,
bottomRow: rows,
leftColumn: 0,
rightColumn: columns,
columns,
rows,
parentId: "0",
widgetName,
renderMode: RenderModes.CANVAS,
parentRowSpace: 1,
parentColumnSpace: 1,
isLoading: false,
};
const {
leftColumn,
topRow,
rightColumn,
bottomRow,
} = yield calculateNewWidgetPosition(newWidget, "0", widgets);
newWidget = {
...newWidget,
leftColumn,
topRow,
rightColumn,
bottomRow,
};
yield put({
type: ReduxActionTypes.WIDGET_ADD_CHILD,
payload: newWidget,
});
const applicationId = yield select(getCurrentApplicationId);
const pageId = yield select(getCurrentPageId);
navigateToCanvas(
{
applicationId,
pageId,
},
window.location.pathname,
pageId,
newWidget.newWidgetId,
);
yield put({
type: ReduxActionTypes.SELECT_WIDGET,
payload: { widgetId: newWidget.newWidgetId },
});
yield put(forceOpenPropertyPane(newWidget.newWidgetId));
yield put(
updateWidgetPropertyRequest(
newWidget.newWidgetId,
"tableData",
`{{${queryName}.data}}`,
RenderModes.CANVAS,
),
);
} catch (error) {
AppToaster.show({
message: "Failed to add the widget",
type: "error",
});
}
}
export default function* widgetOperationSagas() {
yield all([
takeEvery(
ReduxActionTypes.ADD_TABLE_WIDGET_FROM_QUERY,
addTableWidgetFromQuerySaga,
),
takeEvery(ReduxActionTypes.WIDGET_ADD_CHILD, addChildSaga),
takeEvery(ReduxActionTypes.WIDGET_DELETE, deleteSaga),
takeLatest(ReduxActionTypes.WIDGET_MOVE, moveSaga),