From b447aa83453bec71883b4cf06be222e5da70fa7f Mon Sep 17 00:00:00 2001 From: Aswath K Date: Tue, 30 Mar 2021 22:10:23 +0530 Subject: [PATCH 01/76] Allow removing filter on Dropdown Widget --- .../designSystems/blueprint/DropdownComponent.tsx | 3 ++- app/client/src/widgets/DropdownWidget.tsx | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx b/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx index 5c1b1de9b0..cd4613ab79 100644 --- a/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx +++ b/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx @@ -259,7 +259,7 @@ class DropDownComponent extends React.Component { { isBindProperty: true, isTriggerProperty: false, }, + { + propertyName: "isFilterable", + label: "Filterable", + helpText: "Makes the dropdown list filterable", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + }, { propertyName: "isRequired", label: "Required", @@ -111,6 +120,7 @@ class DropdownWidget extends BaseWidget { options: VALIDATION_TYPES.OPTIONS_DATA, selectionType: VALIDATION_TYPES.TEXT, isRequired: VALIDATION_TYPES.BOOLEAN, + isFilterable: VALIDATION_TYPES.BOOLEAN, // onOptionChange: VALIDATION_TYPES.ACTION_SELECTOR, selectedOptionValues: VALIDATION_TYPES.ARRAY, selectedOptionLabels: VALIDATION_TYPES.ARRAY, @@ -180,6 +190,7 @@ class DropdownWidget extends BaseWidget { selectedIndexArr={computedSelectedIndexArr} label={`${this.props.label}`} isLoading={this.props.isLoading} + isFilterable={this.props.isFilterable} disabled={this.props.isDisabled} /> ); @@ -277,6 +288,7 @@ export interface DropdownWidgetProps extends WidgetProps, WithMeta { onOptionChange?: string; defaultOptionValue?: string | string[]; isRequired: boolean; + isFilterable: boolean; selectedOptionValue: string; selectedOptionValueArr: string[]; selectedOptionLabels: string[]; From a6afa8ce4dc728dbf7cd01270b42834a109954a4 Mon Sep 17 00:00:00 2001 From: Aswath K Date: Wed, 31 Mar 2021 08:42:27 +0530 Subject: [PATCH 02/76] Makes isFilterable true by default for DropdownWidget --- app/client/src/mockResponses/WidgetConfigResponse.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/client/src/mockResponses/WidgetConfigResponse.tsx b/app/client/src/mockResponses/WidgetConfigResponse.tsx index c2fb30230a..78fa5c42ab 100644 --- a/app/client/src/mockResponses/WidgetConfigResponse.tsx +++ b/app/client/src/mockResponses/WidgetConfigResponse.tsx @@ -173,6 +173,7 @@ const WidgetConfigResponse: WidgetConfigReducerState = { ], widgetName: "Dropdown", defaultOptionValue: "VEG", + isFilterable: true, version: 1, }, CHECKBOX_WIDGET: { From 42573533cb29b1015c859aaf1006a71115c85dc1 Mon Sep 17 00:00:00 2001 From: Sumit Kumar Date: Tue, 13 Apr 2021 19:58:40 +0530 Subject: [PATCH 03/76] fix NPE by adding null check conditional (#3989) Fix NPE seen on Sentry by adding null check for result body --- .../server/services/NewActionServiceImpl.java | 5 ++++ .../server/services/ActionServiceTest.java | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java index 41f8ee44e0..bac9d46174 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java @@ -710,6 +710,11 @@ public class NewActionServiceImpl extends BaseService()); + return result; + } + List parsedDataTypeList = new ArrayList<>(); Stream.of(ActionResultDataType.values()) .parallel() diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionServiceTest.java index d78db8e1e5..c2ba4f1379 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionServiceTest.java @@ -1307,4 +1307,33 @@ public class ActionServiceTest { executeAndAssertAction(executeActionDTO, actionConfiguration, mockResult, List.of(new ParsedDataType(ActionResultDataType.RAW))); } + + @Test + @WithUserDetails(value = "api_user") + public void testActionExecuteReturnTypeWithNullResultBody() { + Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(pluginExecutor)); + + ActionExecutionResult mockResult = new ActionExecutionResult(); + mockResult.setIsExecutionSuccess(true); + mockResult.setBody(null); + mockResult.setStatusCode("200"); + mockResult.setHeaders(objectMapper.valueToTree(Map.of("response-header-key", "response-header-value"))); + + ActionDTO action = new ActionDTO(); + ActionConfiguration actionConfiguration = new ActionConfiguration(); + actionConfiguration.setHttpMethod(HttpMethod.POST); + actionConfiguration.setBody("random-request-body"); + actionConfiguration.setHeaders(List.of(new Property("random-header-key", "random-header-value"))); + action.setActionConfiguration(actionConfiguration); + action.setPageId(testPage.getId()); + action.setName("testActionExecute"); + action.setDatasource(datasource); + ActionDTO createdAction = newActionService.createAction(action).block(); + + ExecuteActionDTO executeActionDTO = new ExecuteActionDTO(); + executeActionDTO.setActionId(createdAction.getId()); + executeActionDTO.setViewMode(false); + + executeAndAssertAction(executeActionDTO, actionConfiguration, mockResult, new ArrayList<>()); + } } From e0130336eb156eaab513d3a7bf0bffbc067ec074 Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Mon, 26 Apr 2021 12:40:24 +0530 Subject: [PATCH 04/76] added lib for excel export --- app/client/package.json | 3 +- app/client/yarn.lock | 82 +++-------------------------------------- 2 files changed, 8 insertions(+), 77 deletions(-) diff --git a/app/client/package.json b/app/client/package.json index 79bd92c5e4..02fb149675 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -56,6 +56,7 @@ "deep-diff": "^1.0.2", "downloadjs": "^1.4.7", "eslint": "^7.11.0", + "export-from-json": "^1.3.5", "fast-deep-equal": "^3.1.1", "fast-xml-parser": "^3.17.5", "flow-bin": "^0.91.0", @@ -73,6 +74,7 @@ "lint-staged": "^9.2.5", "localforage": "^1.7.3", "lodash": "^4.17.19", + "lodash-es": "4.17.14", "lodash-move": "^1.1.1", "loglevel": "^1.6.7", "lottie-web": "^5.7.4", @@ -118,7 +120,6 @@ "redux-form": "^8.2.6", "redux-saga": "^1.1.3", "reselect": "^4.0.0", - "lodash-es": "4.17.14", "scroll-into-view-if-needed": "^2.2.26", "shallowequal": "^1.1.0", "showdown": "^1.9.1", diff --git a/app/client/yarn.lock b/app/client/yarn.lock index 4a3012d16b..0eb016e21d 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -1627,7 +1627,6 @@ "@babel/runtime@^7.12.5": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" - integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== dependencies: regenerator-runtime "^0.13.4" @@ -2308,7 +2307,6 @@ "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" - integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -2370,7 +2368,6 @@ "@mswjs/cookies@^0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@mswjs/cookies/-/cookies-0.1.4.tgz#85ef872997eea2acd888f21af0b2067224dac244" - integrity sha512-gdtmSv21D4wHTnqF4rrZVX6ye7mQ4nRCTIHYnHBr4SkgoXaiqe3sMvUzXm43+H4PnL0EAKvUTxRVSSXz2xebeg== dependencies: "@types/set-cookie-parser" "^2.4.0" set-cookie-parser "^2.4.6" @@ -2378,7 +2375,6 @@ "@mswjs/interceptors@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.8.1.tgz#8ef43a8b7b25c7b9a2bac67b3702167e25e5fc07" - integrity sha512-OI9FYmtURESZG3QDNz4Yt3osy3HY4T3FjlRw+AG4QS1UDdTSZ0tuPFAkp23nGR9ojmbSSj4gSMjf5+R8Oi/qtQ== dependencies: "@open-draft/until" "^1.0.3" debug "^4.3.0" @@ -2416,7 +2412,6 @@ "@open-draft/until@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-1.0.3.tgz#db9cc719191a62e7d9200f6e7bab21c5b848adca" - integrity sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q== "@optimizely/js-sdk-datafile-manager@^0.8.0": version "0.8.0" @@ -2558,7 +2553,6 @@ "@sentry/browser@6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.2.4.tgz#b74757b1f76e7a525e6eaca39668db36db82cb21" - integrity sha512-OV1CQUxNawncpSEcrA+YccOu72rLC0tyYq/Pc4D/ihpfJmvR0o0L8vZYESay55V5lcqnJPFp8IyCJ2bF8IZTsA== dependencies: "@sentry/core" "6.2.4" "@sentry/types" "6.2.4" @@ -2578,7 +2572,6 @@ "@sentry/core@6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.2.4.tgz#613102074208958c580df4e7e06e9aa6b4d5f40c" - integrity sha512-8Z98OTM4wFS2n3T+V8a6cYWHDAk1byWuMb8JquZLdYgR5O1jkSpSFrhksQ+B/wDbVw05VOolSNFJsDTC2D5qXg== dependencies: "@sentry/hub" "6.2.4" "@sentry/minimal" "6.2.4" @@ -2589,7 +2582,6 @@ "@sentry/hub@6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.2.4.tgz#0e25b851dc04b806713c8d878b1e11696ccf47ea" - integrity sha512-dY8Vj3c4oIirNNNzWkJvoRMzjlU8Nw3PJ/IwhdWjiQhj5/oqOzJwJQSMeOKdOGIhArAifr0hSXdy1+tHGEOOdQ== dependencies: "@sentry/types" "6.2.4" "@sentry/utils" "6.2.4" @@ -2598,7 +2590,6 @@ "@sentry/minimal@6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.2.4.tgz#7d8d490b0942e14cde544c0a77550693e4702d97" - integrity sha512-KN+Abbz5CCAceSMvwymSG8GIVPaz4Y/xuY7R7dA8IlzncHaWRQ/Ss0PXjYUWL4YoTlTK6id1AW0i3JMICHMVgw== dependencies: "@sentry/hub" "6.2.4" "@sentry/types" "6.2.4" @@ -2607,7 +2598,6 @@ "@sentry/react@^6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.2.4.tgz#7d5a67a6e5f01238bf88e91433841da5180916f0" - integrity sha512-0TqM51HwnAUoDSYyK38Bq/m6xLqWHsOL98Uu4HoMMmx6VXW1xf1UDxhjmIQFfjWfYT5tlld0CoDRfTJJlc82Ow== dependencies: "@sentry/browser" "6.2.4" "@sentry/minimal" "6.2.4" @@ -2619,7 +2609,6 @@ "@sentry/tracing@^6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.2.4.tgz#4af650c180a41b72e130c7b92838fa9d1040792e" - integrity sha512-FNPTd22Q487SVyGM4BXlVeeRwPr9CG0OV8bz+GRHQtpVDhL+zdkGlIJYbxZnrOcdyYNVgLCJUPDHqyv55nhU4A== dependencies: "@sentry/hub" "6.2.4" "@sentry/minimal" "6.2.4" @@ -2630,12 +2619,10 @@ "@sentry/types@6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.2.4.tgz#5974e64f000e6084d92d752e6ca199dc2ef4438f" - integrity sha512-c+vEExoj8H67NPaskTvxJBSAtDWzfFXOmlkicEZPUWbkL+Yxxlbzp1lI8K6GOks56UYMUBUU/fwQvv/34cO96g== "@sentry/utils@6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.2.4.tgz#ab6a0bdfa2a32428f6b1ee87082d9bd40a226b11" - integrity sha512-lavbb3yQMUleVffmDkPH7X3dlgbXlyiFNmfER+swJ6WRxa4Yq6I8yea2s6maoqnZMhZe+yztn455DPwXIItfCA== dependencies: "@sentry/types" "6.2.4" tslib "^1.9.3" @@ -3400,7 +3387,6 @@ "@testing-library/dom@^7.28.1": version "7.30.1" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.30.1.tgz#07b6f3ccd7f1f1e34ab0406932073e2971817f3d" - integrity sha512-RQUvqqq2lxTCOffhSNxpX/9fCoR+nwuQPmG5uhuuEH5KBAzNf2bK3OzBoWjm5zKM78SLjnGRAKt8hRjQA4E46A== dependencies: "@babel/code-frame" "^7.10.4" "@babel/runtime" "^7.12.5" @@ -3427,7 +3413,6 @@ "@testing-library/react@^11.2.5": version "11.2.5" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.5.tgz#ae1c36a66c7790ddb6662c416c27863d87818eb9" - integrity sha512-yEx7oIa/UWLe2F2dqK0FtMF9sJWNXD+2PPtp39BvE0Kh9MJ9Kl0HrZAgEuhUJR+Lx8Di6Xz+rKwSdEPY2UV8ZQ== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" @@ -3435,7 +3420,6 @@ "@testing-library/user-event@^13.1.1": version "13.1.1" resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.1.1.tgz#1e011de944cf4d2a917cef6c3046c26389943e24" - integrity sha512-B4roX+0mpXKGj8ndd38YoIo3IV9pmTTWxr/2cOke5apTtrNabEUE0KMBccpcAcYlfPcr7uMu+dxeeC3HdXd9qQ== dependencies: "@babel/runtime" "^7.12.5" @@ -3504,15 +3488,9 @@ dependencies: "@types/tern" "*" -"@types/component-emitter@^1.2.10": - version "1.2.10" - resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.10.tgz#ef5b1589b9f16544642e473db5ea5639107ef3ea" - integrity sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg== - "@types/cookie@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.0.tgz#14f854c0f93d326e39da6e3b6f34f7d37513d108" - integrity sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg== "@types/deep-diff@^1.0.0": version "1.0.0" @@ -3582,7 +3560,6 @@ "@types/inquirer@^7.3.1": version "7.3.1" resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.1.tgz#1f231224e7df11ccfaf4cf9acbcc3b935fea292d" - integrity sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g== dependencies: "@types/through" "*" rxjs "^6.4.0" @@ -3634,7 +3611,6 @@ "@types/js-levenshtein@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@types/js-levenshtein/-/js-levenshtein-1.1.0.tgz#9541eec4ad6e3ec5633270a3a2b55d981edc44a9" - integrity sha512-14t0v1ICYRtRVcHASzes0v/O+TIeASb8aD55cWF1PidtInhFWSXcmhzhHqGjUWf9SUq1w70cvd1cWKUULubAfQ== "@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": version "7.0.6" @@ -3651,7 +3627,6 @@ "@types/marked@^1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/marked/-/marked-1.2.2.tgz#1f858a0e690247ecf3b2eef576f98f86e8d960d4" - integrity sha512-wLfw1hnuuDYrFz97IzJja0pdVsC0oedtS4QsKH1/inyW9qkLQbXgMUqEQT0MVtUBx3twjWeInUfjQbhBVLECXw== "@types/mdast@^3.0.0": version "3.0.3" @@ -3832,7 +3807,6 @@ "@types/react-window@^1.8.2": version "1.8.2" resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.2.tgz#a5a6b2762ce73ffaab7911ee1397cf645f2459fe" - integrity sha512-gP1xam68Wc4ZTAee++zx6pTdDAH08rAkQrWm4B4F/y6hhmlT9Mgx2q8lTCXnrPHXsr15XjRN9+K2DLKcz44qEQ== dependencies: "@types/react" "*" @@ -3871,7 +3845,6 @@ "@types/set-cookie-parser@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/set-cookie-parser/-/set-cookie-parser-2.4.0.tgz#10cc0446bad372827671a5195fbd14ebce4a9baf" - integrity sha512-w7BFUq81sy7H/0jN0K5cax8MwRN6NOSURpY4YuO4+mOgoicxCZ33BUYz+gyF/sUf7uDl2We2yGJfppxzEXoAXQ== dependencies: "@types/node" "*" @@ -3939,7 +3912,6 @@ "@types/through@*": version "0.0.30" resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895" - integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg== dependencies: "@types/node" "*" @@ -5414,7 +5386,6 @@ bluebird@^3.3.5, bluebird@^3.5.5, bluebird@^3.7.2: bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== bn.js@^5.1.1: version "5.1.3" @@ -5947,7 +5918,6 @@ chokidar@^3.4.1: chokidar@^3.4.2: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -6100,7 +6070,6 @@ cliui@^6.0.0: cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" strip-ansi "^6.0.0" @@ -6151,7 +6120,6 @@ code-point-at@^1.0.0: codemirror@^5.59.2: version "5.59.2" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.59.2.tgz#ee674d3a4a8d241af38d52afc482625ba7393922" - integrity sha512-/D5PcsKyzthtSy2NNKCyJi3b+htRkoKv3idswR/tR6UAvMNKA7SrmyZy6fOONJxSRs1JlUWEDAbxqfdArbK8iA== collapse-white-space@^1.0.2: version "1.0.6" @@ -6275,7 +6243,6 @@ compression@^1.7.4: compute-scroll-into-view@^1.0.16: version "1.0.16" resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz#5b7bf4f7127ea2c19b750353d7ce6776a90ee088" - integrity sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ== concat-map@0.0.1: version "0.0.1" @@ -6358,7 +6325,6 @@ cookie@0.4.0: cookie@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== copy-concurrently@^1.0.0: version "1.0.5" @@ -6407,7 +6373,6 @@ core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5: core-js@^3.9.1: version "3.9.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.1.tgz#cec8de593db8eb2a85ffb0dbdeb312cb6e5460ae" - integrity sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -6696,7 +6661,6 @@ cssesc@^3.0.0: cssfontparser@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3" - integrity sha1-9AIvyPlwDGgCnVQghK+69CWj8+M= cssnano-preset-default@^4.0.7: version "4.0.7" @@ -6920,10 +6884,9 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" -debug@^4.3.0, debug@~4.3.1: +debug@^4.3.0: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" @@ -7186,7 +7149,6 @@ doctypes@^1.1.0: dom-accessibility-api@^0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz#b06d059cdd4a4ad9a79275f9d414a5c126241166" - integrity sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ== dom-converter@^0.2: version "0.2.0" @@ -7356,7 +7318,6 @@ element-resize-detector@^1.2.1: elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: bn.js "^4.11.9" brorand "^1.1.0" @@ -7880,7 +7841,6 @@ events@^3.0.0: events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== eventsource@^1.0.7: version "1.0.7" @@ -7994,6 +7954,10 @@ expect@^26.6.0, expect@^26.6.1: jest-message-util "^26.6.1" jest-regex-util "^26.0.0" +export-from-json@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/export-from-json/-/export-from-json-1.3.5.tgz#52e8dab6aacf2827c84fcc304940a1ea5347124b" + express@^4.17.0, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -8536,7 +8500,6 @@ fsevents@^2.1.2, fsevents@^2.1.3, fsevents@~2.1.1, fsevents@~2.1.2: fsevents@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" @@ -8846,7 +8809,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 graphql@^15.4.0: version "15.5.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5" - integrity sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA== growl@1.10.5: version "1.10.5" @@ -9032,7 +8994,6 @@ he@1.2.0, he@^1.2.0: headers-utils@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/headers-utils/-/headers-utils-3.0.2.tgz#dfc65feae4b0e34357308aefbcafa99c895e59ef" - integrity sha512-xAxZkM1dRyGV2Ou5bzMxBPNLoRCjcX+ya7KSWybQD2KwLphxsapUVK6x/02o7f4VU6GPSXch9vNY2+gkU8tYWQ== hex-color-regex@^1.1.0: version "1.1.0" @@ -10042,7 +10003,6 @@ jake@^10.6.1: jest-canvas-mock@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.3.1.tgz#9535d14bc18ccf1493be36ac37dd349928387826" - integrity sha512-5FnSZPrX3Q2ZfsbYNE3wqKR3+XorN8qFzDzB5o0golWgt6EOX1+emBnpOc9IAQ+NXFj8Nzm3h7ZdE/9H0ylBcg== dependencies: cssfontparser "^1.2.1" moo-color "^1.0.2" @@ -10471,7 +10431,6 @@ jest-util@^24.9.0: jest-util@^26.1.0: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" - integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== dependencies: "@jest/types" "^26.6.2" "@types/node" "*" @@ -10563,7 +10522,6 @@ js-base64@^2.1.8: js-levenshtein@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== js-sha256@^0.9.0: version "0.9.0" @@ -11024,12 +10982,10 @@ locate-path@^5.0.0: lodash-es@4.17.14: version "4.17.14" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.14.tgz#12a95a963cc5955683cee3b74e85458954f37ecc" - integrity sha512-7zchRrGa8UZXjD/4ivUWP1867jDkhzTG2c/uj739utSd7O/pFFdxspCemIFKEEjErbcqRzn8nKnGsi7mvTgRPA== lodash-move@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/lodash-move/-/lodash-move-1.1.1.tgz#59f76e0f1ac57e6d8683f531bec07c5b6ea4e348" - integrity sha1-WfduDxrFfm2Gg/UxvsB8W26k40g= dependencies: lodash "^4.6.1" @@ -11106,20 +11062,14 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@4.x: +lodash@4.x, lodash@^4.6.1: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== "lodash@>=3.5 <5", lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.16.2, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@~4.17.10: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" -lodash@^4.6.1: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - log-symbols@3.0.0, log-symbols@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" @@ -11285,7 +11235,6 @@ markdown-to-jsx@^6.10.3, markdown-to-jsx@^6.11.4: marked@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.0.tgz#9662bbcb77ebbded0662a7be66ff929a8611cee5" - integrity sha512-NqRSh2+LlN2NInpqTQnS614Y/3NkVMFFU6sJlRFEpxJ/LHuK/qJECH7/fXZjk4VZstPW/Pevjil/VtSONsLc7Q== marker-clusterer-plus@^2.1.4: version "2.1.4" @@ -11738,7 +11687,6 @@ moment-timezone@*, moment-timezone@^0.5.27, moment-timezone@^0.5.31: moo-color@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/moo-color/-/moo-color-1.0.2.tgz#837c40758d2d58763825d1359a84e330531eca64" - integrity sha512-5iXz5n9LWQzx/C2WesGFfpE6RLamzdHwsn3KpfzShwbfIqs7stnoEpaNErf/7+3mbxwZ4s8Foq7I0tPxw7BWHg== dependencies: color-name "^1.1.4" @@ -11768,7 +11716,6 @@ ms@2.1.2, ms@^2.1.1: msw@^0.28.0: version "0.28.0" resolved "https://registry.yarnpkg.com/msw/-/msw-0.28.0.tgz#abed17416f59241a2100fe6c8740cc1c9a32339b" - integrity sha512-Hh+dPp613tethIFwNg90lvAzrW9T0U39D6AYzV8qIOAWskP49CErrqVWZnmPDQC87o69GzZ9Hl3RGz/65mms3A== dependencies: "@mswjs/cookies" "^0.1.4" "@mswjs/interceptors" "^0.8.0" @@ -11965,7 +11912,6 @@ node-libs-browser@^2.2.1: node-match-path@^0.6.1: version "0.6.2" resolved "https://registry.yarnpkg.com/node-match-path/-/node-match-path-0.6.2.tgz#29a05ed7eda4d325f29d7abb088c12bbf1578e87" - integrity sha512-2VYsUKiovaCZDq1t/3kEqh09743H91WE6B3RzSdjsKh+S/a5z+LQoujMI1JI/RYXqNKFvoqMfye1H0g3Dg9u+g== node-modules-regexp@^1.0.0: version "1.0.0" @@ -12567,7 +12513,6 @@ path-to-regexp@^1.7.0: path-to-regexp@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.0.tgz#f7b3803336104c346889adece614669230645f38" - integrity sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg== path-type@^1.0.0: version "1.1.0" @@ -13405,7 +13350,6 @@ pretty-format@^26.6.0, pretty-format@^26.6.1: pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" - integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== dependencies: "@jest/types" "^26.6.2" ansi-regex "^5.0.0" @@ -13419,7 +13363,6 @@ pretty-hrtime@^1.0.3: prismjs@^1.23.0, prismjs@^1.8.4: version "1.23.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33" - integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA== optionalDependencies: clipboard "^2.0.0" @@ -14390,7 +14333,6 @@ react-window@^1.8.2: react-window@^1.8.6: version "1.8.6" resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112" - integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg== dependencies: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" @@ -15179,7 +15121,6 @@ scriptjs@^2.5.8: scroll-into-view-if-needed@^2.2.26: version "2.2.26" resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.26.tgz#e4917da0c820135ff65ad6f7e4b7d7af568c4f13" - integrity sha512-SQ6AOKfABaSchokAmmaxVnL9IArxEnLEX9j4wAZw+x4iUTb40q7irtHG3z4GtAWz5veVZcCnubXDBRyLVQaohw== dependencies: compute-scroll-into-view "^1.0.16" @@ -15223,7 +15164,6 @@ semver@7.3.2: semver@7.x: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" @@ -15309,7 +15249,6 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: set-cookie-parser@^2.4.6: version "2.4.8" resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz#d0da0ed388bc8f24e706a391f9c9e252a13c58b2" - integrity sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg== set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" @@ -15720,7 +15659,6 @@ static-extend@^0.1.1: statuses@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== stdout-stream@^1.4.0: version "1.4.1" @@ -15773,12 +15711,10 @@ stream-shift@^1.0.0: strict-event-emitter@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.1.0.tgz#fd742c1fb7e3852f0b964ecdae2d7666a6fb7ef8" - integrity sha512-8hSYfU+WKLdNcHVXJ0VxRXiPESalzRe7w1l8dg9+/22Ry+iZQUoQuoJ27R30GMD1TiyYINWsIEGY05WrskhSKw== strict-event-emitter@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.2.0.tgz#78e2f75dc6ea502e5d8a877661065a1e2deedecd" - integrity sha512-zv7K2egoKwkQkZGEaH8m+i2D0XiKzx5jNsiSul6ja2IYFvil10A59Z9Y7PPAAe5OW53dQUf9CfsHKzjZzKkm1w== dependencies: events "^3.3.0" @@ -16456,7 +16392,6 @@ ts-dedent@^1.1.0: ts-jest@^26.5.4: version "26.5.4" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.4.tgz#207f4c114812a9c6d5746dd4d1cdf899eafc9686" - integrity sha512-I5Qsddo+VTm94SukBJ4cPimOoFZsYTeElR2xy6H2TOVs+NsvgYglW8KuQgKoApOKuaU/Ix/vrF9ebFZlb5D2Pg== dependencies: bs-logger "0.x" buffer-from "1.x" @@ -17476,7 +17411,6 @@ wrap-ansi@^6.2.0: wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" @@ -17546,12 +17480,10 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: y18n@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== y18n@^5.0.5: version "5.0.5" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== yallist@^2.1.2: version "2.1.2" @@ -17579,7 +17511,6 @@ yargs-parser@13.1.2, yargs-parser@^13.1.2: yargs-parser@20.x, yargs-parser@^20.2.2: version "20.2.7" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== yargs-parser@^15.0.1: version "15.0.1" @@ -17653,7 +17584,6 @@ yargs@^15.4.1: yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" escalade "^3.1.1" From 4dffd98ee3b85bb3be20a682d07d2fafc88b68b8 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Wed, 28 Apr 2021 15:07:55 +0530 Subject: [PATCH 05/76] Including services and their role (#4193) * Including services and their role * Explicitly mention Google tokens --- app/client/public/privacy-policy.html | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/client/public/privacy-policy.html b/app/client/public/privacy-policy.html index e0938fe862..db20473ea4 100644 --- a/app/client/public/privacy-policy.html +++ b/app/client/public/privacy-policy.html @@ -72,7 +72,7 @@

At appsmith, accessible from www.appsmith.com, one of our main priorities is the privacy of our visitors. This Privacy Policy document contains types of information that is collected and recorded by - appsmith and + appsmith and its "Services" and how we use it.

If you have additional questions or require more information about our Privacy Policy, do not hesitate to @@ -99,13 +99,20 @@

How we use your information

We use the information we collect in various ways, including to:

    -
  • Provide, operate, and maintain our webste
  • -
  • Improve, personalize, and expand our webste
  • -
  • Understand and analyze how you use our webste
  • +
  • Provide, operate, and maintain our website
  • +
  • The information that you provide, or that we receive from third party integrations, + are used to retrieve and process your data as part of our services. + We do not store any of your data on our servers. We may however, + retain your identifiers to provide unhindered access to these services. These identifiers + could be your Google access tokens, for example. + Wherever our services do this, our documentation will contain a reminder for such + access.
  • +
  • Improve, personalize, and expand our website
  • +
  • Understand and analyze how you use our website
  • Develop new products, services, features, and functionality
  • Communicate with you, either directly or through one of our partners, including for customer service, - to provide you with updates and other information relating to the webste, and for + to provide you with updates and other information relating to the website, and for marketing and promotional purposes
  • Send you emails
  • From 4a441b5ca261c503af1f2d8e88e474a02a9b2ac6 Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Wed, 28 Apr 2021 17:36:30 +0530 Subject: [PATCH 06/76] [Bug Fix] : In case the table being renamed has mongo escaped fields, rename the table name in set keeping a track of these widgets as well (#4195) --- .../services/LayoutActionServiceImpl.java | 7 +++ .../services/LayoutActionServiceTest.java | 47 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java index cc130c0611..453602328b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java @@ -223,6 +223,13 @@ public class LayoutActionServiceImpl implements LayoutActionService { } catch (ParseException e) { log.debug("Exception caught during DSL conversion from string to Json object. ", e); } + // DSL has removed all the old names and replaced it with new name. If the change of name + // was one of the mongoEscaped widgets, then update the names in the set as well + Set mongoEscapedWidgetNames = layout.getMongoEscapedWidgetNames(); + if (mongoEscapedWidgetNames.contains(oldName)) { + mongoEscapedWidgetNames.remove(oldName); + mongoEscapedWidgetNames.add(newName); + } page.setLayouts(layouts); // Since the page has most probably changed, save the page and return. return newPageService.saveUnpublishedPage(page); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java index 805d733a1f..0864b1c957 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java @@ -17,6 +17,7 @@ import com.appsmith.server.dtos.LayoutActionUpdateDTO; import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.RefactorActionNameDTO; +import com.appsmith.server.dtos.RefactorNameDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.MockPluginExecutor; @@ -616,4 +617,50 @@ public class LayoutActionServiceTest { throwable.getMessage().equals(AppsmithError.DUPLICATE_KEY_USER_ERROR.getMessage(name, FieldName.NAME))) .verify(); } + + @Test + @WithUserDetails(value = "api_user") + public void tableWidgetKeyEscapeRefactorName() { + Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(new MockPluginExecutor())); + + JSONObject dsl = new JSONObject(); + dsl.put("widgetName", "Table1"); + dsl.put("type", "TABLE_WIDGET"); + Map primaryColumns = new HashMap(); + JSONObject jsonObject = new JSONObject(Map.of("key", "value")); + primaryColumns.put("_id", jsonObject); + primaryColumns.put("_class", jsonObject); + dsl.put("primaryColumns", primaryColumns); + Layout layout = testPage.getLayouts().get(0); + layout.setDsl(dsl); + + layoutActionService.updateLayout(testPage.getId(), layout.getId(), layout).block(); + + RefactorNameDTO refactorNameDTO = new RefactorNameDTO(); + refactorNameDTO.setPageId(testPage.getId()); + refactorNameDTO.setLayoutId(layout.getId()); + refactorNameDTO.setOldName("Table1"); + refactorNameDTO.setNewName("NewNameTable1"); + + Mono widgetRenameMono = layoutActionService.refactorWidgetName(refactorNameDTO).cache(); + + Mono pageFromRepoMono = widgetRenameMono.then(newPageService.findPageById(testPage.getId(), READ_PAGES, false)); + + StepVerifier + .create(Mono.zip(widgetRenameMono, pageFromRepoMono)) + .assertNext(tuple -> { + LayoutDTO updatedLayout = tuple.getT1(); + PageDTO pageFromRepo = tuple.getT2(); + + String widgetName = (String) updatedLayout.getDsl().get("widgetName"); + assertThat(widgetName).isEqualTo("NewNameTable1"); + + Map primaryColumns1 = (Map) updatedLayout.getDsl().get("primaryColumns"); + assertThat(primaryColumns1.keySet()).containsAll(Set.of(FieldName.MONGO_UNESCAPED_ID, FieldName.MONGO_UNESCAPED_CLASS)); + + Map primaryColumns2 = (Map) pageFromRepo.getLayouts().get(0).getDsl().get("primaryColumns"); + assertThat(primaryColumns2.keySet()).containsAll(Set.of(FieldName.MONGO_ESCAPE_ID, FieldName.MONGO_ESCAPE_CLASS)); + }) + .verifyComplete(); + } } From 8a6cd10102a1374517f55914ef5ffab00c0b284e Mon Sep 17 00:00:00 2001 From: Shrikant Sharat Kandula Date: Wed, 21 Apr 2021 19:15:02 +0530 Subject: [PATCH 07/76] Set explicit Java version for CI (#4091) * Set explicit Java version for CI * Trigger Co-authored-by: Nidhi --- .github/workflows/external-client-test.yml | 2 +- .github/workflows/server.yml | 2 +- app/server/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/external-client-test.yml b/.github/workflows/external-client-test.yml index 2b41a166fa..f83389788e 100644 --- a/.github/workflows/external-client-test.yml +++ b/.github/workflows/external-client-test.yml @@ -38,7 +38,7 @@ jobs: - name: Set up JDK 1.11 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: "11.0.10" # Retrieve maven dependencies from cache. After a successful run, these dependencies are cached again - name: Cache maven dependencies diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index d5a79b2dd9..3ac0df6d93 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -50,7 +50,7 @@ jobs: - name: Set up JDK 1.11 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: "11.0.10" # Retrieve maven dependencies from cache. After a successful run, these dependencies are cached again - name: Cache maven dependencies diff --git a/app/server/README.md b/app/server/README.md index ae3296205b..d59286da54 100644 --- a/app/server/README.md +++ b/app/server/README.md @@ -30,4 +30,4 @@ In order to test the code, you can run the following command: mvn -B clean package ``` -Please make sure that you have a local Redis instance running for the test cases. During tests, the MongoDB is run in-memory. So you don't require to be running a local MongoDB instance. +Please make sure that you have a local Redis instance running for the test cases. During tests, the MongoDB is run in-memory. So you don't require to be running a local MongoDB instance. From 398fe551cc6fd03fde341bb5bd84d5c88cd8650b Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Wed, 28 Apr 2021 18:37:35 +0530 Subject: [PATCH 08/76] Handle table data download as excel --- app/client/package.json | 6 +- .../TableComponent/TableDataDownload.tsx | 159 ++++++++++++++++-- app/client/yarn.lock | 94 ++++++++++- 3 files changed, 241 insertions(+), 18 deletions(-) diff --git a/app/client/package.json b/app/client/package.json index 02fb149675..2e3b0c51c6 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -22,6 +22,7 @@ "@sentry/tracing": "^6.2.4", "@sentry/webpack-plugin": "^1.12.1", "@types/chance": "^1.0.7", + "@types/file-saver": "^2.0.2", "@types/lodash": "^4.14.120", "@types/moment-timezone": "^0.5.10", "@types/nanoid": "^2.0.0", @@ -56,9 +57,9 @@ "deep-diff": "^1.0.2", "downloadjs": "^1.4.7", "eslint": "^7.11.0", - "export-from-json": "^1.3.5", "fast-deep-equal": "^3.1.1", "fast-xml-parser": "^3.17.5", + "file-saver": "^2.0.5", "flow-bin": "^0.91.0", "fuse.js": "^3.4.5", "fusioncharts": "^3.16.0", @@ -133,7 +134,8 @@ "typescript": "^3.9.2", "unescape-js": "^1.1.4", "url-search-params-polyfill": "^8.0.0", - "worker-loader": "^3.0.2" + "worker-loader": "^3.0.2", + "xlsx": "^0.16.9" }, "scripts": { "analyze": "source-map-explorer 'build/static/js/*.js'", diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx index 57ac1fdcad..9387136188 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx @@ -1,4 +1,10 @@ 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"; @@ -6,6 +12,43 @@ import { ReactTableColumnProps } from "components/designSystems/appsmith/TableCo import { TableIconWrapper } from "components/designSystems/appsmith/TableComponent/TableStyledWrappers"; import TableActionIcon from "components/designSystems/appsmith/TableComponent/TableActionIcon"; import { isString } from "lodash"; +import styled from "styled-components"; + +const DropDownWrapper = styled.div` + display: flex; + flex-direction: column; + background: white; + z-index: 1; + border-radius: 4px; + border: 1px solid ${Colors.ATHENS_GRAY}; + padding: 8px; +`; + +const OptionWrapper = styled.div` + display: flex; + width: calc(100% - 20px); + justify-content: space-between; + align-items: center; + height: 32px; + box-sizing: border-box; + padding: 8px; + color: ${Colors.OXFORD_BLUE}; + opacity: 0.7; + min-width: 200px; + cursor: pointer; + margin-bottom: 4px; + background: ${Colors.WHITE}; + border-left: none; + border-radius: 4px; + .option-title { + font-weight: 500; + font-size: 14px; + line-height: 24px; + } + &:hover { + background: ${Colors.POLAR}; + } +`; interface TableDataDownloadProps { data: Array>; @@ -13,10 +56,76 @@ interface TableDataDownloadProps { widgetName: string; } +type FileDownloadType = "CSV" | "EXCEL"; + +interface DownloadOptionProps { + label: string; + value: FileDownloadType; +} + +const dowloadOptions: DownloadOptionProps[] = [ + { + label: "CSV", + value: "CSV", + }, + { + label: "Excel", + value: "EXCEL", + }, +]; + const 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<{ [key: string]: any }> = []; + const tableHeaders = props.columns + .map((column: ReactTableColumnProps) => { + if (column.metaProperties && !column.metaProperties.isHidden) { + return column.Header; + } + return null; + }) + .filter((i) => !!i); + tableData.push(tableHeaders); + for (let row = 0; row < props.data.length; row++) { + const data: { [key: string]: any } = props.data[row]; + const tableRow = []; + for (let colIndex = 0; colIndex < props.columns.length; colIndex++) { + const column = props.columns[colIndex]; + if (column.metaProperties && !column.metaProperties.isHidden) { + tableRow.push(data[column.accessor]); + } + } + tableData.push(tableRow); + } + import("xlsx").then((XLSX) => { + const workSheet = XLSX.utils.aoa_to_sheet(tableData); + const workBook = { + Sheets: { data: workSheet, cols: [] }, + SheetNames: ["data"], + }; + const excelBuffer = XLSX.write(workBook, { + bookType: "xlsx", + type: "array", + }); + const fileData = new Blob([excelBuffer], { + type: + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8", + }); + import("file-saver").then((FileSaver) => { + FileSaver.saveAs(fileData, `${props.widgetName}.xlsx`); + }); + }); + }; + const downloadTableDataAsCsv = () => { + selectMenu(true); const csvData = []; csvData.push( props.columns @@ -70,7 +179,7 @@ const TableDataDownload = (props: TableDataDownloadProps) => { anchor.click(); document.body.removeChild(anchor); } - toggleButtonClick(false); + selectMenu(false); }; if (props.columns.length === 0) { @@ -83,16 +192,42 @@ const TableDataDownload = (props: TableDataDownloadProps) => { ); } return ( - { - downloadTableData(); + { + selectMenu(false); }} - className="t--table-download-btn" + isOpen={selected} > - - + { + selectMenu(selected); + }} + className="t--table-download-btn" + > + + + + {dowloadOptions.map((item: DownloadOptionProps, index: number) => { + return ( + { + downloadFile(item.value); + }} + className={`${Classes.POPOVER_DISMISS} t--table-download-data-option`} + > + {item.label} + + ); + })} + + ); }; diff --git a/app/client/yarn.lock b/app/client/yarn.lock index 0eb016e21d..ad399001f2 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -3519,6 +3519,10 @@ version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" +"@types/file-saver@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.2.tgz#bd593ccfaee42ff94a5c1c83bf69ae9be83493b9" + "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -4476,6 +4480,13 @@ adjust-sourcemap-loader@3.0.0: loader-utils "^2.0.0" regex-parser "^2.2.11" +adler-32@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25" + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + agent-base@6: version "6.0.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4" @@ -5791,6 +5802,14 @@ ccount@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" +cfb@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.0.tgz#6a4d0872b525ed60349e1ef51fb4b0bf73eca9a8" + dependencies: + adler-32 "~1.2.0" + crc-32 "~1.2.0" + printj "~1.1.2" + chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -6121,6 +6140,13 @@ codemirror@^5.59.2: version "5.59.2" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.59.2.tgz#ee674d3a4a8d241af38d52afc482625ba7393922" +codepage@~1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99" + dependencies: + commander "~2.14.1" + exit-on-epipe "~1.0.1" + collapse-white-space@^1.0.2: version "1.0.6" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" @@ -6204,6 +6230,14 @@ commander@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" +commander@~2.14.1: + version "2.14.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" + +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -6414,6 +6448,13 @@ craco-babel-loader@^0.1.4: dependencies: "@craco/craco" "^5.0.0" +crc-32@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -7927,6 +7968,10 @@ exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -7954,10 +7999,6 @@ expect@^26.6.0, expect@^26.6.1: jest-message-util "^26.6.1" jest-regex-util "^26.0.0" -export-from-json@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/export-from-json/-/export-from-json-1.3.5.tgz#52e8dab6aacf2827c84fcc304940a1ea5347124b" - express@^4.17.0, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -8158,6 +8199,10 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" +fflate@^0.3.8: + version "0.3.11" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.3.11.tgz#2c440d7180fdeb819e64898d8858af327b042a5d" + figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" @@ -8201,6 +8246,10 @@ file-loader@^4.2.0: loader-utils "^1.2.3" schema-utils "^2.5.0" +file-saver@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38" + file-system-cache@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f" @@ -8415,6 +8464,10 @@ forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" +frac@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -13360,6 +13413,10 @@ pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" +printj@~1.1.0, printj@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + prismjs@^1.23.0, prismjs@^1.8.4: version "1.23.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33" @@ -15590,6 +15647,12 @@ sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" +ssf@~0.11.2: + version "0.11.2" + resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" + dependencies: + frac "~1.1.2" + sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -17218,10 +17281,18 @@ with@^7.0.0: assert-never "^1.2.1" babel-walk "3.0.0-canary-5" +wmf@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" +word@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" + workbox-background-sync@^5.1.4: version "5.1.4" resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz#5ae0bbd455f4e9c319e8d827c055bb86c894fd12" @@ -17461,6 +17532,21 @@ ws@^7.2.3: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" +xlsx@^0.16.9: + version "0.16.9" + resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.16.9.tgz#dacd5bb46bda6dd3743940c9c3dc1e2171826256" + dependencies: + adler-32 "~1.2.0" + cfb "^1.1.4" + codepage "~1.14.0" + commander "~2.17.1" + crc-32 "~1.2.0" + exit-on-epipe "~1.0.1" + fflate "^0.3.8" + ssf "~0.11.2" + wmf "~1.0.1" + word "~0.3.0" + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" From 09748de6c0d6f4bc4e8b934b597c72b3c7216003 Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Wed, 28 Apr 2021 22:27:01 +0530 Subject: [PATCH 09/76] NPE check when there are no mongo escaped widgets (#4200) --- .../com/appsmith/server/services/LayoutActionServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java index 453602328b..0e625ddf4d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java @@ -226,7 +226,7 @@ public class LayoutActionServiceImpl implements LayoutActionService { // DSL has removed all the old names and replaced it with new name. If the change of name // was one of the mongoEscaped widgets, then update the names in the set as well Set mongoEscapedWidgetNames = layout.getMongoEscapedWidgetNames(); - if (mongoEscapedWidgetNames.contains(oldName)) { + if (mongoEscapedWidgetNames != null && mongoEscapedWidgetNames.contains(oldName)) { mongoEscapedWidgetNames.remove(oldName); mongoEscapedWidgetNames.add(newName); } From 92764c8f5c15f139d388ba233887f77b9ca4b718 Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Thu, 29 Apr 2021 14:50:43 +0530 Subject: [PATCH 10/76] Used zipcelx instaed of xlsx lib to download table data as excel --- app/client/package.json | 5 +- .../TableComponent/TableDataDownload.tsx | 66 +++++---- app/client/yarn.lock | 140 +++++------------- 3 files changed, 75 insertions(+), 136 deletions(-) diff --git a/app/client/package.json b/app/client/package.json index 00fa708665..8ed6285f09 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -22,7 +22,6 @@ "@sentry/tracing": "^6.2.4", "@sentry/webpack-plugin": "^1.12.1", "@types/chance": "^1.0.7", - "@types/file-saver": "^2.0.2", "@types/lodash": "^4.14.120", "@types/moment-timezone": "^0.5.10", "@types/nanoid": "^2.0.0", @@ -37,6 +36,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", @@ -59,7 +59,6 @@ "eslint": "^7.11.0", "fast-deep-equal": "^3.1.1", "fast-xml-parser": "^3.17.5", - "file-saver": "^2.0.5", "flow-bin": "^0.91.0", "fuse.js": "^3.4.5", "fusioncharts": "^3.16.0", @@ -137,7 +136,7 @@ "unescape-js": "^1.1.4", "url-search-params-polyfill": "^8.0.0", "worker-loader": "^3.0.2", - "xlsx": "^0.16.9" + "zipcelx": "^1.6.2" }, "scripts": { "analyze": "source-map-explorer 'build/static/js/*.js'", diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx index 3b3be89aa1..fd914ce941 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx @@ -13,6 +13,7 @@ import { TableIconWrapper } from "components/designSystems/appsmith/TableCompone import TableActionIcon from "components/designSystems/appsmith/TableComponent/TableActionIcon"; import styled from "styled-components"; import { transformTableDataIntoCsv } from "./CommonUtilities"; +import zipcelx from "zipcelx"; const DropDownWrapper = styled.div` display: flex; @@ -57,6 +58,11 @@ interface TableDataDownloadProps { type FileDownloadType = "CSV" | "EXCEL"; +type DataCellProps = { + value: string | number; + type: "string" | "number"; +}; + interface DownloadOptionProps { label: string; value: FileDownloadType; @@ -64,11 +70,11 @@ interface DownloadOptionProps { const dowloadOptions: DownloadOptionProps[] = [ { - label: "CSV", + label: "Download as CSV", value: "CSV", }, { - label: "Excel", + label: "Download as Excel", value: "EXCEL", }, ]; @@ -104,27 +110,6 @@ const downloadDataAsCSV = (props: { } }; -const downloadDataAsExcel = (tableData: string[][], fileName: string) => { - import("xlsx").then((XLSX) => { - const workSheet = XLSX.utils.aoa_to_sheet(tableData); - const workBook = { - Sheets: { data: workSheet, cols: [] }, - SheetNames: ["data"], - }; - const excelBuffer = XLSX.write(workBook, { - bookType: "xlsx", - type: "array", - }); - const fileData = new Blob([excelBuffer], { - type: - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8", - }); - import("file-saver").then((FileSaver) => { - FileSaver.saveAs(fileData, `${fileName}.xlsx`); - }); - }); -}; - function TableDataDownload(props: TableDataDownloadProps) { const [selected, selectMenu] = React.useState(false); const downloadFile = (type: string) => { @@ -135,28 +120,49 @@ function TableDataDownload(props: TableDataDownloadProps) { } }; const downloadTableDataAsExcel = () => { - const tableData: string[][] = []; - const tableHeaders: string[] = props.columns + const tableData: Array> = []; + const tableHeaders: Array<{ + value: string | number; + type: string; + }> = props.columns .map((column: ReactTableColumnProps) => { if (column.metaProperties && !column.metaProperties.isHidden) { - return column.Header; + return { + value: column.Header, + type: + column.columnProperties?.columnType === "number" + ? "number" + : "string", + }; } - return ""; + return null; }) .filter((i) => !!i); tableData.push(tableHeaders); for (let row = 0; row < props.data.length; row++) { const data: { [key: string]: any } = props.data[row]; - const tableRow: string[] = []; + const tableRow: Array = []; 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(data[column.accessor]); + tableRow.push({ + value: data[column.accessor], + type: type, + }); } } tableData.push(tableRow); } - downloadDataAsExcel(tableData, props.widgetName); + zipcelx({ + filename: props.widgetName, + sheet: { + data: tableData, + }, + }); }; const downloadTableDataAsCsv = () => { selectMenu(true); diff --git a/app/client/yarn.lock b/app/client/yarn.lock index 30d01ec58c..e7f1d6339f 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -3413,7 +3413,6 @@ "@testing-library/react@^11.2.6": version "11.2.6" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.6.tgz#586a23adc63615985d85be0c903f374dab19200b" - integrity sha512-TXMCg0jT8xmuU8BkKMtp8l7Z50Ykew5WNX8UoIKTaLFwKkP2+1YDhOLA2Ga3wY4x29jyntk7EWfum0kjlYiSjQ== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" @@ -3520,10 +3519,6 @@ version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" -"@types/file-saver@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.2.tgz#bd593ccfaee42ff94a5c1c83bf69ae9be83493b9" - "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -3800,7 +3795,6 @@ "@types/react-test-renderer@^17.0.1": version "17.0.1" resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b" - integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw== dependencies: "@types/react" "*" @@ -3984,10 +3978,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/zipcelx@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@types/zipcelx/-/zipcelx-1.5.0.tgz#e06e9ed51fadbc7fbcf15fbeb2bcbf446750c72e" + "@typescript-eslint/eslint-plugin@^4.15.0": version "4.15.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.1.tgz#835f64aa0a403e5e9e64c10ceaf8d05c3f015180" - integrity sha512-yW2epMYZSpNJXZy22Biu+fLdTG8Mn6b22kR3TqblVk50HGNV8Zya15WAXuQCr8tKw4Qf1BL4QtI6kv6PCkLoJw== dependencies: "@typescript-eslint/experimental-utils" "4.15.1" "@typescript-eslint/scope-manager" "4.15.1" @@ -4013,7 +4010,6 @@ "@typescript-eslint/experimental-utils@4.15.1": version "4.15.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.1.tgz#d744d1ac40570a84b447f7aa1b526368afd17eec" - integrity sha512-9LQRmOzBRI1iOdJorr4jEnQhadxK4c9R2aEAsm7WE/7dq8wkKD1suaV0S/JucTL8QlYUPU1y2yjqg+aGC0IQBQ== dependencies: "@types/json-schema" "^7.0.3" "@typescript-eslint/scope-manager" "4.15.1" @@ -4046,7 +4042,6 @@ "@typescript-eslint/parser@^4.15.0": version "4.15.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.15.1.tgz#4c91a0602733db63507e1dbf13187d6c71a153c4" - integrity sha512-V8eXYxNJ9QmXi5ETDguB7O9diAXlIyS+e3xzLoP/oVE4WCAjssxLIa0mqCLsCGXulYJUfT+GV70Jv1vHsdKwtA== dependencies: "@typescript-eslint/scope-manager" "4.15.1" "@typescript-eslint/types" "4.15.1" @@ -4065,7 +4060,6 @@ "@typescript-eslint/scope-manager@4.15.1": version "4.15.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.15.1.tgz#f6511eb38def2a8a6be600c530c243bbb56ac135" - integrity sha512-ibQrTFcAm7yG4C1iwpIYK7vDnFg+fKaZVfvyOm3sNsGAerKfwPVFtYft5EbjzByDJ4dj1WD8/34REJfw/9wdVA== dependencies: "@typescript-eslint/types" "4.15.1" "@typescript-eslint/visitor-keys" "4.15.1" @@ -4084,7 +4078,6 @@ "@typescript-eslint/types@4.15.1": version "4.15.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.15.1.tgz#da702f544ef1afae4bc98da699eaecd49cf31c8c" - integrity sha512-iGsaUyWFyLz0mHfXhX4zO6P7O3sExQpBJ2dgXB0G5g/8PRVfBBsmQIc3r83ranEQTALLR3Vko/fnCIVqmH+mPw== "@typescript-eslint/types@4.6.0": version "4.6.0" @@ -4106,7 +4099,6 @@ "@typescript-eslint/typescript-estree@4.15.1": version "4.15.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.1.tgz#fa9a9ff88b4a04d901ddbe5b248bc0a00cd610be" - integrity sha512-z8MN3CicTEumrWAEB2e2CcoZa3KP9+SMYLIA2aM49XW3cWIaiVSOAGq30ffR5XHxRirqE90fgLw3e6WmNx5uNw== dependencies: "@typescript-eslint/types" "4.15.1" "@typescript-eslint/visitor-keys" "4.15.1" @@ -4138,7 +4130,6 @@ "@typescript-eslint/visitor-keys@4.15.1": version "4.15.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.1.tgz#c76abbf2a3be8a70ed760f0e5756bf62de5865dd" - integrity sha512-tYzaTP9plooRJY8eNlpAewTOqtWW/4ff/5wBjNVaJ0S0wC4Gpq/zDVRTJa5bq2v1pCNQ08xxMCndcvR+h7lMww== dependencies: "@typescript-eslint/types" "4.15.1" eslint-visitor-keys "^2.0.0" @@ -4558,13 +4549,6 @@ adjust-sourcemap-loader@3.0.0: loader-utils "^2.0.0" regex-parser "^2.2.11" -adler-32@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25" - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - agent-base@6: version "6.0.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4" @@ -5880,14 +5864,6 @@ ccount@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" -cfb@^1.1.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.0.tgz#6a4d0872b525ed60349e1ef51fb4b0bf73eca9a8" - dependencies: - adler-32 "~1.2.0" - crc-32 "~1.2.0" - printj "~1.1.2" - chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -6218,13 +6194,6 @@ codemirror@^5.59.2: version "5.59.2" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.59.2.tgz#ee674d3a4a8d241af38d52afc482625ba7393922" -codepage@~1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99" - dependencies: - commander "~2.14.1" - exit-on-epipe "~1.0.1" - collapse-white-space@^1.0.2: version "1.0.6" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" @@ -6308,14 +6277,6 @@ commander@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" -commander@~2.14.1: - version "2.14.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" - -commander@~2.17.1: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -6526,13 +6487,6 @@ craco-babel-loader@^0.1.4: dependencies: "@craco/craco" "^5.0.0" -crc-32@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -8046,10 +8000,6 @@ exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" -exit-on-epipe@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" - exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -8176,7 +8126,6 @@ extsprintf@^1.2.0: factory.ts@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/factory.ts/-/factory.ts-0.5.1.tgz#4bab72d8457078906aa6ab396c0d341e8a3ab382" - integrity sha512-jwAq8w7MmxUojIFzKezMwTzDc5QoxcqzAA8+n9A0EAWBje2CRHUeBrW9x/ioV2DRjHgkHX7i0G0ipfDhlatIQw== dependencies: clone-deep "^4.0.1" source-map-support "^0.5.9" @@ -8285,14 +8234,9 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -fflate@^0.3.8: - version "0.3.11" - resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.3.11.tgz#2c440d7180fdeb819e64898d8858af327b042a5d" - figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" - integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== figures@^1.7.0: version "1.7.0" @@ -8333,7 +8277,7 @@ file-loader@^4.2.0: loader-utils "^1.2.3" schema-utils "^2.5.0" -file-saver@^2.0.5: +file-saver@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38" @@ -8551,10 +8495,6 @@ forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" -frac@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" - fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -10854,6 +10794,15 @@ jstransformer@1.0.0: array-includes "^3.1.1" object.assign "^4.1.1" +jszip@^3.1.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.6.0.tgz#839b72812e3f97819cc13ac4134ffced95dd6af9" + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + set-immediate-shim "~1.0.1" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -10963,6 +10912,12 @@ lie@3.1.1: dependencies: immediate "~3.0.5" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + dependencies: + immediate "~3.0.5" + line-column@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/line-column/-/line-column-1.0.2.tgz#d25af2936b6f4849172b312e4792d1d987bc34a2" @@ -11145,6 +11100,10 @@ lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" +lodash.escape@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + lodash.flow@^3.3.0: version "3.5.0" resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" @@ -12496,7 +12455,7 @@ paging-algorithm@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/paging-algorithm/-/paging-algorithm-1.0.1.tgz#18abe482a6a202bfaab4b023a407c8cc2072cb8a" -pako@~1.0.5: +pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -13500,10 +13459,6 @@ pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" -printj@~1.1.0, printj@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - prismjs@^1.23.0, prismjs@^1.8.4: version "1.23.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33" @@ -13865,7 +13820,6 @@ raw-loader@^4.0.2: rc-pagination@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.3.tgz#afd779839fefab2cb14248d5e7b74027960bb48b" - integrity sha512-Z7CdC4xGkedfAwcUHPtfqNhYwVyDgkmhkvfsmoByCOwAd89p42t5O5T3ORar1wRmVWf3jxk/Bf4k0atenNvlFA== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.1" @@ -15402,6 +15356,10 @@ set-cookie-parser@^2.4.6: version "2.4.8" resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz#d0da0ed388bc8f24e706a391f9c9e252a13c58b2" +set-immediate-shim@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -15742,12 +15700,6 @@ sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -ssf@~0.11.2: - version "0.11.2" - resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" - dependencies: - frac "~1.1.2" - sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -15765,7 +15717,6 @@ sshpk@^1.7.0: ssri@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" - integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== dependencies: figgy-pudding "^3.5.1" @@ -16601,7 +16552,6 @@ tslib@^2.0.0, tslib@^2.0.1: tslib@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== tslib@~1.13.0: version "1.13.0" @@ -16707,7 +16657,6 @@ typescript-tuple@^2.2.1: typescript@^4.1.3: version "4.1.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72" - integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== ua-parser-js@^0.7.18: version "0.7.22" @@ -17383,18 +17332,10 @@ with@^7.0.0: assert-never "^1.2.1" babel-walk "3.0.0-canary-5" -wmf@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" - word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" -word@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" - workbox-background-sync@^5.1.4: version "5.1.4" resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz#5ae0bbd455f4e9c319e8d827c055bb86c894fd12" @@ -17634,21 +17575,6 @@ ws@^7.2.3: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" -xlsx@^0.16.9: - version "0.16.9" - resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.16.9.tgz#dacd5bb46bda6dd3743940c9c3dc1e2171826256" - dependencies: - adler-32 "~1.2.0" - cfb "^1.1.4" - codepage "~1.14.0" - commander "~2.17.1" - crc-32 "~1.2.0" - exit-on-epipe "~1.0.1" - fflate "^0.3.8" - ssf "~0.11.2" - wmf "~1.0.1" - word "~0.3.0" - xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" @@ -17788,6 +17714,14 @@ yauzl@^2.10.0: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" +zipcelx@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/zipcelx/-/zipcelx-1.6.2.tgz#ae99aa8c04f440d17c52fcdcbc6abc79d6993b3b" + dependencies: + file-saver "^2.0.0" + jszip "^3.1.3" + lodash.escape "^4.0.1" + zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" From 9469571a0cc95b6b2160d982ca6136b67afad14d Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Thu, 29 Apr 2021 15:33:40 +0530 Subject: [PATCH 11/76] Fix type issue --- .../TableComponent/TableDataDownload.tsx | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx index fd914ce941..29b63999f2 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx @@ -121,23 +121,19 @@ function TableDataDownload(props: TableDataDownloadProps) { }; const downloadTableDataAsExcel = () => { const tableData: Array> = []; - const tableHeaders: Array<{ - value: string | number; - type: string; - }> = props.columns - .map((column: ReactTableColumnProps) => { - if (column.metaProperties && !column.metaProperties.isHidden) { - return { - value: column.Header, - type: - column.columnProperties?.columnType === "number" - ? "number" - : "string", - }; - } - return null; + const tableHeaders: Array = props.columns + .filter((column: ReactTableColumnProps) => { + return column.metaProperties && !column.metaProperties.isHidden; }) - .filter((i) => !!i); + .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]; From e3b361a8d4c78804b06bf86007bc85908adb0194 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Mon, 3 May 2021 14:33:03 +0530 Subject: [PATCH 12/76] Change inline functions in jsx to class properties --- app/client/src/widgets/TableWidget/index.tsx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/client/src/widgets/TableWidget/index.tsx b/app/client/src/widgets/TableWidget/index.tsx index 3ab7652ff5..434e7b89d2 100644 --- a/app/client/src/widgets/TableWidget/index.tsx +++ b/app/client/src/widgets/TableWidget/index.tsx @@ -603,6 +603,17 @@ class TableWidget extends BaseWidget { return selectedRowIndices; }; + applyFilters = () => { + (filters: ReactTableFilter[]) => { + this.resetSelectedRowIndex(); + this.props.updateWidgetMetaProperty("filters", filters); + }; + }; + + disableDrag = (disable: boolean) => { + this.disableDrag(disable); + }; + getPageView() { const { pageSize, filteredTableData = [] } = this.props; const tableColumns = this.getTableColumns() || []; @@ -612,16 +623,11 @@ class TableWidget extends BaseWidget { return ( }> { - this.resetSelectedRowIndex(); - this.props.updateWidgetMetaProperty("filters", filters); - }} + applyFilter={this.applyFilters} columnSizeMap={this.props.columnSizeMap} columns={tableColumns} compactMode={this.props.compactMode || CompactModeTypes.DEFAULT} - disableDrag={(disable: boolean) => { - this.disableDrag(disable); - }} + disableDrag={this.disableDrag} editMode={this.props.renderMode === RenderModes.CANVAS} filters={this.props.filters} handleReorderColumn={this.handleReorderColumn} From 2a3d0fd28e1af07e8487e974932fc422d4eac723 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Tue, 4 May 2021 00:12:21 +0530 Subject: [PATCH 13/76] - Destructure TableComponent props --- .../appsmith/TableComponent/index.tsx | 102 ++++++++++++------ 1 file changed, 67 insertions(+), 35 deletions(-) diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx index 0e6c769657..77fea998df 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx @@ -68,10 +68,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 +111,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 +181,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 +191,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,48 +208,48 @@ function ReactTableComponent(props: ReactTableComponentProps) { original: Record; index: number; }) => { - props.onRowClick(row.original, row.index); + onRowClick(row.original, row.index); }; return ( { - 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} + filters={filters} + handleResizeColumn={handleResizeColumn} + height={height} + isLoading={isLoading} nextPageClick={() => { - props.nextPageClick(); + nextPageClick(); }} - pageNo={props.pageNo - 1} - pageSize={props.pageSize || 1} + pageNo={pageNo - 1} + pageSize={pageSize || 1} prevPageClick={() => { - props.prevPageClick(); + prevPageClick(); }} - searchKey={props.searchKey} - searchTableData={props.searchTableData} + 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} /> ); } From adb5f7bc7ac33034b0314a3fc283f7411ff36fbe Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Tue, 4 May 2021 12:21:08 +0530 Subject: [PATCH 14/76] - Memoize ReactTableComponent --- .../appsmith/TableComponent/index.tsx | 38 ++++++++++++++++++- app/client/src/utils/hooks/usePrevious.tsx | 9 +++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 app/client/src/utils/hooks/usePrevious.tsx diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx index 77fea998df..7a3428d089 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx @@ -7,6 +7,8 @@ import { ReactTableFilter, } from "components/designSystems/appsmith/TableComponent/Constants"; import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import usePrevious from "utils/hooks/usePrevious"; +import _ from "lodash"; export interface ColumnMenuOptionProps { content: string | JSX.Element; @@ -254,4 +256,38 @@ function ReactTableComponent(props: ReactTableComponentProps) { ); } -export default ReactTableComponent; +export default React.memo(ReactTableComponent, (prev, next) => { + return ( + prev.applyFilter === next.applyFilter && + prev.columnSizeMap === next.columnSizeMap && + 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.tableData, next.tableData) && + // TODO(Satish) // Check why _.isEqual is not working as expected + (JSON.stringify(prev.columns) === JSON.stringify(next.columns) || + _.isEqual(prev.columns, next.columns)) + ); +}); diff --git a/app/client/src/utils/hooks/usePrevious.tsx b/app/client/src/utils/hooks/usePrevious.tsx new file mode 100644 index 0000000000..a883f87a27 --- /dev/null +++ b/app/client/src/utils/hooks/usePrevious.tsx @@ -0,0 +1,9 @@ +import { useRef, useEffect } from "react"; + +export default function usePrevious(value: any) { + const ref = useRef(value); + useEffect(() => { + ref.current = value; + }); + return ref.current; +} From 611a07af75fda4b766cf6bec831bf94c99b48b0b Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Tue, 4 May 2021 19:45:29 +0530 Subject: [PATCH 15/76] Add eslint rule to sort destructure keys --- app/client/.eslintrc.json | 5 +++-- app/client/package.json | 1 + app/client/yarn.lock | 12 ++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/client/.eslintrc.json b/app/client/.eslintrc.json index fe0ab77466..7cf9b9c110 100644 --- a/app/client/.eslintrc.json +++ b/app/client/.eslintrc.json @@ -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": { diff --git a/app/client/package.json b/app/client/package.json index bc24cf83d9..02f95af730 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -224,6 +224,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", diff --git a/app/client/yarn.lock b/app/client/yarn.lock index 8af878b06b..a6af49a55e 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -7956,6 +7956,13 @@ eslint-plugin-react@^7.21.5: resolve "^1.18.1" string.prototype.matchall "^4.0.2" +eslint-plugin-sort-destructure-keys@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-sort-destructure-keys/-/eslint-plugin-sort-destructure-keys-1.3.5.tgz#c6f45c3e58d4435564025a6ca5f4a838010800fd" + integrity sha512-JmVpidhDsLwZsmRDV7Tf/vZgOAOEQGkLtwToSvX5mD8fuWYS/xkgMRBsalW1fGlc8CgJJwnzropt4oMQ7YCHLg== + dependencies: + natural-compare-lite "^1.4.0" + eslint-plugin-testing-library@^3.9.2: version "3.9.2" resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.9.2.tgz#ea94048fcc4bf2936588af229d78017c780e9dd6" @@ -12122,6 +12129,11 @@ native-url@^0.2.6: dependencies: querystring "^0.2.0" +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q= + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" From 4543bcc39ebd159b0a962f86b2f3074e0768cd23 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Tue, 4 May 2021 19:45:29 +0530 Subject: [PATCH 16/76] Add eslint rule to warn against inline functions in jsx --- app/client/.eslintrc.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/client/.eslintrc.json b/app/client/.eslintrc.json index 7cf9b9c110..e585704a83 100644 --- a/app/client/.eslintrc.json +++ b/app/client/.eslintrc.json @@ -35,7 +35,14 @@ "react/jsx-sort-props": "error", "react/jsx-fragments": "error", "react/jsx-no-useless-fragment": "error", - "sort-destructure-keys/sort-destructure-keys": ["error", {"caseSensitive": false}] + "sort-destructure-keys/sort-destructure-keys": ["warn", {"caseSensitive": false}], + "react/jsx-no-bind": ["warn", { + "ignoreDOMComponents": false, + "ignoreRefs": true, + "allowArrowFunctions": false, + "allowFunctions": false, + "allowBind": false + }] }, "settings": { "react": { From a29b20eca50835b27395d23cdb196ccd9208adc6 Mon Sep 17 00:00:00 2001 From: bhavin Date: Wed, 5 May 2021 11:53:59 +0530 Subject: [PATCH 17/76] fix: set date picker calendar popover position to bottom --- .../components/designSystems/blueprint/DatePickerComponent2.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx b/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx index 13f2aaf2e5..3fd16fe5e7 100644 --- a/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx +++ b/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx @@ -150,6 +150,7 @@ class DatePickerComponent extends React.Component< onChange={this.onDateSelected} parseDate={this.parseDate} placeholder={"Select Date"} + popoverProps={{ position: "bottom" }} showActionsBar timePrecision={TimePrecision.MINUTE} value={value} From e96fa63f6d97910f0b1c349d5049b3ece6c4f3f9 Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Wed, 5 May 2021 12:39:15 +0530 Subject: [PATCH 18/76] Disable client side search when server side search is enabled in table widget --- app/client/src/widgets/TableWidget/derived.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/client/src/widgets/TableWidget/derived.js b/app/client/src/widgets/TableWidget/derived.js index 1d5a39e4fe..77fb93e56d 100644 --- a/app/client/src/widgets/TableWidget/derived.js +++ b/app/client/src/widgets/TableWidget/derived.js @@ -360,7 +360,10 @@ export default { }, }; - const searchKey = props.searchText ? props.searchText.toLowerCase() : ""; + const searchKey = + props.searchText && !props.onSearchTextChanged + ? props.searchText.toLowerCase() + : ""; const finalTableData = sortedTableData.filter((item) => { const searchFound = searchKey From 9fc5770d7209c893d5b63c2674da34b03eb00339 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Wed, 5 May 2021 18:31:11 +0530 Subject: [PATCH 19/76] - Refactor the Cell render function and change it into a class property. - Remove unsed hook. --- .../appsmith/TableComponent/index.tsx | 9 +- app/client/src/utils/hooks/usePrevious.tsx | 9 -- app/client/src/widgets/TableWidget/index.tsx | 101 +++++++++--------- 3 files changed, 56 insertions(+), 63 deletions(-) delete mode 100644 app/client/src/utils/hooks/usePrevious.tsx diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx index 7a3428d089..defd25ed7d 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx @@ -1,14 +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 usePrevious from "utils/hooks/usePrevious"; import _ from "lodash"; +import React, { useEffect, useMemo } from "react"; export interface ColumnMenuOptionProps { content: string | JSX.Element; @@ -286,8 +285,6 @@ export default React.memo(ReactTableComponent, (prev, next) => { prev.widgetName === next.widgetName && prev.width === next.width && _.isEqual(prev.tableData, next.tableData) && - // TODO(Satish) // Check why _.isEqual is not working as expected - (JSON.stringify(prev.columns) === JSON.stringify(next.columns) || - _.isEqual(prev.columns, next.columns)) + _.isEqual(prev.columns, next.columns) ); }); diff --git a/app/client/src/utils/hooks/usePrevious.tsx b/app/client/src/utils/hooks/usePrevious.tsx deleted file mode 100644 index a883f87a27..0000000000 --- a/app/client/src/utils/hooks/usePrevious.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { useRef, useEffect } from "react"; - -export default function usePrevious(value: any) { - const ref = useRef(value); - useEffect(() => { - ref.current = value; - }); - return ref.current; -} diff --git a/app/client/src/widgets/TableWidget/index.tsx b/app/client/src/widgets/TableWidget/index.tsx index 434e7b89d2..a7a383b509 100644 --- a/app/client/src/widgets/TableWidget/index.tsx +++ b/app/client/src/widgets/TableWidget/index.tsx @@ -124,6 +124,58 @@ class TableWidget extends BaseWidget { return cellProperties; }; + cellRenderer = (props: any) => { + const allColumnProperties = this.props.tableColumns || []; + const index = props.column.columnProperties.index; + const columnProperties = allColumnProperties[index]; + const isHidden = !columnProperties.isVisible; + const { componentWidth } = this.getComponentDimensions(); + + let rowIndex: number = props.cell.row.index; + const data = this.props.filteredTableData[rowIndex]; + if (data && data.__originalIndex__) rowIndex = data.__originalIndex__; + + const cellProperties = this.getCellProperties(columnProperties, rowIndex); + if (columnProperties.columnType === "button") { + const buttonProps = { + isSelected: !!props.row.isSelected, + onCommandClick: (action: string, onComplete: () => void) => + this.onCommandClick(rowIndex, action, onComplete), + backgroundColor: cellProperties.buttonStyle || "rgb(3, 179, 101)", + buttonLabelColor: cellProperties.buttonLabelColor || "#FFFFFF", + columnActions: [ + { + id: columnProperties.id, + label: cellProperties.buttonLabel || "Action", + dynamicTrigger: columnProperties.onClick || "", + }, + ], + }; + return renderActions(buttonProps, isHidden, cellProperties); + } else if (columnProperties.columnType === "dropdown") { + let options = []; + try { + options = JSON.parse(columnProperties.dropdownOptions || ""); + } catch (e) {} + return renderDropdown({ + options: options, + onItemSelect: this.onItemSelect, + onOptionChange: columnProperties.onOptionChange || "", + selectedIndex: isNumber(props.cell.value) + ? props.cell.value + : undefined, + }); + } else { + return renderCell( + props.cell.value, + columnProperties.columnType, + isHidden, + cellProperties, + componentWidth, + ); + } + }; + getTableColumns = () => { let columns: ReactTableColumnProps[] = []; const hiddenColumns: ReactTableColumnProps[] = []; @@ -160,54 +212,7 @@ class TableWidget extends BaseWidget { inputFormat: columnProperties?.inputFormat || "", }, columnProperties: columnProperties, - Cell: (props: any) => { - let rowIndex: number = props.cell.row.index; - const data = this.props.filteredTableData[rowIndex]; - if (data && data.__originalIndex__) rowIndex = data.__originalIndex__; - - const cellProperties = this.getCellProperties( - columnProperties, - rowIndex, - ); - if (columnProperties.columnType === "button") { - const buttonProps = { - isSelected: !!props.row.isSelected, - onCommandClick: (action: string, onComplete: () => void) => - this.onCommandClick(rowIndex, action, onComplete), - backgroundColor: cellProperties.buttonStyle || "rgb(3, 179, 101)", - buttonLabelColor: cellProperties.buttonLabelColor || "#FFFFFF", - columnActions: [ - { - id: columnProperties.id, - label: cellProperties.buttonLabel || "Action", - dynamicTrigger: columnProperties.onClick || "", - }, - ], - }; - return renderActions(buttonProps, isHidden, cellProperties); - } else if (columnProperties.columnType === "dropdown") { - let options = []; - try { - options = JSON.parse(columnProperties.dropdownOptions || ""); - } catch (e) {} - return renderDropdown({ - options: options, - onItemSelect: this.onItemSelect, - onOptionChange: columnProperties.onOptionChange || "", - selectedIndex: isNumber(props.cell.value) - ? props.cell.value - : undefined, - }); - } else { - return renderCell( - props.cell.value, - columnProperties.columnType, - isHidden, - cellProperties, - componentWidth, - ); - } - }, + Cell: this.cellRenderer, }; if (isHidden) { columnData.isHidden = true; From 575a9cf120900c3a73a05352bc5e9cd29733a5fe Mon Sep 17 00:00:00 2001 From: Nidhi Date: Wed, 5 May 2021 11:43:47 +0530 Subject: [PATCH 20/76] Resetting cypress in CI --- .github/workflows/client-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client-test.yml b/.github/workflows/client-test.yml index f75b3a7112..e55457c5d2 100644 --- a/.github/workflows/client-test.yml +++ b/.github/workflows/client-test.yml @@ -296,7 +296,7 @@ jobs: - run: echo "All ui-test matrices completed" package: - needs: build + needs: ui-test runs-on: ubuntu-latest defaults: run: From c81216255e6ab17c636ed53f07c930d7d0d76774 Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Wed, 5 May 2021 16:50:59 +0530 Subject: [PATCH 21/76] In case the chart series data id starts with a number, it was incorrectly identified as a number instead of a string which led to incorrect path computed to check in binding paths (#4322) --- app/client/src/workers/evaluationUtils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/client/src/workers/evaluationUtils.ts b/app/client/src/workers/evaluationUtils.ts index c11fd3c8c0..781408fbe8 100644 --- a/app/client/src/workers/evaluationUtils.ts +++ b/app/client/src/workers/evaluationUtils.ts @@ -57,8 +57,7 @@ export const convertPathToString = (arrPath: Array) => { // Todo: improve the logic here // Right now NaN, Infinity, floats, everything works function isInt(val: string | number): boolean { - if (typeof val === "number") return true; - return !isNaN(parseInt(val)); + return Number.isInteger(val) || (_.isString(val) && /^\d+$/.test(val)); } // Removes the entity name from the property path From 925448c099b028efbac52cfdb119958616dae933 Mon Sep 17 00:00:00 2001 From: Rishabh Saxena Date: Wed, 5 May 2021 16:51:15 +0530 Subject: [PATCH 22/76] Log an analytics event for cyclical dependency errors (#4323) --- app/client/src/sagas/EvaluationsSaga.ts | 8 ++++++++ app/client/src/utils/AnalyticsUtil.tsx | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index 7aef086af0..ef782826ee 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -40,6 +40,7 @@ import { } from "constants/messages"; import AppsmithConsole from "utils/AppsmithConsole"; import LOG_TYPE from "entities/AppsmithConsole/logtype"; +import AnalyticsUtil from "utils/AnalyticsUtil"; let widgetTypeConfigMap: WidgetTypeConfigMap; @@ -66,6 +67,13 @@ const evalErrorHandler = (errors: EvalError[]) => { // Level is warning because it could be a user error level: Sentry.Severity.Warning, }); + // Log an analytics event for cyclical dep errors + AnalyticsUtil.logEvent("CYCLICAL_DEPENDENCY_ERROR", { + node, + entityType, + // Level is warning because it could be a user error + level: Sentry.Severity.Warning, + }); } break; diff --git a/app/client/src/utils/AnalyticsUtil.tsx b/app/client/src/utils/AnalyticsUtil.tsx index d23b1505bd..534208b675 100644 --- a/app/client/src/utils/AnalyticsUtil.tsx +++ b/app/client/src/utils/AnalyticsUtil.tsx @@ -119,7 +119,8 @@ export type EventName = | "DEBUGGER_TAB_SWITCH" | "DEBUGGER_ENTITY_NAVIGATION" | "GSHEET_AUTH_INIT" - | "GSHEET_AUTH_COMPLETE"; + | "GSHEET_AUTH_COMPLETE" + | "CYCLICAL_DEPENDENCY_ERROR"; function getApplicationId(location: Location) { const pathSplit = location.pathname.split("/"); From f30e4e4ad2c82e0dc753bd4b4f310432caf16512 Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Wed, 5 May 2021 17:55:39 +0530 Subject: [PATCH 23/76] During updateDependencyMap, when dependencies are getting added for a path, only add if the dependency is not a parent of the path. (#4315) * During updateDependencyMap, when dependencies are getting added for a path, only add if the dependency is not a parent of the path. * To avoid catching all cyclical dependencies, only handling catching incorrect action dependencies when the dependency paths dont yet exist. * Revert "To avoid catching all cyclical dependencies, only handling catching incorrect action dependencies when the dependency paths dont yet exist." This reverts commit c494932289e33287074c56844fbf76c8418875af. * Disabling cypress test which asserts cyclical errors when depending on yourself --- .../DisplayWidgets/Text_spec.js | 54 +++++++++---------- app/client/src/workers/DataTreeEvaluator.ts | 29 +++++++--- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js index cf610c78f5..2732da5b7c 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js @@ -61,33 +61,33 @@ describe("Text Widget Functionality", function() { .should("have.css", "font-size", "18px"); }); - it("Text widget depends on itself", function() { - cy.getCodeMirror().then(($cm) => { - if ($cm.val() !== "") { - cy.get(".CodeMirror textarea") - .first() - .clear({ - force: true, - }); - } - - cy.get(".CodeMirror textarea") - .first() - .type(`{{${this.data.TextName}}}`, { - force: true, - parseSpecialCharSequences: false, - }); - }); - cy.get(commonlocators.toastBody) - .first() - .contains("Cyclic"); - - cy.PublishtheApp(); - cy.get(commonlocators.bodyTextStyle).should( - "have.text", - `{{${this.data.TextName}}}`, - ); - }); + // it("Text widget depends on itself", function() { + // cy.getCodeMirror().then(($cm) => { + // if ($cm.val() !== "") { + // cy.get(".CodeMirror textarea") + // .first() + // .clear({ + // force: true, + // }); + // } + // + // cy.get(".CodeMirror textarea") + // .first() + // .type(`{{${this.data.TextName}}}`, { + // force: true, + // parseSpecialCharSequences: false, + // }); + // }); + // cy.get(commonlocators.toastBody) + // .first() + // .contains("Cyclic"); + // + // cy.PublishtheApp(); + // cy.get(commonlocators.bodyTextStyle).should( + // "have.text", + // `{{${this.data.TextName}}}`, + // ); + // }); afterEach(() => { cy.get(publishPage.backToEditor).click({ force: true }); diff --git a/app/client/src/workers/DataTreeEvaluator.ts b/app/client/src/workers/DataTreeEvaluator.ts index 389c7a7dfd..767815b367 100644 --- a/app/client/src/workers/DataTreeEvaluator.ts +++ b/app/client/src/workers/DataTreeEvaluator.ts @@ -305,7 +305,7 @@ export default class DataTreeEvaluator { Object.keys(dependencyMap).forEach((key) => { dependencyMap[key] = _.flatten( dependencyMap[key].map((path) => - extractReferencesFromBinding(path, this.allKeys), + extractReferencesFromBinding(key, path, this.allKeys), ), ); }); @@ -405,7 +405,6 @@ export default class DataTreeEvaluator { evalPropertyValue = unEvalPropertyValue; } - // debugger; if (isWidget(entity)) { const widgetEntity = entity; const defaultPropertyMap = this.widgetConfigMap[widgetEntity.type] @@ -891,7 +890,7 @@ export default class DataTreeEvaluator { this.dependencyMap[key] = _.uniq( _.flatten( this.dependencyMap[key].map((path) => - extractReferencesFromBinding(path, this.allKeys), + extractReferencesFromBinding(key, path, this.allKeys), ), ), ); @@ -1028,7 +1027,7 @@ export default class DataTreeEvaluator { const propertyBindings = entityPropertyBindings[path]; const references = _.flatten( propertyBindings.map((binding) => - extractReferencesFromBinding(binding, this.allKeys), + extractReferencesFromBinding(path, binding, this.allKeys), ), ); references.forEach((value) => { @@ -1091,14 +1090,17 @@ export default class DataTreeEvaluator { const extractReferencesFromBinding = ( path: string, + dependentPath: string, all: Record, ): Array => { const subDeps: Array = []; - const identifiers = path.match(/[a-zA-Z_$][a-zA-Z_$0-9.\[\]]*/g) || [path]; + const identifiers = dependentPath.match(/[a-zA-Z_$][a-zA-Z_$0-9.\[\]]*/g) || [ + dependentPath, + ]; identifiers.forEach((identifier: string) => { // If the identifier exists directly, add it and return if (all.hasOwnProperty(identifier)) { - subDeps.push(identifier); + pushDependentsInSubDependencyArray(subDeps, path, identifier); return; } const subpaths = _.toPath(identifier); @@ -1111,7 +1113,7 @@ const extractReferencesFromBinding = ( current = convertPathToString(subpaths); // We've found the dep, add it and return if (all.hasOwnProperty(current)) { - subDeps.push(current); + pushDependentsInSubDependencyArray(subDeps, path, current); return; } subpaths.pop(); @@ -1120,6 +1122,19 @@ const extractReferencesFromBinding = ( return _.uniq(subDeps); }; +const pushDependentsInSubDependencyArray = ( + subDeps: string[], + path: string, + dependentPath: string, +): string[] => { + // Only add if path is not a child of dependentPath which ensures that cyclical dependency is not introduced + // when adding parent-child relationships later + if (!isChildPropertyPath(dependentPath, path)) { + subDeps.push(dependentPath); + } + return subDeps; +}; + // TODO cryptic comment below. Dont know if we still need this. Duplicate function // referencing DATA_BIND_REGEX fails for the value "{{Table1.tableData[Table1.selectedRowIndex]}}" if you run it multiple times and don't recreate const isDynamicValue = (value: string): boolean => DATA_BIND_REGEX.test(value); From f193ff4a2124808c998efeecc15a0a86ba0cce55 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Thu, 6 May 2021 12:01:39 +0530 Subject: [PATCH 24/76] - Remove the accidental recursive funciton call in tablewidget --- app/client/src/widgets/TableWidget/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/client/src/widgets/TableWidget/index.tsx b/app/client/src/widgets/TableWidget/index.tsx index a7a383b509..a3ed198da7 100644 --- a/app/client/src/widgets/TableWidget/index.tsx +++ b/app/client/src/widgets/TableWidget/index.tsx @@ -615,7 +615,7 @@ class TableWidget extends BaseWidget { }; }; - disableDrag = (disable: boolean) => { + toggleDrag = (disable: boolean) => { this.disableDrag(disable); }; @@ -632,7 +632,7 @@ class TableWidget extends BaseWidget { columnSizeMap={this.props.columnSizeMap} columns={tableColumns} compactMode={this.props.compactMode || CompactModeTypes.DEFAULT} - disableDrag={this.disableDrag} + disableDrag={this.toggleDrag} editMode={this.props.renderMode === RenderModes.CANVAS} filters={this.props.filters} handleReorderColumn={this.handleReorderColumn} From a5dbb5261b0d98f8dfe4c55c96c659ac7681c0e9 Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Thu, 6 May 2021 13:54:18 +0530 Subject: [PATCH 25/76] Added test case to validate onSearchTextChange function if configured in table widget --- app/client/cypress/fixtures/tableWidgetDsl.json | 6 +++++- .../ClientSideTests/Binding/Bind_tableApi_spec.js | 13 +++++++++++++ app/client/cypress/locators/Widgets.json | 2 ++ .../designSystems/appsmith/SearchComponent.tsx | 1 + 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/client/cypress/fixtures/tableWidgetDsl.json b/app/client/cypress/fixtures/tableWidgetDsl.json index 349f604903..9929225f5e 100644 --- a/app/client/cypress/fixtures/tableWidgetDsl.json +++ b/app/client/cypress/fixtures/tableWidgetDsl.json @@ -67,7 +67,11 @@ "bottomRow": 10, "parentId": "tyiwk4xuq0", "widgetId": "5up3r2iuvs", - "dynamicBindingPathList": [] + "dynamicTriggerPathList": [{ + "key": "onSearchTextChanged" + }], + "onSearchTextChanged": "{{Api1.run()}}", + "selectedRow": "{{Table1.tableData[Table1.selectedRowIndex]}}" } ], "widgetId": "tyiwk4xuq0", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_tableApi_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_tableApi_spec.js index d65d22e80d..fb8eeb6b6e 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_tableApi_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_tableApi_spec.js @@ -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(() => { diff --git a/app/client/cypress/locators/Widgets.json b/app/client/cypress/locators/Widgets.json index 3e67eecebb..514ff56cc2 100644 --- a/app/client/cypress/locators/Widgets.json +++ b/app/client/cypress/locators/Widgets.json @@ -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", diff --git a/app/client/src/components/designSystems/appsmith/SearchComponent.tsx b/app/client/src/components/designSystems/appsmith/SearchComponent.tsx index 46bfac9a87..df90ccb1a4 100644 --- a/app/client/src/components/designSystems/appsmith/SearchComponent.tsx +++ b/app/client/src/components/designSystems/appsmith/SearchComponent.tsx @@ -52,6 +52,7 @@ class SearchComponent extends React.Component< render() { return ( Date: Sun, 9 May 2021 05:14:20 +0100 Subject: [PATCH 26/76] docs: Updates server readme.md (#4375) --- app/server/README.md | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/app/server/README.md b/app/server/README.md index d59286da54..29193833b4 100644 --- a/app/server/README.md +++ b/app/server/README.md @@ -2,32 +2,5 @@ This is the server-side repository for the Appsmith framework. -### How to build -```bash -$ ./build.sh -``` - -For example: -```$bash -$ ./build.sh -DskipTests -``` - -This script will perform the following steps: -1. Compile the code -2. Generate the jars for server & plugins -3. Copy them into the `dist` directory - -### How to run -``` -$ cd ./dist -$ java -jar -Dspring.profiles.active=$env server-1.0-SNAPSHOT.jar -``` - -### How to test -In order to test the code, you can run the following command: - -``` -mvn -B clean package -``` - -Please make sure that you have a local Redis instance running for the test cases. During tests, the MongoDB is run in-memory. So you don't require to be running a local MongoDB instance. +## Dev Setup +For details on setting up the server on your development machine, please refer to the [Setup Guide](https://github.com/appsmithorg/appsmith/blob/master/contributions/ServerSetup.md) From 4c824a1214275a6298da0105d8a710e62131538c Mon Sep 17 00:00:00 2001 From: bhavin Date: Mon, 10 May 2021 13:14:29 +0530 Subject: [PATCH 27/76] fix: datepicker popover adjust height and width. --- .../designSystems/blueprint/DatePickerComponent2.tsx | 1 - app/client/src/globalStyles/popover.ts | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx b/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx index 3fd16fe5e7..13f2aaf2e5 100644 --- a/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx +++ b/app/client/src/components/designSystems/blueprint/DatePickerComponent2.tsx @@ -150,7 +150,6 @@ class DatePickerComponent extends React.Component< onChange={this.onDateSelected} parseDate={this.parseDate} placeholder={"Select Date"} - popoverProps={{ position: "bottom" }} showActionsBar timePrecision={TimePrecision.MINUTE} value={value} diff --git a/app/client/src/globalStyles/popover.ts b/app/client/src/globalStyles/popover.ts index 82cb292a1d..1da1bde98f 100644 --- a/app/client/src/globalStyles/popover.ts +++ b/app/client/src/globalStyles/popover.ts @@ -5,4 +5,11 @@ export const PopoverStyles = createGlobalStyle` .${Classes.POPOVER} { box-shadow: 0px 0px 2px rgb(0 0 0 / 20%), 0px 2px 10px rgb(0 0 0 / 10%); } + + .bp3-datepicker { + .DayPicker { + min-height: 251px !important ; + min-width: 233px !important ; + } + } `; From 30510c56b468bf74d1775b2e2ba71c57291eee2f Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Mon, 10 May 2021 15:08:23 +0530 Subject: [PATCH 28/76] Fix download dropdown UI --- .../icons/control/download-data-icon.svg | 3 +++ .../TableComponent/TableDataDownload.tsx | 23 +++++++++---------- app/client/src/constants/Colors.tsx | 1 + 3 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 app/client/src/assets/icons/control/download-data-icon.svg diff --git a/app/client/src/assets/icons/control/download-data-icon.svg b/app/client/src/assets/icons/control/download-data-icon.svg new file mode 100644 index 0000000000..2045fa1fb3 --- /dev/null +++ b/app/client/src/assets/icons/control/download-data-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx index 29b63999f2..5c5c80f7dc 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx @@ -7,7 +7,7 @@ import { } 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"; @@ -21,33 +21,32 @@ const DropDownWrapper = styled.div` background: white; z-index: 1; border-radius: 4px; - border: 1px solid ${Colors.ATHENS_GRAY}; - padding: 8px; + box-shadow: 0px 12px 28px -8px rgba(0, 0, 0, 0.1); + padding: 0; `; const OptionWrapper = styled.div` display: flex; - width: calc(100% - 20px); + width: 100%; justify-content: space-between; align-items: center; height: 32px; box-sizing: border-box; - padding: 8px; - color: ${Colors.OXFORD_BLUE}; - opacity: 0.7; + padding: 6px 12px; + color: ${Colors.CHARCOAL}; min-width: 200px; cursor: pointer; - margin-bottom: 4px; background: ${Colors.WHITE}; border-left: none; - border-radius: 4px; + border-radius: none; .option-title { font-weight: 500; - font-size: 14px; - line-height: 24px; + font-size: 13px; + line-height: 20px; } &:hover { - background: ${Colors.POLAR}; + background: ${Colors.SEA_SHELL}; + color: ${Colors.CODE_GRAY}; } `; interface TableDataDownloadProps { diff --git a/app/client/src/constants/Colors.tsx b/app/client/src/constants/Colors.tsx index b3e9bbe418..55b7efec2c 100644 --- a/app/client/src/constants/Colors.tsx +++ b/app/client/src/constants/Colors.tsx @@ -75,6 +75,7 @@ export const Colors: Record = { Galliano: "#E0B30E", ROYAL_BLUE: "#457AE6", ALTO2: "#E0DEDE", + SEA_SHELL: "#F1F1F1", }; export type Color = typeof Colors[keyof typeof Colors]; From 9ab8da4671e2e689dcfb94e91d84653156af11cf Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Mon, 10 May 2021 16:54:50 +0530 Subject: [PATCH 29/76] Table header style changes --- .../assets/icons/control/download-table.svg | 1 - .../src/assets/icons/control/filter-icon.svg | 4 +- .../appsmith/SearchComponent.tsx | 6 +- .../appsmith/TableComponent/TableAction.tsx | 61 +++++++++++++++++++ .../TableComponent/TableActionIcon.tsx | 2 +- .../TableComponent/TableDataDownload.tsx | 12 ++-- .../appsmith/TableComponent/TableFilters.tsx | 8 +-- .../appsmith/TableComponent/TableHeader.tsx | 11 ++-- .../TableComponent/TableStyledWrappers.tsx | 10 ++- app/client/src/constants/Colors.tsx | 5 +- 10 files changed, 95 insertions(+), 25 deletions(-) delete mode 100755 app/client/src/assets/icons/control/download-table.svg mode change 100755 => 100644 app/client/src/assets/icons/control/filter-icon.svg create mode 100644 app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx diff --git a/app/client/src/assets/icons/control/download-table.svg b/app/client/src/assets/icons/control/download-table.svg deleted file mode 100755 index 129ee6b5ad..0000000000 --- a/app/client/src/assets/icons/control/download-table.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/control/filter-icon.svg b/app/client/src/assets/icons/control/filter-icon.svg old mode 100755 new mode 100644 index 1723d3efe8..e5a827016e --- a/app/client/src/assets/icons/control/filter-icon.svg +++ b/app/client/src/assets/icons/control/filter-icon.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/app/client/src/components/designSystems/appsmith/SearchComponent.tsx b/app/client/src/components/designSystems/appsmith/SearchComponent.tsx index 46bfac9a87..61fc672d05 100644 --- a/app/client/src/components/designSystems/appsmith/SearchComponent.tsx +++ b/app/client/src/components/designSystems/appsmith/SearchComponent.tsx @@ -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; diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx new file mode 100644 index 0000000000..b4733bf2e5 --- /dev/null +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx @@ -0,0 +1,61 @@ +import React 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) { + return ( + { + props.selectMenu(!props.selected); + e.stopPropagation(); + }} + selected={props.selected} + > + + {props.children} + + {props.title} + {props.icon ? props.icon : null} + + ); +} + +export default TableAction; diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx index d59cdacf23..63899aacec 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx @@ -34,7 +34,7 @@ function TableActionIcon(props: TableActionIconProps) { selected={props.selected} > diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx index 5c5c80f7dc..71bbd73b33 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx @@ -9,8 +9,9 @@ import { IconWrapper } from "constants/IconConstants"; import { Colors } from "constants/Colors"; 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"; @@ -178,6 +179,7 @@ function TableDataDownload(props: TableDataDownloadProps) { + Download ); } @@ -192,16 +194,16 @@ function TableDataDownload(props: TableDataDownloadProps) { }} position={Position.BOTTOM} > - { selectMenu(selected); }} selected={selected} - tooltip="Download" + title="Download" > - + {dowloadOptions.map((item: DownloadOptionProps, index: number) => { return ( diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableFilters.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableFilters.tsx index 145ace9fe5..5347f5235f 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableFilters.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableFilters.tsx @@ -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 > - - + e.stopPropagation()}> {filters.map((filter: ReactTableFilter, index: number) => { diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableHeader.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableHeader.tsx index 8c5ae271c1..0c7e5ffc34 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableHeader.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableHeader.tsx @@ -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); }} > - + Page{" "} @@ -196,7 +199,7 @@ function TableHeader(props: TableHeaderProps) { props.updatePageNo(pageNo + 1, EventType.ON_NEXT_PAGE); }} > - + )} diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx index e516d2d432..25cc63fcd1 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx @@ -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; `; diff --git a/app/client/src/constants/Colors.tsx b/app/client/src/constants/Colors.tsx index 55b7efec2c..0099b1ee0f 100644 --- a/app/client/src/constants/Colors.tsx +++ b/app/client/src/constants/Colors.tsx @@ -29,7 +29,7 @@ export const Colors: Record = { TUNDORA: "#404040", DOVE_GRAY: "#6D6D6D", SLATE_GRAY: "#768896", - SILVER_CHALICE: "#9F9F9F", + SILVER_CHALICE: "#A9A7A7", PORCELAIN: "#EBEEF0", HIT_GRAY: "#A1ACB3", JUNGLE_MIST: "#BCCCD9", @@ -61,7 +61,7 @@ export const Colors: Record = { TROUT_DARK: "#535B62", ALABASTER: "#F9F8F8", WATUSI: "#FFE0D2", - GRAY: "#828282", + GRAY: "#858282", ATHENS_GRAY_DARKER: "#F8F9FA", POMEGRANATE: "#F44336", RIVER_BED: "#4A545B", @@ -76,6 +76,7 @@ export const Colors: Record = { ROYAL_BLUE: "#457AE6", ALTO2: "#E0DEDE", SEA_SHELL: "#F1F1F1", + DANUBE: "#6A86CE", }; export type Color = typeof Colors[keyof typeof Colors]; From f14ca6b6c3c5f35bea82dbc5537eccc206321725 Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Mon, 10 May 2021 17:04:17 +0530 Subject: [PATCH 30/76] Hide sub icon --- .../designSystems/appsmith/TableComponent/TableActionIcon.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx index 63899aacec..46622d072e 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx @@ -40,7 +40,7 @@ function TableActionIcon(props: TableActionIconProps) { > {props.children} - {props.icon ? props.icon : null} + {/* {props.icon ? props.icon : null} */} ); From 78bad85e244fd0ae92b92ae5e929c0715e34d7b0 Mon Sep 17 00:00:00 2001 From: "vicky-primathon.in" Date: Tue, 11 May 2021 12:10:13 +0530 Subject: [PATCH 31/76] Used useCallBack hook and remove inline arrow function --- .../appsmith/TableComponent/TableAction.tsx | 15 +++++++++------ .../appsmith/TableComponent/TableActionIcon.tsx | 1 - .../appsmith/TableComponent/TableDataDownload.tsx | 12 ++++++------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx index b4733bf2e5..e3c1723f6d 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableAction.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useCallback } from "react"; import { IconWrapper } from "constants/IconConstants"; import { Colors } from "constants/Colors"; import styled from "styled-components"; @@ -36,13 +36,17 @@ export const TableIconWrapper = styled.div<{ `; function TableAction(props: TableActionProps) { + const handleIconClick = useCallback( + (e: React.MouseEvent) => { + props.selectMenu(!props.selected); + e.stopPropagation(); + }, + [props.selected], + ); return ( { - props.selectMenu(!props.selected); - e.stopPropagation(); - }} + onClick={handleIconClick} selected={props.selected} > {props.title} - {props.icon ? props.icon : null} ); } diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx index 46622d072e..37b1dac601 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableActionIcon.tsx @@ -40,7 +40,6 @@ function TableActionIcon(props: TableActionIconProps) { > {props.children} - {/* {props.icon ? props.icon : null} */} ); diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx index 71bbd73b33..bd195b1c2f 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableDataDownload.tsx @@ -173,6 +173,10 @@ function TableDataDownload(props: TableDataDownloadProps) { selectMenu(false); }; + const handleCloseMenu = () => { + selectMenu(false); + }; + if (props.columns.length === 0) { return ( @@ -189,16 +193,12 @@ function TableDataDownload(props: TableDataDownloadProps) { interactionKind={PopoverInteractionKind.CLICK} isOpen={selected} minimal - onClose={() => { - selectMenu(false); - }} + onClose={handleCloseMenu} position={Position.BOTTOM} > { - selectMenu(selected); - }} + selectMenu={selectMenu} selected={selected} title="Download" > From 68c258ab3ae551f9e52be179cc8fcc404f48a9e5 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Tue, 11 May 2021 12:25:42 +0530 Subject: [PATCH 32/76] - Remove unncessary anonymous funciton - Use destructured imports --- .../appsmith/TableComponent/index.tsx | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx index defd25ed7d..885886fee1 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/index.tsx @@ -6,7 +6,7 @@ import { } from "components/designSystems/appsmith/TableComponent/Constants"; import Table from "components/designSystems/appsmith/TableComponent/Table"; import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; -import _ from "lodash"; +import { isEqual } from "lodash"; import React, { useEffect, useMemo } from "react"; export interface ColumnMenuOptionProps { @@ -230,14 +230,10 @@ function ReactTableComponent(props: ReactTableComponentProps) { handleResizeColumn={handleResizeColumn} height={height} isLoading={isLoading} - nextPageClick={() => { - nextPageClick(); - }} + nextPageClick={nextPageClick} pageNo={pageNo - 1} pageSize={pageSize || 1} - prevPageClick={() => { - prevPageClick(); - }} + prevPageClick={prevPageClick} searchKey={searchKey} searchTableData={searchTableData} selectTableRow={selectTableRow} @@ -284,7 +280,7 @@ export default React.memo(ReactTableComponent, (prev, next) => { prev.widgetId === next.widgetId && prev.widgetName === next.widgetName && prev.width === next.width && - _.isEqual(prev.tableData, next.tableData) && - _.isEqual(prev.columns, next.columns) + isEqual(prev.tableData, next.tableData) && + isEqual(prev.columns, next.columns) ); }); From 38ece3fbb7fbbb12deeabaf8093c0e39ac002914 Mon Sep 17 00:00:00 2001 From: arunvjn <32433245+arunvjn@users.noreply.github.com> Date: Fri, 7 May 2021 13:24:58 +0530 Subject: [PATCH 33/76] Added null check against datasource url (#4352) (cherry picked from commit 45aa3c57f1d6c9f01f958b3230a5e1465e013f57) --- .../form/fields/EmbeddedDatasourcePathField.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx b/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx index 94ab53e795..1355fcb2e8 100644 --- a/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx +++ b/app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx @@ -173,7 +173,7 @@ class EmbeddedDatasourcePathComponent extends React.Component { hint: () => { const list = datasourceList .filter((datasource) => - datasource.datasourceConfiguration.url.includes( + (datasource.datasourceConfiguration?.url || "").includes( parsed.datasourceUrl, ), ) From 4dff6e4b5c7e32ec398fd6121fd93b9c47d442b0 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Mon, 10 May 2021 15:22:17 +0530 Subject: [PATCH 34/76] Fix: Cannot read property 'label' of undefined & Cannot read property 'length' of undefined (#4389) * fix for label of undefined * add check for data type Co-authored-by: root (cherry picked from commit fc10625d410cb825efe36df490f87802fad2acaf) --- .../components/designSystems/appsmith/ChartComponent.tsx | 6 ++++-- .../designSystems/blueprint/DropdownComponent.tsx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/client/src/components/designSystems/appsmith/ChartComponent.tsx b/app/client/src/components/designSystems/appsmith/ChartComponent.tsx index ca49f9b40b..43b3bf3b7b 100644 --- a/app/client/src/components/designSystems/appsmith/ChartComponent.tsx +++ b/app/client/src/components/designSystems/appsmith/ChartComponent.tsx @@ -185,7 +185,9 @@ class ChartComponent extends React.Component { getSeriesChartData = (data: ChartDataPoint[], categories: string[]) => { const dataMap: { [key: string]: string } = {}; - if (data.length === 0) { + + // if not array or (is array and array length is zero) + if (!Array.isArray(data) || (Array.isArray(data) && data.length === 0)) { return [ { value: "", @@ -218,7 +220,7 @@ class ChartComponent extends React.Component { const seriesChartData: Array> = this.getSeriesChartData(item.data, categories); + >> = this.getSeriesChartData(get(item, "data", []), categories); return { seriesName: item.seriesName, data: seriesChartData, diff --git a/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx b/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx index f5a45770fe..3487aab4b8 100644 --- a/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx +++ b/app/client/src/components/designSystems/blueprint/DropdownComponent.tsx @@ -337,7 +337,7 @@ class DropDownComponent extends React.Component { }; renderTag = (option: DropdownOption) => { - return option.label; + return option?.label; }; isOptionSelected = (selectedOption: DropdownOption) => { From bb74ba876fed517c976c3d34709aa79135959bcb Mon Sep 17 00:00:00 2001 From: arunvjn <32433245+arunvjn@users.noreply.github.com> Date: Mon, 10 May 2021 19:39:26 +0530 Subject: [PATCH 35/76] Revert Gsheets warning modal (#4405) (cherry picked from commit 1b98c2e520441840ebbfd76a8dc91dfd8a5576db) --- .../Editor/SaaSEditor/DatasourceForm.tsx | 111 ++++-------------- 1 file changed, 22 insertions(+), 89 deletions(-) diff --git a/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx b/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx index 8c2f3f01ca..6d636d0729 100644 --- a/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx +++ b/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx @@ -15,7 +15,6 @@ import { connect } from "react-redux"; import { AppState } from "reducers"; import { getDatasource, getPluginImages } from "selectors/entitiesSelector"; import { ReduxAction } from "constants/ReduxActionConstants"; -import GSheetWarning from "assets/images/GSheet-warning.png"; import { deleteDatasource, getOAuthAccessToken, @@ -43,7 +42,6 @@ import { import { Variant } from "components/ads/common"; import { Toaster } from "components/ads/Toast"; import { PluginType } from "entities/Action"; -import FormDialogComponent from "components/editorComponents/form/FormDialogComponent"; import AnalyticsUtil from "utils/AnalyticsUtil"; interface StateProps extends JSONtoFormProps { @@ -90,21 +88,6 @@ const CreateApiButton = styled(BaseButton)` } `; -const ButtonsContainer = styled.div` - display: flex; - width: 100%; - justify-content: flex-end; - align-items: center; - padding: 10px; -`; - -const WarningContainer = styled.div` - display: flex; - width: 100%; - align-items: center; - flex-direction: column; -`; - class DatasourceSaaSEditor extends JSONtoForm { componentDidMount() { super.componentDidMount(); @@ -165,63 +148,6 @@ class DatasourceSaaSEditor extends JSONtoForm { return this.renderForm(content); } - saasInfoForm = (options: any) => { - const { - match: { - params: { applicationId, datasourceId, pageId }, - }, - isSaving, - } = this.props; - return ( -
    - - - The integration is yet to be verified by google, so you will be - shown a safety warning. To continue authorization, please first - click on "Show Advanced", and second "Go to - Appsmith.com" - - Google Sheet Warning - - - - { - AnalyticsUtil.logEvent("GSHEET_AUTH_INIT", { - applicationId, - datasourceId, - pageId, - }); - this.save( - redirectAuthorizationCode( - pageId, - datasourceId, - PluginType.SAAS, - ), - ); - }} - size="small" - text="Continue" - /> - -
    - ); - }; - renderDataSourceConfigForm = (sections: any) => { const { match: { @@ -281,21 +207,28 @@ class DatasourceSaaSEditor extends JSONtoForm { } text="Delete" /> - - } + { + AnalyticsUtil.logEvent("GSHEET_AUTH_INIT", { + applicationId, + datasourceId, + pageId, + }); + this.save( + redirectAuthorizationCode( + pageId, + datasourceId, + PluginType.SAAS, + ), + ); + }} + size="small" + text="Continue" /> From 640959788cb22aa473f4c7e0177cabc864d9d8b1 Mon Sep 17 00:00:00 2001 From: Apeksha Bhosale <7846888+ApekshaBhosale@users.noreply.github.com> Date: Mon, 10 May 2021 19:40:22 +0530 Subject: [PATCH 36/76] match is not a function (#4409) (cherry picked from commit 2138c9059b586807125b16ba77336aaaba4ca828) --- app/client/src/widgets/ListWidget/ListWidget.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/src/widgets/ListWidget/ListWidget.tsx b/app/client/src/widgets/ListWidget/ListWidget.tsx index acffc99698..5b12f32489 100644 --- a/app/client/src/widgets/ListWidget/ListWidget.tsx +++ b/app/client/src/widgets/ListWidget/ListWidget.tsx @@ -224,7 +224,7 @@ class ListWidget extends BaseWidget, WidgetState> { evaluatedProperty.length > itemIndex ) { const evaluatedValue = evaluatedProperty[itemIndex]; - if (isPlainObject(evaluatedValue)) + if (isPlainObject(evaluatedValue) || Array.isArray(evaluatedValue)) set(widget, path, JSON.stringify(evaluatedValue)); else set(widget, path, evaluatedValue); } From c6a8f81d60d9672bf97d95aa6cebe5f3eaffdd64 Mon Sep 17 00:00:00 2001 From: Apeksha Bhosale <7846888+ApekshaBhosale@users.noreply.github.com> Date: Wed, 12 May 2021 12:10:32 +0530 Subject: [PATCH 37/76] Separating js error and validation error for debugger (#4361) * separate js error and validation error * PR comments fixed and added error for pageload action * reverted to jsError message property * small check for empty errors * small changes for Test to pass * space was missing for test case * removed console statement --- .../CodeEditor/EvaluatedValuePopup.tsx | 7 +- .../editorComponents/CodeEditor/index.tsx | 5 +- .../propertyControls/BaseControl.tsx | 1 + .../propertyControls/CodeEditorControl.tsx | 2 + .../propertyControls/InputTextControl.tsx | 5 ++ .../src/entities/AppsmithConsole/logtype.ts | 1 + .../Editor/PropertyPane/PropertyControl.tsx | 23 ++++++- .../reducers/uiReducers/debuggerReducer.ts | 6 +- app/client/src/sagas/ActionExecutionSagas.ts | 12 ++++ app/client/src/sagas/DebuggerSagas.ts | 13 +++- app/client/src/sagas/EvaluationsSaga.ts | 6 ++ .../src/selectors/propertyPaneSelectors.tsx | 7 +- app/client/src/utils/DynamicBindingUtils.ts | 1 + app/client/src/workers/DataTreeEvaluator.ts | 65 ++++++++++++++----- 14 files changed, 126 insertions(+), 28 deletions(-) diff --git a/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx b/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx index c921c70fb8..383fe3a1de 100644 --- a/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx @@ -116,6 +116,7 @@ interface Props { useValidationMessage?: boolean; hideEvaluatedValue?: boolean; evaluationSubstitutionType?: EvaluationSubstitutionType; + jsError?: string; } interface PopoverContentProps { @@ -129,6 +130,7 @@ interface PopoverContentProps { onMouseLeave: () => void; hideEvaluatedValue?: boolean; preparedStatementViewer: boolean; + jsError?: string; } const PreparedStatementViewerContainer = styled.span` @@ -272,7 +274,9 @@ function PopoverContent(props: PopoverContentProps) { {props.hasError && ( - {props.useValidationMessage && props.error + {props.jsError && props.jsError.length + ? props.jsError + : props.useValidationMessage && props.error ? props.error : `This value does not evaluate to type "${props.expected}". Transform it using JS inside '{{ }}'`} @@ -335,6 +339,7 @@ function EvaluatedValuePopup(props: Props) { expected={props.expected} hasError={props.hasError} hideEvaluatedValue={props.hideEvaluatedValue} + jsError={props.jsError} onMouseEnter={() => { setContentHovered(true); }} diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index 8f98ea1af4..f61fe0dc66 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -88,6 +88,7 @@ export type EditorStyleProps = { fill?: boolean; useValidationMessage?: boolean; evaluationSubstitutionType?: EvaluationSubstitutionType; + jsErrorMessage?: string; }; export type EditorProps = EditorStyleProps & @@ -357,8 +358,9 @@ class CodeEditor extends Component { useValidationMessage, hideEvaluatedValue, evaluationSubstitutionType, + jsErrorMessage, } = this.props; - const hasError = !!(meta && meta.error); + const hasError = !!(meta && meta.error) || !!jsErrorMessage; let evaluated = evaluatedValue; if (dataTreePath) { evaluated = _.get(dynamicData, dataTreePath); @@ -402,6 +404,7 @@ class CodeEditor extends Component { hasError={hasError} hideEvaluatedValue={hideEvaluatedValue} isOpen={showEvaluatedValue} + jsError={jsErrorMessage} theme={theme || EditorTheme.LIGHT} useValidationMessage={useValidationMessage} > diff --git a/app/client/src/components/propertyControls/BaseControl.tsx b/app/client/src/components/propertyControls/BaseControl.tsx index 8647dbb6bd..4bf0a88e52 100644 --- a/app/client/src/components/propertyControls/BaseControl.tsx +++ b/app/client/src/components/propertyControls/BaseControl.tsx @@ -41,6 +41,7 @@ export interface ControlData validationMessage?: string; widgetProperties: any; useValidationMessage?: boolean; + jsErrorMessage?: string; } export interface ControlFunctions { onPropertyChange?: (propertyName: string, propertyValue: string) => void; diff --git a/app/client/src/components/propertyControls/CodeEditorControl.tsx b/app/client/src/components/propertyControls/CodeEditorControl.tsx index e081757ed0..5bc78adb25 100644 --- a/app/client/src/components/propertyControls/CodeEditorControl.tsx +++ b/app/client/src/components/propertyControls/CodeEditorControl.tsx @@ -18,6 +18,7 @@ class CodeEditorControl extends BaseControl { dataTreePath, evaluatedValue, useValidationMessage, + jsErrorMessage, } = this.props; const props: Partial = {}; if (dataTreePath) props.dataTreePath = dataTreePath; @@ -27,6 +28,7 @@ class CodeEditorControl extends BaseControl { return ( >; theme?: EditorTheme; hideEvaluatedValue?: boolean; + jsErrorMessage?: string; }) { const { errorMessage, @@ -34,6 +35,7 @@ export function InputText(props: { dataTreePath, evaluatedValue, hideEvaluatedValue, + jsErrorMessage, } = props; return ( @@ -48,6 +50,7 @@ export function InputText(props: { value: value, onChange: onChange, }} + jsErrorMessage={jsErrorMessage} meta={{ error: isValid ? "" : errorMessage, touched: true, @@ -75,6 +78,7 @@ class InputTextControl extends BaseControl { defaultValue, additionalAutoComplete, hideEvaluatedValue, + jsErrorMessage, } = this.props; return ( @@ -85,6 +89,7 @@ class InputTextControl extends BaseControl { expected={expected} hideEvaluatedValue={hideEvaluatedValue} isValid={isValid} + jsErrorMessage={jsErrorMessage} label={label} onChange={this.onTextChange} placeholder={placeholderText} diff --git a/app/client/src/entities/AppsmithConsole/logtype.ts b/app/client/src/entities/AppsmithConsole/logtype.ts index 8fc202ca15..dfbe511f23 100644 --- a/app/client/src/entities/AppsmithConsole/logtype.ts +++ b/app/client/src/entities/AppsmithConsole/logtype.ts @@ -4,6 +4,7 @@ enum LOG_TYPE { ACTION_EXECUTION_ERROR, ACTION_EXECUTION_SUCCESS, ENTITY_DELETED, + EVAL_ERROR, } export default LOG_TYPE; diff --git a/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx b/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx index c5297e4b87..658cbf62f3 100644 --- a/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx +++ b/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx @@ -244,9 +244,14 @@ const PropertyControl = memo((props: Props) => { const getPropertyValidation = ( propertyName: string, - ): { isValid: boolean; validationMessage?: string } => { + ): { + isValid: boolean; + validationMessage?: string; + jsErrorMessage?: string; + } => { let isValid = true; let validationMessage = ""; + let jsErrorMessage = ""; if (widgetProperties) { isValid = widgetProperties.invalidProps ? !_.has(widgetProperties.invalidProps, propertyName) @@ -254,11 +259,17 @@ const PropertyControl = memo((props: Props) => { const validationMsgPresent = widgetProperties.validationMessages && _.has(widgetProperties.validationMessages, propertyName); + const jsValidationMessagePresent = + widgetProperties.jsErrorMessages && + _.has(widgetProperties.jsErrorMessages, propertyName); validationMessage = validationMsgPresent ? _.get(widgetProperties.validationMessages, propertyName) : ""; + jsErrorMessage = jsValidationMessagePresent + ? _.get(widgetProperties.jsErrorMessages, propertyName) + : ""; } - return { isValid, validationMessage }; + return { isValid, validationMessage, jsErrorMessage }; }; const { propertyName, label } = props; @@ -270,13 +281,18 @@ const PropertyControl = memo((props: Props) => { `evaluatedValues.${propertyName}`, ); - const { isValid, validationMessage } = getPropertyValidation(propertyName); + const { + isValid, + validationMessage, + jsErrorMessage, + } = getPropertyValidation(propertyName); const { additionalAutoComplete, ...rest } = props; const config = { ...rest, isValid, propertyValue, validationMessage, + jsErrorMessage, dataTreePath, evaluatedValue, widgetProperties, @@ -293,6 +309,7 @@ const PropertyControl = memo((props: Props) => { delete config.dataTreePath; delete config.evaluatedValue; delete config.expected; + config.jsErrorMessage = ""; } const isDynamic: boolean = isPathADynamicProperty( diff --git a/app/client/src/reducers/uiReducers/debuggerReducer.ts b/app/client/src/reducers/uiReducers/debuggerReducer.ts index 4ad5fa9126..369ea2d1ed 100644 --- a/app/client/src/reducers/uiReducers/debuggerReducer.ts +++ b/app/client/src/reducers/uiReducers/debuggerReducer.ts @@ -49,7 +49,8 @@ const debuggerReducer = createReducer(initialState, { const entityId = action.payload.source.id; const id = - action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR + action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR || + action.payload.logType === LOG_TYPE.EVAL_ERROR ? `${entityId}-${action.payload.source.propertyPath}` : entityId; const previousState = get(state.errors, id, {}); @@ -73,7 +74,8 @@ const debuggerReducer = createReducer(initialState, { const entityId = action.payload.source.id; const isWidgetErrorLog = - action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR; + action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR || + action.payload.logType === LOG_TYPE.EVAL_ERROR; const id = isWidgetErrorLog ? `${entityId}-${action.payload.source.propertyPath}` : entityId; diff --git a/app/client/src/sagas/ActionExecutionSagas.ts b/app/client/src/sagas/ActionExecutionSagas.ts index dcd97f86c4..fb64fcdacf 100644 --- a/app/client/src/sagas/ActionExecutionSagas.ts +++ b/app/client/src/sagas/ActionExecutionSagas.ts @@ -932,6 +932,18 @@ function* executePageLoadAction(pageAction: PageAction) { message += `\nERROR: "${body}"`; } + AppsmithConsole.error({ + logType: LOG_TYPE.ACTION_EXECUTION_ERROR, + text: `Execution failed with status ${response.data.statusCode}`, + source: { + type: ENTITY_TYPE.ACTION, + name: pageAction.name, + id: pageAction.id, + }, + state: response.data?.request ?? null, + message: JSON.stringify(body), + }); + yield put( executeActionError({ actionId: pageAction.id, diff --git a/app/client/src/sagas/DebuggerSagas.ts b/app/client/src/sagas/DebuggerSagas.ts index d072aad539..a4a565a07b 100644 --- a/app/client/src/sagas/DebuggerSagas.ts +++ b/app/client/src/sagas/DebuggerSagas.ts @@ -27,7 +27,12 @@ function* onWidgetUpdateSaga(payload: LogActionPayload) { const dataTree: DataTree = yield select(getDataTree); const widget = dataTree[payload.source.name]; - if (!isWidget(widget) || !widget.validationMessages) return; + if ( + !isWidget(widget) || + !widget.validationMessages || + !widget.jsErrorMessages + ) + return; // Ignore canvas widget updates if (widget.type === WidgetTypes.CANVAS_WIDGET) { @@ -41,14 +46,17 @@ function* onWidgetUpdateSaga(payload: LogActionPayload) { const validationMessages = widget.validationMessages; const validationMessage = validationMessages[propertyPath]; + const jsErrorMessages = widget.jsErrorMessages; + const jsErrorMessage = jsErrorMessages[propertyPath]; const errors = yield select(getDebuggerErrors); const errorId = `${source.id}-${propertyPath}`; const widgetErrorLog = errors[errorId]; if (!widgetErrorLog) return; const noError = isEmpty(validationMessage); + const noJsError = isEmpty(jsErrorMessage); - if (noError) { + if (noError && noJsError) { delete errors[errorId]; yield put({ @@ -121,6 +129,7 @@ function* debuggerLogSaga(action: ReduxAction) { yield call(onWidgetUpdateSaga, payload); yield put(debuggerLog(payload)); return; + case LOG_TYPE.EVAL_ERROR: case LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR: if (payload.source && payload.source.propertyPath) { if (payload.text) { diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index f9a34de445..4975f8a06d 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -103,6 +103,12 @@ const evalErrorHandler = (errors: EvalError[]) => { } case EvalErrorTypes.EVAL_ERROR: { log.debug(error); + AppsmithConsole.error({ + logType: LOG_TYPE.EVAL_ERROR, + text: `The value at ${error.context?.source.propertyPath} is invalid`, + message: error.message, + source: error.context?.source, + }); break; } case EvalErrorTypes.WIDGET_PROPERTY_VALIDATION_ERROR: { diff --git a/app/client/src/selectors/propertyPaneSelectors.tsx b/app/client/src/selectors/propertyPaneSelectors.tsx index 0c8d3b453e..fbcfa0bb27 100644 --- a/app/client/src/selectors/propertyPaneSelectors.tsx +++ b/app/client/src/selectors/propertyPaneSelectors.tsx @@ -49,9 +49,14 @@ export const getWidgetPropsForPropertyPane = createSelector( } if (evaluatedWidget.invalidProps) { - const { invalidProps, validationMessages } = evaluatedWidget; + const { + invalidProps, + validationMessages, + jsErrorMessages, + } = evaluatedWidget; widgetProperties.invalidProps = invalidProps; widgetProperties.validationMessages = validationMessages; + widgetProperties.jsErrorMessages = jsErrorMessages; } } return widgetProperties; diff --git a/app/client/src/utils/DynamicBindingUtils.ts b/app/client/src/utils/DynamicBindingUtils.ts index a3db79aa8e..d8cf9ce8e8 100644 --- a/app/client/src/utils/DynamicBindingUtils.ts +++ b/app/client/src/utils/DynamicBindingUtils.ts @@ -158,6 +158,7 @@ export interface WidgetEvaluatedProps { invalidProps?: Record; validationMessages?: Record; evaluatedValues?: Record; + jsErrorMessages?: Record; } export interface EntityWithBindings { diff --git a/app/client/src/workers/DataTreeEvaluator.ts b/app/client/src/workers/DataTreeEvaluator.ts index 052b98e9ed..f3593d836d 100644 --- a/app/client/src/workers/DataTreeEvaluator.ts +++ b/app/client/src/workers/DataTreeEvaluator.ts @@ -391,6 +391,11 @@ export default class DataTreeEvaluator { let evalPropertyValue; const requiresEval = isABindingPath && isDynamicValue(unEvalPropertyValue); + _.set( + currentTree, + `${entityName}.jsErrorMessages.${propertyPath}`, + "", + ); if (requiresEval) { const evaluationSubstitutionType = entity.bindingPaths[propertyPath] || @@ -401,6 +406,8 @@ export default class DataTreeEvaluator { currentTree, evaluationSubstitutionType, false, + undefined, + fullPropertyPath, ); } catch (e) { this.errors.push({ @@ -545,6 +552,7 @@ export default class DataTreeEvaluator { evaluationSubstitutionType: EvaluationSubstitutionType, returnTriggers: boolean, callBackData?: Array, + fullPropertyPath?: string, ) { // Get the {{binding}} bound values const { stringSegments, jsSnippets } = getDynamicBindings(dynamicBinding); @@ -553,6 +561,7 @@ export default class DataTreeEvaluator { data, jsSnippets[0], callBackData, + fullPropertyPath, ); return result.triggers; } @@ -564,6 +573,7 @@ export default class DataTreeEvaluator { data, jsSnippet, callBackData, + fullPropertyPath, ); return result.result; } else { @@ -590,17 +600,32 @@ export default class DataTreeEvaluator { data: DataTree, js: string, callbackData?: Array, + fullPropertyPath?: string, ): EvalResult { try { return evaluate(js, data, callbackData); } catch (e) { - this.errors.push({ - type: EvalErrorTypes.EVAL_ERROR, - message: e.message, - context: { - binding: js, - }, - }); + if (fullPropertyPath) { + const { propertyPath, entityName } = getEntityNameAndPropertyPath( + fullPropertyPath, + ); + _.set(data, `${entityName}.jsErrorMessages.${propertyPath}`, e.message); + const entity = data[entityName]; + if (isWidget(entity)) { + this.errors.push({ + type: EvalErrorTypes.EVAL_ERROR, + message: e.message, + context: { + source: { + id: entity.widgetId, + name: entity.widgetName, + type: ENTITY_TYPE.WIDGET, + propertyPath: propertyPath, + }, + }, + }); + } + } return { result: undefined, triggers: [] }; } } @@ -622,6 +647,7 @@ export default class DataTreeEvaluator { EvaluationSubstitutionType.TEMPLATE, true, undefined, + fullPropertyPath, ); valueToValidate = triggers; } @@ -640,19 +666,22 @@ export default class DataTreeEvaluator { : transformed; const safeEvaluatedValue = removeFunctions(evaluatedValue); _.set(widget, `evaluatedValues.${propertyPath}`, safeEvaluatedValue); + const jsError = _.get(widget, `jsErrorMessages.${propertyPath}`); if (!isValid) { - this.errors.push({ - type: EvalErrorTypes.WIDGET_PROPERTY_VALIDATION_ERROR, - message: message || "", - context: { - source: { - id: widget.widgetId, - name: widget.widgetName, - type: ENTITY_TYPE.WIDGET, - propertyPath: propertyPath, + if (!jsError) { + this.errors.push({ + type: EvalErrorTypes.WIDGET_PROPERTY_VALIDATION_ERROR, + message: message || "", + context: { + source: { + id: widget.widgetId, + name: widget.widgetName, + type: ENTITY_TYPE.WIDGET, + propertyPath: propertyPath, + }, }, - }, - }); + }); + } _.set(widget, `invalidProps.${propertyPath}`, true); _.set(widget, `validationMessages.${propertyPath}`, message); } else { From cc36bdc0516a3f5b7376632f213f4a5b86390f0d Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 12 May 2021 13:27:28 +0530 Subject: [PATCH 38/76] Fix: TypeError: t.match is not a function (#4445) * add is number check before setting widget property * use toString of lodash Co-authored-by: root --- app/client/src/widgets/ListWidget/ListWidget.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/client/src/widgets/ListWidget/ListWidget.tsx b/app/client/src/widgets/ListWidget/ListWidget.tsx index 5b12f32489..2e41d64f6f 100644 --- a/app/client/src/widgets/ListWidget/ListWidget.tsx +++ b/app/client/src/widgets/ListWidget/ListWidget.tsx @@ -1,6 +1,15 @@ import React from "react"; import log from "loglevel"; -import { compact, get, set, xor, isPlainObject, isNumber, round } from "lodash"; +import { + compact, + get, + set, + xor, + isPlainObject, + isNumber, + round, + toString, +} from "lodash"; import * as Sentry from "@sentry/react"; import WidgetFactory from "utils/WidgetFactory"; @@ -226,7 +235,7 @@ class ListWidget extends BaseWidget, WidgetState> { const evaluatedValue = evaluatedProperty[itemIndex]; if (isPlainObject(evaluatedValue) || Array.isArray(evaluatedValue)) set(widget, path, JSON.stringify(evaluatedValue)); - else set(widget, path, evaluatedValue); + else set(widget, path, toString(evaluatedValue)); } }); } From b514759ad28fd9fef6da202daf1cd398eb528a68 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Wed, 12 May 2021 14:48:13 +0530 Subject: [PATCH 39/76] Added example value for cs domain on client (#4443) --- .env.example | 2 +- .github/workflows/client-test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index ef48c3bc9d..a98011bb3d 100644 --- a/.env.example +++ b/.env.example @@ -57,4 +57,4 @@ APPSMITH_MAIL_SMTP_TLS_ENABLED= #APPSMITH_SENTRY_ENVIRONMENT= # Configure cloud services -# APPSMITH_CLOUD_SERVICES_BASE_URL \ No newline at end of file +# APPSMITH_CLOUD_SERVICES_BASE_URL="https://release-cs.appsmith.com" \ No newline at end of file diff --git a/.github/workflows/client-test.yml b/.github/workflows/client-test.yml index 231976f008..c89e1a66fe 100644 --- a/.github/workflows/client-test.yml +++ b/.github/workflows/client-test.yml @@ -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 From c2af4a97fd84515bb576174b6cd2b23b9796d319 Mon Sep 17 00:00:00 2001 From: Shrikant Sharat Kandula Date: Wed, 12 May 2021 16:41:42 +0530 Subject: [PATCH 40/76] Fix sporadic build errors (#4453) Because of the Java version not being explicitly set in this plugin, the build of the whole project fails sporadically in IntelliJ since it's trying to compile the code as Java 8, which will obviously fail. --- app/server/appsmith-plugins/rapidApiPlugin/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/server/appsmith-plugins/rapidApiPlugin/pom.xml b/app/server/appsmith-plugins/rapidApiPlugin/pom.xml index 1ee8b7b3fd..7a98a62c40 100644 --- a/app/server/appsmith-plugins/rapidApiPlugin/pom.xml +++ b/app/server/appsmith-plugins/rapidApiPlugin/pom.xml @@ -19,6 +19,7 @@ UTF-8 + 11 ${java.version} ${java.version} rapidapi-plugin From 53c2d815f68f360fc785607f9b088579d593ae64 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Wed, 12 May 2021 17:07:59 +0530 Subject: [PATCH 41/76] Fixes refresh token flow (#4450) * Fixes refresh token flow * Review comments * Reverting mistake with CI cs url --- .github/workflows/client-test.yml | 4 ++-- .../java/com/appsmith/external/models/OAuth2.java | 15 +++++++++++++++ .../server/services/NewActionServiceImpl.java | 6 ++---- .../server/solutions/AuthenticationService.java | 6 +++++- .../server/solutions/ReleaseNotesService.java | 2 ++ .../src/main/resources/application.properties | 2 +- app/server/envs/dev.env.example | 2 ++ 7 files changed, 29 insertions(+), 8 deletions(-) diff --git a/.github/workflows/client-test.yml b/.github/workflows/client-test.yml index c89e1a66fe..80533f7782 100644 --- a/.github/workflows/client-test.yml +++ b/.github/workflows/client-test.yml @@ -206,7 +206,7 @@ jobs: --env APPSMITH_ENCRYPTION_PASSWORD=password \ --env APPSMITH_ENCRYPTION_SALT=salt \ --env APPSMITH_IS_SELF_HOSTED=false \ - --env APPSMITH_CLOUD_SERVICES_BASE_URL=https://release-cs.appsmith.com\ + --env APPSMITH_CLOUD_SERVICES_BASE_URL= \ --env APPSMITH_CLOUD_SERVICES_USERNAME= \ --env APPSMITH_CLOUD_SERVICES_PASSWORD= \ ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:release @@ -221,7 +221,7 @@ jobs: --env APPSMITH_ENCRYPTION_PASSWORD=password \ --env APPSMITH_ENCRYPTION_SALT=salt \ --env APPSMITH_IS_SELF_HOSTED=false \ - --env APPSMITH_CLOUD_SERVICES_BASE_URL=https://release-cs.appsmith.com\ + --env APPSMITH_CLOUD_SERVICES_BASE_URL= \ --env APPSMITH_CLOUD_SERVICES_USERNAME= \ --env APPSMITH_CLOUD_SERVICES_PASSWORD= \ ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:nightly diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/OAuth2.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/OAuth2.java index 732e0a24c6..3edd5eca7d 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/OAuth2.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/OAuth2.java @@ -3,6 +3,8 @@ package com.appsmith.external.models; import com.appsmith.external.annotations.documenttype.DocumentType; import com.appsmith.external.annotations.encryption.Encrypted; import com.appsmith.external.constants.Authentication; +import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError; +import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Getter; @@ -12,7 +14,9 @@ import lombok.ToString; import org.apache.logging.log4j.util.Strings; import org.springframework.data.annotation.Transient; import org.springframework.util.StringUtils; +import reactor.core.publisher.Mono; +import java.time.Instant; import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; @@ -73,4 +77,15 @@ public class OAuth2 extends AuthenticationDTO { .collect(Collectors.toSet()); } } + + @Override + public Mono hasExpired() { + if (this.authenticationResponse == null) { + return Mono.error(new AppsmithPluginException( + AppsmithPluginError.PLUGIN_ERROR, + "Expected datasource to have valid authentication tokens at this point")); + } + + return Mono.just(authenticationResponse.expiresAt.isBefore(Instant.now().plusSeconds(60))); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java index 4a77900821..1253696db2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java @@ -58,8 +58,6 @@ import javax.validation.Validator; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -538,11 +536,11 @@ public class NewActionServiceImpl extends BaseService validatedDatasourceMono = authenticationValidator.validateAuthentication(datasource).cache(); - Mono executionMono = validatedDatasourceMono .flatMap(datasourceContextService::getDatasourceContext) // Now that we have the context (connection details), execute the action. - .flatMap(resourceContext -> validatedDatasourceMono.flatMap(datasource1 -> { + .flatMap(resourceContext -> validatedDatasourceMono + .flatMap(datasource1 -> { return (Mono) pluginExecutor.executeParameterized( resourceContext.getConnection(), executeActionDTO, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/AuthenticationService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/AuthenticationService.java index d1fa19064a..5d1c416b78 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/AuthenticationService.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/AuthenticationService.java @@ -422,7 +422,11 @@ public class AuthenticationService { oAuth2.setAuthenticationResponse(authenticationResponse); oAuth2.setIsEncrypted(null); datasource.getDatasourceConfiguration().setAuthentication(oAuth2); - return datasourceService.update(datasource.getId(), datasource); + // We return the same object instead of the update value because the updates value + // will be in the encrypted form + return datasourceService + .update(datasource.getId(), datasource) + .thenReturn(datasource); }); }) .switchIfEmpty(Mono.just(datasource)) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ReleaseNotesService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ReleaseNotesService.java index ef887b5bde..202935e5e1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ReleaseNotesService.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ReleaseNotesService.java @@ -82,6 +82,8 @@ public class ReleaseNotesService { .flatMap(instanceId -> WebClient .create( baseUrl + "/api/v1/releases?instanceId=" + instanceId + + // isCloudHosted should be true only for our cloud instance, + // For docker images that burn the segment key with the image, the CE key will be present "&isSourceInstall=" + (isCloudHosted || StringUtils.isEmpty(segmentConfig.getCeKey())) + (StringUtils.isEmpty(repo) ? "" : ("&repo=" + repo)) ) diff --git a/app/server/appsmith-server/src/main/resources/application.properties b/app/server/appsmith-server/src/main/resources/application.properties index 867f87d1aa..1b86904aa7 100644 --- a/app/server/appsmith-server/src/main/resources/application.properties +++ b/app/server/appsmith-server/src/main/resources/application.properties @@ -66,7 +66,7 @@ admin.emails = ${APPSMITH_ADMIN_EMAILS:} emails.welcome.enabled = ${APPSMITH_EMAILS_WELCOME_ENABLED:true} # Appsmith Cloud Services -appsmith.cloud_services.base_url = ${APPSMITH_CLOUD_SERVICES_BASE_URL:} +appsmith.cloud_services.base_url = ${APPSMITH_CLOUD_SERVICES_BASE_URL:https://cs.appsmith.com} appsmith.cloud_services.username = ${APPSMITH_CLOUD_SERVICES_USERNAME:} appsmith.cloud_services.password = ${APPSMITH_CLOUD_SERVICES_PASSWORD:} github_repo = ${APPSMITH_GITHUB_REPO:} diff --git a/app/server/envs/dev.env.example b/app/server/envs/dev.env.example index e7e74b6bf4..569a50c320 100644 --- a/app/server/envs/dev.env.example +++ b/app/server/envs/dev.env.example @@ -11,6 +11,8 @@ APPSMITH_ENCRYPTION_SALT=abcd APPSMITH_CODEC_SIZE=10 +#APPSMITH_CLOUD_SERVICES_BASE_URL="https://release-cs.appsmith.com" + #APPSMITH_OAUTH2_GOOGLE_CLIENT_ID="" #APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET="" From fb7db810da33c37a787c40917bf0e69a7f048143 Mon Sep 17 00:00:00 2001 From: NandanAnantharamu <67676905+NandanAnantharamu@users.noreply.github.com> Date: Wed, 12 May 2021 17:43:11 +0530 Subject: [PATCH 42/76] Updated Cypress locator for product updates test (#4454) --- .../ClientSideTests/ProductUpdates/ProductUpdates_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ProductUpdates/ProductUpdates_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ProductUpdates/ProductUpdates_spec.js index db433c36c7..338970ff7b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ProductUpdates/ProductUpdates_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ProductUpdates/ProductUpdates_spec.js @@ -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 From 39ca940dfc8e7a4016f0c55eb186919b817d29a2 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Wed, 12 May 2021 19:06:39 +0530 Subject: [PATCH 43/76] Added space in if condition (#4459) --- .github/workflows/client-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client-test.yml b/.github/workflows/client-test.yml index 80533f7782..d83330c8d1 100644 --- a/.github/workflows/client-test.yml +++ b/.github/workflows/client-test.yml @@ -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 From 66c7a0b2525b4c11ba642d4e483e8a125dd15364 Mon Sep 17 00:00:00 2001 From: Apeksha Bhosale <7846888+ApekshaBhosale@users.noreply.github.com> Date: Thu, 13 May 2021 09:50:30 +0530 Subject: [PATCH 44/76] Revert "Separating js error and validation error for debugger (#4361)" (#4447) This reverts commit c6a8f81d60d9672bf97d95aa6cebe5f3eaffdd64. --- .../CodeEditor/EvaluatedValuePopup.tsx | 7 +- .../editorComponents/CodeEditor/index.tsx | 5 +- .../propertyControls/BaseControl.tsx | 1 - .../propertyControls/CodeEditorControl.tsx | 2 - .../propertyControls/InputTextControl.tsx | 5 -- .../src/entities/AppsmithConsole/logtype.ts | 1 - .../Editor/PropertyPane/PropertyControl.tsx | 23 +------ .../reducers/uiReducers/debuggerReducer.ts | 6 +- app/client/src/sagas/ActionExecutionSagas.ts | 12 ---- app/client/src/sagas/DebuggerSagas.ts | 13 +--- app/client/src/sagas/EvaluationsSaga.ts | 6 -- .../src/selectors/propertyPaneSelectors.tsx | 7 +- app/client/src/utils/DynamicBindingUtils.ts | 1 - app/client/src/workers/DataTreeEvaluator.ts | 65 +++++-------------- 14 files changed, 28 insertions(+), 126 deletions(-) diff --git a/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx b/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx index 383fe3a1de..c921c70fb8 100644 --- a/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/EvaluatedValuePopup.tsx @@ -116,7 +116,6 @@ interface Props { useValidationMessage?: boolean; hideEvaluatedValue?: boolean; evaluationSubstitutionType?: EvaluationSubstitutionType; - jsError?: string; } interface PopoverContentProps { @@ -130,7 +129,6 @@ interface PopoverContentProps { onMouseLeave: () => void; hideEvaluatedValue?: boolean; preparedStatementViewer: boolean; - jsError?: string; } const PreparedStatementViewerContainer = styled.span` @@ -274,9 +272,7 @@ function PopoverContent(props: PopoverContentProps) { {props.hasError && ( - {props.jsError && props.jsError.length - ? props.jsError - : props.useValidationMessage && props.error + {props.useValidationMessage && props.error ? props.error : `This value does not evaluate to type "${props.expected}". Transform it using JS inside '{{ }}'`} @@ -339,7 +335,6 @@ function EvaluatedValuePopup(props: Props) { expected={props.expected} hasError={props.hasError} hideEvaluatedValue={props.hideEvaluatedValue} - jsError={props.jsError} onMouseEnter={() => { setContentHovered(true); }} diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index f61fe0dc66..8f98ea1af4 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -88,7 +88,6 @@ export type EditorStyleProps = { fill?: boolean; useValidationMessage?: boolean; evaluationSubstitutionType?: EvaluationSubstitutionType; - jsErrorMessage?: string; }; export type EditorProps = EditorStyleProps & @@ -358,9 +357,8 @@ class CodeEditor extends Component { useValidationMessage, hideEvaluatedValue, evaluationSubstitutionType, - jsErrorMessage, } = this.props; - const hasError = !!(meta && meta.error) || !!jsErrorMessage; + const hasError = !!(meta && meta.error); let evaluated = evaluatedValue; if (dataTreePath) { evaluated = _.get(dynamicData, dataTreePath); @@ -404,7 +402,6 @@ class CodeEditor extends Component { hasError={hasError} hideEvaluatedValue={hideEvaluatedValue} isOpen={showEvaluatedValue} - jsError={jsErrorMessage} theme={theme || EditorTheme.LIGHT} useValidationMessage={useValidationMessage} > diff --git a/app/client/src/components/propertyControls/BaseControl.tsx b/app/client/src/components/propertyControls/BaseControl.tsx index 4bf0a88e52..8647dbb6bd 100644 --- a/app/client/src/components/propertyControls/BaseControl.tsx +++ b/app/client/src/components/propertyControls/BaseControl.tsx @@ -41,7 +41,6 @@ export interface ControlData validationMessage?: string; widgetProperties: any; useValidationMessage?: boolean; - jsErrorMessage?: string; } export interface ControlFunctions { onPropertyChange?: (propertyName: string, propertyValue: string) => void; diff --git a/app/client/src/components/propertyControls/CodeEditorControl.tsx b/app/client/src/components/propertyControls/CodeEditorControl.tsx index 5bc78adb25..e081757ed0 100644 --- a/app/client/src/components/propertyControls/CodeEditorControl.tsx +++ b/app/client/src/components/propertyControls/CodeEditorControl.tsx @@ -18,7 +18,6 @@ class CodeEditorControl extends BaseControl { dataTreePath, evaluatedValue, useValidationMessage, - jsErrorMessage, } = this.props; const props: Partial = {}; if (dataTreePath) props.dataTreePath = dataTreePath; @@ -28,7 +27,6 @@ class CodeEditorControl extends BaseControl { return ( >; theme?: EditorTheme; hideEvaluatedValue?: boolean; - jsErrorMessage?: string; }) { const { errorMessage, @@ -35,7 +34,6 @@ export function InputText(props: { dataTreePath, evaluatedValue, hideEvaluatedValue, - jsErrorMessage, } = props; return ( @@ -50,7 +48,6 @@ export function InputText(props: { value: value, onChange: onChange, }} - jsErrorMessage={jsErrorMessage} meta={{ error: isValid ? "" : errorMessage, touched: true, @@ -78,7 +75,6 @@ class InputTextControl extends BaseControl { defaultValue, additionalAutoComplete, hideEvaluatedValue, - jsErrorMessage, } = this.props; return ( @@ -89,7 +85,6 @@ class InputTextControl extends BaseControl { expected={expected} hideEvaluatedValue={hideEvaluatedValue} isValid={isValid} - jsErrorMessage={jsErrorMessage} label={label} onChange={this.onTextChange} placeholder={placeholderText} diff --git a/app/client/src/entities/AppsmithConsole/logtype.ts b/app/client/src/entities/AppsmithConsole/logtype.ts index dfbe511f23..8fc202ca15 100644 --- a/app/client/src/entities/AppsmithConsole/logtype.ts +++ b/app/client/src/entities/AppsmithConsole/logtype.ts @@ -4,7 +4,6 @@ enum LOG_TYPE { ACTION_EXECUTION_ERROR, ACTION_EXECUTION_SUCCESS, ENTITY_DELETED, - EVAL_ERROR, } export default LOG_TYPE; diff --git a/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx b/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx index 658cbf62f3..c5297e4b87 100644 --- a/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx +++ b/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx @@ -244,14 +244,9 @@ const PropertyControl = memo((props: Props) => { const getPropertyValidation = ( propertyName: string, - ): { - isValid: boolean; - validationMessage?: string; - jsErrorMessage?: string; - } => { + ): { isValid: boolean; validationMessage?: string } => { let isValid = true; let validationMessage = ""; - let jsErrorMessage = ""; if (widgetProperties) { isValid = widgetProperties.invalidProps ? !_.has(widgetProperties.invalidProps, propertyName) @@ -259,17 +254,11 @@ const PropertyControl = memo((props: Props) => { const validationMsgPresent = widgetProperties.validationMessages && _.has(widgetProperties.validationMessages, propertyName); - const jsValidationMessagePresent = - widgetProperties.jsErrorMessages && - _.has(widgetProperties.jsErrorMessages, propertyName); validationMessage = validationMsgPresent ? _.get(widgetProperties.validationMessages, propertyName) : ""; - jsErrorMessage = jsValidationMessagePresent - ? _.get(widgetProperties.jsErrorMessages, propertyName) - : ""; } - return { isValid, validationMessage, jsErrorMessage }; + return { isValid, validationMessage }; }; const { propertyName, label } = props; @@ -281,18 +270,13 @@ const PropertyControl = memo((props: Props) => { `evaluatedValues.${propertyName}`, ); - const { - isValid, - validationMessage, - jsErrorMessage, - } = getPropertyValidation(propertyName); + const { isValid, validationMessage } = getPropertyValidation(propertyName); const { additionalAutoComplete, ...rest } = props; const config = { ...rest, isValid, propertyValue, validationMessage, - jsErrorMessage, dataTreePath, evaluatedValue, widgetProperties, @@ -309,7 +293,6 @@ const PropertyControl = memo((props: Props) => { delete config.dataTreePath; delete config.evaluatedValue; delete config.expected; - config.jsErrorMessage = ""; } const isDynamic: boolean = isPathADynamicProperty( diff --git a/app/client/src/reducers/uiReducers/debuggerReducer.ts b/app/client/src/reducers/uiReducers/debuggerReducer.ts index 369ea2d1ed..4ad5fa9126 100644 --- a/app/client/src/reducers/uiReducers/debuggerReducer.ts +++ b/app/client/src/reducers/uiReducers/debuggerReducer.ts @@ -49,8 +49,7 @@ const debuggerReducer = createReducer(initialState, { const entityId = action.payload.source.id; const id = - action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR || - action.payload.logType === LOG_TYPE.EVAL_ERROR + action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR ? `${entityId}-${action.payload.source.propertyPath}` : entityId; const previousState = get(state.errors, id, {}); @@ -74,8 +73,7 @@ const debuggerReducer = createReducer(initialState, { const entityId = action.payload.source.id; const isWidgetErrorLog = - action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR || - action.payload.logType === LOG_TYPE.EVAL_ERROR; + action.payload.logType === LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR; const id = isWidgetErrorLog ? `${entityId}-${action.payload.source.propertyPath}` : entityId; diff --git a/app/client/src/sagas/ActionExecutionSagas.ts b/app/client/src/sagas/ActionExecutionSagas.ts index fb64fcdacf..dcd97f86c4 100644 --- a/app/client/src/sagas/ActionExecutionSagas.ts +++ b/app/client/src/sagas/ActionExecutionSagas.ts @@ -932,18 +932,6 @@ function* executePageLoadAction(pageAction: PageAction) { message += `\nERROR: "${body}"`; } - AppsmithConsole.error({ - logType: LOG_TYPE.ACTION_EXECUTION_ERROR, - text: `Execution failed with status ${response.data.statusCode}`, - source: { - type: ENTITY_TYPE.ACTION, - name: pageAction.name, - id: pageAction.id, - }, - state: response.data?.request ?? null, - message: JSON.stringify(body), - }); - yield put( executeActionError({ actionId: pageAction.id, diff --git a/app/client/src/sagas/DebuggerSagas.ts b/app/client/src/sagas/DebuggerSagas.ts index a4a565a07b..d072aad539 100644 --- a/app/client/src/sagas/DebuggerSagas.ts +++ b/app/client/src/sagas/DebuggerSagas.ts @@ -27,12 +27,7 @@ function* onWidgetUpdateSaga(payload: LogActionPayload) { const dataTree: DataTree = yield select(getDataTree); const widget = dataTree[payload.source.name]; - if ( - !isWidget(widget) || - !widget.validationMessages || - !widget.jsErrorMessages - ) - return; + if (!isWidget(widget) || !widget.validationMessages) return; // Ignore canvas widget updates if (widget.type === WidgetTypes.CANVAS_WIDGET) { @@ -46,17 +41,14 @@ function* onWidgetUpdateSaga(payload: LogActionPayload) { const validationMessages = widget.validationMessages; const validationMessage = validationMessages[propertyPath]; - const jsErrorMessages = widget.jsErrorMessages; - const jsErrorMessage = jsErrorMessages[propertyPath]; const errors = yield select(getDebuggerErrors); const errorId = `${source.id}-${propertyPath}`; const widgetErrorLog = errors[errorId]; if (!widgetErrorLog) return; const noError = isEmpty(validationMessage); - const noJsError = isEmpty(jsErrorMessage); - if (noError && noJsError) { + if (noError) { delete errors[errorId]; yield put({ @@ -129,7 +121,6 @@ function* debuggerLogSaga(action: ReduxAction) { yield call(onWidgetUpdateSaga, payload); yield put(debuggerLog(payload)); return; - case LOG_TYPE.EVAL_ERROR: case LOG_TYPE.WIDGET_PROPERTY_VALIDATION_ERROR: if (payload.source && payload.source.propertyPath) { if (payload.text) { diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index 4975f8a06d..f9a34de445 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -103,12 +103,6 @@ const evalErrorHandler = (errors: EvalError[]) => { } case EvalErrorTypes.EVAL_ERROR: { log.debug(error); - AppsmithConsole.error({ - logType: LOG_TYPE.EVAL_ERROR, - text: `The value at ${error.context?.source.propertyPath} is invalid`, - message: error.message, - source: error.context?.source, - }); break; } case EvalErrorTypes.WIDGET_PROPERTY_VALIDATION_ERROR: { diff --git a/app/client/src/selectors/propertyPaneSelectors.tsx b/app/client/src/selectors/propertyPaneSelectors.tsx index fbcfa0bb27..0c8d3b453e 100644 --- a/app/client/src/selectors/propertyPaneSelectors.tsx +++ b/app/client/src/selectors/propertyPaneSelectors.tsx @@ -49,14 +49,9 @@ export const getWidgetPropsForPropertyPane = createSelector( } if (evaluatedWidget.invalidProps) { - const { - invalidProps, - validationMessages, - jsErrorMessages, - } = evaluatedWidget; + const { invalidProps, validationMessages } = evaluatedWidget; widgetProperties.invalidProps = invalidProps; widgetProperties.validationMessages = validationMessages; - widgetProperties.jsErrorMessages = jsErrorMessages; } } return widgetProperties; diff --git a/app/client/src/utils/DynamicBindingUtils.ts b/app/client/src/utils/DynamicBindingUtils.ts index d8cf9ce8e8..a3db79aa8e 100644 --- a/app/client/src/utils/DynamicBindingUtils.ts +++ b/app/client/src/utils/DynamicBindingUtils.ts @@ -158,7 +158,6 @@ export interface WidgetEvaluatedProps { invalidProps?: Record; validationMessages?: Record; evaluatedValues?: Record; - jsErrorMessages?: Record; } export interface EntityWithBindings { diff --git a/app/client/src/workers/DataTreeEvaluator.ts b/app/client/src/workers/DataTreeEvaluator.ts index f3593d836d..052b98e9ed 100644 --- a/app/client/src/workers/DataTreeEvaluator.ts +++ b/app/client/src/workers/DataTreeEvaluator.ts @@ -391,11 +391,6 @@ export default class DataTreeEvaluator { let evalPropertyValue; const requiresEval = isABindingPath && isDynamicValue(unEvalPropertyValue); - _.set( - currentTree, - `${entityName}.jsErrorMessages.${propertyPath}`, - "", - ); if (requiresEval) { const evaluationSubstitutionType = entity.bindingPaths[propertyPath] || @@ -406,8 +401,6 @@ export default class DataTreeEvaluator { currentTree, evaluationSubstitutionType, false, - undefined, - fullPropertyPath, ); } catch (e) { this.errors.push({ @@ -552,7 +545,6 @@ export default class DataTreeEvaluator { evaluationSubstitutionType: EvaluationSubstitutionType, returnTriggers: boolean, callBackData?: Array, - fullPropertyPath?: string, ) { // Get the {{binding}} bound values const { stringSegments, jsSnippets } = getDynamicBindings(dynamicBinding); @@ -561,7 +553,6 @@ export default class DataTreeEvaluator { data, jsSnippets[0], callBackData, - fullPropertyPath, ); return result.triggers; } @@ -573,7 +564,6 @@ export default class DataTreeEvaluator { data, jsSnippet, callBackData, - fullPropertyPath, ); return result.result; } else { @@ -600,32 +590,17 @@ export default class DataTreeEvaluator { data: DataTree, js: string, callbackData?: Array, - fullPropertyPath?: string, ): EvalResult { try { return evaluate(js, data, callbackData); } catch (e) { - if (fullPropertyPath) { - const { propertyPath, entityName } = getEntityNameAndPropertyPath( - fullPropertyPath, - ); - _.set(data, `${entityName}.jsErrorMessages.${propertyPath}`, e.message); - const entity = data[entityName]; - if (isWidget(entity)) { - this.errors.push({ - type: EvalErrorTypes.EVAL_ERROR, - message: e.message, - context: { - source: { - id: entity.widgetId, - name: entity.widgetName, - type: ENTITY_TYPE.WIDGET, - propertyPath: propertyPath, - }, - }, - }); - } - } + this.errors.push({ + type: EvalErrorTypes.EVAL_ERROR, + message: e.message, + context: { + binding: js, + }, + }); return { result: undefined, triggers: [] }; } } @@ -647,7 +622,6 @@ export default class DataTreeEvaluator { EvaluationSubstitutionType.TEMPLATE, true, undefined, - fullPropertyPath, ); valueToValidate = triggers; } @@ -666,22 +640,19 @@ export default class DataTreeEvaluator { : transformed; const safeEvaluatedValue = removeFunctions(evaluatedValue); _.set(widget, `evaluatedValues.${propertyPath}`, safeEvaluatedValue); - const jsError = _.get(widget, `jsErrorMessages.${propertyPath}`); if (!isValid) { - if (!jsError) { - this.errors.push({ - type: EvalErrorTypes.WIDGET_PROPERTY_VALIDATION_ERROR, - message: message || "", - context: { - source: { - id: widget.widgetId, - name: widget.widgetName, - type: ENTITY_TYPE.WIDGET, - propertyPath: propertyPath, - }, + this.errors.push({ + type: EvalErrorTypes.WIDGET_PROPERTY_VALIDATION_ERROR, + message: message || "", + context: { + source: { + id: widget.widgetId, + name: widget.widgetName, + type: ENTITY_TYPE.WIDGET, + propertyPath: propertyPath, }, - }); - } + }, + }); _.set(widget, `invalidProps.${propertyPath}`, true); _.set(widget, `validationMessages.${propertyPath}`, message); } else { From e74d99b794e50a54b78a41934d56f13510c9a998 Mon Sep 17 00:00:00 2001 From: Sumit Kumar Date: Thu, 13 May 2021 11:59:43 +0530 Subject: [PATCH 45/76] fix NPE (#4448) fix NPE --- .../java/com/external/plugins/MongoPlugin.java | 18 +++++++++++++++++- .../com/external/plugins/MongoPluginTest.java | 7 ++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java b/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java index 96ac1c4a82..1a335e387e 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java @@ -590,6 +590,22 @@ public class MongoPlugin extends BasePlugin { } } + private boolean hostStringHasConnectionURIHead(String host) { + if (!StringUtils.isEmpty(host) && (host.contains("mongodb://") || host.contains("mongodb+srv"))) { + return true; + } + + return false; + } + + private boolean isHostStringConnectionURI(Endpoint endpoint) { + if (endpoint != null && hostStringHasConnectionURIHead(endpoint.getHost())) { + return true; + } + + return false; + } + @Override public Set validateDatasource(DatasourceConfiguration datasourceConfiguration) { Set invalids = new HashSet<>(); @@ -641,7 +657,7 @@ public class MongoPlugin extends BasePlugin { if (!CollectionUtils.isEmpty(endpoints)) { boolean usingUri = endpoints .stream() - .anyMatch(endPoint -> endPoint.getHost().matches(MONGO_URI_REGEX)); + .anyMatch(endPoint -> isHostStringConnectionURI(endPoint)); if (usingUri) { invalids.add("It seems that you are trying to use a mongo connection string URI. Please " + diff --git a/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java b/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java index 1709486140..cb0bd64724 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java +++ b/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java @@ -496,7 +496,12 @@ public class MongoPluginTest { @Test public void testErrorMessageOnNonSrvUri() { DatasourceConfiguration dsConfig = createDatasourceConfiguration(); - dsConfig.getEndpoints().get(0).setHost("mongodb://user:pass@url.net:1234,url.net:1234/dbName"); + List endpoints = new ArrayList<>(); + endpoints.add(new Endpoint("url", 123L)); + endpoints.add(null); + endpoints.add(new Endpoint(null, 123L)); + endpoints.add(new Endpoint("mongodb://user:pass@url.net:1234,url.net:1234/dbName", 123L)); + dsConfig.setEndpoints(endpoints); dsConfig.setProperties(List.of(new Property("Import from URI", "No"))); Mono> invalidsMono = Mono.just(pluginExecutor.validateDatasource(dsConfig)); From f2d228c346aa672a74272d55898522f35816aead Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Thu, 13 May 2021 12:41:11 +0530 Subject: [PATCH 46/76] - Add no shadow eslint rule --- app/client/.eslintrc.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/client/.eslintrc.json b/app/client/.eslintrc.json index e585704a83..98978c9688 100644 --- a/app/client/.eslintrc.json +++ b/app/client/.eslintrc.json @@ -35,14 +35,15 @@ "react/jsx-sort-props": "error", "react/jsx-fragments": "error", "react/jsx-no-useless-fragment": "error", - "sort-destructure-keys/sort-destructure-keys": ["warn", {"caseSensitive": false}], + "sort-destructure-keys/sort-destructure-keys": ["error", {"caseSensitive": false}], "react/jsx-no-bind": ["warn", { "ignoreDOMComponents": false, "ignoreRefs": true, "allowArrowFunctions": false, "allowFunctions": false, "allowBind": false - }] + }], + "no-shadow": ["error", { "builtinGlobals": true }] }, "settings": { "react": { From 27af947852d1fe5519f58558229faec8f6e40b08 Mon Sep 17 00:00:00 2001 From: Shrikant Sharat Kandula Date: Thu, 13 May 2021 12:52:43 +0530 Subject: [PATCH 47/76] APIs for adding and removing reactions on comments (#4457) * Add APIs for reacting and unreacting on comments * Add tests for Reactions APIs * Fix s/create/delete typo Co-authored-by: Nidhi * Deletion is successful if more than one are deleted Co-authored-by: Nidhi --- .../server/controllers/CommentController.java | 20 ++++ .../com/appsmith/server/domains/Comment.java | 13 +++ .../repositories/CustomCommentRepository.java | 6 ++ .../CustomCommentRepositoryImpl.java | 47 ++++++++++ .../server/services/CommentService.java | 3 + .../server/services/CommentServiceImpl.java | 35 ++++++- .../server/services/CommentServiceTest.java | 92 +++++++++++++++++++ 7 files changed, 215 insertions(+), 1 deletion(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/CommentController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/CommentController.java index d11e22af62..7d37d09b08 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/CommentController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/CommentController.java @@ -85,4 +85,24 @@ public class CommentController extends BaseController new ResponseDTO<>(HttpStatus.OK.value(), deletedResource, null)); } + @PostMapping("/{commentId}/reactions") + public Mono> createReaction( + @PathVariable String commentId, + @Valid @RequestBody Comment.Reaction reaction + ) { + log.debug("Going to create reaction on comment with id: {}", commentId); + return service.createReaction(commentId, reaction) + .map(isSaved -> new ResponseDTO<>(HttpStatus.OK.value(), isSaved, null)); + } + + @DeleteMapping("/{commentId}/reactions") + public Mono> deleteReaction( + @PathVariable String commentId, + @Valid @RequestBody Comment.Reaction reaction + ) { + log.debug("Going to delete reaction on comment with id: {}", commentId); + return service.deleteReaction(commentId, reaction) + .map(isSaved -> new ResponseDTO<>(HttpStatus.OK.value(), isSaved, null)); + } + } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Comment.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Comment.java index dc67d106f4..178424aac4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Comment.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Comment.java @@ -1,12 +1,14 @@ package com.appsmith.server.domains; import com.appsmith.external.models.BaseDomain; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.data.mongodb.core.mapping.Document; +import java.util.Date; import java.util.List; import java.util.Map; @@ -32,6 +34,8 @@ public class Comment extends BaseDomain { Body body; + List reactions; + @Data public static class Body { List blocks; @@ -79,4 +83,13 @@ public class Comment extends BaseDomain { } } + @Data + public static class Reaction { + String emoji; + String byUsername; + String byName; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssX", timezone = "UTC") + Date createdAt; + } + } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepository.java index 816b1e2ae4..38ce4c6d4d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepository.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepository.java @@ -1,7 +1,13 @@ package com.appsmith.server.repositories; import com.appsmith.server.domains.Comment; +import com.mongodb.client.result.UpdateResult; +import reactor.core.publisher.Mono; public interface CustomCommentRepository extends AppsmithRepository { + Mono pushReaction(String commentId, Comment.Reaction reaction); + + Mono deleteReaction(String commentId, Comment.Reaction reaction); + } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepositoryImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepositoryImpl.java index 0bb974fea9..78d187bd26 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepositoryImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomCommentRepositoryImpl.java @@ -1,10 +1,18 @@ package com.appsmith.server.repositories; import com.appsmith.server.domains.Comment; +import com.appsmith.server.domains.QComment; +import com.mongodb.client.result.UpdateResult; import lombok.extern.slf4j.Slf4j; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.core.convert.MongoConverter; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import static org.springframework.data.mongodb.core.query.Criteria.where; @Component @Slf4j @@ -14,4 +22,43 @@ public class CustomCommentRepositoryImpl extends BaseAppsmithRepositoryImpl pushReaction(String commentId, Comment.Reaction reaction) { + final String reactionsField = fieldName(QComment.comment.reactions); + return mongoOperations.updateFirst( + Query.query(new Criteria().andOperator( + where("id").is(commentId), + Criteria + .where(reactionsField) + .not() + .elemMatch(where("emoji").is(reaction.getEmoji()).and("byUsername").is(reaction.getByUsername())) + )), + new Update().addToSet(reactionsField, reaction), + Comment.class + ); + } + + /** + * Atomically delete a reaction, by a user, if the reaction by that user exists on this comment. + * @param commentId UUID string of the comment on which to delete a reaction. + * @param reaction The reaction object to be deleted. + * @return Mono that publishes an UpdateResult that will contain the number of reactions deleted. It's usually 0 or 1, but can theoretically be more. + */ + @Override + public Mono deleteReaction(String commentId, Comment.Reaction reaction) { + reaction.setByName(null); + reaction.setCreatedAt(null); + return mongoOperations.updateFirst( + Query.query(where("id").is(commentId)), + new Update().pull(fieldName(QComment.comment.reactions), reaction), + Comment.class + ); + } + } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentService.java index 452b7ac4e8..4960633140 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentService.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentService.java @@ -20,4 +20,7 @@ public interface CommentService extends CrudService { Mono deleteThread(String threadId); + Mono createReaction(String commentId, Comment.Reaction reaction); + + Mono deleteReaction(String commentId, Comment.Reaction reaction); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentServiceImpl.java index c3a3b2d82f..432f0c84b1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CommentServiceImpl.java @@ -14,13 +14,13 @@ import com.appsmith.server.helpers.PolicyUtils; import com.appsmith.server.repositories.CommentRepository; import com.appsmith.server.repositories.CommentThreadRepository; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; @@ -28,6 +28,7 @@ import reactor.core.scheduler.Scheduler; import javax.validation.Validator; import java.time.Instant; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -271,4 +272,36 @@ public class CommentServiceImpl extends BaseService createReaction(String commentId, Comment.Reaction reaction) { + return Mono.zip( + repository.findById(commentId, AclPermission.READ_COMMENT), + sessionUserService.getCurrentUser() + ) + .flatMap(tuple -> { + final User user = tuple.getT2(); + + reaction.setByUsername(user.getUsername()); + reaction.setByName(user.getName()); + reaction.setCreatedAt(new Date(Instant.now().toEpochMilli())); + + return repository.pushReaction(commentId, reaction) + .map(result -> result.getModifiedCount() == 1L); + }); + } + + @Override + public Mono deleteReaction(String commentId, Comment.Reaction reaction) { + return Mono.zip( + repository.findById(commentId, AclPermission.READ_COMMENT), + sessionUserService.getCurrentUser() + ) + .flatMap(tuple -> { + final User user = tuple.getT2(); + reaction.setByUsername(user.getUsername()); + return repository.deleteReaction(commentId, reaction) + .map(result -> result.getModifiedCount() > 0); + }); + } + } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CommentServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CommentServiceTest.java index 100e6d3301..7c29eb748d 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CommentServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CommentServiceTest.java @@ -6,6 +6,7 @@ import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Comment; import com.appsmith.server.domains.CommentThread; import com.appsmith.server.domains.Organization; +import com.appsmith.server.repositories.CommentRepository; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; @@ -33,6 +34,9 @@ public class CommentServiceTest { @Autowired CommentService commentService; + @Autowired + CommentRepository commentRepository; + @Autowired ApplicationService applicationService; @@ -98,6 +102,12 @@ public class CommentServiceTest { return comment; } + private Comment.Reaction makeReaction(String emoji) { + Comment.Reaction reaction = new Comment.Reaction(); + reaction.setEmoji(emoji); + return reaction; + } + @Test @WithUserDetails(value = "api_user") public void deleteValidComment() { @@ -135,4 +145,86 @@ public class CommentServiceTest { }) .verifyComplete(); } + + @Test + @WithUserDetails(value = "api_user") + public void testAddReaction() { + Organization organization = new Organization(); + organization.setName("ReactionsOrg"); + Mono reactionMono = organizationService + .create(organization) + .flatMap(org -> { + Application testApplication = new Application(); + testApplication.setName("ReactionApp"); + return applicationPageService + .createApplication(testApplication, org.getId()); + }) + .flatMap(application -> { + final CommentThread thread = new CommentThread(); + thread.setApplicationId(application.getId()); + thread.setComments(List.of(makePlainTextComment("Test Comment"))); + return commentService.createThread(thread); + }) + .flatMap(commentThread -> Mono.just(commentThread.getComments().get(0))) + .flatMap(comment -> { + assert comment.getId() != null; + return commentService + .createReaction(comment.getId(), makeReaction("x")) + .then(commentRepository.findById(comment.getId())); + }) + .cache(); + + StepVerifier + .create(reactionMono) + .assertNext(comment -> { + assertThat(comment.getReactions()).hasSize(1); + Comment.Reaction r1 = comment.getReactions().get(0); + assertThat(r1.getEmoji()).isEqualTo("x"); + assertThat(r1.getByName()).isEqualTo("api_user"); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails(value = "api_user") + public void testAddAndRemoveReaction() { + Organization organization = new Organization(); + organization.setName("ReactionsOrg"); + Mono reactionMono = organizationService + .create(organization) + .flatMap(org -> { + Application testApplication = new Application(); + testApplication.setName("ReactionApp"); + return applicationPageService + .createApplication(testApplication, org.getId()); + }) + .flatMap(application -> { + final CommentThread thread = new CommentThread(); + thread.setApplicationId(application.getId()); + thread.setComments(List.of(makePlainTextComment("Test Comment"))); + return commentService.createThread(thread); + }) + .flatMap(commentThread -> Mono.just(commentThread.getComments().get(0))) + .flatMap(comment -> { + assert comment.getId() != null; + return Mono.when( + commentService.createReaction(comment.getId(), makeReaction("x")), + commentService.createReaction(comment.getId(), makeReaction("y")) + ) + .then(commentService.deleteReaction(comment.getId(), makeReaction("x"))) + .then(commentRepository.findById(comment.getId())); + }) + .cache(); + + StepVerifier + .create(reactionMono) + .assertNext(comment -> { + assertThat(comment.getReactions()).hasSize(1); + Comment.Reaction r1 = comment.getReactions().get(0); + assertThat(r1.getEmoji()).isEqualTo("y"); + assertThat(r1.getByName()).isEqualTo("api_user"); + }) + .verifyComplete(); + } + } From ea451ef061db7b9a7b5805171f418f9892a81ade Mon Sep 17 00:00:00 2001 From: Nidhi Date: Thu, 13 May 2021 13:30:23 +0530 Subject: [PATCH 48/76] Add default configs for prod and tests (#4464) * Added default cs config for prod and tests * Env variable for new installations * K8s defaults --- .github/workflows/client-test.yml | 4 ++-- app/client/public/index.html | 2 +- deploy/k8s/scripts/appsmith-configmap.yaml.sh | 1 + deploy/k8s/scripts/nginx-configmap.yaml | 1 + deploy/template/docker.env.sh | 4 ++++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/client-test.yml b/.github/workflows/client-test.yml index d83330c8d1..a124259ceb 100644 --- a/.github/workflows/client-test.yml +++ b/.github/workflows/client-test.yml @@ -206,7 +206,7 @@ jobs: --env APPSMITH_ENCRYPTION_PASSWORD=password \ --env APPSMITH_ENCRYPTION_SALT=salt \ --env APPSMITH_IS_SELF_HOSTED=false \ - --env APPSMITH_CLOUD_SERVICES_BASE_URL= \ + --env APPSMITH_CLOUD_SERVICES_BASE_URL=https://release-cs.appsmith.com\ --env APPSMITH_CLOUD_SERVICES_USERNAME= \ --env APPSMITH_CLOUD_SERVICES_PASSWORD= \ ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:release @@ -221,7 +221,7 @@ jobs: --env APPSMITH_ENCRYPTION_PASSWORD=password \ --env APPSMITH_ENCRYPTION_SALT=salt \ --env APPSMITH_IS_SELF_HOSTED=false \ - --env APPSMITH_CLOUD_SERVICES_BASE_URL= \ + --env APPSMITH_CLOUD_SERVICES_BASE_URL=https://release-cs.appsmith.com\ --env APPSMITH_CLOUD_SERVICES_USERNAME= \ --env APPSMITH_CLOUD_SERVICES_PASSWORD= \ ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-server:nightly diff --git a/app/client/public/index.html b/app/client/public/index.html index 558f9ccca9..70250975eb 100755 --- a/app/client/public/index.html +++ b/app/client/public/index.html @@ -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" }; diff --git a/deploy/k8s/scripts/appsmith-configmap.yaml.sh b/deploy/k8s/scripts/appsmith-configmap.yaml.sh index d664292f6f..463b99f299 100644 --- a/deploy/k8s/scripts/appsmith-configmap.yaml.sh +++ b/deploy/k8s/scripts/appsmith-configmap.yaml.sh @@ -30,4 +30,5 @@ data: APPSMITH_REDIS_URL: redis://redis-service:6379 APPSMITH_MONGODB_URI: $mongo_protocol$encoded_mongo_root_user:$encoded_mongo_root_password@$mongo_host/$mongo_db?retryWrites=true&authSource=admin APPSMITH_DISABLE_TELEMETRY: "$disable_telemetry" + APPSMITH_CLOUD_SERVICES_BASE_URL: "https://cs.appsmith.com" EOF diff --git a/deploy/k8s/scripts/nginx-configmap.yaml b/deploy/k8s/scripts/nginx-configmap.yaml index b2fbc721bf..b9253d36bf 100644 --- a/deploy/k8s/scripts/nginx-configmap.yaml +++ b/deploy/k8s/scripts/nginx-configmap.yaml @@ -36,6 +36,7 @@ data: sub_filter __APPSMITH_INTERCOM_APP_ID__ '${APPSMITH_INTERCOM_APP_ID}'; sub_filter __APPSMITH_MAIL_ENABLED__ '${APPSMITH_MAIL_ENABLED}'; sub_filter __APPSMITH_DISABLE_TELEMETRY__ '${APPSMITH_DISABLE_TELEMETRY}'; + sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}'; } location /f { diff --git a/deploy/template/docker.env.sh b/deploy/template/docker.env.sh index 6bbeb5e901..342287dbc5 100644 --- a/deploy/template/docker.env.sh +++ b/deploy/template/docker.env.sh @@ -59,4 +59,8 @@ APPSMITH_DISABLE_TELEMETRY=$disable_telemetry # APPSMITH_CODEC_SIZE= # ******************************* +# ****** CLOUD SERVICES ******* +APPSMITH_CLOUD_SERVICES_BASE_URL=https://cs.appsmith.com +# ******************************* + EOF From 8ad7eecdebe3f93a4149164c7912b6d2fb2ab853 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Thu, 13 May 2021 14:05:39 +0530 Subject: [PATCH 49/76] - Auto fix sort ddestructured props rule --- app/client/.eslintrc.json | 2 +- app/client/src/api/ImportApi.ts | 2 +- .../AppComments/AppCommentsHeader.tsx | 2 +- .../src/comments/CommentCard/CommentCard.tsx | 6 +-- .../CommentCard/CommentContextMenu.tsx | 2 +- .../inlineComments/InlineCommentPin.tsx | 2 +- .../UnpublishedCommentThread.tsx | 4 +- .../src/comments/tests/Comments.test.tsx | 4 +- app/client/src/components/ads/Button.tsx | 2 +- .../src/components/ads/DraggableList.tsx | 6 +-- .../components/ads/DraggableListComponent.tsx | 8 ++-- .../src/components/ads/EditableText.tsx | 6 +-- app/client/src/components/ads/EmojiPicker.tsx | 2 +- .../src/components/ads/MentionsInput.tsx | 10 ++--- .../src/components/ads/ScrollIndicator.tsx | 8 ++-- app/client/src/components/ads/Table.tsx | 6 +-- app/client/src/components/ads/TextInput.tsx | 2 +- .../src/components/ads/TreeDropdown.tsx | 10 ++--- .../designSystems/appsmith/ChartComponent.tsx | 2 +- .../appsmith/CreatableDropdown.tsx | 10 ++--- .../appsmith/DraggableListComponent.tsx | 10 ++--- .../designSystems/appsmith/Dropdown.tsx | 2 +- .../appsmith/TableComponent/CascadeFields.tsx | 12 +++--- .../appsmith/TableComponent/Table.tsx | 4 +- .../appsmith/TextInputComponent.tsx | 4 +- .../designSystems/appsmith/VideoComponent.tsx | 14 +++---- .../blueprint/DropdownComponent.tsx | 2 +- .../blueprint/SwitchComponent.tsx | 6 +-- .../designSystems/blueprint/TextComponent.tsx | 12 +++--- .../editorComponents/ActionCreator.tsx | 2 +- .../CodeEditor/EvaluatedValuePopup.tsx | 2 +- .../editorComponents/CodeEditor/index.tsx | 28 +++++++------- .../Debugger/DebuggerLogs.tsx | 2 +- .../editorComponents/Debugger/EntityLink.tsx | 2 +- .../editorComponents/DragLayerComponent.tsx | 2 +- .../editorComponents/DraggableComponent.tsx | 2 +- .../editorComponents/DropTargetComponent.tsx | 2 +- .../EditorContextProvider.tsx | 16 ++++---- .../editorComponents/EntityNameComponent.tsx | 4 +- .../GlobalSearch/ActionLink.tsx | 2 +- .../GlobalSearch/AlgoliaSearchWrapper.tsx | 2 +- .../GlobalSearch/GlobalSearchHotKeys.tsx | 2 +- .../GlobalSearch/SearchModal.tsx | 2 +- .../GlobalSearch/SearchResults.tsx | 8 ++-- .../editorComponents/GlobalSearch/index.tsx | 2 +- .../GlobalSearch/parseDocumentationContent.ts | 2 +- .../GlobalSearch/useRecentEntities.tsx | 2 +- .../editorComponents/NavBarItem.tsx | 10 ++--- .../editorComponents/ResizableComponent.tsx | 2 +- .../fields/EmbeddedDatasourcePathField.tsx | 6 +-- .../formControls/CheckboxControl.tsx | 2 +- .../formControls/DropDownControl.tsx | 2 +- .../formControls/DynamicInputTextControl.tsx | 4 +- .../formControls/DynamicTextFieldControl.tsx | 6 +-- .../formControls/FilePickerControl.tsx | 2 +- .../formControls/FixedKeyInputControl.tsx | 8 ++-- .../formControls/InputNumberControl.tsx | 8 ++-- .../formControls/InputTextControl.tsx | 20 +++++----- .../components/formControls/SwitchControl.tsx | 4 +- .../propertyControls/ButtonTabControl.tsx | 4 +- .../propertyControls/ChartDataControl.tsx | 8 ++-- .../propertyControls/CodeEditorControl.tsx | 8 ++-- .../ComputeTablePropertyControl.tsx | 16 ++++---- .../CustomFusionChartControl.tsx | 4 +- .../propertyControls/IconTabControl.tsx | 4 +- .../propertyControls/InputTextControl.tsx | 18 ++++----- .../PrimaryColumnsControl.tsx | 8 ++-- .../propertyControls/StepControl.tsx | 2 +- .../propertyControls/TabControl.tsx | 2 +- app/client/src/constants/DefaultTheme.tsx | 6 +-- .../src/entities/DataTree/dataTreeFactory.ts | 6 +-- .../viewer/GetAppViewerHeaderCTA.tsx | 2 +- .../src/pages/AppViewer/viewer/PageTabs.tsx | 4 +- .../AppViewer/viewer/PageTabsContainer.tsx | 4 +- .../Applications/CreateApplicationForm.tsx | 2 +- .../Applications/ForkApplicationModal.tsx | 2 +- .../ProductUpdatesModal/ReleaseComponent.tsx | 2 +- .../ProductUpdatesModal/index.tsx | 2 +- app/client/src/pages/Applications/index.tsx | 6 +-- .../pages/Editor/APIEditor/ApiHomeScreen.tsx | 26 ++++++------- .../src/pages/Editor/APIEditor/Form.tsx | 14 +++---- .../pages/Editor/APIEditor/PostBodyData.tsx | 8 ++-- .../Editor/APIEditor/ProviderTemplates.tsx | 2 +- .../Editor/APIEditor/RapidApiEditorForm.tsx | 14 +++---- .../Editor/APIEditor/ResultPagination.tsx | 8 ++-- .../src/pages/Editor/APIEditor/index.tsx | 14 +++---- .../pages/Editor/DataSourceEditor/DBForm.tsx | 10 ++--- .../DataSourceEditor/DatasourceHome.tsx | 6 +-- .../DataSourceEditor/DatasourceSection.tsx | 2 +- .../Editor/DataSourceEditor/JSONtoForm.tsx | 2 +- .../RestAPIDatasourceForm.tsx | 12 +++--- .../pages/Editor/DataSourceEditor/index.tsx | 38 +++++++++---------- app/client/src/pages/Editor/EditorHeader.tsx | 12 +++--- app/client/src/pages/Editor/EditorSidebar.tsx | 4 +- .../src/pages/Editor/Explorer/Entity/Name.tsx | 2 +- .../pages/Editor/Explorer/EntityExplorer.tsx | 2 +- .../pages/Editor/Explorer/TreeDropdown.tsx | 10 ++--- .../Editor/Explorer/Widgets/WidgetEntity.tsx | 4 +- .../PropertyPane/PanelPropertiesEditor.tsx | 4 +- .../Editor/PropertyPane/PropertyControl.tsx | 6 +-- .../Editor/QueryEditor/EditorJSONtoForm.tsx | 20 +++++----- .../Editor/QueryEditor/QueryHomeScreen.tsx | 4 +- .../src/pages/Editor/QueryEditor/Table.tsx | 4 +- .../pages/Editor/QueryEditor/TemplateMenu.tsx | 4 +- .../src/pages/Editor/QueryEditor/index.tsx | 12 +++--- .../pages/Editor/SaaSEditor/ActionForm.tsx | 6 +-- .../Editor/SaaSEditor/DatasourceForm.tsx | 8 ++-- .../src/pages/Editor/SaaSEditor/ListView.tsx | 8 ++-- .../src/pages/Editor/ShareApplicationForm.tsx | 8 ++-- app/client/src/pages/Editor/routes.tsx | 2 +- app/client/src/pages/Editor/utils.ts | 2 +- .../src/pages/UserAuth/ForgotPassword.tsx | 2 +- app/client/src/pages/UserAuth/Login.tsx | 2 +- .../src/pages/UserAuth/ResetPassword.tsx | 8 ++-- app/client/src/pages/UserAuth/SignUp.tsx | 2 +- app/client/src/pages/UserAuth/helpers.ts | 4 +- .../src/pages/common/ErrorPageHeader.tsx | 2 +- app/client/src/pages/common/NotFound.tsx | 2 +- .../pages/organization/AppInviteUsersForm.tsx | 10 ++--- .../organization/CreateOrganizationForm.tsx | 4 +- app/client/src/pages/organization/Members.tsx | 4 +- .../pages/organization/OrgInviteUsersForm.tsx | 12 +++--- .../commentsReducer/commentsReducer.ts | 4 +- .../handleAddCommentToThreadSuccess.ts | 2 +- .../handleCreateNewCommentThreadSuccess.ts | 2 +- .../src/reducers/uiReducers/editorReducer.tsx | 6 +-- .../uiReducers/propertyPaneReducer.tsx | 2 +- .../reducers/uiReducers/queryPaneReducer.ts | 2 +- app/client/src/resizable/index.tsx | 2 +- app/client/src/sagas/ActionExecutionSagas.ts | 2 +- app/client/src/sagas/ActionSagas.ts | 2 +- app/client/src/sagas/ApiPaneSagas.ts | 4 +- app/client/src/sagas/ApplicationSagas.tsx | 4 +- app/client/src/sagas/CommentSagas/index.ts | 4 +- app/client/src/sagas/CurlImportSagas.ts | 2 +- app/client/src/sagas/DatasourcesSagas.ts | 2 +- app/client/src/sagas/ErrorSagas.tsx | 4 +- app/client/src/sagas/EvaluationsSaga.ts | 4 +- app/client/src/sagas/OrgSagas.ts | 2 +- app/client/src/sagas/PageSagas.tsx | 4 +- app/client/src/sagas/QueryPaneSagas.ts | 8 ++-- app/client/src/sagas/RecentEntitiesSagas.ts | 2 +- app/client/src/sagas/SaaSPaneSagas.ts | 2 +- app/client/src/sagas/WidgetBlueprintSagas.ts | 2 +- app/client/src/sagas/WidgetOperationSagas.tsx | 38 +++++++++---------- app/client/src/sagas/userSagas.tsx | 12 +++--- app/client/src/selectors/editorSelectors.tsx | 2 +- .../src/utils/autocomplete/TernServer.ts | 2 +- .../src/utils/hooks/useDynamicAppLayout.tsx | 2 +- .../src/utils/hooks/useIsScrolledToBottom.tsx | 2 +- app/client/src/widgets/ContainerWidget.tsx | 2 +- app/client/src/widgets/DropdownWidget.tsx | 2 +- .../src/widgets/ListWidget/ListWidget.tsx | 10 ++--- app/client/src/widgets/MetaHOC.tsx | 2 +- app/client/src/widgets/TableWidget/index.tsx | 2 +- .../src/widgets/Tabs/TabsWidget.test.tsx | 2 +- app/client/src/widgets/Tabs/TabsWidget.tsx | 2 +- app/client/src/widgets/VideoWidget.tsx | 2 +- app/client/src/workers/DataTreeEvaluator.ts | 4 +- app/client/src/workers/evaluation.worker.ts | 8 ++-- .../src/workers/evaluationSubstitution.ts | 4 +- app/client/src/workers/evaluationUtils.ts | 2 +- app/client/src/workers/validations.ts | 8 ++-- 163 files changed, 468 insertions(+), 468 deletions(-) diff --git a/app/client/.eslintrc.json b/app/client/.eslintrc.json index 98978c9688..441567e873 100644 --- a/app/client/.eslintrc.json +++ b/app/client/.eslintrc.json @@ -43,7 +43,7 @@ "allowFunctions": false, "allowBind": false }], - "no-shadow": ["error", { "builtinGlobals": true }] + "no-shadow": ["warn", { "builtinGlobals": true }] }, "settings": { "react": { diff --git a/app/client/src/api/ImportApi.ts b/app/client/src/api/ImportApi.ts index 310d4c5515..eac6e0ad76 100644 --- a/app/client/src/api/ImportApi.ts +++ b/app/client/src/api/ImportApi.ts @@ -14,7 +14,7 @@ class CurlImportApi extends Api { static curlImportURL = `v1/import`; static curlImport(request: CurlImportRequest): AxiosPromise { - const { pageId, name, curl, organizationId } = request; + const { curl, name, organizationId, pageId } = request; return Api.post(CurlImportApi.curlImportURL, curl, { type: "CURL", pageId, diff --git a/app/client/src/comments/AppComments/AppCommentsHeader.tsx b/app/client/src/comments/AppComments/AppCommentsHeader.tsx index 5fb37c55a6..8a2e1a7f39 100644 --- a/app/client/src/comments/AppComments/AppCommentsHeader.tsx +++ b/app/client/src/comments/AppComments/AppCommentsHeader.tsx @@ -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]); diff --git a/app/client/src/comments/CommentCard/CommentCard.tsx b/app/client/src/comments/CommentCard/CommentCard.tsx index ed09cb9ccd..05374ec28c 100644 --- a/app/client/src/comments/CommentCard/CommentCard.tsx +++ b/app/client/src/comments/CommentCard/CommentCard.tsx @@ -91,10 +91,10 @@ const useSelectCommentUsingQuery = (commentId: string) => { function CommentCard({ comment, - isParentComment, - toggleResolved, - resolved, commentThreadId, + isParentComment, + resolved, + toggleResolved, }: { comment: Comment; isParentComment?: boolean; diff --git a/app/client/src/comments/CommentCard/CommentContextMenu.tsx b/app/client/src/comments/CommentCard/CommentContextMenu.tsx index bef783b01c..e9b525a5c4 100644 --- a/app/client/src/comments/CommentCard/CommentContextMenu.tsx +++ b/app/client/src/comments/CommentCard/CommentContextMenu.tsx @@ -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( diff --git a/app/client/src/comments/inlineComments/InlineCommentPin.tsx b/app/client/src/comments/inlineComments/InlineCommentPin.tsx index 6a265d8a40..65e1a367cc 100644 --- a/app/client/src/comments/inlineComments/InlineCommentPin.tsx +++ b/app/client/src/comments/inlineComments/InlineCommentPin.tsx @@ -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, }); diff --git a/app/client/src/comments/inlineComments/UnpublishedCommentThread.tsx b/app/client/src/comments/inlineComments/UnpublishedCommentThread.tsx index 5861dbd56c..df54754a7f 100644 --- a/app/client/src/comments/inlineComments/UnpublishedCommentThread.tsx +++ b/app/client/src/comments/inlineComments/UnpublishedCommentThread.tsx @@ -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, }); diff --git a/app/client/src/comments/tests/Comments.test.tsx b/app/client/src/comments/tests/Comments.test.tsx index 07ad0806b6..dd3cb0fb05 100644 --- a/app/client/src/comments/tests/Comments.test.tsx +++ b/app/client/src/comments/tests/Comments.test.tsx @@ -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(
    , @@ -87,7 +87,7 @@ describe("Comment threads", () => { done(); }); it("accept replies", async (done) => { - const { getByDataCy, findByText, findByDataCy } = render( + const { findByDataCy, findByText, getByDataCy } = render(
    , diff --git a/app/client/src/components/ads/Button.tsx b/app/client/src/components/ads/Button.tsx index ea97229575..b380b1f70f 100644 --- a/app/client/src/components/ads/Button.tsx +++ b/app/client/src/components/ads/Button.tsx @@ -380,7 +380,7 @@ function TextLoadingState({ text }: { text?: string }) { return {text}; } -function IconLoadingState({ size, icon }: { size?: Size; icon?: IconName }) { +function IconLoadingState({ icon, size }: { size?: Size; icon?: IconName }) { return ; } diff --git a/app/client/src/components/ads/DraggableList.tsx b/app/client/src/components/ads/DraggableList.tsx index 79a03ed66d..a14d9bc176 100644 --- a/app/client/src/components/ads/DraggableList.tsx +++ b/app/client/src/components/ads/DraggableList.tsx @@ -32,7 +32,7 @@ const updateSpringStyles = ( // Styles when items are dragged/idle const dragIdleSpringStyles = ( order: Array, - { 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(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) => ( + ItemRenderer={({ index, item }: any) => renderComponent({ deleteOption, updateOption, diff --git a/app/client/src/components/ads/EditableText.tsx b/app/client/src/components/ads/EditableText.tsx index bca0528165..9fc1374617 100644 --- a/app/client/src/components/ads/EditableText.tsx +++ b/app/client/src/components/ads/EditableText.tsx @@ -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); diff --git a/app/client/src/components/ads/EmojiPicker.tsx b/app/client/src/components/ads/EmojiPicker.tsx index 7829e7ec0e..719abcd789 100644 --- a/app/client/src/components/ads/EmojiPicker.tsx +++ b/app/client/src/components/ads/EmojiPicker.tsx @@ -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; diff --git a/app/client/src/components/ads/MentionsInput.tsx b/app/client/src/components/ads/MentionsInput.tsx index 94525cb16f..1c2b8c2031 100644 --- a/app/client/src/components/ads/MentionsInput.tsx +++ b/app/client/src/components/ads/MentionsInput.tsx @@ -25,13 +25,13 @@ type Props = { }; function MentionsInput({ - onSubmit, - suggestions, - onSearchSuggestions, - editorState, - setEditorState, autoFocus, + editorState, + onSearchSuggestions, + onSubmit, placeholder, + setEditorState, + suggestions, }: Props) { const ref = useRef(null); const [open, setOpen] = useState(false); diff --git a/app/client/src/components/ads/ScrollIndicator.tsx b/app/client/src/components/ads/ScrollIndicator.tsx index c9219337b0..7ffc3fafef 100644 --- a/app/client/src/components/ads/ScrollIndicator.tsx +++ b/app/client/src/components/ads/ScrollIndicator.tsx @@ -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; diff --git a/app/client/src/components/ads/Table.tsx b/app/client/src/components/ads/Table.tsx index fdfd1501be..2c1f3d8e5c 100644 --- a/app/client/src/components/ads/Table.tsx +++ b/app/client/src/components/ads/Table.tsx @@ -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 ( diff --git a/app/client/src/components/ads/TextInput.tsx b/app/client/src/components/ads/TextInput.tsx index 633528236b..4fc64505d0 100644 --- a/app/client/src/components/ads/TextInput.tsx +++ b/app/client/src/components/ads/TextInput.tsx @@ -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 ? ( { 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) { diff --git a/app/client/src/components/designSystems/appsmith/CreatableDropdown.tsx b/app/client/src/components/designSystems/appsmith/CreatableDropdown.tsx index d6465d62a9..7220d1656c 100644 --- a/app/client/src/components/designSystems/appsmith/CreatableDropdown.tsx +++ b/app/client/src/components/designSystems/appsmith/CreatableDropdown.tsx @@ -77,14 +77,14 @@ const selectStyles = { class CreatableDropdown extends React.Component { render() { const { - placeholder, - options, - isLoading, - input, - noOptionsMessage, components, + input, inputValue, + isLoading, + noOptionsMessage, onInputChange, + options, + placeholder, } = this.props; const optionalProps: Partial = {}; if (noOptionsMessage) optionalProps.noOptionsMessage = noOptionsMessage; diff --git a/app/client/src/components/designSystems/appsmith/DraggableListComponent.tsx b/app/client/src/components/designSystems/appsmith/DraggableListComponent.tsx index ca1fb37219..967ef2a981 100644 --- a/app/client/src/components/designSystems/appsmith/DraggableListComponent.tsx +++ b/app/client/src/components/designSystems/appsmith/DraggableListComponent.tsx @@ -81,16 +81,16 @@ export class DroppableComponent extends React.Component< render() { const { - renderComponent, deleteOption, - updateOption, - toggleVisibility, onEdit, + renderComponent, + toggleVisibility, + updateOption, } = this.props; return ( - {({ innerRef, droppableProps, placeholder }) => ( + {({ droppableProps, innerRef, placeholder }) => ( } {...droppableProps} @@ -103,7 +103,7 @@ export class DroppableComponent extends React.Component< index={index} key={item.id} > - {({ innerRef, draggableProps, dragHandleProps }) => ( + {({ draggableProps, dragHandleProps, innerRef }) => ( } {...draggableProps} diff --git a/app/client/src/components/designSystems/appsmith/Dropdown.tsx b/app/client/src/components/designSystems/appsmith/Dropdown.tsx index ecade3fff9..92e1a76645 100644 --- a/app/client/src/components/designSystems/appsmith/Dropdown.tsx +++ b/app/client/src/components/designSystems/appsmith/Dropdown.tsx @@ -53,7 +53,7 @@ const selectStyles = { }; export function BaseDropdown(props: DropdownProps) { - const { input, customSelectStyles } = props; + const { customSelectStyles, input } = props; return (