Merge branch 'release' into fix/dropdown-overlap-modal
This commit is contained in:
commit
18e5dde01d
|
|
@ -57,4 +57,4 @@ APPSMITH_MAIL_SMTP_TLS_ENABLED=
|
|||
#APPSMITH_SENTRY_ENVIRONMENT=
|
||||
|
||||
# Configure cloud services
|
||||
# APPSMITH_CLOUD_SERVICES_BASE_URL
|
||||
# APPSMITH_CLOUD_SERVICES_BASE_URL="https://release-cs.appsmith.com"
|
||||
2
.github/workflows/client-test.yml
vendored
2
.github/workflows/client-test.yml
vendored
|
|
@ -297,7 +297,7 @@ jobs:
|
|||
|
||||
- name: Return status for ui-matrix
|
||||
run: |
|
||||
if [[${{ needs.ui-test.result }} == "success" ]]; then
|
||||
if [[ "${{ needs.ui-test.result }}" == "success" ]]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// This JSON file configures the eslint plugin. It supports comments as well as per the JSON5 spec
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["react", "@typescript-eslint", "prettier", "react-hooks"],
|
||||
"plugins": ["react", "@typescript-eslint", "prettier", "react-hooks","sort-destructure-keys"],
|
||||
"extends": [
|
||||
"plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
|
|
@ -34,7 +34,8 @@
|
|||
"react/self-closing-comp": "error",
|
||||
"react/jsx-sort-props": "error",
|
||||
"react/jsx-fragments": "error",
|
||||
"react/jsx-no-useless-fragment": "error"
|
||||
"react/jsx-no-useless-fragment": "error",
|
||||
"sort-destructure-keys/sort-destructure-keys": ["error", {"caseSensitive": false}]
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
"detachFromLayout": true,
|
||||
"widgetId": "0",
|
||||
"topRow": 0,
|
||||
"bottomRow": 2960,
|
||||
"bottomRow": 740,
|
||||
"containerStyle": "none",
|
||||
"snapRows": 33,
|
||||
"parentRowSpace": 1,
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@
|
|||
"parentRowSpace": 38,
|
||||
"leftColumn": 3,
|
||||
"rightColumn": 11,
|
||||
"topRow": 0,
|
||||
"topRow": 1,
|
||||
"bottomRow": 12,
|
||||
"parentId": "yt4ouwn0sk",
|
||||
"widgetId": "673etzjyv9",
|
||||
|
|
|
|||
184
app/client/cypress/fixtures/chartUpdatedDsl.json
Normal file
184
app/client/cypress/fixtures/chartUpdatedDsl.json
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
{
|
||||
"dsl": {
|
||||
"widgetName": "MainContainer",
|
||||
"backgroundColor": "none",
|
||||
"rightColumn": 966,
|
||||
"snapColumns": 64,
|
||||
"detachFromLayout": true,
|
||||
"widgetId": "0",
|
||||
"topRow": 0,
|
||||
"bottomRow": 5168,
|
||||
"containerStyle": "none",
|
||||
"snapRows": 129,
|
||||
"parentRowSpace": 1,
|
||||
"type": "CANVAS_WIDGET",
|
||||
"canExtend": true,
|
||||
"version": 20,
|
||||
"minHeight": 450,
|
||||
"parentColumnSpace": 1,
|
||||
"dynamicBindingPathList": [],
|
||||
"leftColumn": 0,
|
||||
"children": [
|
||||
{
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"widgetName": "Container1",
|
||||
"rightColumn": 32,
|
||||
"orientation": "VERTICAL",
|
||||
"snapColumns": 16,
|
||||
"widgetId": "mxbaasg65u",
|
||||
"containerStyle": "card",
|
||||
"topRow": 0,
|
||||
"bottomRow": 36,
|
||||
"parentRowSpace": 38,
|
||||
"isVisible": true,
|
||||
"type": "CONTAINER_WIDGET",
|
||||
"version": 1,
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 75.25,
|
||||
"dynamicBindingPathList": [],
|
||||
"leftColumn": 0,
|
||||
"children": [
|
||||
{
|
||||
"backgroundColor": "transparent",
|
||||
"widgetName": "59gdivzv7s",
|
||||
"rightColumn": 2408,
|
||||
"orientation": "VERTICAL",
|
||||
"snapColumns": 16,
|
||||
"detachFromLayout": true,
|
||||
"widgetId": "bxekwxgc1i",
|
||||
"containerStyle": "none",
|
||||
"topRow": 0,
|
||||
"bottomRow": 20,
|
||||
"parentRowSpace": 1,
|
||||
"isVisible": true,
|
||||
"type": "CANVAS_WIDGET",
|
||||
"canExtend": false,
|
||||
"version": 1,
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 1,
|
||||
"leftColumn": 0,
|
||||
"dynamicBindingPathList": [],
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"widgetName": "Container3",
|
||||
"rightColumn": 64,
|
||||
"orientation": "VERTICAL",
|
||||
"snapColumns": 16,
|
||||
"widgetId": "i331vll2mg",
|
||||
"containerStyle": "card",
|
||||
"topRow": 36,
|
||||
"bottomRow": 92,
|
||||
"parentRowSpace": 38,
|
||||
"isVisible": true,
|
||||
"type": "CONTAINER_WIDGET",
|
||||
"version": 1,
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 75.25,
|
||||
"dynamicBindingPathList": [],
|
||||
"leftColumn": 0,
|
||||
"children": [
|
||||
{
|
||||
"backgroundColor": "transparent",
|
||||
"widgetName": "rhfg2vf1n5",
|
||||
"rightColumn": 4816,
|
||||
"orientation": "VERTICAL",
|
||||
"snapColumns": 16,
|
||||
"detachFromLayout": true,
|
||||
"widgetId": "rglduihhzk",
|
||||
"containerStyle": "none",
|
||||
"topRow": 0,
|
||||
"bottomRow": 20,
|
||||
"parentRowSpace": 1,
|
||||
"isVisible": true,
|
||||
"type": "CANVAS_WIDGET",
|
||||
"canExtend": false,
|
||||
"version": 1,
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 1,
|
||||
"leftColumn": 0,
|
||||
"dynamicBindingPathList": [],
|
||||
"children": [
|
||||
{
|
||||
"isVisible": true,
|
||||
"widgetName": "Chart1",
|
||||
"chartType": "LINE_CHART",
|
||||
"chartName": "Last week's revenue",
|
||||
"allowHorizontalScroll": false,
|
||||
"version": 1,
|
||||
"chartData": {
|
||||
"q4pm3w97mo": {
|
||||
"seriesName": "Sales",
|
||||
"data": ""
|
||||
}
|
||||
},
|
||||
"xAxisName": "Last Week",
|
||||
"yAxisName": "Total Order Revenue $",
|
||||
"type": "CHART_WIDGET",
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 14.59375,
|
||||
"parentRowSpace": 10,
|
||||
"leftColumn": 20,
|
||||
"rightColumn": 44,
|
||||
"topRow": 16,
|
||||
"bottomRow": 48,
|
||||
"parentId": "rglduihhzk",
|
||||
"widgetId": "snzfh3qjo8",
|
||||
"dynamicBindingPathList": [],
|
||||
"dynamicTriggerPathList": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"widgetName": "Container4",
|
||||
"rightColumn": 64,
|
||||
"orientation": "VERTICAL",
|
||||
"snapColumns": 16,
|
||||
"widgetId": "qznzsquf70",
|
||||
"containerStyle": "card",
|
||||
"topRow": 0,
|
||||
"bottomRow": 36,
|
||||
"parentRowSpace": 38,
|
||||
"isVisible": true,
|
||||
"type": "CONTAINER_WIDGET",
|
||||
"version": 1,
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 75.25,
|
||||
"dynamicBindingPathList": [],
|
||||
"leftColumn": 32,
|
||||
"children": [
|
||||
{
|
||||
"backgroundColor": "transparent",
|
||||
"widgetName": "3bn6uv0vy4",
|
||||
"rightColumn": 2408,
|
||||
"orientation": "VERTICAL",
|
||||
"snapColumns": 16,
|
||||
"detachFromLayout": true,
|
||||
"widgetId": "7vm5mdu8ey",
|
||||
"containerStyle": "none",
|
||||
"topRow": 0,
|
||||
"bottomRow": 1368,
|
||||
"parentRowSpace": 1,
|
||||
"isVisible": true,
|
||||
"type": "CANVAS_WIDGET",
|
||||
"canExtend": false,
|
||||
"version": 1,
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 1,
|
||||
"leftColumn": 0,
|
||||
"dynamicBindingPathList": [],
|
||||
"children": [
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
42
app/client/cypress/fixtures/debuggerTableDsl.json
Normal file
42
app/client/cypress/fixtures/debuggerTableDsl.json
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"dsl": {
|
||||
"widgetName": "MainContainer",
|
||||
"backgroundColor": "none",
|
||||
"rightColumn": 1224,
|
||||
"snapColumns": 16,
|
||||
"detachFromLayout": true,
|
||||
"widgetId": "0",
|
||||
"topRow": 0,
|
||||
"bottomRow": 1280,
|
||||
"containerStyle": "none",
|
||||
"snapRows": 33,
|
||||
"parentRowSpace": 1,
|
||||
"type": "CANVAS_WIDGET",
|
||||
"canExtend": true,
|
||||
"version": 9,
|
||||
"minHeight": 1292,
|
||||
"parentColumnSpace": 1,
|
||||
"dynamicBindingPathList": [],
|
||||
"leftColumn": 0,
|
||||
"children": [
|
||||
{
|
||||
"isVisible": true,
|
||||
"label": "Data",
|
||||
"widgetName": "Table1",
|
||||
"searchKey": "",
|
||||
"tableData": "{{TestApi.data.users}}",
|
||||
"type": "TABLE_WIDGET",
|
||||
"isLoading": false,
|
||||
"parentColumnSpace": 74,
|
||||
"parentRowSpace": 40,
|
||||
"leftColumn": 1,
|
||||
"rightColumn": 9,
|
||||
"topRow": 7,
|
||||
"bottomRow": 14,
|
||||
"parentId": "0",
|
||||
"widgetId": "7miqot30xy",
|
||||
"dynamicBindingPathList": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
"type": "CANVAS_WIDGET",
|
||||
"canExtend": true,
|
||||
"dynamicBindingPathList": [],
|
||||
"version": 4,
|
||||
"minHeight": 1292,
|
||||
"parentColumnSpace": 1,
|
||||
"leftColumn": 0,
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@
|
|||
"backgroundColor": "Gray",
|
||||
"rightColumn": 11,
|
||||
"widgetId": "z62mnh15y5",
|
||||
"topRow": 0,
|
||||
"topRow": 1,
|
||||
"bottomRow": 13,
|
||||
"parentRowSpace": 38,
|
||||
"isVisible": true,
|
||||
|
|
|
|||
|
|
@ -67,7 +67,11 @@
|
|||
"bottomRow": 10,
|
||||
"parentId": "tyiwk4xuq0",
|
||||
"widgetId": "5up3r2iuvs",
|
||||
"dynamicBindingPathList": []
|
||||
"dynamicTriggerPathList": [{
|
||||
"key": "onSearchTextChanged"
|
||||
}],
|
||||
"onSearchTextChanged": "{{Api1.run()}}",
|
||||
"selectedRow": "{{Table1.tableData[Table1.selectedRowIndex]}}"
|
||||
}
|
||||
],
|
||||
"widgetId": "tyiwk4xuq0",
|
||||
|
|
|
|||
|
|
@ -122,5 +122,6 @@
|
|||
"accessTokenUrl": "https://oauth.mocklab.io/oauth/token",
|
||||
"oauthResponse": "169444434892406",
|
||||
"authorizationURL": "https://oauth.mocklab.io/oauth/authorize",
|
||||
"basicURl": "https://envyenksqii9nf3.m.pipedream.net"
|
||||
"basicURl": "https://envyenksqii9nf3.m.pipedream.net",
|
||||
"methodWithQueryParam": "users?q=mimeType='application/vnd.google-apps.spreadsheet'"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,4 +39,16 @@ describe("API Panel Test Functionality", function() {
|
|||
cy.xpath(apiwidget.headerKey).should("be.visible");
|
||||
cy.xpath(apiwidget.headerKey).should("have.value", "");
|
||||
});
|
||||
|
||||
it("Should correctly parse query params", function() {
|
||||
cy.NavigateToAPI_Panel();
|
||||
cy.CreateAPI("APIWithQueryParams");
|
||||
cy.get("textarea").should(
|
||||
"have.attr",
|
||||
"placeholder",
|
||||
"https://mock-api.appsmith.com/users",
|
||||
);
|
||||
cy.enterDatasourceAndPath(testdata.baseUrl, testdata.methodWithQueryParam);
|
||||
cy.ValidateQueryParams({ key: "q", value:"mimeType='application/vnd.google-apps.spreadsheet'" });
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ let duplicateApplicationDsl;
|
|||
|
||||
describe("Duplicate application", function() {
|
||||
before(() => {
|
||||
dsl.dsl.version = 20; // latest migrated version
|
||||
cy.addDsl(dsl);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ let forkedApplicationDsl;
|
|||
|
||||
describe("Fork application across orgs", function() {
|
||||
before(() => {
|
||||
dsl.dsl.version = 20; // latest migrated version
|
||||
cy.addDsl(dsl);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ const dsl = require("../../../../fixtures/tableWidgetDsl.json");
|
|||
const pages = require("../../../../locators/Pages.json");
|
||||
const apiPage = require("../../../../locators/ApiEditor.json");
|
||||
const publishPage = require("../../../../locators/publishWidgetspage.json");
|
||||
const widgetsPage = require("../../../../locators/Widgets.json");
|
||||
|
||||
describe("Test Create Api and Bind to Table widget", function() {
|
||||
let apiData;
|
||||
|
|
@ -43,6 +44,18 @@ describe("Test Create Api and Bind to Table widget", function() {
|
|||
cy.readTabledataPublish("0", "1").then((tabData) => {
|
||||
expect(apiData).to.eq(`\"${tabData}\"`);
|
||||
});
|
||||
cy.get(commonlocators.backToEditor).click();
|
||||
});
|
||||
|
||||
it("Validate onSearchTextChanged function is called when configured for search text", function() {
|
||||
cy.SearchEntityandOpen("Table1");
|
||||
cy.get(".t--widget-tablewidget .t--search-input")
|
||||
.first()
|
||||
.type("Currey");
|
||||
cy.wait(5000);
|
||||
cy.readTabledataPublish("0", "1").then((tabData) => {
|
||||
expect(apiData).to.eq(`\"${tabData}\"`);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
const dsl = require("../../../../fixtures/buttondsl.json");
|
||||
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||
const debuggerLocators = require("../../../../locators/Debugger.json");
|
||||
|
||||
describe("Debugger logs", function() {
|
||||
before(() => {
|
||||
|
|
@ -11,4 +13,19 @@ describe("Debugger logs", function() {
|
|||
cy.get(".t--debugger").click();
|
||||
cy.get(".t--debugger-log-state").contains("Test");
|
||||
});
|
||||
|
||||
it("Reset debugger state", function() {
|
||||
cy.openPropertyPane("buttonwidget");
|
||||
cy.get(".t--property-control-visible")
|
||||
.find(".t--js-toggle")
|
||||
.click();
|
||||
cy.testJsontext("visible", "Test");
|
||||
|
||||
cy.get(commonlocators.homeIcon).click({ force: true });
|
||||
cy.generateUUID().then((id) => {
|
||||
cy.CreateAppInFirstListedOrg(id);
|
||||
|
||||
cy.contains(debuggerLocators.debuggerIcon, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
const dsl = require("../../../../fixtures/debuggerTableDsl.json");
|
||||
const explorer = require("../../../../locators/explorerlocators.json");
|
||||
const debuggerLocators = require("../../../../locators/Debugger.json");
|
||||
const testdata = require("../../../../fixtures/testdata.json");
|
||||
|
||||
describe("Check debugger logs state when there are onPageLoad actions", function() {
|
||||
before(() => {
|
||||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Check debugger logs state when there are onPageLoad actions", function() {
|
||||
cy.openPropertyPane("tablewidget");
|
||||
cy.testJsontext("tabledata", "{{TestApi.data.users}}");
|
||||
cy.NavigateToAPI_Panel();
|
||||
cy.CreateAPI("TestApi");
|
||||
cy.enterDatasourceAndPath(testdata.baseUrl, testdata.methods);
|
||||
cy.SaveAndRunAPI();
|
||||
|
||||
cy.get(explorer.addWidget).click();
|
||||
|
||||
cy.reload();
|
||||
cy.contains(debuggerLocators.debuggerIcon, 0);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
const dsl = require("../../../../fixtures/buttondsl.json");
|
||||
|
||||
describe("Widget error state", function() {
|
||||
before(() => {
|
||||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Check widget error state", function() {
|
||||
cy.openPropertyPane("buttonwidget");
|
||||
|
||||
cy.get(".t--property-control-visible")
|
||||
.find(".t--js-toggle")
|
||||
.click();
|
||||
cy.testJsontext("visible", "Test");
|
||||
|
||||
cy.contains(".t--widget-error-count", 1);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||
const viewWidgetsPage = require("../../../../locators/ViewWidgets.json");
|
||||
const publish = require("../../../../locators/publishWidgetspage.json");
|
||||
const dsl = require("../../../../fixtures/displayWidgetDsl.json");
|
||||
const dsl = require("../../../../fixtures/chartUpdatedDsl.json");
|
||||
const pages = require("../../../../locators/Pages.json");
|
||||
|
||||
describe("Chart Widget Functionality", function() {
|
||||
|
|
@ -43,7 +43,11 @@ describe("Chart Widget Functionality", function() {
|
|||
cy.get(viewWidgetsPage.chartType)
|
||||
.last()
|
||||
.should("have.text", "Column Chart");
|
||||
cy.testJsontext("chartseries", JSON.stringify(this.data.chartInput));
|
||||
cy.testJsontext(
|
||||
"chart-series-data-control",
|
||||
JSON.stringify(this.data.chartInput),
|
||||
);
|
||||
cy.get(".t--propertypane").click("right");
|
||||
cy.get(viewWidgetsPage.chartWidget)
|
||||
.should("be.visible")
|
||||
.and((chart) => {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ describe("Modal Widget Functionality", function() {
|
|||
|
||||
it("Add new Modal", () => {
|
||||
cy.get(explorer.addWidget).click();
|
||||
cy.dragAndDropToCanvas("modalwidget", { x: 300, y: -300 });
|
||||
cy.dragAndDropToCanvas("modalwidget", { x: 300, y: 300 });
|
||||
cy.get(".t--modal-widget").should("exist");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ describe("Test Suite to validate copy/paste table Widget", function() {
|
|||
.contains("UNDO")
|
||||
.click({ force: true });
|
||||
*/
|
||||
cy.GlobalSearchEntity("Table2");
|
||||
cy.GlobalSearchEntity("Table1Copy");
|
||||
cy.get(".t--entity-collapse-toggle")
|
||||
.last()
|
||||
.click();
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(8);
|
||||
expect($lis.eq(0)).to.contain("{{Table2.selectedRow}}");
|
||||
expect($lis.eq(1)).to.contain("{{Table2.selectedRows}}");
|
||||
expect($lis.eq(0)).to.contain("{{Table1Copy.selectedRow}}");
|
||||
expect($lis.eq(1)).to.contain("{{Table1Copy.selectedRows}}");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ describe("Entity explorer Drag and Drop widgets testcases", function() {
|
|||
cy.get(commonlocators.entityExplorersearch)
|
||||
.clear()
|
||||
.type("form");
|
||||
cy.dragAndDropToCanvas("formwidget", { x: 300, y: -300 });
|
||||
cy.dragAndDropToCanvas("formwidget", { x: 300, y: 80 });
|
||||
cy.get(formWidgetsPage.formD).click();
|
||||
/**
|
||||
* @param{Text} Random Text
|
||||
* @param{FormWidget}Mouseover
|
||||
|
|
|
|||
|
|
@ -101,10 +101,11 @@ describe("Entity explorer tests related to query and datasource", function() {
|
|||
.find(explorer.collapse)
|
||||
.click();
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(3);
|
||||
expect($lis).to.have.length(4);
|
||||
expect($lis.eq(0)).to.contain("{{Query1.isLoading}}");
|
||||
expect($lis.eq(1)).to.contain("{{Query1.data}}");
|
||||
expect($lis.eq(2)).to.contain("{{Query1.run()}}");
|
||||
expect($lis.eq(2)).to.contain("{{Query1.responseMeta}}");
|
||||
expect($lis.eq(3)).to.contain("{{Query1.run()}}");
|
||||
});
|
||||
cy.Createpage(pageid);
|
||||
cy.GlobalSearchEntity("Query1");
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ describe("Test Suite to validate copy/delete/undo functionalites", function() {
|
|||
cy.wait(500);
|
||||
cy.get(commonlocators.toastBody)
|
||||
.first()
|
||||
.contains("Copied");
|
||||
.contains("Copied")
|
||||
.click();
|
||||
cy.get("body").type(`{${modifierKey}}v`, { force: true });
|
||||
cy.wait("@updateLayout").should(
|
||||
"have.nested.property",
|
||||
|
|
@ -45,11 +46,11 @@ describe("Test Suite to validate copy/delete/undo functionalites", function() {
|
|||
cy.get(commonlocators.toastAction)
|
||||
.contains("UNDO")
|
||||
.click({ force: true });
|
||||
cy.GlobalSearchEntity("Form1");
|
||||
cy.GlobalSearchEntity("FormTestCopy");
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(2);
|
||||
expect($lis.eq(0)).to.contain("{{Form1.isVisible}}");
|
||||
expect($lis.eq(1)).to.contain("{{Form1.data}}");
|
||||
expect($lis.eq(0)).to.contain("{{FormTestCopy.isVisible}}");
|
||||
expect($lis.eq(1)).to.contain("{{FormTestCopy.data}}");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -74,9 +74,9 @@ describe("DatePicker Widget Property pane tests with js bindings", function() {
|
|||
cy.get(".t--property-control-defaultdate .bp3-input").type("2020-02-01");
|
||||
cy.closePropertyPane();
|
||||
cy.openPropertyPane("datepickerwidget2");
|
||||
cy.get(formWidgetsPage.toggleJsMinDate).click();
|
||||
cy.get(formWidgetsPage.toggleJsMinDate).click({ force: true });
|
||||
cy.get(".t--property-control-mindate .bp3-input").type("2020-01-01");
|
||||
cy.get(formWidgetsPage.toggleJsMaxDate).click();
|
||||
cy.get(formWidgetsPage.toggleJsMaxDate).click({ force: true });
|
||||
cy.get(".t--property-control-maxdate .bp3-input").type("2020-02-10");
|
||||
cy.closePropertyPane();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ describe("GlobalSearch", function() {
|
|||
.its("store")
|
||||
.invoke("getState")
|
||||
.then((state) => {
|
||||
const { selectedWidget } = state.ui.widgetDragResize;
|
||||
expect(selectedWidget).to.be.equal(table.widgetId);
|
||||
const { lastSelectedWidget } = state.ui.widgetDragResize;
|
||||
expect(lastSelectedWidget).to.be.equal(table.widgetId);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ describe("Onboarding", function() {
|
|||
|
||||
// Add widget
|
||||
cy.get(".t--add-widget").click();
|
||||
cy.dragAndDropToCanvas("tablewidget", { x: 30, y: -30 });
|
||||
cy.dragAndDropToCanvas("tablewidget", { x: 360, y: 20 });
|
||||
|
||||
// wait for animation duration
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe("Check for product updates button and modal", function() {
|
|||
const { releaseItems, newReleasesCount } = state.ui.releases;
|
||||
if (Array.isArray(releaseItems) && releaseItems.length > 0) {
|
||||
cy.get("[data-cy=t--product-updates-btn]")
|
||||
.contains(newReleasesCount)
|
||||
.contains("What's New?")
|
||||
.click({ force: true });
|
||||
//eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(500); // modal transition
|
||||
|
|
|
|||
|
|
@ -1,22 +1,26 @@
|
|||
const testdata = require("../../../../fixtures/testdata.json");
|
||||
describe("Create a rest datasource", function() {
|
||||
beforeEach(() => {
|
||||
cy.startRoutesForDatasource();
|
||||
});
|
||||
/*
|
||||
* Commenting this spec as its flaky
|
||||
*
|
||||
* */
|
||||
// const testdata = require("../../../../fixtures/testdata.json");
|
||||
// describe("Create a rest datasource", function() {
|
||||
// beforeEach(() => {
|
||||
// cy.startRoutesForDatasource();
|
||||
// });
|
||||
|
||||
it("Create a rest datasource", function() {
|
||||
cy.NavigateToAPI_Panel();
|
||||
cy.CreateAPI("Testapi");
|
||||
cy.enterDatasource(testdata.basicURl);
|
||||
cy.get(".t--store-as-datasource").click();
|
||||
cy.addBasicProfileDetails("test", "test@123");
|
||||
cy.saveDatasource();
|
||||
cy.contains(".datasource-highlight", "envyenksqii9nf3.m.pipedream.net");
|
||||
cy.SaveAndRunAPI();
|
||||
cy.wait(2000);
|
||||
var encodedStringBtoA = btoa("test:test@123");
|
||||
cy.log(encodedStringBtoA);
|
||||
cy.ResponseStatusCheck(testdata.successStatusCode);
|
||||
cy.ResponseTextCheck("Basic ".concat(encodedStringBtoA));
|
||||
});
|
||||
});
|
||||
// it("Create a rest datasource", function() {
|
||||
// cy.NavigateToAPI_Panel();
|
||||
// cy.CreateAPI("Testapi");
|
||||
// cy.enterDatasource(testdata.basicURl);
|
||||
// cy.get(".t--store-as-datasource").click();
|
||||
// cy.addBasicProfileDetails("test", "test@123");
|
||||
// cy.saveDatasource();
|
||||
// cy.contains(".datasource-highlight", "envyenksqii9nf3.m.pipedream.net");
|
||||
// cy.SaveAndRunAPI();
|
||||
// cy.wait(2000);
|
||||
// var encodedStringBtoA = btoa("test:test@123");
|
||||
// cy.log(encodedStringBtoA);
|
||||
// cy.ResponseStatusCheck(testdata.successStatusCode);
|
||||
// cy.ResponseTextCheck("Basic ".concat(encodedStringBtoA));
|
||||
// });
|
||||
// });
|
||||
|
|
|
|||
|
|
@ -27,10 +27,11 @@ describe("Entity explorer API pane related testcases", function() {
|
|||
.find(explorer.collapse)
|
||||
.click();
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(3);
|
||||
expect($lis).to.have.length(4);
|
||||
expect($lis.eq(0)).to.contain("{{FirstAPI.isLoading}}");
|
||||
expect($lis.eq(1)).to.contain("{{FirstAPI.data}}");
|
||||
expect($lis.eq(2)).to.contain("{{FirstAPI.run()}}");
|
||||
expect($lis.eq(2)).to.contain("{{FirstAPI.responseMeta}}");
|
||||
expect($lis.eq(3)).to.contain("{{FirstAPI.run()}}");
|
||||
});
|
||||
cy.get(apiwidget.actionlist)
|
||||
.contains(testdata.Get)
|
||||
|
|
|
|||
|
|
@ -54,10 +54,11 @@ describe("Entity explorer tests related to copy query", function() {
|
|||
.find(explorer.collapse)
|
||||
.click();
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(3);
|
||||
expect($lis).to.have.length(4);
|
||||
expect($lis.eq(0)).to.contain("{{Query1.isLoading}}");
|
||||
expect($lis.eq(1)).to.contain("{{Query1.data}}");
|
||||
expect($lis.eq(2)).to.contain("{{Query1.run()}}");
|
||||
expect($lis.eq(2)).to.contain("{{Query1.responseMeta}}");
|
||||
expect($lis.eq(3)).to.contain("{{Query1.run()}}");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -71,16 +72,18 @@ describe("Entity explorer tests related to copy query", function() {
|
|||
.invoke("show")
|
||||
.click({ force: true });
|
||||
cy.copyEntityToPage(pageid);
|
||||
cy.SearchEntityandOpen("Query1Copy");
|
||||
cy.SearchEntityandOpen("Query1");
|
||||
cy.runQuery();
|
||||
cy.get(`.t--entity.action:contains(Query1Copy)`)
|
||||
cy.get(`.t--entity.action:contains(Query1)`).should("have.length", 2);
|
||||
cy.get(`.t--entity.action:contains(Query1)`)
|
||||
.find(explorer.collapse)
|
||||
.click();
|
||||
.click({ multiple: true });
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(3);
|
||||
expect($lis.eq(0)).to.contain("{{Query1Copy.isLoading}}");
|
||||
expect($lis.eq(1)).to.contain("{{Query1Copy.data}}");
|
||||
expect($lis.eq(2)).to.contain("{{Query1Copy.run()}}");
|
||||
expect($lis).to.have.length(4);
|
||||
expect($lis.eq(0)).to.contain("{{Query1.isLoading}}");
|
||||
expect($lis.eq(1)).to.contain("{{Query1.data}}");
|
||||
expect($lis.eq(2)).to.contain("{{Query1.responseMeta}}");
|
||||
expect($lis.eq(3)).to.contain("{{Query1.run()}}");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -109,7 +112,7 @@ describe("Entity explorer tests related to copy query", function() {
|
|||
);
|
||||
});
|
||||
|
||||
cy.SearchEntityandOpen("Query1Copy");
|
||||
cy.SearchEntityandOpen("Query1");
|
||||
cy.deleteQuery();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
3
app/client/cypress/locators/Debugger.json
Normal file
3
app/client/cypress/locators/Debugger.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"debuggerIcon": ".t--debugger"
|
||||
}
|
||||
|
|
@ -38,6 +38,8 @@
|
|||
"textInputval": ".t--draggable-textwidget span.t--widget-name",
|
||||
"textCenterAlign": ".t--property-control-textalign .t--icon-tab-CENTER",
|
||||
"ColumnAction": ".t--property-control-rowbutton button",
|
||||
"SearchTextChangeAction": ".t--property-control-onsearchtextchanged button",
|
||||
"tableSearchTextChangeSelected": ".t--property-control-onsearchtextchanged",
|
||||
"videoWidget": ".t--draggable-videowidget",
|
||||
"autoPlay": ".t--property-control-autoplay > .bp3-control > .bp3-control-indicator",
|
||||
"defaultOption": ".t--property-control-defaultoption .CodeMirror-code",
|
||||
|
|
|
|||
|
|
@ -52,5 +52,8 @@
|
|||
"actionlist": ".action div div",
|
||||
"settings": "li:contains('Settings')",
|
||||
"onPageLoad": "[data-cy=executeOnLoad]",
|
||||
"renameEntity": ".single-select >div:contains('Edit Name')"
|
||||
"renameEntity": ".single-select >div:contains('Edit Name')",
|
||||
"paramsTab": "//li//span[text()='Params']",
|
||||
"paramKey": "(//div[contains(@class,'t--actionConfiguration.queryParameters[0].key.0')]//textarea)[1]",
|
||||
"paramValue": "(//div[contains(@class,'t--actionConfiguration.queryParameters[0].value.0')]//textarea)[1]"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1143,7 +1143,7 @@ Cypress.Commands.add("widgetText", (text, inputcss, innercss) => {
|
|||
cy.get(inputcss)
|
||||
.first()
|
||||
.trigger("mouseover", { force: true });
|
||||
cy.get(innercss).should("have.text", text);
|
||||
cy.contains(innercss, text);
|
||||
});
|
||||
|
||||
Cypress.Commands.add("editColName", (text) => {
|
||||
|
|
@ -1870,11 +1870,11 @@ Cypress.Commands.add("testDatasource", () => {
|
|||
|
||||
Cypress.Commands.add("saveDatasource", () => {
|
||||
cy.get(".t--save-datasource").click();
|
||||
cy.wait("@saveDatasource").should(
|
||||
"have.nested.property",
|
||||
"response.body.responseMeta.status",
|
||||
200,
|
||||
);
|
||||
cy.wait("@saveDatasource")
|
||||
.then((xhr) => {
|
||||
cy.log(JSON.stringify(xhr.response.body));
|
||||
})
|
||||
.should("have.nested.property", "response.body.responseMeta.status", 200);
|
||||
});
|
||||
|
||||
Cypress.Commands.add("testSaveDatasource", () => {
|
||||
|
|
@ -2011,8 +2011,8 @@ Cypress.Commands.add("dragAndDropToCanvas", (widgetType, { x, y }) => {
|
|||
.trigger("mousedown", { button: 0 }, { force: true })
|
||||
.trigger("mousemove", x, y, { force: true });
|
||||
cy.get(explorer.dropHere)
|
||||
.click()
|
||||
.trigger("mouseup", { force: true });
|
||||
.click(x, y + 20)
|
||||
.trigger("mouseup", x, y + 20, { force: true });
|
||||
});
|
||||
|
||||
Cypress.Commands.add("executeDbQuery", (queryName) => {
|
||||
|
|
@ -2035,7 +2035,9 @@ Cypress.Commands.add("openPropertyPane", (widgetType) => {
|
|||
.first()
|
||||
.trigger("mouseover", { force: true })
|
||||
.wait(500);
|
||||
cy.get(`${selector}:first-of-type .t--widget-propertypane-toggle`)
|
||||
cy.get(
|
||||
`${selector}:first-of-type .t--widget-propertypane-toggle > .t--widget-name`,
|
||||
)
|
||||
.first()
|
||||
.click({ force: true });
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
|
|
@ -2342,3 +2344,11 @@ Cypress.Commands.add("callApi", (apiname) => {
|
|||
Cypress.Commands.add("assertPageSave", () => {
|
||||
cy.get(commonlocators.saveStatusSuccess);
|
||||
});
|
||||
|
||||
Cypress.Commands.add("ValidateQueryParams", (param) => {
|
||||
cy.xpath(apiwidget.paramsTab)
|
||||
.should("be.visible")
|
||||
.click({ force: true });
|
||||
cy.xpath(apiwidget.paramKey).first().contains(param.key);
|
||||
cy.xpath(apiwidget.paramValue).first().contains(param.value);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ module.exports = {
|
|||
"test/(.*)": "<rootDir>/test/$1",
|
||||
},
|
||||
globals: {
|
||||
"ts-jest": {
|
||||
isolatedModules: true,
|
||||
},
|
||||
APPSMITH_FEATURE_CONFIGS: {
|
||||
sentry: {
|
||||
dsn: parseConfig("__APPSMITH_SENTRY_DSN__"),
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
"@types/react-table": "^7.0.13",
|
||||
"@types/styled-components": "^5.1.3",
|
||||
"@types/tinycolor2": "^1.4.2",
|
||||
"@types/zipcelx": "^1.5.0",
|
||||
"@uppy/core": "^1.16.0",
|
||||
"@uppy/dashboard": "^1.16.0",
|
||||
"@uppy/file-input": "^1.4.22",
|
||||
|
|
@ -144,7 +145,8 @@
|
|||
"typescript": "^4.1.3",
|
||||
"unescape-js": "^1.1.4",
|
||||
"url-search-params-polyfill": "^8.0.0",
|
||||
"worker-loader": "^3.0.2"
|
||||
"worker-loader": "^3.0.2",
|
||||
"zipcelx": "^1.6.2"
|
||||
},
|
||||
"scripts": {
|
||||
"analyze": "source-map-explorer 'build/static/js/*.js'",
|
||||
|
|
@ -224,6 +226,7 @@
|
|||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"eslint-plugin-react": "^7.21.3",
|
||||
"eslint-plugin-react-hooks": "^2.3.0",
|
||||
"eslint-plugin-sort-destructure-keys": "^1.3.5",
|
||||
"factory.ts": "^0.5.1",
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"mocha": "^7.1.0",
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@
|
|||
intercomAppID: APP_ID,
|
||||
mailEnabled: parseConfig("__APPSMITH_MAIL_ENABLED__"),
|
||||
disableTelemetry: DISABLE_TELEMETRY === "" || DISABLE_TELEMETRY,
|
||||
cloudServicesBaseUrl: parseConfig("__APPSMITH_CLOUD_SERVICES_BASE_URL__")
|
||||
cloudServicesBaseUrl: parseConfig("__APPSMITH_CLOUD_SERVICES_BASE_URL__") || "https://cs.appsmith.com"
|
||||
};
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -233,6 +233,12 @@ export const updateActionProperty = (
|
|||
});
|
||||
};
|
||||
|
||||
export const executePageLoadActionsComplete = () => {
|
||||
return {
|
||||
type: ReduxActionTypes.EXECUTE_PAGE_LOAD_ACTIONS_COMPLETE,
|
||||
};
|
||||
};
|
||||
|
||||
export const setActionsToExecuteOnPageLoad = (
|
||||
actions: Array<{
|
||||
executeOnLoad: boolean;
|
||||
|
|
|
|||
|
|
@ -29,3 +29,7 @@ export const updateErrorLog = (payload: Message) => ({
|
|||
type: ReduxActionTypes.DEBUGGER_UPDATE_ERROR_LOG,
|
||||
payload,
|
||||
});
|
||||
|
||||
export const resetDebuggerState = () => ({
|
||||
type: ReduxActionTypes.RESET_DEBUGGER_STATE,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -203,6 +203,12 @@ export type WidgetDelete = {
|
|||
isShortcut?: boolean;
|
||||
};
|
||||
|
||||
export type MultipleWidgetDeletePayload = {
|
||||
widgetIds: string[];
|
||||
disallowUndo?: boolean;
|
||||
isShortcut?: boolean;
|
||||
};
|
||||
|
||||
export type WidgetResize = {
|
||||
widgetId: string;
|
||||
leftColumn: number;
|
||||
|
|
|
|||
|
|
@ -65,11 +65,27 @@ export const focusWidget = (
|
|||
|
||||
export const selectWidget = (
|
||||
widgetId?: string,
|
||||
): ReduxAction<{ widgetId?: string }> => ({
|
||||
isMultiSelect?: boolean,
|
||||
): ReduxAction<{ widgetId?: string; isMultiSelect?: boolean }> => ({
|
||||
type: ReduxActionTypes.SELECT_WIDGET,
|
||||
payload: { widgetId },
|
||||
payload: { widgetId, isMultiSelect },
|
||||
});
|
||||
|
||||
export const selectAllWidgets = (
|
||||
widgetIds?: string[],
|
||||
): ReduxAction<{ widgetIds?: string[] }> => {
|
||||
return {
|
||||
type: ReduxActionTypes.SELECT_MULTIPLE_WIDGETS,
|
||||
payload: { widgetIds },
|
||||
};
|
||||
};
|
||||
|
||||
export const selectAllWidgetsInit = () => {
|
||||
return {
|
||||
type: ReduxActionTypes.SELECT_MULTIPLE_WIDGETS_INIT,
|
||||
};
|
||||
};
|
||||
|
||||
export const showModal = (id: string) => {
|
||||
return {
|
||||
type: ReduxActionTypes.SHOW_MODAL,
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ export const apiFailureResponseInterceptor = (error: any) => {
|
|||
// Redirect to login and set a redirect url.
|
||||
history.replace({
|
||||
pathname: AUTH_LOGIN_URL,
|
||||
search: `redirectUrl=${currentUrl}`,
|
||||
search: `redirectUrl=${encodeURIComponent(currentUrl)}`,
|
||||
});
|
||||
return Promise.reject({
|
||||
code: ERROR_CODES.REQUEST_NOT_AUTHORISED,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class CurlImportApi extends Api {
|
|||
static curlImportURL = `v1/import`;
|
||||
|
||||
static curlImport(request: CurlImportRequest): AxiosPromise<ApiResponse> {
|
||||
const { pageId, name, curl, organizationId } = request;
|
||||
const { curl, name, organizationId, pageId } = request;
|
||||
return Api.post(CurlImportApi.curlImportURL, curl, {
|
||||
type: "CURL",
|
||||
pageId,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.63664 2.85717L5.50677 2.85717L7.06542 2.85717L7.06542 6.59999L5.81828 6.59999L8.0001 9.34284L10.1819 6.59999L8.93555 6.59999L8.93555 2.85717L10.4938 2.85717L12.3639 2.85717C13.741 2.85717 14.8574 4.08528 14.8574 5.60003C14.8574 6.88094 14.0551 7.9486 12.9761 8.24963C12.8564 10.9733 10.8173 13.1429 8.31197 13.1429C5.83467 13.1429 3.81243 11.022 3.65223 8.34083C2.25399 8.3518 1.14313 7.10654 1.14313 5.60003C1.14313 4.08529 2.2596 2.85717 3.63664 2.85717Z" fill="#A9A7A7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 630 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 20 20"><g><path fill="#2E3D49" d="M16.125 8.36658C15.5583 5.49158 13.0333 3.33325 10 3.33325C7.59167 3.33325 5.5 4.69992 4.45833 6.69992C1.95 6.96658 0 9.09158 0 11.6666C0 14.4249 2.24167 16.6666 5 16.6666H15.8333C18.1333 16.6666 20 14.7999 20 12.4999C20 10.2999 18.2917 8.51658 16.125 8.36658ZM14.1667 10.8333L10 14.9999L5.83333 10.8333H8.33333V7.49992H11.6667V10.8333H14.1667Z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 479 B |
4
app/client/src/assets/icons/control/filter-icon.svg
Executable file → Normal file
4
app/client/src/assets/icons/control/filter-icon.svg
Executable file → Normal file
|
|
@ -1 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 20 20"><g><path fill="#2E3D49" d="M11.6014 16C11.4571 16 11.3168 15.9532 11.2014 15.8667L8.53472 13.8333C8.45315 13.7705 8.38723 13.6897 8.34212 13.5972C8.29701 13.5047 8.27394 13.4029 8.27472 13.3V11.12L5.07472 4.97333C5.02202 4.87161 4.99642 4.75802 5.0004 4.64352C5.00438 4.52903 5.0378 4.41749 5.09743 4.31966C5.15706 4.22184 5.24089 4.14104 5.34084 4.08504C5.4408 4.02905 5.55349 3.99976 5.66805 4H15.0014C15.1171 4.00002 15.2308 4.03015 15.3313 4.08743C15.4318 4.1447 15.5157 4.22715 15.5747 4.32667C15.6332 4.42801 15.664 4.54298 15.664 4.66C15.664 4.77703 15.6332 4.89199 15.5747 4.99333L12.2414 11.1333V15.3333C12.2423 15.4576 12.2084 15.5796 12.1436 15.6856C12.0788 15.7916 11.9857 15.8774 11.8747 15.9333C11.7894 15.9747 11.6962 15.9975 11.6014 16Z"/></g></svg>
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.6 2.40002C4.48366 2.40002 5.2 3.11637 5.2 4.00002C5.2 4.88368 4.48366 5.60002 3.6 5.60002C2.71634 5.60002 2 4.88368 2 4.00002C2 3.11637 2.71634 2.40002 3.6 2.40002ZM6.12187 4C6.12187 3.64281 6 3.28 6 3.28H14V4.72L6 4.7144C6 4.7144 6.12187 4.3572 6.12187 4ZM10 7.28C10 7.28 9.87813 7.64281 9.87813 8C9.87813 8.3572 10 8.7144 10 8.7144L2 8.72001V7.28H10ZM12.4 6.40002C11.5163 6.40002 10.8 7.11637 10.8 8.00002C10.8 8.88368 11.5163 9.60002 12.4 9.60002C13.2837 9.60002 14 8.88368 14 8.00002C14 7.11637 13.2837 6.40002 12.4 6.40002ZM6 11.28C6 11.28 6.12187 11.6428 6.12187 12C6.12187 12.3572 6 12.7144 6 12.7144L14 12.72V11.28H6ZM3.6 10.4C4.48366 10.4 5.2 11.1164 5.2 12C5.2 12.8837 4.48366 13.6 3.6 13.6C2.71634 13.6 2 12.8837 2 12C2 11.1164 2.71634 10.4 3.6 10.4Z" fill="#A9A7A7"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 860 B After Width: | Height: | Size: 935 B |
|
|
@ -26,7 +26,7 @@ type Props = {
|
|||
};
|
||||
|
||||
const AppCommentsHeader = withTheme(
|
||||
({ onClose, isOpen, setIsOpen, theme }: Props) => {
|
||||
({ isOpen, onClose, setIsOpen, theme }: Props) => {
|
||||
const showCommentThreads = useCallback(() => {
|
||||
if (!isOpen) setIsOpen(true);
|
||||
}, [isOpen]);
|
||||
|
|
|
|||
|
|
@ -91,10 +91,10 @@ const useSelectCommentUsingQuery = (commentId: string) => {
|
|||
|
||||
function CommentCard({
|
||||
comment,
|
||||
isParentComment,
|
||||
toggleResolved,
|
||||
resolved,
|
||||
commentThreadId,
|
||||
isParentComment,
|
||||
resolved,
|
||||
toggleResolved,
|
||||
}: {
|
||||
comment: Comment;
|
||||
isParentComment?: boolean;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ type Props = {
|
|||
deleteComment: typeof noop;
|
||||
};
|
||||
|
||||
function CommentContextMenu({ pin, copyCommentLink, deleteComment }: Props) {
|
||||
function CommentContextMenu({ copyCommentLink, deleteComment, pin }: Props) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const options = useMemo(
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ const useSelectCommentThreadUsingQuery = (commentThreadId: string) => {
|
|||
const InlineCommentPin = withTheme(
|
||||
({ commentThreadId, theme }: { commentThreadId: string; theme: Theme }) => {
|
||||
const commentThread = useSelector(commentThreadsSelector(commentThreadId));
|
||||
const { top, left } = get(commentThread, "position", {
|
||||
const { left, top } = get(commentThread, "position", {
|
||||
top: 0,
|
||||
left: 0,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ const CommentTriggerContainer = styled.div<{ top: number; left: number }>`
|
|||
// TODO look into drying this up using comment thread component
|
||||
const UnpublishedCommentThread = withTheme(
|
||||
({
|
||||
theme,
|
||||
commentThread,
|
||||
theme,
|
||||
}: {
|
||||
commentThread: CommentThread;
|
||||
theme: Theme;
|
||||
}) => {
|
||||
const { top, left } = get(commentThread, "position", {
|
||||
const { left, top } = get(commentThread, "position", {
|
||||
top: 0,
|
||||
left: 0,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ describe("Comment threads", () => {
|
|||
});
|
||||
|
||||
it("can be created", async (done) => {
|
||||
const { getByDataCy, getAllByDataCy, findByDataCy, findByText } = render(
|
||||
const { findByDataCy, findByText, getAllByDataCy, getByDataCy } = render(
|
||||
<OverlayCommentsWrapper refId="0">
|
||||
<div style={{ height: 100, width: 100 }} />
|
||||
</OverlayCommentsWrapper>,
|
||||
|
|
@ -87,7 +87,7 @@ describe("Comment threads", () => {
|
|||
done();
|
||||
});
|
||||
it("accept replies", async (done) => {
|
||||
const { getByDataCy, findByText, findByDataCy } = render(
|
||||
const { findByDataCy, findByText, getByDataCy } = render(
|
||||
<OverlayCommentsWrapper refId="0">
|
||||
<div style={{ height: 100, width: 100 }} />
|
||||
</OverlayCommentsWrapper>,
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ function TextLoadingState({ text }: { text?: string }) {
|
|||
return <VisibilityWrapper>{text}</VisibilityWrapper>;
|
||||
}
|
||||
|
||||
function IconLoadingState({ size, icon }: { size?: Size; icon?: IconName }) {
|
||||
function IconLoadingState({ icon, size }: { size?: Size; icon?: IconName }) {
|
||||
return <Icon invisible name={icon} size={IconSizeProp(size)} />;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const updateSpringStyles = (
|
|||
// Styles when items are dragged/idle
|
||||
const dragIdleSpringStyles = (
|
||||
order: Array<number>,
|
||||
{ down, originalIndex, curIndex, y, itemHeight }: SpringStyleProps,
|
||||
{ curIndex, down, itemHeight, originalIndex, y }: SpringStyleProps,
|
||||
) => (index: number) => {
|
||||
// picked/dragged item style
|
||||
if (down && index === originalIndex) {
|
||||
|
|
@ -59,7 +59,7 @@ const DraggableListWrapper = styled.div`
|
|||
}
|
||||
`;
|
||||
|
||||
function DraggableList({ items, ItemRenderer, onUpdate, itemHeight }: any) {
|
||||
function DraggableList({ itemHeight, ItemRenderer, items, onUpdate }: any) {
|
||||
// order of items in the list
|
||||
const order = useRef<any>(items.map((_: any, index: any) => index));
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ function DraggableList({ items, ItemRenderer, onUpdate, itemHeight }: any) {
|
|||
}}
|
||||
style={{ height: items.length * itemHeight }}
|
||||
>
|
||||
{springs.map(({ zIndex, y, scale }, i) => (
|
||||
{springs.map(({ scale, y, zIndex }, i) => (
|
||||
<animated.div
|
||||
{...bind(i)}
|
||||
data-rbd-draggable-id={items[i].id}
|
||||
|
|
|
|||
|
|
@ -45,15 +45,15 @@ export class DroppableComponent extends React.Component<
|
|||
|
||||
render() {
|
||||
const {
|
||||
renderComponent,
|
||||
deleteOption,
|
||||
updateOption,
|
||||
toggleVisibility,
|
||||
onEdit,
|
||||
renderComponent,
|
||||
toggleVisibility,
|
||||
updateOption,
|
||||
} = this.props;
|
||||
return (
|
||||
<DraggableList
|
||||
ItemRenderer={({ item, index }: any) =>
|
||||
ItemRenderer={({ index, item }: any) =>
|
||||
renderComponent({
|
||||
deleteOption,
|
||||
updateOption,
|
||||
|
|
|
|||
|
|
@ -154,11 +154,11 @@ const IconWrapper = styled.div`
|
|||
|
||||
export function EditableText(props: EditableTextProps) {
|
||||
const {
|
||||
onBlur,
|
||||
onTextChanged,
|
||||
isInvalid: inputValidation,
|
||||
defaultValue,
|
||||
isEditingDefault,
|
||||
isInvalid: inputValidation,
|
||||
onBlur,
|
||||
onTextChanged,
|
||||
valueTransform,
|
||||
} = props;
|
||||
const [isEditing, setIsEditing] = useState(!!isEditingDefault);
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import { Theme } from "constants/DefaultTheme";
|
|||
// TODO remove: (trigger tests)
|
||||
const EmojiPicker = withTheme(
|
||||
({
|
||||
theme,
|
||||
onSelectEmoji,
|
||||
theme,
|
||||
}: {
|
||||
theme: Theme;
|
||||
onSelectEmoji: (e: React.MouseEvent, emojiObject: IEmojiData) => void;
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ type Props = {
|
|||
};
|
||||
|
||||
function MentionsInput({
|
||||
onSubmit,
|
||||
suggestions,
|
||||
onSearchSuggestions,
|
||||
editorState,
|
||||
setEditorState,
|
||||
autoFocus,
|
||||
editorState,
|
||||
onSearchSuggestions,
|
||||
onSubmit,
|
||||
placeholder,
|
||||
setEditorState,
|
||||
suggestions,
|
||||
}: Props) {
|
||||
const ref = useRef<Editor | null>(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ interface Props {
|
|||
mode?: "DARK" | "LIGHT";
|
||||
}
|
||||
function ScrollIndicator({
|
||||
containerRef,
|
||||
top,
|
||||
bottom,
|
||||
right,
|
||||
alwaysShowScrollbar,
|
||||
bottom,
|
||||
containerRef,
|
||||
right,
|
||||
top,
|
||||
}: Props) {
|
||||
const [{ thumbPosition }, setThumbPosition] = useSpring<{
|
||||
thumbPosition: number;
|
||||
|
|
|
|||
|
|
@ -93,14 +93,14 @@ interface TableProps {
|
|||
}
|
||||
|
||||
function Table(props: TableProps) {
|
||||
const { data, columns } = props;
|
||||
const { columns, data } = props;
|
||||
|
||||
const {
|
||||
getTableProps,
|
||||
getTableBodyProps,
|
||||
getTableProps,
|
||||
headerGroups,
|
||||
rows,
|
||||
prepareRow,
|
||||
rows,
|
||||
} = useTable({ columns, data }, useSortBy);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ const boxStyles = (
|
|||
const StyledInput = styled((props) => {
|
||||
// we are removing non input related props before passing them in the components
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { inputStyle, inputRef, dataType, theme, ...inputProps } = props;
|
||||
const { dataType, inputRef, inputStyle, theme, ...inputProps } = props;
|
||||
return props.asyncControl ? (
|
||||
<AsyncControllableInput
|
||||
{...inputProps}
|
||||
|
|
|
|||
|
|
@ -137,13 +137,13 @@ function getSelectedOption(
|
|||
|
||||
export default function TreeDropdown(props: TreeDropdownProps) {
|
||||
const {
|
||||
selectedValue,
|
||||
defaultText,
|
||||
optionTree,
|
||||
onSelect,
|
||||
getDefaults,
|
||||
selectedLabelModifier,
|
||||
displayValue,
|
||||
getDefaults,
|
||||
onSelect,
|
||||
optionTree,
|
||||
selectedLabelModifier,
|
||||
selectedValue,
|
||||
toggle,
|
||||
} = props;
|
||||
const selectedOption = getSelectedOption(
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class ChartComponent extends React.Component<ChartComponentProps> {
|
|||
chartInstance = new FusionCharts();
|
||||
|
||||
getChartType = () => {
|
||||
const { chartType, allowHorizontalScroll, chartData } = this.props;
|
||||
const { allowHorizontalScroll, chartData, chartType } = this.props;
|
||||
const dataLength = Object.keys(chartData).length;
|
||||
const isMSChart = dataLength > 1;
|
||||
switch (chartType) {
|
||||
|
|
|
|||
|
|
@ -77,14 +77,14 @@ const selectStyles = {
|
|||
class CreatableDropdown extends React.Component<DropdownProps> {
|
||||
render() {
|
||||
const {
|
||||
placeholder,
|
||||
options,
|
||||
isLoading,
|
||||
input,
|
||||
noOptionsMessage,
|
||||
components,
|
||||
input,
|
||||
inputValue,
|
||||
isLoading,
|
||||
noOptionsMessage,
|
||||
onInputChange,
|
||||
options,
|
||||
placeholder,
|
||||
} = this.props;
|
||||
const optionalProps: Partial<DropdownProps> = {};
|
||||
if (noOptionsMessage) optionalProps.noOptionsMessage = noOptionsMessage;
|
||||
|
|
|
|||
|
|
@ -81,16 +81,16 @@ export class DroppableComponent extends React.Component<
|
|||
|
||||
render() {
|
||||
const {
|
||||
renderComponent,
|
||||
deleteOption,
|
||||
updateOption,
|
||||
toggleVisibility,
|
||||
onEdit,
|
||||
renderComponent,
|
||||
toggleVisibility,
|
||||
updateOption,
|
||||
} = this.props;
|
||||
return (
|
||||
<DragDropContext onDragEnd={this.onDragEnd}>
|
||||
<Droppable droppableId="droppable">
|
||||
{({ innerRef, droppableProps, placeholder }) => (
|
||||
{({ droppableProps, innerRef, placeholder }) => (
|
||||
<DroppableWrapper
|
||||
ref={innerRef as React.Ref<HTMLDivElement>}
|
||||
{...droppableProps}
|
||||
|
|
@ -103,7 +103,7 @@ export class DroppableComponent extends React.Component<
|
|||
index={index}
|
||||
key={item.id}
|
||||
>
|
||||
{({ innerRef, draggableProps, dragHandleProps }) => (
|
||||
{({ draggableProps, dragHandleProps, innerRef }) => (
|
||||
<ItemWrapper
|
||||
ref={innerRef as React.Ref<HTMLDivElement>}
|
||||
{...draggableProps}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ const selectStyles = {
|
|||
};
|
||||
|
||||
export function BaseDropdown(props: DropdownProps) {
|
||||
const { input, customSelectStyles } = props;
|
||||
const { customSelectStyles, input } = props;
|
||||
return (
|
||||
<Select
|
||||
menuPortalTarget={document.body}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import React, { CSSProperties, ReactNode, useMemo } from "react";
|
||||
import React, { CSSProperties, ReactNode, useCallback, useMemo } from "react";
|
||||
import { BaseStyle } from "widgets/BaseWidget";
|
||||
import { WIDGET_PADDING } from "constants/WidgetConstants";
|
||||
import { generateClassName } from "utils/generators";
|
||||
import styled from "styled-components";
|
||||
import { useClickOpenPropPane } from "utils/hooks/useClickOpenPropPane";
|
||||
import { stopEventPropagation } from "utils/AppsmithUtils";
|
||||
import { Layers } from "constants/Layers";
|
||||
|
||||
const PositionedWidget = styled.div`
|
||||
&:hover {
|
||||
|
|
@ -42,14 +44,24 @@ export function PositionedContainer(props: PositionedContainerProps) {
|
|||
height: props.style.componentHeight + (props.style.heightUnit || "px"),
|
||||
width: props.style.componentWidth + (props.style.widthUnit || "px"),
|
||||
padding: padding + "px",
|
||||
zIndex: Layers.positionedWidget,
|
||||
backgroundColor: "inherit",
|
||||
};
|
||||
}, [props.style]);
|
||||
|
||||
const openPropPane = useCallback((e) => openPropertyPane(e, props.widgetId), [
|
||||
props.widgetId,
|
||||
openPropertyPane,
|
||||
]);
|
||||
|
||||
return (
|
||||
<PositionedWidget
|
||||
className={containerClassName}
|
||||
data-testid="test-widget"
|
||||
id={props.widgetId}
|
||||
onClickCapture={openPropertyPane}
|
||||
onClick={stopEventPropagation}
|
||||
// Positioned Widget is the top enclosure for all widgets and clicks on/inside the widget should not be propogated/bubbled out of this Container.
|
||||
onClickCapture={openPropPane}
|
||||
//Before you remove: This is used by property pane to reference the element
|
||||
style={containerStyle}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React from "react";
|
|||
import styled from "styled-components";
|
||||
import { InputGroup } from "@blueprintjs/core";
|
||||
import { debounce } from "lodash";
|
||||
import { Colors } from "constants/Colors";
|
||||
|
||||
interface SearchProps {
|
||||
onSearch: (value: any) => void;
|
||||
|
|
@ -13,9 +14,12 @@ const SearchInputWrapper = styled(InputGroup)`
|
|||
&&& input {
|
||||
box-shadow: none;
|
||||
font-size: 12px;
|
||||
color: ${Colors.SILVER_CHALICE};
|
||||
}
|
||||
&&& svg {
|
||||
opacity: 0.6;
|
||||
path {
|
||||
fill: ${Colors.SILVER_CHALICE};
|
||||
}
|
||||
}
|
||||
margin: 5px 16px;
|
||||
width: 250px;
|
||||
|
|
@ -52,6 +56,7 @@ class SearchComponent extends React.Component<
|
|||
render() {
|
||||
return (
|
||||
<SearchInputWrapper
|
||||
className="t--search-input"
|
||||
leftIcon="search"
|
||||
onChange={this.handleSearch}
|
||||
placeholder={this.props.placeholder}
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ function CascadeField(props: CascadeFieldProps) {
|
|||
}
|
||||
|
||||
function Fields(props: CascadeFieldProps & { state: CascadeFieldState }) {
|
||||
const { index, removeFilter, applyFilter, hasAnyFilters } = props;
|
||||
const { applyFilter, hasAnyFilters, index, removeFilter } = props;
|
||||
const [state, dispatch] = React.useReducer(CaseCaseFieldReducer, props.state);
|
||||
const handleRemoveFilter = () => {
|
||||
dispatch({ type: CascadeFieldActionTypes.DELETE_FILTER });
|
||||
|
|
@ -470,16 +470,16 @@ function Fields(props: CascadeFieldProps & { state: CascadeFieldState }) {
|
|||
};
|
||||
|
||||
const {
|
||||
operator,
|
||||
column,
|
||||
condition,
|
||||
showConditions,
|
||||
value,
|
||||
showInput,
|
||||
showDateInput,
|
||||
conditions,
|
||||
isDeleted,
|
||||
isUpdate,
|
||||
operator,
|
||||
showConditions,
|
||||
showDateInput,
|
||||
showInput,
|
||||
value,
|
||||
} = state;
|
||||
useEffect(() => {
|
||||
if (!isDeleted && isUpdate) {
|
||||
|
|
|
|||
|
|
@ -111,12 +111,12 @@ export function Table(props: TableProps) {
|
|||
const pageCount = Math.ceil(props.data.length / props.pageSize);
|
||||
const currentPageIndex = props.pageNo < pageCount ? props.pageNo : 0;
|
||||
const {
|
||||
getTableProps,
|
||||
getTableBodyProps,
|
||||
getTableProps,
|
||||
headerGroups,
|
||||
prepareRow,
|
||||
page,
|
||||
pageOptions,
|
||||
prepareRow,
|
||||
state,
|
||||
} = useTable(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
import React, { useCallback } from "react";
|
||||
import { IconWrapper } from "constants/IconConstants";
|
||||
import { Colors } from "constants/Colors";
|
||||
import styled from "styled-components";
|
||||
|
||||
interface TableActionProps {
|
||||
selected: boolean;
|
||||
selectMenu: (selected: boolean) => void;
|
||||
className: string;
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const TableIconWrapper = styled.div<{
|
||||
selected?: boolean;
|
||||
disabled?: boolean;
|
||||
}>`
|
||||
background: ${(props) => (props.selected ? Colors.Gallery : "transparent")};
|
||||
height: 38px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: ${(props) => (props.disabled ? 0.6 : 1)};
|
||||
cursor: ${(props) => !props.disabled && "pointer"};
|
||||
color: ${(props) => (props.selected ? Colors.CODE_GRAY : Colors.GRAY)};
|
||||
.action-title {
|
||||
margin-left: 4px;
|
||||
}
|
||||
position: relative;
|
||||
margin-left: 5px;
|
||||
padding: 0 5px;
|
||||
&:hover {
|
||||
background: ${Colors.ATHENS_GRAY};
|
||||
}
|
||||
`;
|
||||
|
||||
function TableAction(props: TableActionProps) {
|
||||
const handleIconClick = useCallback(
|
||||
(e: React.MouseEvent<HTMLElement>) => {
|
||||
props.selectMenu(!props.selected);
|
||||
e.stopPropagation();
|
||||
},
|
||||
[props.selected],
|
||||
);
|
||||
return (
|
||||
<TableIconWrapper
|
||||
className={props.className}
|
||||
onClick={handleIconClick}
|
||||
selected={props.selected}
|
||||
>
|
||||
<IconWrapper
|
||||
color={props.selected ? Colors.CODE_GRAY : Colors.GRAY}
|
||||
height={20}
|
||||
width={20}
|
||||
>
|
||||
{props.children}
|
||||
</IconWrapper>
|
||||
<span className="action-title">{props.title}</span>
|
||||
</TableIconWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export default TableAction;
|
||||
|
|
@ -34,13 +34,12 @@ function TableActionIcon(props: TableActionIconProps) {
|
|||
selected={props.selected}
|
||||
>
|
||||
<IconWrapper
|
||||
color={props.selected ? Colors.OXFORD_BLUE : Colors.CADET_BLUE}
|
||||
color={props.selected ? Colors.CODE_GRAY : Colors.GRAY}
|
||||
height={20}
|
||||
width={20}
|
||||
>
|
||||
{props.children}
|
||||
</IconWrapper>
|
||||
{props.icon ? props.icon : null}
|
||||
</TableIconWrapper>
|
||||
</Tooltip>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,84 @@
|
|||
import React from "react";
|
||||
import {
|
||||
Popover,
|
||||
Classes,
|
||||
PopoverInteractionKind,
|
||||
Position,
|
||||
} from "@blueprintjs/core";
|
||||
import { IconWrapper } from "constants/IconConstants";
|
||||
import { Colors } from "constants/Colors";
|
||||
import { ReactComponent as DownloadIcon } from "assets/icons/control/download-table.svg";
|
||||
import { ReactComponent as DownloadIcon } from "assets/icons/control/download-data-icon.svg";
|
||||
import { ReactTableColumnProps } from "components/designSystems/appsmith/TableComponent/Constants";
|
||||
import { TableIconWrapper } from "components/designSystems/appsmith/TableComponent/TableStyledWrappers";
|
||||
import TableActionIcon from "components/designSystems/appsmith/TableComponent/TableActionIcon";
|
||||
import TableAction, {
|
||||
TableIconWrapper,
|
||||
} from "components/designSystems/appsmith/TableComponent/TableAction";
|
||||
import styled from "styled-components";
|
||||
import { transformTableDataIntoCsv } from "./CommonUtilities";
|
||||
import zipcelx from "zipcelx";
|
||||
|
||||
const DropDownWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: white;
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 12px 28px -8px rgba(0, 0, 0, 0.1);
|
||||
padding: 0;
|
||||
`;
|
||||
|
||||
const OptionWrapper = styled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 32px;
|
||||
box-sizing: border-box;
|
||||
padding: 6px 12px;
|
||||
color: ${Colors.CHARCOAL};
|
||||
min-width: 200px;
|
||||
cursor: pointer;
|
||||
background: ${Colors.WHITE};
|
||||
border-left: none;
|
||||
border-radius: none;
|
||||
.option-title {
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
}
|
||||
&:hover {
|
||||
background: ${Colors.SEA_SHELL};
|
||||
color: ${Colors.CODE_GRAY};
|
||||
}
|
||||
`;
|
||||
interface TableDataDownloadProps {
|
||||
data: Array<Record<string, unknown>>;
|
||||
columns: ReactTableColumnProps[];
|
||||
widgetName: string;
|
||||
}
|
||||
|
||||
type FileDownloadType = "CSV" | "EXCEL";
|
||||
|
||||
type DataCellProps = {
|
||||
value: string | number;
|
||||
type: "string" | "number";
|
||||
};
|
||||
|
||||
interface DownloadOptionProps {
|
||||
label: string;
|
||||
value: FileDownloadType;
|
||||
}
|
||||
|
||||
const dowloadOptions: DownloadOptionProps[] = [
|
||||
{
|
||||
label: "Download as CSV",
|
||||
value: "CSV",
|
||||
},
|
||||
{
|
||||
label: "Download as Excel",
|
||||
value: "EXCEL",
|
||||
},
|
||||
];
|
||||
|
||||
const downloadDataAsCSV = (props: {
|
||||
csvData: Array<Array<any>>;
|
||||
fileName: string;
|
||||
|
|
@ -45,9 +111,57 @@ const downloadDataAsCSV = (props: {
|
|||
};
|
||||
|
||||
function TableDataDownload(props: TableDataDownloadProps) {
|
||||
const [selected, toggleButtonClick] = React.useState(false);
|
||||
const downloadTableData = () => {
|
||||
toggleButtonClick(true);
|
||||
const [selected, selectMenu] = React.useState(false);
|
||||
const downloadFile = (type: string) => {
|
||||
if (type === "CSV") {
|
||||
downloadTableDataAsCsv();
|
||||
} else if (type === "EXCEL") {
|
||||
downloadTableDataAsExcel();
|
||||
}
|
||||
};
|
||||
const downloadTableDataAsExcel = () => {
|
||||
const tableData: Array<Array<DataCellProps>> = [];
|
||||
const tableHeaders: Array<DataCellProps> = props.columns
|
||||
.filter((column: ReactTableColumnProps) => {
|
||||
return column.metaProperties && !column.metaProperties.isHidden;
|
||||
})
|
||||
.map((column: ReactTableColumnProps) => {
|
||||
return {
|
||||
value: column.Header,
|
||||
type:
|
||||
column.columnProperties?.columnType === "number"
|
||||
? "number"
|
||||
: "string",
|
||||
};
|
||||
});
|
||||
tableData.push(tableHeaders);
|
||||
for (let row = 0; row < props.data.length; row++) {
|
||||
const data: { [key: string]: any } = props.data[row];
|
||||
const tableRow: Array<DataCellProps> = [];
|
||||
for (let colIndex = 0; colIndex < props.columns.length; colIndex++) {
|
||||
const column = props.columns[colIndex];
|
||||
const type =
|
||||
column.columnProperties?.columnType === "number"
|
||||
? "number"
|
||||
: "string";
|
||||
if (column.metaProperties && !column.metaProperties.isHidden) {
|
||||
tableRow.push({
|
||||
value: data[column.accessor],
|
||||
type: type,
|
||||
});
|
||||
}
|
||||
}
|
||||
tableData.push(tableRow);
|
||||
}
|
||||
zipcelx({
|
||||
filename: props.widgetName,
|
||||
sheet: {
|
||||
data: tableData,
|
||||
},
|
||||
});
|
||||
};
|
||||
const downloadTableDataAsCsv = () => {
|
||||
selectMenu(true);
|
||||
const csvData = transformTableDataIntoCsv({
|
||||
columns: props.columns,
|
||||
data: props.data,
|
||||
|
|
@ -56,7 +170,11 @@ function TableDataDownload(props: TableDataDownloadProps) {
|
|||
csvData: csvData,
|
||||
fileName: `${props.widgetName}.csv`,
|
||||
});
|
||||
toggleButtonClick(false);
|
||||
selectMenu(false);
|
||||
};
|
||||
|
||||
const handleCloseMenu = () => {
|
||||
selectMenu(false);
|
||||
};
|
||||
|
||||
if (props.columns.length === 0) {
|
||||
|
|
@ -65,20 +183,43 @@ function TableDataDownload(props: TableDataDownloadProps) {
|
|||
<IconWrapper color={Colors.CADET_BLUE} height={20} width={20}>
|
||||
<DownloadIcon />
|
||||
</IconWrapper>
|
||||
<span className="action-title">Download</span>
|
||||
</TableIconWrapper>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TableActionIcon
|
||||
className="t--table-download-btn"
|
||||
selectMenu={() => {
|
||||
downloadTableData();
|
||||
}}
|
||||
selected={selected}
|
||||
tooltip="Download"
|
||||
<Popover
|
||||
enforceFocus={false}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
isOpen={selected}
|
||||
minimal
|
||||
onClose={handleCloseMenu}
|
||||
position={Position.BOTTOM}
|
||||
>
|
||||
<DownloadIcon />
|
||||
</TableActionIcon>
|
||||
<TableAction
|
||||
className="t--table-download-btn"
|
||||
selectMenu={selectMenu}
|
||||
selected={selected}
|
||||
title="Download"
|
||||
>
|
||||
<DownloadIcon />
|
||||
</TableAction>
|
||||
<DropDownWrapper>
|
||||
{dowloadOptions.map((item: DownloadOptionProps, index: number) => {
|
||||
return (
|
||||
<OptionWrapper
|
||||
className={`${Classes.POPOVER_DISMISS} t--table-download-data-option`}
|
||||
key={index}
|
||||
onClick={() => {
|
||||
downloadFile(item.value);
|
||||
}}
|
||||
>
|
||||
{item.label}
|
||||
</OptionWrapper>
|
||||
);
|
||||
})}
|
||||
</DropDownWrapper>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { ReactComponent as FilterIcon } from "assets/icons/control/filter-icon.s
|
|||
import { TableIconWrapper } from "components/designSystems/appsmith/TableComponent/TableStyledWrappers";
|
||||
import Button from "components/editorComponents/Button";
|
||||
import CascadeFields from "components/designSystems/appsmith/TableComponent/CascadeFields";
|
||||
import TableActionIcon from "components/designSystems/appsmith/TableComponent/TableActionIcon";
|
||||
import TableAction from "components/designSystems/appsmith/TableComponent/TableAction";
|
||||
import {
|
||||
ReactTableColumnProps,
|
||||
Condition,
|
||||
|
|
@ -173,7 +173,7 @@ function TableFilters(props: TableFilterProps) {
|
|||
position={Position.BOTTOM}
|
||||
usePortal
|
||||
>
|
||||
<TableActionIcon
|
||||
<TableAction
|
||||
className="t--table-filter-toggle-btn"
|
||||
icon={
|
||||
hasAnyFilters ? (
|
||||
|
|
@ -184,10 +184,10 @@ function TableFilters(props: TableFilterProps) {
|
|||
selectMenu(selected);
|
||||
}}
|
||||
selected={selected}
|
||||
tooltip="Filters"
|
||||
title="Filters"
|
||||
>
|
||||
<FilterIcon />
|
||||
</TableActionIcon>
|
||||
</TableAction>
|
||||
<TableFilterOuterWrapper>
|
||||
<TableFilerWrapper onClick={(e) => e.stopPropagation()}>
|
||||
{filters.map((filter: ReactTableFilter, index: number) => {
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
|||
const PageNumberInputWrapper = styled(NumericInput)`
|
||||
&&& input {
|
||||
box-shadow: none;
|
||||
border: 1px solid ${Colors.DANUBE};
|
||||
background: linear-gradient(0deg, ${Colors.WHITE}, ${Colors.WHITE}),
|
||||
${Colors.POLAR};
|
||||
border: 1px solid ${Colors.GREEN};
|
||||
border-radius: none;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
|
|
@ -37,6 +37,9 @@ const PageNumberInputWrapper = styled(NumericInput)`
|
|||
text-align: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
&&&.bp3-control-group > :only-child {
|
||||
border-radius: 0;
|
||||
}
|
||||
margin: 0 8px;
|
||||
`;
|
||||
|
||||
|
|
@ -173,7 +176,7 @@ function TableHeader(props: TableHeaderProps) {
|
|||
props.updatePageNo(pageNo + 1, EventType.ON_PREV_PAGE);
|
||||
}}
|
||||
>
|
||||
<Icon color={Colors.HIT_GRAY} icon="chevron-left" iconSize={16} />
|
||||
<Icon color={Colors.GRAY} icon="chevron-left" iconSize={16} />
|
||||
</PaginationItemWrapper>
|
||||
<RowWrapper>
|
||||
Page{" "}
|
||||
|
|
@ -196,7 +199,7 @@ function TableHeader(props: TableHeaderProps) {
|
|||
props.updatePageNo(pageNo + 1, EventType.ON_NEXT_PAGE);
|
||||
}}
|
||||
>
|
||||
<Icon color={Colors.HIT_GRAY} icon="chevron-right" iconSize={16} />
|
||||
<Icon color={Colors.GRAY} icon="chevron-right" iconSize={16} />
|
||||
</PaginationItemWrapper>
|
||||
</PaginationWrapper>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -232,18 +232,16 @@ export const PaginationWrapper = styled.div`
|
|||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 8px 20px;
|
||||
color: ${Colors.GRAY};
|
||||
`;
|
||||
|
||||
export const PaginationItemWrapper = styled.div<{
|
||||
disabled?: boolean;
|
||||
selected?: boolean;
|
||||
}>`
|
||||
background: ${(props) =>
|
||||
props.disabled ? Colors.ATHENS_GRAY : Colors.WHITE};
|
||||
border: 1px solid
|
||||
${(props) => (props.selected ? Colors.GREEN : Colors.GEYSER_LIGHT)};
|
||||
background: ${(props) => (props.disabled ? Colors.MERCURY : Colors.WHITE)};
|
||||
border: 1px solid ${Colors.ALTO2};
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
|
|
@ -477,7 +475,7 @@ export const RowWrapper = styled.div`
|
|||
justify-content: center;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: ${Colors.THUNDER};
|
||||
color: ${Colors.GRAY};
|
||||
margin: 0 4px;
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import React, { useEffect, useMemo } from "react";
|
||||
import Table from "components/designSystems/appsmith/TableComponent/Table";
|
||||
import {
|
||||
ColumnTypes,
|
||||
CompactMode,
|
||||
ReactTableColumnProps,
|
||||
ReactTableFilter,
|
||||
} from "components/designSystems/appsmith/TableComponent/Constants";
|
||||
import Table from "components/designSystems/appsmith/TableComponent/Table";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { isEqual } from "lodash";
|
||||
import React, { useEffect, useMemo } from "react";
|
||||
|
||||
export interface ColumnMenuOptionProps {
|
||||
content: string | JSX.Element;
|
||||
|
|
@ -68,10 +69,42 @@ interface ReactTableComponentProps {
|
|||
}
|
||||
|
||||
function ReactTableComponent(props: ReactTableComponentProps) {
|
||||
const {
|
||||
applyFilter,
|
||||
columns,
|
||||
columnSizeMap,
|
||||
compactMode,
|
||||
disableDrag,
|
||||
editMode,
|
||||
filters,
|
||||
handleReorderColumn,
|
||||
handleResizeColumn,
|
||||
height,
|
||||
isLoading,
|
||||
nextPageClick,
|
||||
onRowClick,
|
||||
pageNo,
|
||||
pageSize,
|
||||
prevPageClick,
|
||||
searchKey,
|
||||
searchTableData,
|
||||
selectedRowIndex,
|
||||
selectedRowIndices,
|
||||
serverSidePaginationEnabled,
|
||||
sortTableColumn: _sortTableColumn,
|
||||
tableData,
|
||||
triggerRowSelection,
|
||||
updateCompactMode,
|
||||
updatePageNo,
|
||||
widgetId,
|
||||
widgetName,
|
||||
width,
|
||||
} = props;
|
||||
|
||||
const { columnOrder, hiddenColumns } = useMemo(() => {
|
||||
const order: string[] = [];
|
||||
const hidden: string[] = [];
|
||||
props.columns.forEach((item) => {
|
||||
columns.forEach((item) => {
|
||||
if (item.isHidden) {
|
||||
hidden.push(item.accessor);
|
||||
} else {
|
||||
|
|
@ -79,12 +112,12 @@ function ReactTableComponent(props: ReactTableComponentProps) {
|
|||
}
|
||||
});
|
||||
return { columnOrder: order, hiddenColumns: hidden };
|
||||
}, [props.columns]);
|
||||
}, [columns]);
|
||||
|
||||
useEffect(() => {
|
||||
let dragged = -1;
|
||||
const headers = Array.prototype.slice.call(
|
||||
document.querySelectorAll(`#table${props.widgetId} .draggable-header`),
|
||||
document.querySelectorAll(`#table${widgetId} .draggable-header`),
|
||||
);
|
||||
headers.forEach((header, i) => {
|
||||
header.setAttribute("draggable", true);
|
||||
|
|
@ -149,7 +182,7 @@ function ReactTableComponent(props: ReactTableComponentProps) {
|
|||
if (movedColumnName && movedColumnName.length === 1) {
|
||||
newColumnOrder.splice(i, 0, movedColumnName[0]);
|
||||
}
|
||||
props.handleReorderColumn([...newColumnOrder, ...hiddenColumns]);
|
||||
handleReorderColumn([...newColumnOrder, ...hiddenColumns]);
|
||||
} else {
|
||||
dragged = -1;
|
||||
}
|
||||
|
|
@ -159,15 +192,15 @@ function ReactTableComponent(props: ReactTableComponentProps) {
|
|||
|
||||
const sortTableColumn = (columnIndex: number, asc: boolean) => {
|
||||
if (columnIndex === -1) {
|
||||
props.sortTableColumn("", asc);
|
||||
_sortTableColumn("", asc);
|
||||
} else {
|
||||
const column = props.columns[columnIndex];
|
||||
const column = columns[columnIndex];
|
||||
const columnType = column.metaProperties?.type || ColumnTypes.TEXT;
|
||||
if (
|
||||
columnType !== ColumnTypes.IMAGE &&
|
||||
columnType !== ColumnTypes.VIDEO
|
||||
) {
|
||||
props.sortTableColumn(column.accessor, asc);
|
||||
_sortTableColumn(column.accessor, asc);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -176,50 +209,80 @@ function ReactTableComponent(props: ReactTableComponentProps) {
|
|||
original: Record<string, unknown>;
|
||||
index: number;
|
||||
}) => {
|
||||
props.onRowClick(row.original, row.index);
|
||||
onRowClick(row.original, row.index);
|
||||
};
|
||||
|
||||
return (
|
||||
<Table
|
||||
applyFilter={props.applyFilter}
|
||||
columnSizeMap={props.columnSizeMap}
|
||||
columns={props.columns}
|
||||
compactMode={props.compactMode}
|
||||
data={props.tableData}
|
||||
applyFilter={applyFilter}
|
||||
columnSizeMap={columnSizeMap}
|
||||
columns={columns}
|
||||
compactMode={compactMode}
|
||||
data={tableData}
|
||||
disableDrag={() => {
|
||||
props.disableDrag(true);
|
||||
disableDrag(true);
|
||||
}}
|
||||
editMode={props.editMode}
|
||||
editMode={editMode}
|
||||
enableDrag={() => {
|
||||
props.disableDrag(false);
|
||||
disableDrag(false);
|
||||
}}
|
||||
filters={props.filters}
|
||||
handleResizeColumn={props.handleResizeColumn}
|
||||
height={props.height}
|
||||
isLoading={props.isLoading}
|
||||
nextPageClick={() => {
|
||||
props.nextPageClick();
|
||||
}}
|
||||
pageNo={props.pageNo - 1}
|
||||
pageSize={props.pageSize || 1}
|
||||
prevPageClick={() => {
|
||||
props.prevPageClick();
|
||||
}}
|
||||
searchKey={props.searchKey}
|
||||
searchTableData={props.searchTableData}
|
||||
filters={filters}
|
||||
handleResizeColumn={handleResizeColumn}
|
||||
height={height}
|
||||
isLoading={isLoading}
|
||||
nextPageClick={nextPageClick}
|
||||
pageNo={pageNo - 1}
|
||||
pageSize={pageSize || 1}
|
||||
prevPageClick={prevPageClick}
|
||||
searchKey={searchKey}
|
||||
searchTableData={searchTableData}
|
||||
selectTableRow={selectTableRow}
|
||||
selectedRowIndex={props.selectedRowIndex}
|
||||
selectedRowIndices={props.selectedRowIndices}
|
||||
serverSidePaginationEnabled={props.serverSidePaginationEnabled}
|
||||
selectedRowIndex={selectedRowIndex}
|
||||
selectedRowIndices={selectedRowIndices}
|
||||
serverSidePaginationEnabled={serverSidePaginationEnabled}
|
||||
sortTableColumn={sortTableColumn}
|
||||
triggerRowSelection={props.triggerRowSelection}
|
||||
updateCompactMode={props.updateCompactMode}
|
||||
updatePageNo={props.updatePageNo}
|
||||
widgetId={props.widgetId}
|
||||
widgetName={props.widgetName}
|
||||
width={props.width}
|
||||
triggerRowSelection={triggerRowSelection}
|
||||
updateCompactMode={updateCompactMode}
|
||||
updatePageNo={updatePageNo}
|
||||
widgetId={widgetId}
|
||||
widgetName={widgetName}
|
||||
width={width}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default ReactTableComponent;
|
||||
export default React.memo(ReactTableComponent, (prev, next) => {
|
||||
return (
|
||||
prev.applyFilter === next.applyFilter &&
|
||||
prev.compactMode === next.compactMode &&
|
||||
prev.disableDrag === next.disableDrag &&
|
||||
prev.editMode === next.editMode &&
|
||||
prev.filters === next.filters &&
|
||||
prev.handleReorderColumn === next.handleReorderColumn &&
|
||||
prev.handleResizeColumn === next.handleResizeColumn &&
|
||||
prev.height === next.height &&
|
||||
prev.isLoading === next.isLoading &&
|
||||
prev.nextPageClick === next.nextPageClick &&
|
||||
prev.onRowClick === next.onRowClick &&
|
||||
prev.pageNo === next.pageNo &&
|
||||
prev.pageSize === next.pageSize &&
|
||||
prev.prevPageClick === next.prevPageClick &&
|
||||
prev.searchKey === next.searchKey &&
|
||||
prev.searchTableData === next.searchTableData &&
|
||||
prev.selectedRowIndex === next.selectedRowIndex &&
|
||||
prev.selectedRowIndices === next.selectedRowIndices &&
|
||||
prev.serverSidePaginationEnabled === next.serverSidePaginationEnabled &&
|
||||
prev.sortTableColumn === next.sortTableColumn &&
|
||||
prev.triggerRowSelection === next.triggerRowSelection &&
|
||||
prev.updateCompactMode === next.updateCompactMode &&
|
||||
prev.updatePageNo === next.updatePageNo &&
|
||||
prev.widgetId === next.widgetId &&
|
||||
prev.widgetName === next.widgetName &&
|
||||
prev.width === next.width &&
|
||||
isEqual(prev.columnSizeMap, next.columnSizeMap) &&
|
||||
isEqual(prev.tableData, next.tableData) &&
|
||||
// Using JSON stringify becuase isEqual doesnt work with functions,
|
||||
// and we are not changing the columns manually.
|
||||
JSON.stringify(prev.columns) === JSON.stringify(next.columns)
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const TabsContainerWrapper = styled.div<{
|
|||
`;
|
||||
|
||||
const ChildrenWrapper = styled.div`
|
||||
height: 100%;
|
||||
height: calc(100% - 40px);
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background: ${(props) => props.theme.colors.builderBodyBG};
|
||||
|
|
|
|||
|
|
@ -109,11 +109,11 @@ export class BaseTextInput extends Component<TextInputProps, TextInputState> {
|
|||
};
|
||||
render() {
|
||||
const {
|
||||
className,
|
||||
input,
|
||||
meta,
|
||||
showError,
|
||||
className,
|
||||
refHandler,
|
||||
showError,
|
||||
...rest
|
||||
} = this.props;
|
||||
const hasError = !!(
|
||||
|
|
|
|||
|
|
@ -29,18 +29,18 @@ const Error = styled.span``;
|
|||
|
||||
export default function VideoComponent(props: VideoComponentProps) {
|
||||
const {
|
||||
url,
|
||||
autoplay,
|
||||
controls,
|
||||
onStart,
|
||||
onPlay,
|
||||
onPause,
|
||||
onEnded,
|
||||
onReady,
|
||||
onProgress,
|
||||
onSeek,
|
||||
onError,
|
||||
onPause,
|
||||
onPlay,
|
||||
onProgress,
|
||||
onReady,
|
||||
onSeek,
|
||||
onStart,
|
||||
player,
|
||||
url,
|
||||
} = props;
|
||||
return url ? (
|
||||
<ReactPlayer
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ const StyledMultiDropDown = styled(MultiDropDown)<{
|
|||
|
||||
class DropDownComponent extends React.Component<DropDownComponentProps> {
|
||||
render() {
|
||||
const { selectedIndexArr, options } = this.props;
|
||||
const { options, selectedIndexArr } = this.props;
|
||||
const selectedItems = selectedIndexArr
|
||||
? _.map(selectedIndexArr, (index) => options[index])
|
||||
: [];
|
||||
|
|
@ -259,7 +259,7 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
|
|||
<StyledSingleDropDown
|
||||
className={this.props.isLoading ? Classes.SKELETON : ""}
|
||||
disabled={this.props.disabled}
|
||||
filterable
|
||||
filterable={this.props.isFilterable}
|
||||
itemListPredicate={this.itemListPredicate}
|
||||
itemRenderer={this.renderSingleSelectItem}
|
||||
items={this.props.options}
|
||||
|
|
@ -267,6 +267,11 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
|
|||
popoverProps={{
|
||||
minimal: true,
|
||||
usePortal: true,
|
||||
modifiers: {
|
||||
preventOverflow: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
popoverClassName: "select-popover-wrapper",
|
||||
}}
|
||||
>
|
||||
|
|
@ -294,6 +299,11 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
|
|||
popoverProps={{
|
||||
minimal: true,
|
||||
usePortal: true,
|
||||
modifiers: {
|
||||
preventOverflow: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
popoverClassName: "select-popover-wrapper",
|
||||
}}
|
||||
resetOnSelect
|
||||
|
|
@ -412,6 +422,7 @@ export interface DropDownComponentProps extends ComponentProps {
|
|||
selectedIndexArr: number[];
|
||||
options: DropdownOption[];
|
||||
isLoading: boolean;
|
||||
isFilterable: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React, { ReactNode, RefObject, useRef, useEffect } from "react";
|
|||
import { Overlay, Classes } from "@blueprintjs/core";
|
||||
import styled from "styled-components";
|
||||
import { getCanvasClassName } from "utils/generators";
|
||||
import { Layers } from "constants/Layers";
|
||||
|
||||
const Container = styled.div<{
|
||||
width: number;
|
||||
|
|
@ -80,7 +81,7 @@ export function ModalComponent(props: ModalComponentProps) {
|
|||
left={props.left}
|
||||
top={props.top}
|
||||
width={props.width}
|
||||
zIndex={props.zIndex !== undefined ? props.zIndex : 2}
|
||||
zIndex={props.zIndex !== undefined ? props.zIndex : Layers.modalWidget}
|
||||
>
|
||||
<Overlay
|
||||
canEscapeKeyClose={props.canEscapeKeyClose}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ const SwitchComponentContainer = styled.div`
|
|||
`;
|
||||
|
||||
export function SwitchComponent({
|
||||
label,
|
||||
isSwitchedOn,
|
||||
alignWidget,
|
||||
onChange,
|
||||
isDisabled,
|
||||
isLoading,
|
||||
isSwitchedOn,
|
||||
label,
|
||||
onChange,
|
||||
}: SwitchComponentProps) {
|
||||
const switchAlignClass =
|
||||
alignWidget === "RIGHT" ? Alignment.RIGHT : Alignment.LEFT;
|
||||
|
|
|
|||
|
|
@ -76,13 +76,13 @@ export interface TextComponentProps extends ComponentProps {
|
|||
class TextComponent extends React.Component<TextComponentProps> {
|
||||
render() {
|
||||
const {
|
||||
text,
|
||||
ellipsize,
|
||||
textAlign,
|
||||
fontStyle,
|
||||
fontSize,
|
||||
textColor,
|
||||
backgroundColor,
|
||||
ellipsize,
|
||||
fontSize,
|
||||
fontStyle,
|
||||
text,
|
||||
textAlign,
|
||||
textColor,
|
||||
} = this.props;
|
||||
return (
|
||||
<TextContainer>
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ export const modalGetter = (value: string) => {
|
|||
};
|
||||
|
||||
export const stringToJS = (string: string): string => {
|
||||
const { stringSegments, jsSnippets } = getDynamicBindings(string);
|
||||
const { jsSnippets, stringSegments } = getDynamicBindings(string);
|
||||
const js = stringSegments
|
||||
.map((segment, index) => {
|
||||
if (jsSnippets[index] && jsSnippets[index].length > 0) {
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ type PreparedStatementValue = {
|
|||
export function PreparedStatementViewer(props: {
|
||||
evaluatedValue: PreparedStatementValue;
|
||||
}) {
|
||||
const { value, parameters } = props.evaluatedValue;
|
||||
const { parameters, value } = props.evaluatedValue;
|
||||
const stringSegments = value.split(/\$\d/);
|
||||
const $params = [...value.matchAll(/\$\d/g)].map((matches) => matches[0]);
|
||||
const paramsWithTooltips = $params.map((param) => (
|
||||
|
|
|
|||
|
|
@ -337,26 +337,26 @@ class CodeEditor extends Component<Props, State> {
|
|||
|
||||
render() {
|
||||
const {
|
||||
border,
|
||||
borderLess,
|
||||
className,
|
||||
dataTreePath,
|
||||
disabled,
|
||||
dynamicData,
|
||||
evaluatedValue,
|
||||
evaluationSubstitutionType,
|
||||
expected,
|
||||
fill,
|
||||
height,
|
||||
hideEvaluatedValue,
|
||||
hoverInteraction,
|
||||
input,
|
||||
meta,
|
||||
theme,
|
||||
disabled,
|
||||
className,
|
||||
placeholder,
|
||||
showLightningMenu,
|
||||
dataTreePath,
|
||||
dynamicData,
|
||||
expected,
|
||||
size,
|
||||
evaluatedValue,
|
||||
height,
|
||||
borderLess,
|
||||
border,
|
||||
hoverInteraction,
|
||||
fill,
|
||||
theme,
|
||||
useValidationMessage,
|
||||
hideEvaluatedValue,
|
||||
evaluationSubstitutionType,
|
||||
} = this.props;
|
||||
const hasError = !!(meta && meta.error);
|
||||
let evaluated = evaluatedValue;
|
||||
|
|
|
|||
|
|
@ -422,20 +422,13 @@ export const DynamicAutocompleteInputWrapper = styled.div<{
|
|||
height: 100%;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
border-color: ${(props) =>
|
||||
!props.isError && props.isActive && props.skin === Skin.DARK
|
||||
? Colors.ALABASTER
|
||||
: "transparent"};
|
||||
border: 1px solid ${(props) => (!props.isError ? "transparent" : "red")};
|
||||
> span:first-of-type {
|
||||
width: 30px;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
}
|
||||
&:hover {
|
||||
border-color: ${(props) =>
|
||||
!props.isError && props.skin === Skin.DARK
|
||||
? Colors.ALABASTER
|
||||
: "transparent"};
|
||||
.lightning-menu {
|
||||
background: ${(props) => (!props.isNotHover ? "#090707" : "")};
|
||||
svg {
|
||||
|
|
@ -451,7 +444,6 @@ export const DynamicAutocompleteInputWrapper = styled.div<{
|
|||
}
|
||||
}
|
||||
}
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
.lightning-menu {
|
||||
z-index: 1 !important;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ function DebbuggerLogs(props: Props) {
|
|||
const [filter, setFilter] = useState("");
|
||||
const [searchQuery, setSearchQuery] = useState(props.searchQuery);
|
||||
const filteredLogs = useFilteredLogs(searchQuery, filter);
|
||||
const { paginatedData, next } = usePagination(filteredLogs);
|
||||
const { next, paginatedData } = usePagination(filteredLogs);
|
||||
const listRef = useRef<HTMLDivElement>(null);
|
||||
const selectedFilter = useMemo(
|
||||
() => LOGS_FILTER_OPTIONS.find((option) => option.value === filter),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ function ActionLink(props: EntityLinkProps) {
|
|||
|
||||
const onClick = useCallback(() => {
|
||||
if (action) {
|
||||
const { pageId, pluginType, id } = action;
|
||||
const { id, pageId, pluginType } = action;
|
||||
const actionConfig = getActionConfig(pluginType);
|
||||
const url =
|
||||
applicationId && actionConfig?.getURL(applicationId, pageId, id);
|
||||
|
|
|
|||
|
|
@ -10,15 +10,17 @@ import { showDebugger as showDebuggerAction } from "actions/debuggerActions";
|
|||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import { Colors } from "constants/Colors";
|
||||
import { getTypographyByKey } from "constants/DefaultTheme";
|
||||
import { Layers } from "constants/Layers";
|
||||
|
||||
const Container = styled.div<{ errorCount: number }>`
|
||||
z-index: ${Layers.debugger};
|
||||
background-color: ${(props) =>
|
||||
props.theme.colors.debugger.floatingButton.background};
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
cursor: pointer;
|
||||
padding: 19px;
|
||||
padding: ${(props) => props.theme.spaces[6]}px;
|
||||
color: ${(props) => props.theme.colors.debugger.floatingButton.color};
|
||||
border-radius: 50px;
|
||||
box-shadow: ${(props) => props.theme.colors.debugger.floatingButton.shadow};
|
||||
|
|
@ -33,11 +35,9 @@ const Container = styled.div<{ errorCount: number }>`
|
|||
|
||||
.debugger-count {
|
||||
color: ${Colors.WHITE};
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
${(props) => getTypographyByKey(props, "h6")}
|
||||
height: 20px;
|
||||
padding: 6px;
|
||||
height: 16px;
|
||||
padding: ${(props) => props.theme.spaces[1]}px;
|
||||
background-color: ${(props) =>
|
||||
!!props.errorCount
|
||||
? props.theme.colors.debugger.floatingButton.errorCount
|
||||
|
|
@ -75,7 +75,7 @@ function Debugger() {
|
|||
errorCount={errorCount}
|
||||
onClick={onClick}
|
||||
>
|
||||
<Icon name="bug" size={IconSize.XXXL} />
|
||||
<Icon name="bug" size={IconSize.XL} />
|
||||
<div className="debugger-count">{errorCount}</div>
|
||||
</Container>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@ const WrappedDragLayer = styled.div<{
|
|||
);
|
||||
background-size: ${(props) => props.columnWidth}px
|
||||
${(props) => props.rowHeight}px;
|
||||
background-position: -${(props) => props.columnWidth / 2}px -${(props) =>
|
||||
props.rowHeight / 2}px;
|
||||
background-position: -${(props) => props.columnWidth / 2 - 3.5}px -${(
|
||||
props,
|
||||
) => props.rowHeight / 2 - 1.5}px;
|
||||
`;
|
||||
|
||||
type DragLayerProps = {
|
||||
|
|
@ -71,7 +72,7 @@ function DragLayerComponent(props: DragLayerProps) {
|
|||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
const { isDragging, currentOffset, widget, canDrop } = useDragLayer(
|
||||
const { canDrop, currentOffset, isDragging, widget } = useDragLayer(
|
||||
(monitor) => ({
|
||||
isDragging: monitor.isDragging(),
|
||||
currentOffset: monitor.getSourceClientOffset(),
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ function DraggableComponent(props: DraggableComponentProps) {
|
|||
const showPropertyPane = useShowPropertyPane();
|
||||
|
||||
// Dispatch hook handy to set a widget as focused/selected
|
||||
const { selectWidget, focusWidget } = useWidgetSelection();
|
||||
const { focusWidget, selectWidget } = useWidgetSelection();
|
||||
|
||||
// Dispatch hook handy to set any `DraggableComponent` as dragging/ not dragging
|
||||
// The value is boolean
|
||||
|
|
@ -68,9 +68,12 @@ function DraggableComponent(props: DraggableComponentProps) {
|
|||
// This state tells us which widget is selected
|
||||
// The value is the widgetId of the selected widget
|
||||
const selectedWidget = useSelector(
|
||||
(state: AppState) => state.ui.widgetDragResize.selectedWidget,
|
||||
(state: AppState) => state.ui.widgetDragResize.lastSelectedWidget,
|
||||
);
|
||||
|
||||
const selectedWidgets = useSelector(
|
||||
(state: AppState) => state.ui.widgetDragResize.selectedWidgets,
|
||||
);
|
||||
// This state tels us which widget is focused
|
||||
// The value is the widgetId of the focused widget.
|
||||
const focusedWidget = useSelector(
|
||||
|
|
@ -142,16 +145,6 @@ function DraggableComponent(props: DraggableComponentProps) {
|
|||
// True when any widget is dragging or resizing, including this one
|
||||
const isResizingOrDragging = !!isResizing || !!isDragging;
|
||||
|
||||
// When the draggable is clicked
|
||||
const handleClick = (e: any) => {
|
||||
if (!isResizingOrDragging) {
|
||||
selectWidget &&
|
||||
selectedWidget !== props.widgetId &&
|
||||
selectWidget(props.widgetId);
|
||||
}
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
// When mouse is over this draggable
|
||||
const handleMouseOver = (e: any) => {
|
||||
focusWidget &&
|
||||
|
|
@ -160,7 +153,9 @@ function DraggableComponent(props: DraggableComponentProps) {
|
|||
focusWidget(props.widgetId);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
const shouldRenderComponent = !(
|
||||
selectedWidgets.includes(props.widgetId) && isDragging
|
||||
);
|
||||
// Display this draggable based on the current drag state
|
||||
const style: CSSProperties = {
|
||||
display: isCurrentWidgetDragging ? "none" : "block",
|
||||
|
|
@ -187,14 +182,9 @@ function DraggableComponent(props: DraggableComponentProps) {
|
|||
|
||||
const className = `${classNameForTesting}`;
|
||||
|
||||
const shouldRenderComponent = !(
|
||||
selectedWidget === props.widgetId && isDragging
|
||||
);
|
||||
|
||||
return (
|
||||
<DraggableWrapper
|
||||
className={className}
|
||||
onClick={handleClick}
|
||||
onMouseOver={handleMouseOver}
|
||||
ref={drag}
|
||||
style={style}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export function DropTargetComponent(props: DropTargetComponentProps) {
|
|||
const { updateWidget } = useContext(EditorContext);
|
||||
const occupiedSpaces = useSelector(getOccupiedSpaces);
|
||||
const selectedWidget = useSelector(
|
||||
(state: AppState) => state.ui.widgetDragResize.selectedWidget,
|
||||
(state: AppState) => state.ui.widgetDragResize.lastSelectedWidget,
|
||||
);
|
||||
const isResizing = useSelector(
|
||||
(state: AppState) => state.ui.widgetDragResize.isResizing,
|
||||
|
|
@ -99,7 +99,7 @@ export function DropTargetComponent(props: DropTargetComponentProps) {
|
|||
const [rows, setRows] = useState(snapRows);
|
||||
|
||||
const showPropertyPane = useShowPropertyPane();
|
||||
const { selectWidget, focusWidget } = useWidgetSelection();
|
||||
const { deselectAll, focusWidget, selectWidget } = useWidgetSelection();
|
||||
const updateCanvasSnapRows = useCanvasSnapRowsUpdateHook();
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -237,12 +237,9 @@ export function DropTargetComponent(props: DropTargetComponentProps) {
|
|||
const handleFocus = (e: any) => {
|
||||
if (!isResizing && !isDragging) {
|
||||
if (!props.parentId) {
|
||||
selectWidget && selectWidget(props.widgetId);
|
||||
deselectAll();
|
||||
focusWidget && focusWidget(props.widgetId);
|
||||
showPropertyPane && showPropertyPane();
|
||||
} else {
|
||||
selectWidget && selectWidget(props.parentId);
|
||||
focusWidget && focusWidget(props.parentId);
|
||||
}
|
||||
}
|
||||
// commenting this out to allow propagation of click events
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import styled from "styled-components";
|
|||
import { snapToGrid } from "utils/helpers";
|
||||
import { IntentColors } from "constants/DefaultTheme";
|
||||
import { useSpring, animated, interpolate, config } from "react-spring";
|
||||
import { Layers } from "constants/Layers";
|
||||
|
||||
const SPRING_CONFIG = {
|
||||
...config.gentle,
|
||||
|
|
@ -124,6 +125,7 @@ export const DropZone = forwardRef(
|
|||
height={props.height * props.parentRowHeight}
|
||||
ref={ref}
|
||||
style={{
|
||||
zIndex: Layers.animatedDropZone,
|
||||
transform: interpolate(
|
||||
[X, Y],
|
||||
(x: number, y: number) => `translate3d(${x}px,${y}px,0)`,
|
||||
|
|
@ -135,6 +137,7 @@ export const DropZone = forwardRef(
|
|||
candrop={props.canDrop}
|
||||
height={props.height * props.parentRowHeight}
|
||||
style={{
|
||||
zIndex: Layers.animatedSnappingDropZone,
|
||||
transform: interpolate(
|
||||
[snappedX, snappedY],
|
||||
(x: number, y: number) => `translate3d(${x}px,${y}px,0)`,
|
||||
|
|
|
|||
|
|
@ -55,15 +55,15 @@ type EditorContextProviderProps = EditorContextType & {
|
|||
|
||||
function EditorContextProvider(props: EditorContextProviderProps) {
|
||||
const {
|
||||
executeAction,
|
||||
updateWidget,
|
||||
updateWidgetProperty,
|
||||
updateWidgetMetaProperty,
|
||||
disableDrag,
|
||||
children,
|
||||
resetChildrenMetaProperty,
|
||||
deleteWidgetProperty,
|
||||
batchUpdateWidgetProperty,
|
||||
children,
|
||||
deleteWidgetProperty,
|
||||
disableDrag,
|
||||
executeAction,
|
||||
resetChildrenMetaProperty,
|
||||
updateWidget,
|
||||
updateWidgetMetaProperty,
|
||||
updateWidgetProperty,
|
||||
} = props;
|
||||
return (
|
||||
<EditorContext.Provider
|
||||
|
|
|
|||
|
|
@ -127,10 +127,10 @@ class EntityNameComponent extends React.Component<
|
|||
const { focused } = this.state;
|
||||
const {
|
||||
isValid,
|
||||
onChange,
|
||||
placeholder,
|
||||
validationMessage,
|
||||
value,
|
||||
placeholder,
|
||||
onChange,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ export const StyledActionLink = styled.span<{ isActiveItem?: boolean }>`
|
|||
|
||||
export const ActionLink = withTheme(
|
||||
({
|
||||
isActiveItem,
|
||||
item,
|
||||
theme,
|
||||
isActiveItem,
|
||||
}: {
|
||||
item: SearchItem;
|
||||
theme: Theme;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ type SearchProps = {
|
|||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
function Search({ query, children }: SearchProps) {
|
||||
function Search({ children, query }: SearchProps) {
|
||||
const [queryInState, setQueryInState] = useState(query);
|
||||
const debouncedSetQueryInState = useCallback(
|
||||
debounce(setQueryInState, 100),
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user