Merge branch 'release' of https://github.com/appsmithorg/appsmith into release
This commit is contained in:
commit
af24f95ca9
|
|
@ -9,12 +9,9 @@ describe("Moustache test Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Moustache test Functionality", function() {
|
||||
//cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.widgetText("Api", widgetsPage.textWidget, widgetsPage.textInputval);
|
||||
cy.testCodeMirror("/api/users/2");
|
||||
cy.NavigateToEntityExplorer();
|
||||
cy.wait(10000);
|
||||
cy.NavigateToAPI_Panel();
|
||||
cy.log("Navigation to API Panel screen successful");
|
||||
cy.CreateAPI("TestAPINew");
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ describe("Duplicate application", function() {
|
|||
.contains("Duplicate")
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(explorerlocators.entityExplorer).should("be.visible");
|
||||
cy.wait("@getPage").should(
|
||||
"have.nested.property",
|
||||
"response.body.responseMeta.status",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ describe("Binding the Datepicker and Text Widget", function() {
|
|||
/**
|
||||
* Bind DatePicker1 to Text for "selectedDate"
|
||||
*/
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.testJsontext("text", "{{DatePicker1.selectedDate}}");
|
||||
cy.get(commonlocators.editPropCrossButton).click();
|
||||
|
|
@ -50,7 +49,6 @@ describe("Binding the Datepicker and Text Widget", function() {
|
|||
});
|
||||
|
||||
it("DatePicker1-text: Change the date in DatePicker1 and Validate the same in text widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +106,6 @@ describe("Binding the Datepicker and Text Widget", function() {
|
|||
/**
|
||||
* Bind the DatePicker1 and DatePicker2 along with hard coded text to Text widget
|
||||
*/
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.testJsontext(
|
||||
"text",
|
||||
|
|
|
|||
|
|
@ -16,15 +16,14 @@ describe("Test Create Api and Bind to Table widget", function() {
|
|||
});
|
||||
|
||||
it("Table-Text, Validate Server Side Pagination of Paginate with Table Page No", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tablewidget");
|
||||
cy.SearchEntityandOpen("Table1");
|
||||
/**Bind Api1 with Table widget */
|
||||
cy.testJsontext("tabledata", "{{Api1.data.users}}");
|
||||
cy.CheckWidgetProperties(commonlocators.serverSidePaginationCheckbox);
|
||||
/**Bind Table with Textwidget with selected row */
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.SearchEntityandOpen("Text1");
|
||||
cy.testJsontext("text", "{{Table1.selectedRow.url}}");
|
||||
cy.SearchEntityandOpen("Table1");
|
||||
cy.readTabledata("0", "0").then(tabData => {
|
||||
const tableData = tabData;
|
||||
localStorage.setItem("tableDataPage1", tableData);
|
||||
|
|
@ -43,7 +42,6 @@ describe("Test Create Api and Bind to Table widget", function() {
|
|||
cy.get(commonlocators.rightArrowBtn).click({ force: true });
|
||||
cy.validateToastMessage("done");
|
||||
cy.ValidatePublishTableData("11");
|
||||
|
||||
cy.get(publishPage.backToEditor).click({ force: true });
|
||||
});
|
||||
|
||||
|
|
@ -59,13 +57,12 @@ describe("Test Create Api and Bind to Table widget", function() {
|
|||
parseSpecialCharSequences: false,
|
||||
});
|
||||
cy.WaitAutoSave();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.SearchEntityandOpen("Text1");
|
||||
//cy.openPropertyPane("textwidget");
|
||||
/** Bind the Table widget with Text widget*/
|
||||
cy.testJsontext("text", "{{Table1.selectedRow.url}}");
|
||||
cy.get(commonlocators.editPropCrossButton).click();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tablewidget");
|
||||
cy.SearchEntityandOpen("Table1");
|
||||
cy.testJsontext("tabledata", "{{Api2.data.users}}");
|
||||
cy.callApi("Api2");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@ describe("Test Create Api and Bind to Table widget", function() {
|
|||
});
|
||||
|
||||
it("Test_Validate the Api data is updated on Table widget", function() {
|
||||
//cy.get(pages.pagesIcon).click({ force: true });
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tablewidget");
|
||||
cy.SearchEntityandOpen("Table1");
|
||||
//cy.openPropertyPane("tablewidget");
|
||||
cy.testJsontext("tabledata", "{{Api1.data}}");
|
||||
cy.get(commonlocators.editPropCrossButton).click();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ describe("Text-Chart Binding Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Text-Chart Binding Functionality View", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.testJsontext("text", JSON.stringify(this.data.chartInputValidate));
|
||||
cy.get(commonlocators.TextInside).should(
|
||||
|
|
@ -17,7 +16,6 @@ describe("Text-Chart Binding Functionality", function() {
|
|||
JSON.stringify(this.data.chartInputValidate),
|
||||
);
|
||||
cy.closePropertyPane();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("chartwidget");
|
||||
cy.get(viewWidgetsPage.chartType)
|
||||
.find(commonlocators.dropdownbuttonclick)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ describe("Text-Table Binding Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Text-Table Binding Functionality For Id", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tablewidget");
|
||||
/**
|
||||
* @param(Index) Provide index value to select the row.
|
||||
|
|
@ -43,7 +42,6 @@ describe("Text-Table Binding Functionality", function() {
|
|||
cy.get(publish.backToEditor)
|
||||
.first()
|
||||
.click();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.isSelectRow(2);
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.testJsontext("text", "{{Table1.selectedRow.email}}");
|
||||
|
|
@ -68,7 +66,6 @@ describe("Text-Table Binding Functionality", function() {
|
|||
cy.get(publish.backToEditor)
|
||||
.first()
|
||||
.click();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.testJsontext("text", "{{Table1.pageSize}}");
|
||||
cy.get(commonlocators.TableRow)
|
||||
|
|
@ -95,7 +92,6 @@ describe("Text-Table Binding Functionality", function() {
|
|||
* @param(Index) Provide index value to select the row.
|
||||
*/
|
||||
cy.isSelectRow(1);
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
cy.testJsontext("text", JSON.stringify(this.data.textfun));
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("Chart Widget Functionality", function() {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("chartwidget");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("Image Widget Functionality", function() {
|
|||
});
|
||||
|
||||
it("Image Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("imagewidget");
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
|
|
@ -43,7 +42,6 @@ describe("Image Widget Functionality", function() {
|
|||
});
|
||||
it("Image Widget Functionality To Unchecked Visible Widget", function() {
|
||||
cy.get(publish.backToEditor).click();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("imagewidget");
|
||||
cy.togglebarDisable(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -51,7 +49,6 @@ describe("Image Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Image Widget Functionality To Check Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("imagewidget");
|
||||
cy.togglebar(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("Table Widget Functionality", function() {
|
|||
});
|
||||
|
||||
it("Table Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tablewidget");
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("Text Widget Functionality", function() {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("textwidget");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("Dynamic input autocomplete", () => {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("opens autocomplete for bindings", () => {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("buttonwidget");
|
||||
cy.get(dynamicInputLocators.input)
|
||||
.first()
|
||||
|
|
@ -57,14 +56,11 @@ describe("Dynamic input autocomplete", () => {
|
|||
});
|
||||
it("opens current value popup", () => {
|
||||
// Test on widgets pane
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("buttonwidget");
|
||||
cy.get(dynamicInputLocators.input)
|
||||
.first()
|
||||
.focus();
|
||||
cy.assertEvaluatedValuePopup("string");
|
||||
|
||||
cy.NavigateToEntityExplorer();
|
||||
// Test on api pane
|
||||
cy.NavigateToAPI_Panel();
|
||||
cy.get(apiwidget.createapi).click({ force: true });
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ describe("Entity explorer tests related to widgets and validation", function() {
|
|||
});
|
||||
|
||||
it("Widget edit/delete/copy to clipboard validation", function() {
|
||||
cy.NavigateToEntityExplorer();
|
||||
cy.SearchEntityandOpen("Text1");
|
||||
cy.get(explorer.collapse)
|
||||
.last()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ describe("Button Widget Functionality", function() {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("buttonwidget");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("Checkbox Widget Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Checkbox Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("checkboxwidget");
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
|
|
@ -45,7 +44,6 @@ describe("Checkbox Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Checkbox Functionality To Check Disabled Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("checkboxwidget");
|
||||
cy.togglebar(commonlocators.Disablejs + " " + "input");
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -53,7 +51,6 @@ describe("Checkbox Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Checkbox Functionality To Check Enabled Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("checkboxwidget");
|
||||
cy.togglebarDisable(commonlocators.Disablejs + " " + "input");
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -61,7 +58,6 @@ describe("Checkbox Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Checkbox Functionality To Unchecked Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("checkboxwidget");
|
||||
cy.togglebarDisable(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -69,7 +65,6 @@ describe("Checkbox Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Checkbox Functionality To Check Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("checkboxwidget");
|
||||
cy.togglebar(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("DatePicker Widget Functionality", function() {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("datepickerwidget");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ describe("Dropdown Widget Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Dropdown Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("dropdownwidget");
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
|
|
@ -48,7 +47,6 @@ describe("Dropdown Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Dropdown Functionality To Unchecked Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("dropdownwidget");
|
||||
cy.togglebarDisable(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -56,7 +54,6 @@ describe("Dropdown Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Dropdown Functionality To Check Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("dropdownwidget");
|
||||
cy.togglebar(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ describe("FilePicker Widget Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("FilePicker Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("filepickerwidget");
|
||||
|
||||
//Checking the edit props for FilePicker and also the properties of FilePicker widget
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ describe("Form Widget Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Form Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("formwidget");
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
|
|
@ -45,7 +44,6 @@ describe("Form Widget Functionality", function() {
|
|||
});
|
||||
it("Form Widget Functionality To Unchecked Visible Widget", function() {
|
||||
cy.get(publish.backToEditor).click();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("formwidget");
|
||||
cy.togglebarDisable(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ describe("Input Widget Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Input Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("inputwidget");
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
|
|
@ -65,7 +64,6 @@ describe("Input Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click({ force: true });
|
||||
});
|
||||
it("Input Widget Functionality To Check Disabled Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("inputwidget");
|
||||
cy.togglebar(commonlocators.Disablejs + " " + "input");
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -73,7 +71,6 @@ describe("Input Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click({ force: true });
|
||||
});
|
||||
it("Input Widget Functionality To Check Enabled Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("inputwidget");
|
||||
cy.togglebarDisable(commonlocators.Disablejs + " " + "input");
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -81,7 +78,6 @@ describe("Input Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click({ force: true });
|
||||
});
|
||||
it("Input Functionality To Unchecked Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("inputwidget");
|
||||
cy.togglebarDisable(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -89,7 +85,6 @@ describe("Input Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click({ force: true });
|
||||
});
|
||||
it("Input Functionality To Check Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("inputwidget");
|
||||
cy.togglebar(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ describe("Radio Widget Functionality", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Radio Widget Functionality", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("radiogroupwidget");
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
|
|
@ -59,7 +58,6 @@ describe("Radio Widget Functionality", function() {
|
|||
});
|
||||
it("Radio Functionality To Unchecked Visible Widget", function() {
|
||||
cy.get(publish.backToEditor).click();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("radiogroupwidget");
|
||||
cy.togglebarDisable(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -67,7 +65,6 @@ describe("Radio Widget Functionality", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Radio Functionality To Check Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("radiogroupwidget");
|
||||
cy.togglebar(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("RichTextEditor Widget Functionality", function() {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("richtexteditorwidget");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ describe("Tab widget test", function() {
|
|||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Tab Widget Functionality Test", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tabswidget");
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
|
|
@ -60,7 +59,6 @@ describe("Tab widget test", function() {
|
|||
});
|
||||
it("Tab Widget Functionality To Unchecked Visible Widget", function() {
|
||||
cy.get(publish.backToEditor).click();
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tabswidget");
|
||||
cy.togglebarDisable(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
@ -68,7 +66,6 @@ describe("Tab widget test", function() {
|
|||
cy.get(publish.backToEditor).click();
|
||||
});
|
||||
it("Tab Widget Functionality To Check Visible Widget", function() {
|
||||
cy.get(pages.widgetsEditor).click();
|
||||
cy.openPropertyPane("tabswidget");
|
||||
cy.togglebar(commonlocators.visibleCheckbox);
|
||||
cy.PublishtheApp();
|
||||
|
|
|
|||
|
|
@ -1554,8 +1554,6 @@ Cypress.Commands.add("ValidatePublishTableData", value => {
|
|||
});
|
||||
|
||||
Cypress.Commands.add("ValidatePaginateResponseUrlData", runTestCss => {
|
||||
cy.NavigateToEntityExplorer();
|
||||
cy.NavigateToApiEditor();
|
||||
cy.SearchEntityandOpen("Api2");
|
||||
cy.NavigateToPaginationTab();
|
||||
cy.RunAPI();
|
||||
|
|
@ -1573,7 +1571,7 @@ Cypress.Commands.add("ValidatePaginateResponseUrlData", runTestCss => {
|
|||
const respBody = tabData.match(/"(.*)"/)[0];
|
||||
localStorage.setItem("respBody", respBody);
|
||||
cy.log(respBody);
|
||||
cy.get(pages.widgetsEditor).click({ force: true });
|
||||
cy.SearchEntityandOpen("Table1");
|
||||
// cy.openPropertyPane("tablewidget");
|
||||
// cy.testJsontext("tabledata", "{{Api2.data.results}}");
|
||||
cy.isSelectRow(0);
|
||||
|
|
|
|||
|
|
@ -15,13 +15,10 @@ export const createDatasourceFromForm = (payload: CreateDatasourceConfig) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const updateDatasource = (
|
||||
payload: Datasource,
|
||||
reinitializeForm?: boolean,
|
||||
) => {
|
||||
export const updateDatasource = (payload: Datasource) => {
|
||||
return {
|
||||
type: ReduxActionTypes.UPDATE_DATASOURCE_INIT,
|
||||
payload: { datasource: payload, reinitializeForm: !!reinitializeForm },
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +1,169 @@
|
|||
import { ReactNode } from "react";
|
||||
import { IconName } from "./Icon";
|
||||
import { CommonComponentProps } from "./common";
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import Icon, { IconName, IconSize } from "./Icon";
|
||||
import { CommonComponentProps, Classes } from "./common";
|
||||
import styled from "styled-components";
|
||||
import Text, { TextType } from "./Text";
|
||||
|
||||
type DropdownOption = {
|
||||
label: string;
|
||||
label?: string;
|
||||
value: string;
|
||||
id?: string;
|
||||
icon: IconName; // Create an icon library
|
||||
icon?: IconName;
|
||||
onSelect?: (option: DropdownOption) => void;
|
||||
children?: DropdownOption[];
|
||||
};
|
||||
|
||||
export enum DropdownDisplayType {
|
||||
TAGS = "TAGS",
|
||||
CHECKBOXES = "CHECKBOXES",
|
||||
}
|
||||
|
||||
type DropdownProps = CommonComponentProps & {
|
||||
options: DropdownOption[];
|
||||
selectHandler: (selectedValue: string) => void;
|
||||
selected?: DropdownOption;
|
||||
multiselectDisplayType?: DropdownDisplayType;
|
||||
checked?: boolean;
|
||||
multi?: boolean;
|
||||
autocomplete?: boolean;
|
||||
addItem?: {
|
||||
displayText: string;
|
||||
addItemHandler: (name: string) => void;
|
||||
};
|
||||
toggle?: ReactNode;
|
||||
selected: DropdownOption;
|
||||
};
|
||||
|
||||
export default function Button(props: DropdownProps) {
|
||||
return null;
|
||||
const DropdownContainer = styled.div`
|
||||
width: 260px;
|
||||
`;
|
||||
|
||||
const Selected = styled.div<{ isOpen: boolean; disabled?: boolean }>`
|
||||
padding: ${props => props.theme.spaces[4]}px
|
||||
${props => props.theme.spaces[6]}px;
|
||||
background: ${props =>
|
||||
props.disabled
|
||||
? props.theme.colors.blackShades[2]
|
||||
: props.theme.colors.blackShades[0]};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
${props =>
|
||||
props.isOpen && !props.disabled
|
||||
? `border: 1.2px solid ${props.theme.colors.info.main}`
|
||||
: null};
|
||||
${props =>
|
||||
props.isOpen && !props.disabled ? "box-sizing: border-box" : null};
|
||||
${props =>
|
||||
props.isOpen && !props.disabled
|
||||
? "box-shadow: 0px 0px 4px 4px rgba(203, 72, 16, 0.18)"
|
||||
: null};
|
||||
.${Classes.TEXT} {
|
||||
${props =>
|
||||
props.disabled
|
||||
? `color: ${props.theme.colors.blackShades[6]}`
|
||||
: `color: ${props.theme.colors.blackShades[7]}`};
|
||||
}
|
||||
`;
|
||||
|
||||
const DropdownWrapper = styled.div`
|
||||
margin-top: ${props => props.theme.spaces[2] - 1}px;
|
||||
background: ${props => props.theme.colors.blackShades[3]};
|
||||
box-shadow: 0px 12px 28px rgba(0, 0, 0, 0.6);
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const OptionWrapper = styled.div<{ selected: boolean }>`
|
||||
padding: ${props => props.theme.spaces[4]}px
|
||||
${props => props.theme.spaces[6]}px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
${props =>
|
||||
props.selected ? `background: ${props.theme.colors.blackShades[4]}` : null};
|
||||
.${Classes.TEXT} {
|
||||
${props =>
|
||||
props.selected ? `color: ${props.theme.colors.blackShades[9]}` : null};
|
||||
}
|
||||
.${Classes.ICON} {
|
||||
margin-right: ${props => props.theme.spaces[5]}px;
|
||||
svg {
|
||||
path {
|
||||
${props =>
|
||||
props.selected
|
||||
? `fill: ${props.theme.colors.blackShades[8]}`
|
||||
: `fill: ${props.theme.colors.blackShades[6]}`};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.${Classes.TEXT} {
|
||||
color: ${props => props.theme.colors.blackShades[9]};
|
||||
}
|
||||
.${Classes.ICON} {
|
||||
svg {
|
||||
path {
|
||||
fill: ${props => props.theme.colors.blackShades[8]};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const LabelWrapper = styled.div<{ label?: string }>`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-item: flex-start;
|
||||
|
||||
${props =>
|
||||
props.label
|
||||
? `
|
||||
.${Classes.TEXT}:last-child {
|
||||
margin-top: ${props.theme.spaces[2] - 1}px;
|
||||
}
|
||||
`
|
||||
: null}
|
||||
`;
|
||||
|
||||
export default function Dropdown(props: DropdownProps) {
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
const [selected, setSelected] = useState<DropdownOption>(props.selected);
|
||||
|
||||
useEffect(() => {
|
||||
setSelected(props.selected);
|
||||
}, [props.selected]);
|
||||
|
||||
const optionClickHandler = useCallback((option: DropdownOption) => {
|
||||
setSelected(option);
|
||||
setIsOpen(false);
|
||||
option.onSelect && option.onSelect(option);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<DropdownContainer tabIndex={0} onBlur={() => setIsOpen(false)}>
|
||||
<Selected
|
||||
isOpen={isOpen}
|
||||
disabled={props.disabled}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
>
|
||||
<Text type={TextType.P1}>{selected.value}</Text>
|
||||
<Icon name="downArrow" size={IconSize.SMALL} />
|
||||
</Selected>
|
||||
|
||||
{isOpen && !props.disabled ? (
|
||||
<DropdownWrapper>
|
||||
{props.options.map((option: DropdownOption, index: number) => {
|
||||
return (
|
||||
<OptionWrapper
|
||||
key={index}
|
||||
selected={selected.value === option.value}
|
||||
onClick={() => optionClickHandler(option)}
|
||||
>
|
||||
{option.icon ? (
|
||||
<Icon name={option.icon} size={IconSize.LARGE} />
|
||||
) : null}
|
||||
<LabelWrapper label={option.label}>
|
||||
{option.label ? (
|
||||
<Text type={TextType.H5}>{option.value}</Text>
|
||||
) : (
|
||||
<Text type={TextType.P1}>{option.value}</Text>
|
||||
)}
|
||||
{option.label ? (
|
||||
<Text type={TextType.P3}>{option.label}</Text>
|
||||
) : null}
|
||||
</LabelWrapper>
|
||||
</OptionWrapper>
|
||||
);
|
||||
})}
|
||||
</DropdownWrapper>
|
||||
) : null}
|
||||
</DropdownContainer>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { ReactComponent as ErrorIcon } from "assets/icons/ads/error.svg";
|
|||
import { ReactComponent as SuccessIcon } from "assets/icons/ads/success.svg";
|
||||
import { ReactComponent as SearchIcon } from "assets/icons/ads/search.svg";
|
||||
import { ReactComponent as CloseIcon } from "assets/icons/ads/close.svg";
|
||||
import { ReactComponent as DownArrow } from "assets/icons/ads/down_arrow.svg";
|
||||
import { ReactComponent as ShareIcon } from "assets/icons/ads/share.svg";
|
||||
import { ReactComponent as RocketIcon } from "assets/icons/ads/launch.svg";
|
||||
import { ReactComponent as WorkspaceIcon } from "assets/icons/ads/workspace.svg";
|
||||
|
|
@ -72,6 +73,7 @@ export const IconCollection = [
|
|||
"plus",
|
||||
"invite-user",
|
||||
"view-all",
|
||||
"downArrow",
|
||||
] as const;
|
||||
|
||||
export type IconName = typeof IconCollection[number];
|
||||
|
|
@ -143,6 +145,9 @@ const Icon = (props: IconProps & CommonComponentProps) => {
|
|||
case "close":
|
||||
returnIcon = <CloseIcon />;
|
||||
break;
|
||||
case "downArrow":
|
||||
returnIcon = <DownArrow />;
|
||||
break;
|
||||
case "share":
|
||||
returnIcon = <ShareIcon />;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,28 +1,30 @@
|
|||
import React, { memo } from "react";
|
||||
import { Switch, Route } from "react-router";
|
||||
import styled from "styled-components";
|
||||
import { WIDGETS_URL } from "constants/routes";
|
||||
import WidgetSidebar from "pages/Editor/WidgetSidebar";
|
||||
import ExplorerSidebar from "pages/Editor/Explorer";
|
||||
import { PanelStack, Classes } from "@blueprintjs/core";
|
||||
import { Colors } from "constants/Colors";
|
||||
|
||||
const SidebarWrapper = styled.div`
|
||||
background-color: ${Colors.MINE_SHAFT};
|
||||
padding: 0px 0 0 6px;
|
||||
width: ${props => props.theme.sidebarWidth};
|
||||
|
||||
color: ${props => props.theme.colors.textOnDarkBG};
|
||||
overflow-y: auto;
|
||||
& .${Classes.PANEL_STACK} {
|
||||
height: 100%;
|
||||
.${Classes.PANEL_STACK_VIEW} {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const initialPanel = { component: ExplorerSidebar };
|
||||
|
||||
export const Sidebar = memo(() => {
|
||||
return (
|
||||
<SidebarWrapper className="t--sidebar">
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
path={WIDGETS_URL()}
|
||||
component={WidgetSidebar}
|
||||
name={"WidgetSidebar"}
|
||||
/>
|
||||
<Route component={ExplorerSidebar} name={"ExplorerSidebar"} />
|
||||
</Switch>
|
||||
<PanelStack initialPanel={initialPanel} showPanelHeader={false} />
|
||||
</SidebarWrapper>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
112
app/client/src/components/stories/Dropdown.stories.tsx
Normal file
112
app/client/src/components/stories/Dropdown.stories.tsx
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
import React from "react";
|
||||
import { withKnobs, select, boolean, text } from "@storybook/addon-knobs";
|
||||
import { withDesign } from "storybook-addon-designs";
|
||||
import Dropdown from "components/ads/Dropdown";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { IconCollection } from "components/ads/Icon";
|
||||
import { StoryWrapper } from "./Tabs.stories";
|
||||
|
||||
export default {
|
||||
title: "Dropdown",
|
||||
component: Dropdown,
|
||||
decorators: [withKnobs, withDesign],
|
||||
};
|
||||
|
||||
export const Text = () => (
|
||||
<StoryWrapper>
|
||||
<Dropdown
|
||||
options={[
|
||||
{
|
||||
id: "111abc",
|
||||
value: text("1st Option", "First option"),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
{
|
||||
id: "222abc",
|
||||
value: text("2nd Option", "Second option"),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
{
|
||||
id: "322abc",
|
||||
value: text("3rd Option", "Third option"),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
]}
|
||||
selected={{
|
||||
id: select("Selected id", ["111abc", "222abc", "333abc"], "111abc"),
|
||||
value: text("Selected value", "First option"),
|
||||
}}
|
||||
disabled={boolean("disabled", false)}
|
||||
></Dropdown>
|
||||
</StoryWrapper>
|
||||
);
|
||||
|
||||
export const IconAndText = () => (
|
||||
<StoryWrapper>
|
||||
<Dropdown
|
||||
options={[
|
||||
{
|
||||
id: "111abc",
|
||||
value: text("1st Option", "Delete"),
|
||||
icon: select("1st Icon", IconCollection, "delete"),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
{
|
||||
id: "222abc",
|
||||
value: text("2nd Option", "User"),
|
||||
icon: select("2nd Icon", IconCollection, "user"),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
{
|
||||
id: "322abc",
|
||||
value: text("3rd Option", "General"),
|
||||
icon: select("3rd Icon", IconCollection, "general"),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
]}
|
||||
selected={{
|
||||
id: select("Selected id", ["111abc", "222abc", "333abc"], "111abc"),
|
||||
value: text("Selected value", "Delete"),
|
||||
}}
|
||||
disabled={boolean("disabled", false)}
|
||||
></Dropdown>
|
||||
</StoryWrapper>
|
||||
);
|
||||
|
||||
export const LabelAndText = () => (
|
||||
<StoryWrapper>
|
||||
<Dropdown
|
||||
options={[
|
||||
{
|
||||
id: "111abc",
|
||||
value: text("1st Option", "Admin"),
|
||||
label: text(
|
||||
"1st label",
|
||||
"Can edit, view and invite other user to an app",
|
||||
),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
{
|
||||
id: "222abc",
|
||||
value: text("2nd Option", "Developer"),
|
||||
label: text("2nd label", "Can view and invite other user to an app"),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
{
|
||||
id: "322abc",
|
||||
value: text("3rd Option", "User"),
|
||||
label: text(
|
||||
"3rd label",
|
||||
"Can view and invite other user to an app and…",
|
||||
),
|
||||
onSelect: action("selected-option"),
|
||||
},
|
||||
]}
|
||||
selected={{
|
||||
id: select("Selected id", ["111abc", "222abc", "333abc"], "111abc"),
|
||||
value: text("Selected value", "Developer"),
|
||||
}}
|
||||
disabled={boolean("disabled", false)}
|
||||
></Dropdown>
|
||||
</StoryWrapper>
|
||||
);
|
||||
|
|
@ -645,7 +645,7 @@ export const theme: Theme = {
|
|||
},
|
||||
],
|
||||
sidebarWidth: "320px",
|
||||
headerHeight: "50px",
|
||||
headerHeight: "48px",
|
||||
canvasPadding: "20px 0 200px 0",
|
||||
sideNav: {
|
||||
maxWidth: 220,
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
export const ENTITY_EXPLORER_SEARCH_ID = "entity-explorer-search";
|
||||
export const ENTITY_EXPLORER_SEARCH_LOCATION_HASH = "#search";
|
||||
export const WIDGETS_SEARCH_ID = "#widgets-search";
|
||||
|
|
|
|||
|
|
@ -157,3 +157,7 @@ export const SHOW_REQUEST = "Show Request";
|
|||
|
||||
export const TABLE_FILTER_COLUMN_TYPE_CALLOUT =
|
||||
"Change column datatype to see filter operators";
|
||||
|
||||
export const WIDGET_SIDEBAR_TITLE = "Widgets";
|
||||
export const WIDGET_SIDEBAR_CAPTION =
|
||||
"To add a widget, please drag and drop a widget on the canvas to the right";
|
||||
|
|
|
|||
|
|
@ -50,19 +50,6 @@ export const BUILDER_PAGE_URL = (
|
|||
);
|
||||
};
|
||||
|
||||
export const WIDGETS_URL = (
|
||||
applicationId = ":applicationId",
|
||||
pageId = ":pageId",
|
||||
params?: Record<string, string>,
|
||||
): string => {
|
||||
if (!pageId) return APPLICATIONS_URL;
|
||||
const queryParams = convertToQueryParams(params);
|
||||
return (
|
||||
`${BUILDER_BASE_URL(applicationId)}/pages/${pageId}/edit/widgets` +
|
||||
queryParams
|
||||
);
|
||||
};
|
||||
|
||||
export const API_EDITOR_URL = (
|
||||
applicationId = ":applicationId",
|
||||
pageId = ":pageId",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import history from "utils/history";
|
|||
import { saveActionName } from "actions/actionActions";
|
||||
import EntityProperties from "../Entity/EntityProperties";
|
||||
import { ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
||||
import { ExplorerURLParams } from "../helpers";
|
||||
import { useParams } from "react-router";
|
||||
|
||||
const getUpdateActionNameReduxAction = (id: string, name: string) => {
|
||||
return saveActionName({ id, name });
|
||||
|
|
@ -21,6 +23,7 @@ type ExplorerActionEntityProps = {
|
|||
};
|
||||
|
||||
export const ExplorerActionEntity = memo((props: ExplorerActionEntityProps) => {
|
||||
const { pageId } = useParams<ExplorerURLParams>();
|
||||
const switchToAction = useCallback(() => {
|
||||
props.url && history.push(props.url);
|
||||
}, [props.url]);
|
||||
|
|
@ -51,7 +54,9 @@ export const ExplorerActionEntity = memo((props: ExplorerActionEntityProps) => {
|
|||
<EntityProperties
|
||||
entityName={props.action.config.name}
|
||||
entityType={ENTITY_TYPE.ACTION}
|
||||
isCurrentPage={props.pageId === pageId}
|
||||
step={props.step + 1}
|
||||
entity={props.action}
|
||||
/>
|
||||
</Entity>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ export const ExplorerActionsGroup = memo((props: ExplorerActionsGroupProps) => {
|
|||
entityId={props.page.pageId + "_" + props.config?.type}
|
||||
step={props.step}
|
||||
disabled={!!props.searchKeyword && (!childNode || !props.actions.length)}
|
||||
createFn={switchToCreateActionPage}
|
||||
onCreate={switchToCreateActionPage}
|
||||
isDefaultExpanded={
|
||||
props.config?.isGroupExpanded(params, props.page.pageId) ||
|
||||
!!props.searchKeyword
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { ExplorerURLParams, getDatasourceIdFromURL } from "../helpers";
|
|||
import Entity, { EntityClassNames } from "../Entity";
|
||||
import { DATA_SOURCES_EDITOR_ID_URL } from "constants/routes";
|
||||
import history from "utils/history";
|
||||
import { updateDatasource } from "actions/datasourceActions";
|
||||
import { saveDatasourceName } from "actions/datasourceActions";
|
||||
|
||||
type ExplorerDatasourceEntityProps = {
|
||||
datasource: Datasource;
|
||||
|
|
@ -32,12 +32,9 @@ export const ExplorerDatasourceEntity = (
|
|||
const datasourceIdFromURL = getDatasourceIdFromURL();
|
||||
const active = datasourceIdFromURL === props.datasource.id;
|
||||
|
||||
const updateDatasourceName = useCallback(
|
||||
(id: string, name: string) => {
|
||||
return updateDatasource({ ...props.datasource, name: name }, active);
|
||||
},
|
||||
[props.datasource, active],
|
||||
);
|
||||
const updateDatasourceName = (id: string, name: string) =>
|
||||
saveDatasourceName({ id, name });
|
||||
|
||||
return (
|
||||
<Entity
|
||||
entityId={props.datasource.id}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export const ExplorerDatasourcesGroup = (
|
|||
) > -1 || !!props.searchKeyword
|
||||
}
|
||||
disabled={disableDatasourceGroup}
|
||||
createFn={() => {
|
||||
onCreate={() => {
|
||||
history.push(
|
||||
DATA_SOURCES_EDITOR_URL(params.applicationId, params.pageId),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -14,11 +14,19 @@ import { evaluateDataTreeWithoutFunctions } from "selectors/dataTreeSelectors";
|
|||
export const EntityProperties = (props: {
|
||||
entityType: ENTITY_TYPE;
|
||||
entityName: string;
|
||||
isCurrentPage: boolean;
|
||||
step: number;
|
||||
entity?: any;
|
||||
}) => {
|
||||
let entity: any;
|
||||
const dataTree: DataTree = useSelector(evaluateDataTreeWithoutFunctions);
|
||||
const entity: any = dataTree[props.entityName];
|
||||
if (!entity) return null;
|
||||
if (props.isCurrentPage && dataTree[props.entityName]) {
|
||||
entity = dataTree[props.entityName];
|
||||
} else if (props.entity) {
|
||||
entity = props.entity;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
let config: any;
|
||||
let entityProperties: Array<EntityPropertyProps> = [];
|
||||
|
|
@ -42,7 +50,7 @@ export const EntityProperties = (props: {
|
|||
}
|
||||
return {
|
||||
propertyName: actionProperty,
|
||||
entityName: entity.name,
|
||||
entityName: props.entityName,
|
||||
value,
|
||||
step: props.step,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -82,13 +82,13 @@ export type EntityProps = {
|
|||
action?: () => void;
|
||||
active?: boolean;
|
||||
isDefaultExpanded?: boolean;
|
||||
createFn?: () => void;
|
||||
onCreate?: () => void;
|
||||
contextMenu?: ReactNode;
|
||||
searchKeyword?: string;
|
||||
step: number;
|
||||
updateEntityName?: (id: string, name: string) => any;
|
||||
runActionOnExpand?: boolean;
|
||||
nameTransformFn?: (input: string, limit?: number) => string;
|
||||
onNameEdit?: (input: string, limit?: number) => string;
|
||||
};
|
||||
|
||||
export const Entity = forwardRef(
|
||||
|
|
@ -155,13 +155,13 @@ export const Entity = forwardRef(
|
|||
className={`${EntityClassNames.NAME}`}
|
||||
ref={itemRef}
|
||||
name={props.name}
|
||||
nameTransformFn={props.nameTransformFn}
|
||||
nameTransformFn={props.onNameEdit}
|
||||
isEditing={!!props.updateEntityName && isEditing}
|
||||
updateEntityName={updateNameCallback}
|
||||
searchKeyword={props.searchKeyword}
|
||||
/>
|
||||
<AddButton
|
||||
onClick={props.createFn}
|
||||
onClick={props.onCreate}
|
||||
className={`${EntityClassNames.ADD_BUTTON}`}
|
||||
/>
|
||||
{props.contextMenu}
|
||||
|
|
|
|||
|
|
@ -63,15 +63,19 @@ const Underline = styled.div`
|
|||
`;
|
||||
/*eslint-disable react/display-name */
|
||||
export const ExplorerSearch = forwardRef(
|
||||
(props: { clear: () => void }, ref: Ref<HTMLInputElement>) => {
|
||||
(
|
||||
props: { clear: () => void; placeholder?: string },
|
||||
ref: Ref<HTMLInputElement>,
|
||||
) => {
|
||||
return (
|
||||
<ExplorerSearchWrapper>
|
||||
<Icon icon="search" iconSize={12} />
|
||||
<input
|
||||
id={ENTITY_EXPLORER_SEARCH_ID}
|
||||
type="text"
|
||||
placeholder="Search entities..."
|
||||
placeholder={props.placeholder || "Search entities..."}
|
||||
ref={ref}
|
||||
autoComplete="off"
|
||||
/>
|
||||
<Icon icon="cross" iconSize={12} onClick={props.clear} />
|
||||
<Underline className="underline" />
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ type ExplorerPageEntityProps = {
|
|||
actions: any[];
|
||||
step: number;
|
||||
searchKeyword?: string;
|
||||
showWidgetsSidebar: () => void;
|
||||
};
|
||||
export const ExplorerPageEntity = (props: ExplorerPageEntityProps) => {
|
||||
const params = useParams<ExplorerURLParams>();
|
||||
|
|
@ -50,6 +51,9 @@ export const ExplorerPageEntity = (props: ExplorerPageEntityProps) => {
|
|||
|
||||
const icon = props.page.isDefault ? homePageIcon : pageIcon;
|
||||
|
||||
let addWidgetsFn;
|
||||
if (isCurrentPage) addWidgetsFn = props.showWidgetsSidebar;
|
||||
|
||||
return (
|
||||
<Entity
|
||||
icon={icon}
|
||||
|
|
@ -62,13 +66,14 @@ export const ExplorerPageEntity = (props: ExplorerPageEntityProps) => {
|
|||
isDefaultExpanded={isCurrentPage || !!props.searchKeyword}
|
||||
updateEntityName={updatePage}
|
||||
contextMenu={contextMenu}
|
||||
nameTransformFn={resolveAsSpaceChar}
|
||||
onNameEdit={resolveAsSpaceChar}
|
||||
>
|
||||
<ExplorerWidgetGroup
|
||||
step={props.step + 1}
|
||||
searchKeyword={props.searchKeyword}
|
||||
widgets={props.widgets}
|
||||
pageId={props.page.pageId}
|
||||
addWidgetsFn={addWidgetsFn}
|
||||
/>
|
||||
|
||||
{getActionGroups(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ type ExplorerPageGroupProps = {
|
|||
step: number;
|
||||
widgets?: Record<string, WidgetProps>;
|
||||
actions: Record<string, any[]>;
|
||||
showWidgetsSidebar: () => void;
|
||||
};
|
||||
|
||||
export const ExplorerPageGroup = (props: ExplorerPageGroupProps) => {
|
||||
|
|
@ -46,6 +47,7 @@ export const ExplorerPageGroup = (props: ExplorerPageGroupProps) => {
|
|||
actions={pageActions}
|
||||
searchKeyword={props.searchKeyword}
|
||||
page={page}
|
||||
showWidgetsSidebar={props.showWidgetsSidebar}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
@ -61,7 +63,7 @@ export const ExplorerPageGroup = (props: ExplorerPageGroupProps) => {
|
|||
action={noop}
|
||||
entityId="Pages"
|
||||
step={props.step}
|
||||
createFn={createPageCallback}
|
||||
onCreate={createPageCallback}
|
||||
>
|
||||
{pageEntities}
|
||||
</Entity>
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ export type WidgetEntityProps = {
|
|||
};
|
||||
|
||||
export const WidgetEntity = memo((props: WidgetEntityProps) => {
|
||||
const params = useParams<ExplorerURLParams>();
|
||||
const { pageId } = useParams<ExplorerURLParams>();
|
||||
|
||||
const { navigateToWidget, isWidgetSelected } = useWidget(
|
||||
props.widgetProps.widgetId,
|
||||
props.widgetProps.type,
|
||||
|
|
@ -139,7 +140,9 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => {
|
|||
<EntityProperties
|
||||
entityType={ENTITY_TYPE.WIDGET}
|
||||
entityName={props.widgetProps.widgetName}
|
||||
isCurrentPage={pageId === props.pageId}
|
||||
step={props.step + 1}
|
||||
entity={props.widgetProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -162,15 +165,13 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => {
|
|||
active={isWidgetSelected}
|
||||
entityId={props.widgetProps.widgetId}
|
||||
step={props.step}
|
||||
updateEntityName={
|
||||
props.pageId === params?.pageId ? updateWidgetName : noop
|
||||
}
|
||||
updateEntityName={props.pageId === pageId ? updateWidgetName : noop}
|
||||
searchKeyword={props.searchKeyword}
|
||||
isDefaultExpanded={
|
||||
(!!props.searchKeyword && !!props.widgetProps.children) ||
|
||||
!!props.isDefaultExpanded
|
||||
}
|
||||
contextMenu={props.pageId === params?.pageId && contextMenu}
|
||||
contextMenu={props.pageId === pageId && contextMenu}
|
||||
>
|
||||
{children}
|
||||
</Entity>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
} from "constants/WidgetConstants";
|
||||
import { useParams } from "react-router";
|
||||
import { ExplorerURLParams } from "../helpers";
|
||||
import { BUILDER_PAGE_URL, WIDGETS_URL } from "constants/routes";
|
||||
import { BUILDER_PAGE_URL } from "constants/routes";
|
||||
import { Link } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import { AppState } from "reducers";
|
||||
|
|
@ -108,6 +108,7 @@ type ExplorerWidgetGroupProps = {
|
|||
step: number;
|
||||
widgets?: WidgetTree;
|
||||
searchKeyword?: string;
|
||||
addWidgetsFn?: () => void;
|
||||
};
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
|
|
@ -155,13 +156,8 @@ export const ExplorerWidgetGroup = memo((props: ExplorerWidgetGroupProps) => {
|
|||
) : (
|
||||
" "
|
||||
)}
|
||||
click the{" "}
|
||||
<React.Fragment>
|
||||
<StyledLink to={WIDGETS_URL(params.applicationId, props.pageId)}>
|
||||
Widgets
|
||||
</StyledLink>
|
||||
</React.Fragment>{" "}
|
||||
navigation menu icon on the left to drag and drop widgets
|
||||
click the <strong>+</strong> icon on the <strong>Widgets</strong> group
|
||||
to drag and drop widgets
|
||||
</EntityPlaceholder>
|
||||
);
|
||||
} else if (!childNode && props.searchKeyword) return null;
|
||||
|
|
@ -170,7 +166,7 @@ export const ExplorerWidgetGroup = memo((props: ExplorerWidgetGroupProps) => {
|
|||
<Entity
|
||||
key={props.pageId + "_widgets"}
|
||||
icon={widgetIcon}
|
||||
className="group widgets"
|
||||
className={`group widgets ${props.addWidgetsFn ? "current" : ""}`}
|
||||
step={props.step}
|
||||
name="Widgets"
|
||||
disabled={!props.widgets && !!props.searchKeyword}
|
||||
|
|
@ -179,6 +175,7 @@ export const ExplorerWidgetGroup = memo((props: ExplorerWidgetGroupProps) => {
|
|||
!!props.searchKeyword ||
|
||||
(params.pageId === props.pageId && !!selectedWidget)
|
||||
}
|
||||
onCreate={props.addWidgetsFn}
|
||||
>
|
||||
{childNode}
|
||||
</Entity>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useRef, MutableRefObject } from "react";
|
||||
import React, { useRef, MutableRefObject, useCallback } from "react";
|
||||
import styled from "styled-components";
|
||||
import Divider from "components/editorComponents/Divider";
|
||||
import {
|
||||
|
|
@ -11,8 +11,12 @@ import Search from "./ExplorerSearch";
|
|||
import ExplorerPageGroup from "./Pages/PageGroup";
|
||||
import ExplorerDatasourcesGroup from "./Datasources/DatasourcesGroup";
|
||||
import { scrollbarDark } from "constants/DefaultTheme";
|
||||
import { NonIdealState, Classes } from "@blueprintjs/core";
|
||||
|
||||
import { NonIdealState, Classes, IPanelProps } from "@blueprintjs/core";
|
||||
import WidgetSidebar from "../WidgetSidebar";
|
||||
import { BUILDER_PAGE_URL } from "constants/routes";
|
||||
import history from "utils/history";
|
||||
import { useParams } from "react-router";
|
||||
import { ExplorerURLParams } from "./helpers";
|
||||
const Wrapper = styled.div`
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
|
|
@ -29,7 +33,8 @@ const StyledDivider = styled(Divider)`
|
|||
border-bottom-color: rgba(255, 255, 255, 0.1);
|
||||
`;
|
||||
|
||||
const EntityExplorer = () => {
|
||||
const EntityExplorer = (props: IPanelProps) => {
|
||||
const { applicationId, pageId } = useParams<ExplorerURLParams>();
|
||||
const searchInputRef: MutableRefObject<HTMLInputElement | null> = useRef(
|
||||
null,
|
||||
);
|
||||
|
|
@ -51,6 +56,11 @@ const EntityExplorer = () => {
|
|||
const noDatasource = !datasources || datasources.length === 0;
|
||||
noResults = noWidgets && noActions && noDatasource;
|
||||
}
|
||||
const { openPanel } = props;
|
||||
const showWidgetsSidebar = useCallback(() => {
|
||||
history.push(BUILDER_PAGE_URL(applicationId, pageId));
|
||||
openPanel({ component: WidgetSidebar });
|
||||
}, [openPanel, applicationId, pageId]);
|
||||
|
||||
return (
|
||||
<Wrapper ref={explorerRef}>
|
||||
|
|
@ -60,6 +70,7 @@ const EntityExplorer = () => {
|
|||
step={0}
|
||||
widgets={widgets}
|
||||
actions={actions}
|
||||
showWidgetsSidebar={showWidgetsSidebar}
|
||||
/>
|
||||
{noResults && (
|
||||
<NoResult
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import EditorsRouter from "./routes";
|
||||
import Navbar from "./Navbar";
|
||||
import WidgetsEditor from "./WidgetsEditor";
|
||||
import styled from "styled-components";
|
||||
import Sidebar from "components/editorComponents/Sidebar";
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
|
|
@ -17,7 +17,7 @@ const EditorContainer = styled.div`
|
|||
const MainContainer = () => {
|
||||
return (
|
||||
<Container>
|
||||
<Navbar />
|
||||
<Sidebar />
|
||||
<EditorContainer>
|
||||
<EditorsRouter />
|
||||
<WidgetsEditor />
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
import React from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import SidebarComponent from "components/editorComponents/Sidebar";
|
||||
import NavBarItem from "components/editorComponents/NavBarItem";
|
||||
import {
|
||||
BuilderRouteParams,
|
||||
BUILDER_PAGE_URL,
|
||||
WIDGETS_URL,
|
||||
} from "constants/routes";
|
||||
import { Colors } from "constants/Colors";
|
||||
import { MenuIcons } from "icons/MenuIcons";
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 5fr;
|
||||
width: ${props => props.theme.sidebarWidth};
|
||||
box-shadow: 0px 1px 3px ${Colors.MINE_SHAFT};
|
||||
background-color: ${Colors.MINE_SHAFT};
|
||||
z-index: 3;
|
||||
`;
|
||||
|
||||
const NavBar = styled.div`
|
||||
background-color: ${Colors.MINE_SHAFT};
|
||||
color: ${props => props.theme.colors.textOnDarkBG};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0px 0px 4px ${Colors.CODE_GRAY};
|
||||
`;
|
||||
|
||||
const Navbar = () => {
|
||||
const params = useParams<BuilderRouteParams>();
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<NavBar>
|
||||
<NavBarItem
|
||||
icon={MenuIcons.EXPLORER_ICON}
|
||||
path={BUILDER_PAGE_URL(params.applicationId, params.pageId)}
|
||||
width={16}
|
||||
height={16}
|
||||
className="t--nav-link-entity-explorer"
|
||||
title="Explorer"
|
||||
isActive={(expected: string, current: string) => {
|
||||
// Currently, the explorer shows on all paths except for the
|
||||
// WIDGETS_URL path
|
||||
|
||||
// get the applicationId and pageId from the current location pathname
|
||||
const found = current.match(
|
||||
/^\/applications\/(?<applicationId>\w+)\/pages\/(?<pageId>\w+)\//,
|
||||
);
|
||||
// In this case: expected = BUILDER_PAGE_URL(applicationId, pageId)
|
||||
// If current url begins with expected url AND
|
||||
// If the current url isn't the WIDGETS_URL THEN
|
||||
// this is an explorer sidebar path
|
||||
return (
|
||||
current.indexOf(expected) === 0 &&
|
||||
current !==
|
||||
WIDGETS_URL(found?.groups?.applicationId, found?.groups?.pageId)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<NavBarItem
|
||||
icon={MenuIcons.WIDGETS_ICON}
|
||||
path={WIDGETS_URL(params.applicationId, params.pageId)}
|
||||
width={16}
|
||||
height={16}
|
||||
className="t--nav-link-widgets-editor"
|
||||
title="Widgets"
|
||||
exact
|
||||
isActive={(expected: string, current: string) => expected === current}
|
||||
/>
|
||||
</NavBar>
|
||||
<SidebarComponent />
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
Navbar.displayName = "Navbar";
|
||||
|
||||
Navbar.whyDidYouRender = {
|
||||
logOnDifferentValues: false,
|
||||
customName: "MainSidebar",
|
||||
};
|
||||
|
||||
export default Navbar;
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
import React from "react";
|
||||
import React, { useRef, useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import WidgetCard from "./WidgetCard";
|
||||
import styled from "styled-components";
|
||||
import { WidgetCardProps } from "widgets/BaseWidget";
|
||||
import { getWidgetCards } from "selectors/editorSelectors";
|
||||
import { getColorWithOpacity } from "constants/DefaultTheme";
|
||||
|
||||
type WidgetSidebarProps = {
|
||||
cards: { [id: string]: WidgetCardProps[] };
|
||||
};
|
||||
import { IPanelProps, Icon, Classes } from "@blueprintjs/core";
|
||||
import { Colors } from "constants/Colors";
|
||||
import ExplorerSearch from "./Explorer/ExplorerSearch";
|
||||
import { debounce } from "lodash";
|
||||
import produce from "immer";
|
||||
import { WIDGET_SIDEBAR_CAPTION } from "constants/messages";
|
||||
|
||||
const MainWrapper = styled.div`
|
||||
text-transform: capitalize;
|
||||
|
|
@ -43,22 +45,108 @@ const CardsWrapper = styled.div`
|
|||
align-items: stretch;
|
||||
`;
|
||||
|
||||
const WidgetSidebar = () => {
|
||||
const CloseIcon = styled(Icon)`
|
||||
&&.${Classes.ICON} {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
opacity: 0.6;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Header = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: 7fr 1fr;
|
||||
`;
|
||||
|
||||
const Info = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: space-around;
|
||||
text-transform: none;
|
||||
h4 {
|
||||
margin-top: 0px;
|
||||
}
|
||||
p {
|
||||
opacity: 0.6;
|
||||
}
|
||||
`;
|
||||
|
||||
const WidgetSidebar = (props: IPanelProps) => {
|
||||
const cards = useSelector(getWidgetCards);
|
||||
const groups = Object.keys(cards);
|
||||
const [filteredCards, setFilteredCards] = useState(cards);
|
||||
const searchInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const clearSearchInput = () => {
|
||||
if (searchInputRef.current) searchInputRef.current.value = "";
|
||||
};
|
||||
const search = debounce((e: any) => {
|
||||
const keyword = e.target.value.toLowerCase();
|
||||
let filteredCards = cards;
|
||||
if (keyword.trim().length > 0) {
|
||||
filteredCards = produce(cards, draft => {
|
||||
for (const [key, value] of Object.entries(cards)) {
|
||||
value.forEach((card, index) => {
|
||||
if (card.widgetCardName.toLowerCase().indexOf(keyword) === -1) {
|
||||
delete draft[key][index];
|
||||
}
|
||||
});
|
||||
draft[key] = draft[key].filter(Boolean);
|
||||
if (draft[key].length === 0) {
|
||||
delete draft[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
setFilteredCards(filteredCards);
|
||||
}, 300);
|
||||
useEffect(() => {
|
||||
const el: HTMLInputElement | null = searchInputRef.current;
|
||||
|
||||
el?.addEventListener("keydown", search);
|
||||
el?.addEventListener("cleared", search);
|
||||
return () => {
|
||||
el?.removeEventListener("keydown", search);
|
||||
el?.removeEventListener("cleared", search);
|
||||
};
|
||||
}, [searchInputRef, search]);
|
||||
const groups = Object.keys(filteredCards);
|
||||
return (
|
||||
<MainWrapper>
|
||||
{groups.map((group: string) => (
|
||||
<React.Fragment key={group}>
|
||||
<h5>{group}</h5>
|
||||
<CardsWrapper>
|
||||
{cards[group].map((card: WidgetCardProps) => (
|
||||
<WidgetCard details={card} key={card.key} />
|
||||
))}
|
||||
</CardsWrapper>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</MainWrapper>
|
||||
<>
|
||||
<ExplorerSearch
|
||||
ref={searchInputRef}
|
||||
clear={clearSearchInput}
|
||||
placeholder="Search widgets..."
|
||||
/>
|
||||
|
||||
<MainWrapper>
|
||||
<Header>
|
||||
<Info>
|
||||
<p>{WIDGET_SIDEBAR_CAPTION}</p>
|
||||
</Info>
|
||||
<CloseIcon
|
||||
className="t--close-widgets-sidebar"
|
||||
icon="cross"
|
||||
iconSize={16}
|
||||
color={Colors.WHITE}
|
||||
onClick={props.closePanel}
|
||||
/>
|
||||
</Header>
|
||||
{groups.map((group: string) => (
|
||||
<React.Fragment key={group}>
|
||||
<h5>{group}</h5>
|
||||
<CardsWrapper>
|
||||
{filteredCards[group].map((card: WidgetCardProps) => (
|
||||
<WidgetCard details={card} key={card.key} />
|
||||
))}
|
||||
</CardsWrapper>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</MainWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { withRouter, RouteComponentProps } from "react-router-dom";
|
|||
import {
|
||||
BuilderRouteParams,
|
||||
getApplicationViewerPageURL,
|
||||
BUILDER_PAGE_URL,
|
||||
} from "constants/routes";
|
||||
import { AppState } from "reducers";
|
||||
import MainContainer from "./MainContainer";
|
||||
|
|
@ -32,9 +31,8 @@ import { initEditor } from "actions/initActions";
|
|||
import { editorInitializer } from "utils/EditorUtils";
|
||||
import {
|
||||
ENTITY_EXPLORER_SEARCH_ID,
|
||||
ENTITY_EXPLORER_SEARCH_LOCATION_HASH,
|
||||
WIDGETS_SEARCH_ID,
|
||||
} from "constants/Explorer";
|
||||
import history from "utils/history";
|
||||
import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";
|
||||
import { getAppsmithConfigs } from "configs";
|
||||
import { getCurrentUser } from "selectors/usersSelectors";
|
||||
|
|
@ -66,19 +64,14 @@ class Editor extends Component<Props> {
|
|||
combo="meta + f"
|
||||
label="Search entities"
|
||||
onKeyDown={(e: any) => {
|
||||
//TODO(abhinav): make this id into a constant.
|
||||
const el = document.getElementById(ENTITY_EXPLORER_SEARCH_ID);
|
||||
if (!el) {
|
||||
history.push(
|
||||
`${BUILDER_PAGE_URL(
|
||||
this.props.currentApplicationId,
|
||||
this.props.currentPageId,
|
||||
)}${ENTITY_EXPLORER_SEARCH_LOCATION_HASH}`,
|
||||
);
|
||||
} else {
|
||||
el?.focus();
|
||||
}
|
||||
|
||||
const entitySearchInput = document.getElementById(
|
||||
ENTITY_EXPLORER_SEARCH_ID,
|
||||
);
|
||||
const widgetSearchInput = document.getElementById(
|
||||
WIDGETS_SEARCH_ID,
|
||||
);
|
||||
if (entitySearchInput) entitySearchInput.focus();
|
||||
if (widgetSearchInput) widgetSearchInput.focus();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import {
|
|||
getCurlImportPageURL,
|
||||
API_EDITOR_URL_WITH_SELECTED_PAGE_ID,
|
||||
getProviderTemplatesURL,
|
||||
WIDGETS_URL,
|
||||
} from "constants/routes";
|
||||
import styled from "styled-components";
|
||||
import AppRoute from "pages/common/AppRoute";
|
||||
|
|
@ -63,8 +62,7 @@ class EditorsRouter extends React.Component<
|
|||
this.state = {
|
||||
isVisible:
|
||||
this.props.location.pathname !==
|
||||
BUILDER_PAGE_URL(applicationId, pageId) &&
|
||||
this.props.location.pathname !== WIDGETS_URL(applicationId, pageId),
|
||||
BUILDER_PAGE_URL(applicationId, pageId),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -74,8 +72,7 @@ class EditorsRouter extends React.Component<
|
|||
this.setState({
|
||||
isVisible:
|
||||
this.props.location.pathname !==
|
||||
BUILDER_PAGE_URL(applicationId, pageId) &&
|
||||
this.props.location.pathname !== WIDGETS_URL(applicationId, pageId),
|
||||
BUILDER_PAGE_URL(applicationId, pageId),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,14 +155,9 @@ export function* deleteDatasourceSaga(
|
|||
}
|
||||
}
|
||||
|
||||
function* updateDatasourceSaga(
|
||||
actionPayload: ReduxAction<{
|
||||
datasource: Datasource;
|
||||
reinitializeForm: boolean;
|
||||
}>,
|
||||
) {
|
||||
function* updateDatasourceSaga(actionPayload: ReduxAction<Datasource>) {
|
||||
try {
|
||||
const datasourcePayload = _.omit(actionPayload.payload.datasource, "name");
|
||||
const datasourcePayload = _.omit(actionPayload.payload, "name");
|
||||
|
||||
const response: GenericApiResponse<Datasource> = yield DatasourcesApi.updateDatasource(
|
||||
datasourcePayload,
|
||||
|
|
@ -184,9 +179,6 @@ function* updateDatasourceSaga(
|
|||
id: response.data.id,
|
||||
},
|
||||
});
|
||||
if (actionPayload.payload.reinitializeForm) {
|
||||
yield put(initialize(DATASOURCE_DB_FORM, datasourcePayload));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
yield put({
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user