diff --git a/.github/workflows/integration-tests-command.yml b/.github/workflows/integration-tests-command.yml index f5e1d3cae2..67af01bea8 100644 --- a/.github/workflows/integration-tests-command.yml +++ b/.github/workflows/integration-tests-command.yml @@ -1097,7 +1097,7 @@ jobs: - run: echo "::set-output name=run_result::success" > ~/run_result ui-test-result: - needs: ui-test + needs: [ui-test, fat-conatiner-test] # Only run if the ui-test with matrices step is successful if: always() runs-on: ubuntu-latest @@ -1209,7 +1209,7 @@ jobs: run: echo "$PAYLOAD_CONTEXT" package: - needs: ui-test + needs: [ui-test, fat-conatiner-test] runs-on: ubuntu-latest defaults: run: diff --git a/.github/workflows/test-build-docker-image.yml b/.github/workflows/test-build-docker-image.yml index 2ccb522e01..842c7c243c 100644 --- a/.github/workflows/test-build-docker-image.yml +++ b/.github/workflows/test-build-docker-image.yml @@ -1159,7 +1159,7 @@ jobs: - run: echo "::set-output name=run_result::success" > ~/run_result ui-test-result: - needs: ui-test + needs: [ui-test, fat-container-test] if: always() && (github.event_name == 'workflow_dispatch' || github.event_name == 'push' || @@ -1220,7 +1220,7 @@ jobs: fi package: - needs: ui-test + needs: [ui-test, fat-container-test] runs-on: ubuntu-latest # Run this job irrespective of tests failing, if this is the release branch; or only if the tests pass, if this is the master branch. diff --git a/Dockerfile b/Dockerfile index f5abba4cdb..d845507e7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,10 +10,12 @@ ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 # Update APT packages - Base Layer -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - supervisor curl cron certbot nginx gnupg wget netcat openssh-client \ - software-properties-common gettext openjdk-11-jre \ - python3-pip python-setuptools git \ +RUN apt-get update \ + && apt-get upgrade --yes \ + && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ + supervisor curl cron certbot nginx gnupg wget netcat openssh-client \ + software-properties-common gettext openjdk-11-jre \ + python3-pip python-setuptools git \ && add-apt-repository ppa:redislabs/redis \ && pip install --no-cache-dir git+https://github.com/coderanger/supervisor-stdout@973ba19967cdaf46d9c1634d1675fc65b9574f6e \ && apt-get remove -y git python3-pip \ diff --git a/app/client/.gitignore b/app/client/.gitignore index f801f7de68..74d2f32c28 100755 --- a/app/client/.gitignore +++ b/app/client/.gitignore @@ -8,6 +8,7 @@ # testing /coverage +/stacks # production /build diff --git a/app/client/cypress/fixtures/AForceMigrationExport.json b/app/client/cypress/fixtures/AForceMigrationExport.json new file mode 100644 index 0000000000..acd39132cc --- /dev/null +++ b/app/client/cypress/fixtures/AForceMigrationExport.json @@ -0,0 +1,11988 @@ +{ + "clientSchemaVersion": 1, + "serverSchemaVersion": 3, + "exportedApplication": { + "name": "Community Issues", + "isPublic": false, + "appIsExample": false, + "unreadCommentThreads": 0, + "color": "#CCCCCC", + "icon": "arrow-right", + "slug": "community-issues", + "evaluationVersion": 2, + "applicationVersion": 1, + "isManualUpdate": false, + "new": true + }, + "datasourceList": [ + { + "userPermissions": [ + "execute:datasources", + "manage:datasources", + "read:datasources" + ], + "gitSyncId": "620251c917bfcd7d6017a1fc_622201ea20daed7797f5693c", + "name": "AForceDB", + "pluginId": "postgres-plugin", + "invalids": [ + + ], + "messages": [ + + ], + "isConfigured": true, + "isValid": true, + "new": true + } + ], + "pageList": [ + { + "userPermissions": [ + "read:pages", + "manage:pages" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623762992e5d3f189d0c3c25", + "unpublishedPage": { + "name": "Issues", + "slug": "issues", + "layouts": [ + { + "id": "Issues", + "userPermissions": [ + + ], + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1082.0, + "snapColumns": 64.0, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0.0, + "bottomRow": 1160.0, + "containerStyle": "none", + "snapRows": 125.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 53.0, + "minHeight": 940.0, + "parentColumnSpace": 1.0, + "dynamicBindingPathList": [ + + ], + "leftColumn": 0.0, + "children": [ + { + "widgetName": "upvote_modal", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.4975978e.svg", + "topRow": 90.0, + "bottomRow": 90.0, + "parentRowSpace": 1.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "animateLoading": true, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Canvas5", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 470.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 478.0, + "parentColumnSpace": 1.0, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "upvote_label_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + } + ], + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET_V2", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.labels.map((label) => {\n return {\n\t label: label,\n\t value: label\n }\n})}}", + "animateLoading": true, + "parentColumnSpace": 16.3125, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{GithubManager.getLabels()}}", + "placeholderText": "Select label(s)", + "isDisabled": false, + "key": "5rw0979hv0", + "isRequired": true, + "rightColumn": 64.0, + "widgetId": "xdplbo2hdw", + "isVisible": true, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{fetch_labels.run({ filterText: upvote_label_select.filterText })}}" + }, + { + "widgetName": "Text12Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 15.0, + "bottomRow": 19.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Comment", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "LEFT", + "widgetId": "hx56ibu1uk", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "comment_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 19.0, + "bottomRow": 31.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "resetOnSubmit": true, + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": false, + "rightColumn": 62.0, + "widgetId": "x2u0y4ound", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Icon2", + "rightColumn": 64.0, + "onClick": "{{closeModal('upvote_modal')}}", + "iconName": "cross", + "buttonColor": "#2E3D49", + "displayName": "Icon", + "iconSVG": "/static/media/icon.31d6cfe0.svg", + "widgetId": "nphe3f67yt", + "topRow": 1.0, + "bottomRow": 5.0, + "isVisible": true, + "type": "ICON_BUTTON_WIDGET", + "version": 1.0, + "hideCard": true, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "leftColumn": 58.0, + "dynamicBindingPathList": [ + + ], + "borderRadius": "SHARP", + "buttonVariant": "TERTIARY", + "iconSize": 24.0, + "key": "aeg87lexno" + }, + { + "widgetName": "Text11", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 1.0, + "bottomRow": 5.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Upvote Issue", + "key": "fzyz91gt8q", + "rightColumn": 41.0, + "textAlign": "LEFT", + "widgetId": "bfqckgaole", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "HEADING1" + }, + { + "widgetName": "Button5", + "onClick": "{{closeModal('upvote_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 41.0, + "bottomRow": 45.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 30.0, + "dynamicBindingPathList": [ + + ], + "text": "Close", + "isDisabled": false, + "key": "oz6v5ujks3", + "rightColumn": 42.0, + "isDefaultClickDisabled": true, + "widgetId": "2mnhq3yf99", + "buttonStyle": "PRIMARY", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "SECONDARY" + }, + { + "widgetName": "Button6", + "onClick": "{{IssueManager.addComment()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isDisabled" + } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 41.0, + "bottomRow": 45.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 42.0, + "dynamicBindingPathList": [ + { + "key": "isDisabled" + } + ], + "text": "Save", + "isDisabled": "{{!comment_link_input.isValid || IssueManager.getAssignedLabels(upvote_label_select.selectedOptionValues).length == 0}}", + "key": "oz6v5ujks3", + "rightColumn": 64.0, + "isDefaultClickDisabled": true, + "widgetId": "8ph22tfh2p", + "buttonStyle": "PRIMARY_BUTTON", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY" + }, + { + "widgetName": "Text12", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 6.0, + "bottomRow": 10.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Link", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "LEFT", + "widgetId": "gculfyyarv", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "comment_link_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 10.0, + "bottomRow": 14.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": true, + "rightColumn": 62.0, + "widgetId": "hhr3oe3adk", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Text25", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 31.0, + "bottomRow": 35.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "Labels", + "key": "z1pp8v2iis", + "rightColumn": 17.0, + "textAlign": "LEFT", + "widgetId": "jj9lerbuso", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "rightColumn": 0.0, + "detachFromLayout": true, + "widgetId": "a189hjos00", + "isVisible": true, + "version": 1.0, + "parentId": "wfscrnavzk", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "key": "9ppzbhlnqc", + "height": 478.0, + "rightColumn": 0.0, + "detachFromLayout": true, + "widgetId": "wfscrnavzk", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "width": 456.0 + }, + { + "widgetName": "Tabs1", + "isCanvas": true, + "dynamicPropertyPathList": [ + { + "key": "isVisible" + }, + { + "key": "onTabSelected" + } + ], + "displayName": "Tabs", + "iconSVG": "/static/media/icon.74a6d653.svg", + "topRow": 5.0, + "bottomRow": 89.0, + "parentRowSpace": 10.0, + "type": "TABS_WIDGET", + "hideCard": false, + "shouldScrollContents": false, + "animateLoading": false, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + { + "key": "onTabSelected" + } + ], + "leftColumn": 44.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "children": [ + { + "tabId": "tab1", + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 830.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 400.0, + "parentColumnSpace": 1.0, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "template": { + "Canvas1Copy": { + "widgetName": "Canvas1Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 400.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "dropDisabled": true, + "openParentPropertyPane": true, + "minHeight": 400.0, + "noPad": true, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + "2mnw941o3c" + ], + "key": "6u4x0kf3h8", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "ucvwcx91v9", + "containerStyle": "none", + "isVisible": true, + "version": 1.0, + "parentId": "cu1twhxgsd", + "renderMode": "CANVAS", + "isLoading": false + }, + "Container1": { + "boxShadow": "NONE", + "widgetName": "Container1", + "borderColor": "transparent", + "disallowCopy": true, + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3.svg", + "topRow": 0.0, + "bottomRow": 12.0, + "dragDisabled": true, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "openParentPropertyPane": true, + "isDeletable": false, + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + "tog68u9on9" + ], + "borderWidth": "0", + "key": "kvuew872nd", + "disablePropertyPane": true, + "backgroundColor": "white", + "rightColumn": 64.0, + "widgetId": "2mnw941o3c", + "containerStyle": "card", + "isVisible": true, + "version": 1.0, + "parentId": "ucvwcx91v9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "0" + }, + "Canvas2Copy": { + "widgetName": "Canvas2Copy", + "detachFromLayout": true, + "displayName": "Canvas", + "widgetId": "tog68u9on9", + "containerStyle": "none", + "topRow": 0.0, + "bottomRow": 120.0, + "parentRowSpace": 1.0, + "isVisible": true, + "type": "CANVAS_WIDGET", + "canExtend": false, + "version": 1.0, + "hideCard": true, + "parentId": "2mnw941o3c", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + "kklt0cg1tk", + "7sjskfdsub", + "6sjuuvj9ls", + "22rrixkfjj", + "05joyb6dqj" + ], + "key": "6u4x0kf3h8" + }, + "Text2": { + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{List1.listData.map((currentItem) => currentItem.author)}}", + "key": "fzyz91gt8q", + "rightColumn": 29.0, + "textAlign": "LEFT", + "widgetId": "kklt0cg1tk", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "HEADING" + }, + "Text3": { + "widgetName": "Text3", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 4.0, + "bottomRow": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{List1.listData.map((currentItem) => currentItem.comment)}}", + "key": "fzyz91gt8q", + "rightColumn": 64.0, + "textAlign": "LEFT", + "widgetId": "7sjskfdsub", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "", + "textColor": "#231F20", + "version": 1.0, + "shouldScroll": true, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "BODY" + }, + "IconButton2": { + "boxShadow": "NONE", + "widgetName": "IconButton2", + "onClick": "{{List1.listData.map((currentItem) => navigateTo(currentItem.link, {},'NEW_WINDOW'))}}", + "buttonColor": "#03B365", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 56.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 64.0, + "iconName": "link", + "widgetId": "6sjuuvj9ls", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + "IconButton3": { + "boxShadow": "NONE", + "widgetName": "IconButton3", + "onClick": "{{IssueManager.deleteComment()}}", + "buttonColor": "#F86A2B", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 49.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 56.0, + "iconName": "trash", + "widgetId": "22rrixkfjj", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + "Text14": { + "widgetName": "Text14", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.1357421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 33.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "{{List1.listData.map((currentItem) => moment(currentItem.created_at).format(\"Do MMM\"))}}", + "key": "w50usn0v9g", + "rightColumn": 49.0, + "textAlign": "RIGHT", + "widgetId": "05joyb6dqj", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2" + } + }, + "widgetName": "List1", + "listData": "{{fetch_comments.data}}", + "isCanvas": true, + "displayName": "List", + "iconSVG": "/static/media/icon.9925ee17.svg", + "topRow": 0.0, + "bottomRow": 81.0, + "parentRowSpace": 10.0, + "type": "LIST_WIDGET", + "hideCard": false, + "gridGap": 0.0, + "animateLoading": true, + "parentColumnSpace": 6.7265625, + "dynamicTriggerPathList": [ + { + "key": "template.IconButton2.onClick" + }, + { + "key": "template.IconButton3.onClick" + } + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "listData" + }, + { + "key": "template.Text3.text" + }, + { + "key": "template.Text2.text" + }, + { + "key": "template.Text14.text" + }, + { + "key": "template.Text2.text" + }, + { + "key": "template.Text3.text" + }, + { + "key": "template.IconButton2.onClick" + }, + { + "key": "template.Text14.text" + } + ], + "gridType": "vertical", + "enhancements": true, + "children": [ + { + "widgetName": "Canvas1Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 400.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "dropDisabled": true, + "openParentPropertyPane": true, + "minHeight": 400.0, + "noPad": true, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "boxShadow": "NONE", + "widgetName": "Container1", + "borderColor": "transparent", + "disallowCopy": true, + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3.svg", + "topRow": 0.0, + "bottomRow": 12.0, + "dragDisabled": true, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "openParentPropertyPane": true, + "isDeletable": false, + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Canvas2Copy", + "detachFromLayout": true, + "displayName": "Canvas", + "widgetId": "tog68u9on9", + "containerStyle": "none", + "topRow": 0.0, + "bottomRow": 120.0, + "parentRowSpace": 1.0, + "isVisible": true, + "type": "CANVAS_WIDGET", + "canExtend": false, + "version": 1.0, + "hideCard": true, + "parentId": "2mnw941o3c", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{currentItem.author}}", + "key": "fzyz91gt8q", + "rightColumn": 29.0, + "textAlign": "LEFT", + "widgetId": "kklt0cg1tk", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "HEADING" + }, + { + "widgetName": "Text3", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 4.0, + "bottomRow": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{currentItem.comment}}", + "key": "fzyz91gt8q", + "rightColumn": 64.0, + "textAlign": "LEFT", + "widgetId": "7sjskfdsub", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "", + "textColor": "#231F20", + "version": 1.0, + "shouldScroll": true, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "BODY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton2", + "onClick": "{{navigateTo(currentItem.link, {},'NEW_WINDOW')}}", + "buttonColor": "#03B365", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 56.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 64.0, + "iconName": "link", + "widgetId": "6sjuuvj9ls", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton3", + "onClick": "{{IssueManager.deleteComment()}}", + "buttonColor": "#F86A2B", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 49.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 56.0, + "iconName": "trash", + "widgetId": "22rrixkfjj", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "Text14", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.1357421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 33.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "{{moment(currentItem.created_at).format(\"Do MMM\")}}", + "key": "w50usn0v9g", + "rightColumn": 49.0, + "textAlign": "RIGHT", + "widgetId": "05joyb6dqj", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2" + } + ], + "key": "6u4x0kf3h8" + } + ], + "borderWidth": "0", + "key": "kvuew872nd", + "disablePropertyPane": true, + "backgroundColor": "white", + "rightColumn": 64.0, + "widgetId": "2mnw941o3c", + "containerStyle": "card", + "isVisible": true, + "version": 1.0, + "parentId": "ucvwcx91v9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "0" + } + ], + "key": "6u4x0kf3h8", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "ucvwcx91v9", + "containerStyle": "none", + "isVisible": true, + "version": 1.0, + "parentId": "cu1twhxgsd", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "privateWidgets": { + "Text2": true, + "Text3": true, + "IconButton2": true, + "IconButton3": true, + "Text14": true + }, + "key": "0d6epexg6w", + "backgroundColor": "transparent", + "rightColumn": 64.0, + "itemBackgroundColor": "#F6F7F8", + "widgetId": "cu1twhxgsd", + "isVisible": true, + "parentId": "e05q08c1nq", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "tabName": "Upvotes", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "e05q08c1nq", + "isVisible": true, + "version": 1.0, + "parentId": "n316autef7", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "tabId": "tab2", + "widgetName": "Canvas2", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 800.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 400.0, + "parentColumnSpace": 1.0, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Text5", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Title", + "key": "fzyz91gt8q", + "rightColumn": 12.0, + "textAlign": "LEFT", + "widgetId": "hb6ha60ybn", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text6", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 8.0, + "bottomRow": 12.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Description", + "key": "fzyz91gt8q", + "rightColumn": 26.0, + "textAlign": "LEFT", + "widgetId": "5ohkvurob7", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text7", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 31.0, + "bottomRow": 35.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Type", + "key": "fzyz91gt8q", + "rightColumn": 16.0, + "textAlign": "LEFT", + "widgetId": "ldimms4xqb", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text8", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 39.0, + "bottomRow": 43.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "Labels: {{Table1.selectedRow.labels.join(\",\")}}", + "key": "fzyz91gt8q", + "rightColumn": 63.0, + "textAlign": "LEFT", + "widgetId": "r5pmq8fk8b", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text9", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Github Issue Link", + "key": "fzyz91gt8q", + "rightColumn": 24.0, + "textAlign": "LEFT", + "widgetId": "imcqf02q27", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Button1", + "onClick": "{{IssueManager.update()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "isDisabled" + } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 74.0, + "bottomRow": 78.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 42.0, + "dynamicBindingPathList": [ + { + "key": "isDisabled" + } + ], + "text": "Save", + "isDisabled": "{{!edit_link_input.isValid || !edit_type_input.isValid || !edit_title_input.text || IssueManager.getAssignedLabels(edit_label_select.selectedOptionValues).length == 0}}", + "key": "oz6v5ujks3", + "rightColumn": 63.0, + "isDefaultClickDisabled": true, + "widgetId": "xl37pbnn45", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY" + }, + { + "widgetName": "edit_title_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 4.0, + "bottomRow": 8.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "mtq0kmoqpi", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{Table1.selectedRow.title}}" + }, + { + "widgetName": "edit_description_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 12.0, + "bottomRow": 23.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "7kjh660g7v", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{Table1.selectedRow.description}}" + }, + { + "widgetName": "edit_type_input", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.type}}", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{Configs.type}}", + "placeholderText": "Select option", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "pnfwyps2nc", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "edit_issue_select", + "isFilterable": true, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 51.0, + "bottomRow": 55.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.github_issue_id || \"\"}}", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{GithubManager.getIssues()}}", + "placeholderText": "Search Github Issue", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "kuwxh0qtmg", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{GithubManager.searchIssues(edit_issue_select.filterText)}}" + }, + { + "widgetName": "Button4", + "onClick": "{{IssueManager.delete()}}", + "buttonColor": "#DD4B34", + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 74.0, + "bottomRow": 78.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 32.0, + "dynamicBindingPathList": [ + + ], + "text": "", + "isDisabled": false, + "key": "oz6v5ujks3", + "rightColumn": 41.0, + "isDefaultClickDisabled": true, + "iconName": "trash", + "widgetId": "ehrkah2uam", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY", + "iconAlign": "left" + }, + { + "widgetName": "Text15", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 55.0, + "bottomRow": 59.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Answer Link", + "key": "w50usn0v9g", + "rightColumn": 30.0, + "textAlign": "LEFT", + "widgetId": "ljq0eqe3o5", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "edit_answer_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 59.0, + "bottomRow": 63.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Documentation / Example app URL", + "isDisabled": false, + "key": "iqxzeop4oc", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "82zz8zgqm9", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton6", + "onClick": "{{fetch_github_issue.run(() => navigateTo('https://github.com/appsmithorg/appsmith/issues/' + fetch_github_issue.data[0].issue_number, {},'NEW_WINDOW'))}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isVisible" + } + ], + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 24.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "isDisabled": false, + "key": "xtq2jih6i3", + "rightColumn": 31.0, + "iconName": "link", + "widgetId": "yv95jo8zuk", + "isVisible": "{{!!Table1.selectedRow.github_issue_id}}", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "Text17", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 26.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "{{Table1.selectedRow.author}}\n{{moment(Table1.selectedRow.created_at).format(\"Do MMM YYYY\")}}", + "key": "2y13r0w088", + "rightColumn": 63.0, + "disableLink": true, + "textAlign": "RIGHT", + "widgetId": "r0psmbf17o", + "isVisible": true, + "fontStyle": "", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text18", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 23.0, + "bottomRow": 27.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.1884765625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Issue Link", + "key": "2y13r0w088", + "rightColumn": 22.0, + "textAlign": "LEFT", + "widgetId": "784m9ua7xy", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "edit_link_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 27.0, + "bottomRow": 31.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.1884765625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Discord / Github / Discourse / Intercom msg URL", + "isDisabled": false, + "key": "xkaggmfnaa", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "hlhsn0qacz", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{Table1.selectedRow.link || \"\"}}" + }, + { + "widgetName": "Text19", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 63.0, + "bottomRow": 67.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "States", + "key": "r0yrfpzmtn", + "rightColumn": 14.0, + "textAlign": "LEFT", + "widgetId": "5vtar11iru", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "edit_states_select", + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 67.0, + "bottomRow": 71.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.states}}", + "animateLoading": true, + "parentColumnSpace": 5.87890625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{Configs.states}}", + "placeholderText": "Select state(s)", + "isDisabled": false, + "key": "lmf0nxzr5a", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "qemq1k1zhf", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton9", + "onClick": "{{IssueManager.createGithubIssue()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + + ], + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 4.78515625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 52.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "6o86hsevdn", + "rightColumn": 63.0, + "iconName": "cube-add", + "widgetId": "uj3oiub9lt", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton10", + "onClick": "{{remove_github_issue.run().then(() => fetch_issues.run())}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isVisible" + } + ], + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 4.78515625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 31.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "isDisabled": false, + "key": "66ba61jgdc", + "rightColumn": 38.0, + "iconName": "remove", + "widgetId": "ria4v9jmjk", + "isVisible": "{{!!Table1.selectedRow.github_issue_id}}", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "edit_label_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + } + ], + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 43.0, + "bottomRow": 47.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET_V2", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.labels.map((label) => {\n return {\n\t label: label,\n\t value: label\n }\n})}}", + "animateLoading": true, + "parentColumnSpace": 16.3125, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{GithubManager.getLabels()}}", + "placeholderText": "Select label(s)", + "isDisabled": false, + "key": "5rw0979hv0", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "ufwxmsi8gy", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{fetch_labels.run({ filterText: edit_label_select.filterText })}}" + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "tabName": "Details", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "devkwyks4k", + "isVisible": true, + "version": 1.0, + "parentId": "n316autef7", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "key": "5hk6y4h4e6", + "rightColumn": 64.0, + "widgetId": "n316autef7", + "defaultTab": "Details", + "onTabSelected": "{{Tabs1.selectedTab === \"Upvotes\" ? fetch_comments.run() : undefined}}", + "shouldShowTabs": true, + "tabsObj": { + "tab2": { + "label": "Details", + "id": "tab2", + "widgetId": "devkwyks4k", + "isVisible": true, + "index": 0.0 + }, + "tab1": { + "label": "Upvotes", + "id": "tab1", + "widgetId": "e05q08c1nq", + "isVisible": true, + "index": 1.0 + } + }, + "isVisible": "{{!!Table1.selectedRow.id}}", + "version": 3.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "FilePicker1", + "displayName": "FilePicker", + "iconSVG": "/static/media/icon.7c5ad9c3.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "allowedFileTypes": [ + + ], + "type": "FILE_PICKER_WIDGET_V2", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 59.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "vhc66isyeb", + "isRequired": false, + "rightColumn": 64.0, + "isDefaultClickDisabled": true, + "widgetId": "bitkgcu3n8", + "defaultSelectedFiles": [ + + ], + "isVisible": false, + "label": "Select Files", + "maxFileSize": "5", + "version": 1.0, + "fileDataType": "Text", + "parentId": "0", + "selectedFiles": [ + + ], + "renderMode": "CANVAS", + "isLoading": false, + "files": [ + + ], + "maxNumFiles": 1.0 + }, + { + "boxShadow": "NONE", + "widgetName": "AddIssue", + "onClick": "{{showModal('add_issue_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 9.8095703125, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 44.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 47.0, + "iconName": "add", + "widgetId": "11kdci9jhn", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "SHARP", + "buttonVariant": "TERTIARY", + "boxShadowColor": "" + }, + { + "widgetName": "add_issue_modal", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.4975978e.svg", + "topRow": 90.0, + "bottomRow": 114.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 14.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Canvas3", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 720.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 694.0, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "label_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + } + ], + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET_V2", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "", + "animateLoading": true, + "parentColumnSpace": 16.3125, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{GithubManager.getLabels()}}", + "placeholderText": "Select label(s)", + "isDisabled": false, + "key": "5rw0979hv0", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "ankv8zz1xp", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{fetch_labels.run({ filterText: label_select.filterText })}}" + }, + { + "widgetName": "Text19Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 45.0, + "bottomRow": 49.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "States", + "key": "r0yrfpzmtn", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "i9kgqmx0tz", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "states_select", + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 45.0, + "bottomRow": 49.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.states}}", + "animateLoading": true, + "parentColumnSpace": 5.87890625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{Configs.states}}", + "placeholderText": "Select state(s)", + "isDisabled": false, + "key": "lmf0nxzr5a", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "qawnxpxdix", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "Text5Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 16.0, + "bottomRow": 20.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Title", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "2mh922944s", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "title_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 16.0, + "bottomRow": 20.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "glfkj7n61g", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{GithubManager.getSelectedGithubIssue()?.title || \"\"}}" + }, + { + "widgetName": "Text6Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 21.0, + "bottomRow": 25.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Description", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "tx9h5i8ovw", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "description_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 21.0, + "bottomRow": 29.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "xp8otc7k1c", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Text7Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 6.0, + "bottomRow": 10.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Type", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "xa5lprgkkr", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "type_select", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 6.0, + "bottomRow": 10.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Configs.type}}", + "placeholderText": "Select Type", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "jw4tgzde1z", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "Text8Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Labels", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "483a8ji8wb", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text9Copy", + "dynamicPropertyPathList": [ + { + "key": "isVisible" + } + ], + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 11.0, + "bottomRow": 15.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "text": "Github Issue", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "cj7wnbg01q", + "isVisible": "{{type_select.selectedOptionValue === \"Feature\" || type_select.selectedOptionValue === \"Bug\"}}", + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "add_issue_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + }, + { + "key": "isVisible" + } + ], + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 11.0, + "bottomRow": 15.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "isVisible" + } + ], + "options": "{{GithubManager.getIssues()}}", + "placeholderText": "Search Github Issues", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "mle8h2yllt", + "isVisible": "{{type_select.selectedOptionValue === \"Feature\" || type_select.selectedOptionValue === \"Bug\"}}", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{GithubManager.searchIssues(add_issue_select.filterText)}}" + }, + { + "widgetName": "Text10", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "New Issue", + "key": "fzyz91gt8q", + "rightColumn": 28.0, + "textAlign": "LEFT", + "widgetId": "240nwl18xx", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "HEADING1" + }, + { + "widgetName": "Button2", + "onClick": "{{closeModal('add_issue_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 63.0, + "bottomRow": 67.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 26.0, + "dynamicBindingPathList": [ + + ], + "text": "Close", + "isDisabled": false, + "key": "oz6v5ujks3", + "rightColumn": 38.0, + "isDefaultClickDisabled": true, + "widgetId": "qk4c4nfb1q", + "buttonStyle": "PRIMARY", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "SECONDARY" + }, + { + "widgetName": "Button3", + "onClick": "{{IssueManager.create_issue()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isDisabled" + } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 63.0, + "bottomRow": 67.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 38.0, + "dynamicBindingPathList": [ + { + "key": "isDisabled" + } + ], + "text": "Confirm", + "isDisabled": "{{!link_input.isValid || !type_select.isValid || !title_input.text || IssueManager.getAssignedLabels(label_select.selectedOptionValues).length == 0}}", + "key": "oz6v5ujks3", + "rightColumn": 63.0, + "isDefaultClickDisabled": true, + "widgetId": "mhnwwl1t95", + "buttonStyle": "PRIMARY_BUTTON", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton5", + "onClick": "{{closeModal('add_issue_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 57.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "1b5hj6tv0b", + "rightColumn": 64.0, + "iconName": "cross", + "widgetId": "6tvffrozwj", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "Text13", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 30.0, + "bottomRow": 34.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Issue Link", + "key": "w50usn0v9g", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "w91q3a6doy", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "link_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 30.0, + "bottomRow": 34.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Discord / Github / Discourse / Intercom msg URL", + "isDisabled": false, + "key": "iqxzeop4oc", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "erhs9rotun", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{add_issue_select.selectedOptionValue ? \n\"https://github.com/appsmithorg/appsmith/issues/\" + GithubManager.getSelectedGithubIssue()?.issue_number : \"\"}}" + }, + { + "widgetName": "answer_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 40.0, + "bottomRow": 44.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Documentation / Example app URL", + "isDisabled": false, + "key": "iqxzeop4oc", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "335stzmyk5", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Text16", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 40.0, + "bottomRow": 44.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Answer Link", + "key": "w50usn0v9g", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "h9drw49jnw", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "8tzkaielld", + "isVisible": true, + "version": 1.0, + "parentId": "rxoie5b5j5", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "key": "9ppzbhlnqc", + "height": 694.0, + "rightColumn": 38.0, + "detachFromLayout": true, + "widgetId": "rxoie5b5j5", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "width": 456.0 + }, + { + "boxShadow": "NONE", + "widgetName": "RefreshIssues", + "onClick": "{{IssueManager.fetchIssues()}}", + "buttonColor": "#2E3D49", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 9.8095703125, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 41.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 44.0, + "iconName": "refresh", + "widgetId": "pu0p8ahn8i", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "SHARP", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "sort_select", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "GITHUB", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 20.3125, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 30.0, + "dynamicBindingPathList": [ + + ], + "options": "[\n {\n \"label\": \"Most Github Votes\",\n \"value\": \"GITHUB\"\n },\n {\n \"label\": \"Most Upvotes\",\n \"value\": \"VOTES\"\n },\n\t{\n \"label\": \"Most Commentors\",\n \"value\": \"COMMENTORS\"\n },\n\t{\n \"label\": \"Most Recent\",\n \"value\": \"RECENT\"\n }\n]", + "placeholderText": "Select option", + "isDisabled": false, + "key": "at2ne0v8x9", + "isRequired": true, + "rightColumn": 41.0, + "widgetId": "ra23cq4tyo", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{fetch_issues.run()}}" + }, + { + "widgetName": "type_filter", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "GREEN", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 23.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Configs.type}}", + "placeholderText": "Type", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": false, + "rightColumn": 30.0, + "widgetId": "eznbmvwewn", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{IssueManager.fetchIssues()}}" + }, + { + "widgetName": "status_filter", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 14.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Configs.states}}", + "placeholderText": "States", + "isDisabled": false, + "key": "52qeg2r9uo", + "isRequired": false, + "rightColumn": 23.0, + "widgetId": "sinxumk3m3", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{IssueManager.fetchIssues()}}" + }, + { + "widgetName": "pod_filter", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 7.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Utils.getPodLabels()}}", + "placeholderText": "Pods", + "isDisabled": false, + "key": "qjixxicfzt", + "isRequired": false, + "rightColumn": 14.0, + "widgetId": "ajzvz766xg", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{IssueManager.fetchIssues()}}" + }, + { + "multiRowSelection": false, + "onSort": "", + "isVisibleDownload": false, + "iconSVG": "/static/media/icon.db8a9cbd.svg", + "topRow": 5.0, + "isSortable": false, + "onPageChange": "{{fetch_issues.run()}}", + "type": "TABLE_WIDGET", + "animateLoading": true, + "dynamicBindingPathList": [ + { + "key": "tableData" + }, + { + "key": "primaryColumns.unique_commentors.computedValue" + }, + { + "key": "primaryColumns.total_reactions.computedValue" + }, + { + "key": "primaryColumns.upvote_id.computedValue" + }, + { + "key": "primaryColumns.count.computedValue" + }, + { + "key": "primaryColumns.link.computedValue" + }, + { + "key": "primaryColumns.answer.isCellVisible" + }, + { + "key": "primaryColumns.state.computedValue" + }, + { + "key": "primaryColumns.type.computedValue" + }, + { + "key": "primaryColumns.labels.computedValue" + }, + { + "key": "primaryColumns.description.computedValue" + }, + { + "key": "primaryColumns.title.computedValue" + }, + { + "key": "primaryColumns.created_at.computedValue" + }, + { + "key": "primaryColumns.author.computedValue" + }, + { + "key": "primaryColumns.github_issue_id.computedValue" + }, + { + "key": "primaryColumns.id.computedValue" + }, + { + "key": "primaryColumns.states.computedValue" + }, + { + "key": "primaryColumns.updated_at.computedValue" + }, + { + "key": "derivedColumns.customColumn2.computedValue" + }, + { + "key": "primaryColumns.customColumn2.computedValue" + } + ], + "leftColumn": 0.0, + "delimiter": ",", + "isVisibleFilters": true, + "isVisible": true, + "enableClientSideSearch": true, + "version": 3.0, + "totalRecordsCount": 0.0, + "isLoading": false, + "onSearchTextChanged": "{{fetch_issues.run()}}", + "columnSizeMap": { + "task": 245.0, + "step": 62.0, + "status": 75.0, + "id": 61.0, + "type": 88.0, + "title": 590.0, + "date": 101.0, + "created_at": 150.0, + "count": 69.00000000000001, + "customColumn1": 91.0, + "answer": 91.0, + "total_reactions": 60.0, + "unique_commentors": 144.0, + "states": 155.0, + "customColumn2": 93.0, + "state": 111.0, + "link": 188.0, + "description": 187.0, + "author": 157.0, + "github_issue_id": 163.0 + }, + "widgetName": "Table1", + "defaultPageSize": 0.0, + "columnOrder": [ + "type", + "title", + "customColumn2", + "states", + "total_reactions", + "unique_commentors", + "upvote_id", + "id", + "github_issue_id", + "author", + "created_at", + "description", + "labels", + "state", + "link", + "count", + "answer", + "updated_at", + "customColumn1" + ], + "dynamicPropertyPathList": [ + { + "key": "primaryColumns.answer.onClick" + }, + { + "key": "primaryColumns.answer.isCellVisible" + } + ], + "displayName": "Table", + "bottomRow": 89.0, + "parentRowSpace": 10.0, + "defaultSelectedRow": "0", + "hideCard": false, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + { + "key": "primaryColumns.customColumn1.onClick" + }, + { + "key": "onRowSelected" + }, + { + "key": "onPageChange" + }, + { + "key": "onSearchTextChanged" + }, + { + "key": "onSort" + }, + { + "key": "primaryColumns.answer.onClick" + } + ], + "primaryColumns": { + "customColumn1": { + "index": 7.0, + "width": 150.0, + "id": "customColumn1", + "columnType": "iconButton", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "UpVote", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.customColumn1))}}", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#38AFF4", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "buttonLabel": "{{Table1.sanitizedTableData.map((currentRow) => ( 'Upvote'))}}", + "iconName": "caret-up", + "borderRadius": "ROUNDED", + "buttonVariant": "SECONDARY", + "onClick": "{{showModal('upvote_modal')}}", + "horizontalAlignment": "LEFT", + "textSize": "PARAGRAPH" + }, + "id": { + "index": 0.0, + "width": 150.0, + "id": "id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "id", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.id))}}" + }, + "github_issue_id": { + "index": 1.0, + "width": 150.0, + "id": "github_issue_id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "github_issue_id", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.github_issue_id))}}" + }, + "author": { + "index": 2.0, + "width": 150.0, + "id": "author", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "author", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.author))}}" + }, + "created_at": { + "index": 3.0, + "width": 150.0, + "id": "created_at", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "created_at", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.created_at))}}" + }, + "title": { + "index": 4.0, + "width": 150.0, + "id": "title", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Title", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.title))}}" + }, + "description": { + "index": 5.0, + "width": 150.0, + "id": "description", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "description", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.description))}}" + }, + "labels": { + "index": 6.0, + "width": 150.0, + "id": "labels", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "labels", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.labels))}}" + }, + "type": { + "index": 7.0, + "width": 150.0, + "id": "type", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Type", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.type))}}" + }, + "state": { + "index": 8.0, + "width": 150.0, + "id": "state", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "state", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.state))}}" + }, + "answer": { + "index": 9.0, + "width": 150.0, + "id": "answer", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "iconButton", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": "{{Table1.sanitizedTableData.map((currentRow) => ( !!currentRow.answer))}}", + "isDerived": false, + "label": "Answer", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.answer))}}", + "iconName": "duplicate", + "buttonVariant": "TERTIARY", + "buttonColor": "#2E3D49", + "onClick": "{{copyToClipboard(currentRow.answer); showAlert('Copied');}}" + }, + "link": { + "index": 11.0, + "width": 150.0, + "id": "link", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "link", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.link))}}" + }, + "count": { + "index": 12.0, + "width": 150.0, + "id": "count", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "columnType": "number", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Votes", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.count))}}" + }, + "upvote_id": { + "index": 13.0, + "width": 150.0, + "id": "upvote_id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "upvote_id", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.upvote_id))}}" + }, + "total_reactions": { + "index": 14.0, + "width": 150.0, + "id": "total_reactions", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "+1", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.total_reactions))}}" + }, + "unique_commentors": { + "index": 15.0, + "width": 150.0, + "id": "unique_commentors", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Commentors", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.unique_commentors))}}" + }, + "states": { + "index": 16.0, + "width": 150.0, + "id": "states", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "States", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.states))}}" + }, + "updated_at": { + "index": 16.0, + "width": 150.0, + "id": "updated_at", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "updated_at", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.updated_at))}}" + }, + "customColumn2": { + "index": 18.0, + "width": 150.0, + "id": "customColumn2", + "horizontalAlignment": "CENTER", + "columnType": "text", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "Status", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( Configs.getTitleState(currentRow.states)))}}", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#03B365", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "textSize": "PARAGRAPH" + } + }, + "onRowSelected": "{{resetWidget(\"Tabs1\")}}", + "key": "tr3pdljkm8", + "derivedColumns": { + "customColumn1": { + "index": 7.0, + "width": 150.0, + "id": "customColumn1", + "columnType": "iconButton", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "UpVote", + "computedValue": "", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#38AFF4", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "buttonLabel": "{{Table1.sanitizedTableData.map((currentRow) => ( 'Upvote'))}}", + "iconName": "caret-up", + "borderRadius": "ROUNDED", + "buttonVariant": "PRIMARY", + "horizontalAlignment": "LEFT", + "textSize": "PARAGRAPH" + }, + "customColumn2": { + "index": 18.0, + "width": 150.0, + "id": "customColumn2", + "horizontalAlignment": "CENTER", + "columnType": "text", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "Status", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( Configs.getTitleState(currentRow.states)))}}", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#03B365", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "textSize": "PARAGRAPH" + } + }, + "rightColumn": 44.0, + "textSize": "PARAGRAPH", + "widgetId": "zsilqrkvkw", + "tableData": "{{IssueManager.getIssueData()}}", + "label": "Data", + "searchKey": "", + "parentId": "0", + "serverSidePaginationEnabled": true, + "renderMode": "CANVAS", + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "verticalAlignment": "CENTER" + }, + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 16.71875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "🗓 Issues", + "key": "t8e7qdq1ol", + "rightColumn": 7.0, + "textAlign": "LEFT", + "widgetId": "yyqsgarlj7", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "HEADING1" + } + ] + }, + "layoutOnLoadActions": [ + [ + { + "id": "Issues_search_github_issues", + "name": "search_github_issues", + "confirmBeforeExecute": false, + "pluginType": "DB", + "jsonPathKeys": [ + "\"%\" + this.params.searchText + \"%\"" + ], + "timeoutInMillisecond": 10000 + }, + { + "id": "Issues_fetch_label_config", + "name": "fetch_label_config", + "confirmBeforeExecute": false, + "pluginType": "API", + "jsonPathKeys": [ + + ], + "timeoutInMillisecond": 10000 + } + ], + [ + { + "id": "Issues_fetch_comments", + "name": "fetch_comments", + "confirmBeforeExecute": false, + "pluginType": "DB", + "jsonPathKeys": [ + "Table1.selectedRow.id" + ], + "timeoutInMillisecond": 10000 + } + ], + [ + { + "id": "Issues_fetch_labels", + "name": "fetch_labels", + "confirmBeforeExecute": false, + "pluginType": "API", + "jsonPathKeys": [ + + ], + "timeoutInMillisecond": 10000 + }, + { + "id": "Issues_fetch_issues", + "name": "fetch_issues", + "confirmBeforeExecute": false, + "pluginType": "DB", + "jsonPathKeys": [ + "appsmith.URL.queryParams.id ? \" and global_issues.id=\" + appsmith.URL.queryParams.id: \"\"", + "type_filter.selectedOptionValue && type_filter.selectedOptionValue !== \"ALL\" ? \"and global_issues.type ='\" + type_filter.selectedOptionValue + \"'\" : \"\"", + "\"%\" + Table1.searchText + \"%\"", + "(Table1.pageNo - 1) * Table1.pageSize", + "Table1.pageSize", + "status_filter.selectedOptionValue && status_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + status_filter.selectedOptionValue + \"' =ANY(global_issues.states)\" : \"\"", + "pod_filter.selectedOptionValue && pod_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + pod_filter.selectedOptionValue + \"'=ANY(global_issues.labels)\" : \"\"", + "sort_select.selectedOptionValue === \"GITHUB\" ? \"total_reactions desc, count desc, upvote_id desc\" : sort_select.selectedOptionValue === \"VOTES\" ? \"count desc, upvote_id desc, total_reactions desc\" : sort_select.selectedOptionValue === \"COMMENTORS\" ? \"unique_commentors desc, total_reactions desc, count desc, upvote_id desc\" : \"updated_at desc\"" + ], + "timeoutInMillisecond": 10000 + } + ] + ], + "new": false + } + ], + "userPermissions": [ + + ], + "isHidden": false + }, + "publishedPage": { + "name": "Issues", + "slug": "issues", + "layouts": [ + { + "id": "Issues", + "userPermissions": [ + + ], + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1082.0, + "snapColumns": 64.0, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0.0, + "bottomRow": 1160.0, + "containerStyle": "none", + "snapRows": 125.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 53.0, + "minHeight": 940.0, + "parentColumnSpace": 1.0, + "dynamicBindingPathList": [ + + ], + "leftColumn": 0.0, + "children": [ + { + "widgetName": "upvote_modal", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.4975978e.svg", + "topRow": 90.0, + "bottomRow": 90.0, + "parentRowSpace": 1.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "animateLoading": true, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Canvas5", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 470.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 478.0, + "parentColumnSpace": 1.0, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "upvote_label_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + } + ], + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET_V2", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.labels.map((label) => {\n return {\n\t label: label,\n\t value: label\n }\n})}}", + "animateLoading": true, + "parentColumnSpace": 16.3125, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{GithubManager.getLabels()}}", + "placeholderText": "Select label(s)", + "isDisabled": false, + "key": "5rw0979hv0", + "isRequired": true, + "rightColumn": 64.0, + "widgetId": "xdplbo2hdw", + "isVisible": true, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{fetch_labels.run({ filterText: upvote_label_select.filterText })}}" + }, + { + "widgetName": "Text12Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 15.0, + "bottomRow": 19.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Comment", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "LEFT", + "widgetId": "hx56ibu1uk", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "comment_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 19.0, + "bottomRow": 31.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "resetOnSubmit": true, + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": false, + "rightColumn": 62.0, + "widgetId": "x2u0y4ound", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Icon2", + "rightColumn": 64.0, + "onClick": "{{closeModal('upvote_modal')}}", + "iconName": "cross", + "buttonColor": "#2E3D49", + "displayName": "Icon", + "iconSVG": "/static/media/icon.31d6cfe0.svg", + "widgetId": "nphe3f67yt", + "topRow": 1.0, + "bottomRow": 5.0, + "isVisible": true, + "type": "ICON_BUTTON_WIDGET", + "version": 1.0, + "hideCard": true, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "leftColumn": 58.0, + "dynamicBindingPathList": [ + + ], + "borderRadius": "SHARP", + "buttonVariant": "TERTIARY", + "iconSize": 24.0, + "key": "aeg87lexno" + }, + { + "widgetName": "Text11", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 1.0, + "bottomRow": 5.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Upvote Issue", + "key": "fzyz91gt8q", + "rightColumn": 41.0, + "textAlign": "LEFT", + "widgetId": "bfqckgaole", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "HEADING1" + }, + { + "widgetName": "Button5", + "onClick": "{{closeModal('upvote_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 41.0, + "bottomRow": 45.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 30.0, + "dynamicBindingPathList": [ + + ], + "text": "Close", + "isDisabled": false, + "key": "oz6v5ujks3", + "rightColumn": 42.0, + "isDefaultClickDisabled": true, + "widgetId": "2mnhq3yf99", + "buttonStyle": "PRIMARY", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "SECONDARY" + }, + { + "widgetName": "Button6", + "onClick": "{{IssueManager.addComment()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isDisabled" + } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 41.0, + "bottomRow": 45.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 42.0, + "dynamicBindingPathList": [ + { + "key": "isDisabled" + } + ], + "text": "Save", + "isDisabled": "{{!comment_link_input.isValid || IssueManager.getAssignedLabels(upvote_label_select.selectedOptionValues).length == 0}}", + "key": "oz6v5ujks3", + "rightColumn": 64.0, + "isDefaultClickDisabled": true, + "widgetId": "8ph22tfh2p", + "buttonStyle": "PRIMARY_BUTTON", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY" + }, + { + "widgetName": "Text12", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 6.0, + "bottomRow": 10.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Link", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "LEFT", + "widgetId": "gculfyyarv", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "comment_link_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 10.0, + "bottomRow": 14.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": true, + "rightColumn": 62.0, + "widgetId": "hhr3oe3adk", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Text25", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 31.0, + "bottomRow": 35.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "Labels", + "key": "z1pp8v2iis", + "rightColumn": 17.0, + "textAlign": "LEFT", + "widgetId": "jj9lerbuso", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "a189hjos00", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "rightColumn": 0.0, + "detachFromLayout": true, + "widgetId": "a189hjos00", + "isVisible": true, + "version": 1.0, + "parentId": "wfscrnavzk", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "key": "9ppzbhlnqc", + "height": 478.0, + "rightColumn": 0.0, + "detachFromLayout": true, + "widgetId": "wfscrnavzk", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "width": 456.0 + }, + { + "widgetName": "Tabs1", + "isCanvas": true, + "dynamicPropertyPathList": [ + { + "key": "isVisible" + }, + { + "key": "onTabSelected" + } + ], + "displayName": "Tabs", + "iconSVG": "/static/media/icon.74a6d653.svg", + "topRow": 5.0, + "bottomRow": 89.0, + "parentRowSpace": 10.0, + "type": "TABS_WIDGET", + "hideCard": false, + "shouldScrollContents": false, + "animateLoading": false, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + { + "key": "onTabSelected" + } + ], + "leftColumn": 44.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "children": [ + { + "tabId": "tab1", + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 830.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 400.0, + "parentColumnSpace": 1.0, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "template": { + "Canvas1Copy": { + "widgetName": "Canvas1Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 400.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "dropDisabled": true, + "openParentPropertyPane": true, + "minHeight": 400.0, + "noPad": true, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + "2mnw941o3c" + ], + "key": "6u4x0kf3h8", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "ucvwcx91v9", + "containerStyle": "none", + "isVisible": true, + "version": 1.0, + "parentId": "cu1twhxgsd", + "renderMode": "CANVAS", + "isLoading": false + }, + "Container1": { + "boxShadow": "NONE", + "widgetName": "Container1", + "borderColor": "transparent", + "disallowCopy": true, + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3.svg", + "topRow": 0.0, + "bottomRow": 12.0, + "dragDisabled": true, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "openParentPropertyPane": true, + "isDeletable": false, + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + "tog68u9on9" + ], + "borderWidth": "0", + "key": "kvuew872nd", + "disablePropertyPane": true, + "backgroundColor": "white", + "rightColumn": 64.0, + "widgetId": "2mnw941o3c", + "containerStyle": "card", + "isVisible": true, + "version": 1.0, + "parentId": "ucvwcx91v9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "0" + }, + "Canvas2Copy": { + "widgetName": "Canvas2Copy", + "detachFromLayout": true, + "displayName": "Canvas", + "widgetId": "tog68u9on9", + "containerStyle": "none", + "topRow": 0.0, + "bottomRow": 120.0, + "parentRowSpace": 1.0, + "isVisible": true, + "type": "CANVAS_WIDGET", + "canExtend": false, + "version": 1.0, + "hideCard": true, + "parentId": "2mnw941o3c", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + "kklt0cg1tk", + "7sjskfdsub", + "6sjuuvj9ls", + "22rrixkfjj", + "05joyb6dqj" + ], + "key": "6u4x0kf3h8" + }, + "Text2": { + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{List1.listData.map((currentItem) => currentItem.author)}}", + "key": "fzyz91gt8q", + "rightColumn": 29.0, + "textAlign": "LEFT", + "widgetId": "kklt0cg1tk", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "HEADING" + }, + "Text3": { + "widgetName": "Text3", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 4.0, + "bottomRow": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{List1.listData.map((currentItem) => currentItem.comment)}}", + "key": "fzyz91gt8q", + "rightColumn": 64.0, + "textAlign": "LEFT", + "widgetId": "7sjskfdsub", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "", + "textColor": "#231F20", + "version": 1.0, + "shouldScroll": true, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "BODY" + }, + "IconButton2": { + "boxShadow": "NONE", + "widgetName": "IconButton2", + "onClick": "{{List1.listData.map((currentItem) => navigateTo(currentItem.link, {},'NEW_WINDOW'))}}", + "buttonColor": "#03B365", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 56.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 64.0, + "iconName": "link", + "widgetId": "6sjuuvj9ls", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + "IconButton3": { + "boxShadow": "NONE", + "widgetName": "IconButton3", + "onClick": "{{IssueManager.deleteComment()}}", + "buttonColor": "#F86A2B", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 49.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 56.0, + "iconName": "trash", + "widgetId": "22rrixkfjj", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + "Text14": { + "widgetName": "Text14", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.1357421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 33.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "{{List1.listData.map((currentItem) => moment(currentItem.created_at).format(\"Do MMM\"))}}", + "key": "w50usn0v9g", + "rightColumn": 49.0, + "textAlign": "RIGHT", + "widgetId": "05joyb6dqj", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2" + } + }, + "widgetName": "List1", + "listData": "{{fetch_comments.data}}", + "isCanvas": true, + "displayName": "List", + "iconSVG": "/static/media/icon.9925ee17.svg", + "topRow": 0.0, + "bottomRow": 81.0, + "parentRowSpace": 10.0, + "type": "LIST_WIDGET", + "hideCard": false, + "gridGap": 0.0, + "animateLoading": true, + "parentColumnSpace": 6.7265625, + "dynamicTriggerPathList": [ + { + "key": "template.IconButton2.onClick" + }, + { + "key": "template.IconButton3.onClick" + } + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "listData" + }, + { + "key": "template.Text3.text" + }, + { + "key": "template.Text2.text" + }, + { + "key": "template.Text14.text" + }, + { + "key": "template.Text2.text" + }, + { + "key": "template.Text3.text" + }, + { + "key": "template.IconButton2.onClick" + }, + { + "key": "template.Text14.text" + } + ], + "gridType": "vertical", + "enhancements": true, + "children": [ + { + "widgetName": "Canvas1Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 400.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "dropDisabled": true, + "openParentPropertyPane": true, + "minHeight": 400.0, + "noPad": true, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "boxShadow": "NONE", + "widgetName": "Container1", + "borderColor": "transparent", + "disallowCopy": true, + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3.svg", + "topRow": 0.0, + "bottomRow": 12.0, + "dragDisabled": true, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "openParentPropertyPane": true, + "isDeletable": false, + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Canvas2Copy", + "detachFromLayout": true, + "displayName": "Canvas", + "widgetId": "tog68u9on9", + "containerStyle": "none", + "topRow": 0.0, + "bottomRow": 120.0, + "parentRowSpace": 1.0, + "isVisible": true, + "type": "CANVAS_WIDGET", + "canExtend": false, + "version": 1.0, + "hideCard": true, + "parentId": "2mnw941o3c", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{currentItem.author}}", + "key": "fzyz91gt8q", + "rightColumn": 29.0, + "textAlign": "LEFT", + "widgetId": "kklt0cg1tk", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "HEADING" + }, + { + "widgetName": "Text3", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 4.0, + "bottomRow": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "leftColumn": 1.0, + "text": "{{currentItem.comment}}", + "key": "fzyz91gt8q", + "rightColumn": 64.0, + "textAlign": "LEFT", + "widgetId": "7sjskfdsub", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "", + "textColor": "#231F20", + "version": 1.0, + "shouldScroll": true, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2", + "textStyle": "BODY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton2", + "onClick": "{{navigateTo(currentItem.link, {},'NEW_WINDOW')}}", + "buttonColor": "#03B365", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 56.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 64.0, + "iconName": "link", + "widgetId": "6sjuuvj9ls", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton3", + "onClick": "{{IssueManager.deleteComment()}}", + "buttonColor": "#F86A2B", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.2890625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 49.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 56.0, + "iconName": "trash", + "widgetId": "22rrixkfjj", + "logBlackList": { + "isVisible": true, + "iconName": true, + "borderRadius": true, + "boxShadow": true, + "buttonColor": true, + "buttonVariant": true, + "isDisabled": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "Text14", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.1357421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 33.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "{{moment(currentItem.created_at).format(\"Do MMM\")}}", + "key": "w50usn0v9g", + "rightColumn": 49.0, + "textAlign": "RIGHT", + "widgetId": "05joyb6dqj", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "tog68u9on9", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH2" + } + ], + "key": "6u4x0kf3h8" + } + ], + "borderWidth": "0", + "key": "kvuew872nd", + "disablePropertyPane": true, + "backgroundColor": "white", + "rightColumn": 64.0, + "widgetId": "2mnw941o3c", + "containerStyle": "card", + "isVisible": true, + "version": 1.0, + "parentId": "ucvwcx91v9", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "0" + } + ], + "key": "6u4x0kf3h8", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "ucvwcx91v9", + "containerStyle": "none", + "isVisible": true, + "version": 1.0, + "parentId": "cu1twhxgsd", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "privateWidgets": { + "Text2": true, + "Text3": true, + "IconButton2": true, + "IconButton3": true, + "Text14": true + }, + "key": "0d6epexg6w", + "backgroundColor": "transparent", + "rightColumn": 64.0, + "itemBackgroundColor": "#F6F7F8", + "widgetId": "cu1twhxgsd", + "isVisible": true, + "parentId": "e05q08c1nq", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "tabName": "Upvotes", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "e05q08c1nq", + "isVisible": true, + "version": 1.0, + "parentId": "n316autef7", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "tabId": "tab2", + "widgetName": "Canvas2", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 800.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 400.0, + "parentColumnSpace": 1.0, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Text5", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Title", + "key": "fzyz91gt8q", + "rightColumn": 12.0, + "textAlign": "LEFT", + "widgetId": "hb6ha60ybn", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text6", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 8.0, + "bottomRow": 12.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Description", + "key": "fzyz91gt8q", + "rightColumn": 26.0, + "textAlign": "LEFT", + "widgetId": "5ohkvurob7", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text7", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 31.0, + "bottomRow": 35.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Type", + "key": "fzyz91gt8q", + "rightColumn": 16.0, + "textAlign": "LEFT", + "widgetId": "ldimms4xqb", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text8", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 39.0, + "bottomRow": 43.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "Labels: {{Table1.selectedRow.labels.join(\",\")}}", + "key": "fzyz91gt8q", + "rightColumn": 63.0, + "textAlign": "LEFT", + "widgetId": "r5pmq8fk8b", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text9", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Github Issue Link", + "key": "fzyz91gt8q", + "rightColumn": 24.0, + "textAlign": "LEFT", + "widgetId": "imcqf02q27", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Button1", + "onClick": "{{IssueManager.update()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "isDisabled" + } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 74.0, + "bottomRow": 78.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 42.0, + "dynamicBindingPathList": [ + { + "key": "isDisabled" + } + ], + "text": "Save", + "isDisabled": "{{!edit_link_input.isValid || !edit_type_input.isValid || !edit_title_input.text || IssueManager.getAssignedLabels(edit_label_select.selectedOptionValues).length == 0}}", + "key": "oz6v5ujks3", + "rightColumn": 63.0, + "isDefaultClickDisabled": true, + "widgetId": "xl37pbnn45", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY" + }, + { + "widgetName": "edit_title_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 4.0, + "bottomRow": 8.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "mtq0kmoqpi", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{Table1.selectedRow.title}}" + }, + { + "widgetName": "edit_description_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 12.0, + "bottomRow": 23.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "7kjh660g7v", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{Table1.selectedRow.description}}" + }, + { + "widgetName": "edit_type_input", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.type}}", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{Configs.type}}", + "placeholderText": "Select option", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "pnfwyps2nc", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "edit_issue_select", + "isFilterable": true, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 51.0, + "bottomRow": 55.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.github_issue_id || \"\"}}", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{GithubManager.getIssues()}}", + "placeholderText": "Search Github Issue", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "kuwxh0qtmg", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{GithubManager.searchIssues(edit_issue_select.filterText)}}" + }, + { + "widgetName": "Button4", + "onClick": "{{IssueManager.delete()}}", + "buttonColor": "#DD4B34", + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 74.0, + "bottomRow": 78.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 32.0, + "dynamicBindingPathList": [ + + ], + "text": "", + "isDisabled": false, + "key": "oz6v5ujks3", + "rightColumn": 41.0, + "isDefaultClickDisabled": true, + "iconName": "trash", + "widgetId": "ehrkah2uam", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY", + "iconAlign": "left" + }, + { + "widgetName": "Text15", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 55.0, + "bottomRow": 59.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Answer Link", + "key": "w50usn0v9g", + "rightColumn": 30.0, + "textAlign": "LEFT", + "widgetId": "ljq0eqe3o5", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "edit_answer_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 59.0, + "bottomRow": 63.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Documentation / Example app URL", + "isDisabled": false, + "key": "iqxzeop4oc", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "82zz8zgqm9", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton6", + "onClick": "{{fetch_github_issue.run(() => navigateTo('https://github.com/appsmithorg/appsmith/issues/' + fetch_github_issue.data[0].issue_number, {},'NEW_WINDOW'))}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isVisible" + } + ], + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 24.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "isDisabled": false, + "key": "xtq2jih6i3", + "rightColumn": 31.0, + "iconName": "link", + "widgetId": "yv95jo8zuk", + "isVisible": "{{!!Table1.selectedRow.github_issue_id}}", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "Text17", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 26.0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "{{Table1.selectedRow.author}}\n{{moment(Table1.selectedRow.created_at).format(\"Do MMM YYYY\")}}", + "key": "2y13r0w088", + "rightColumn": 63.0, + "disableLink": true, + "textAlign": "RIGHT", + "widgetId": "r0psmbf17o", + "isVisible": true, + "fontStyle": "", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text18", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 23.0, + "bottomRow": 27.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.1884765625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Issue Link", + "key": "2y13r0w088", + "rightColumn": 22.0, + "textAlign": "LEFT", + "widgetId": "784m9ua7xy", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "edit_link_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 27.0, + "bottomRow": 31.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.1884765625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Discord / Github / Discourse / Intercom msg URL", + "isDisabled": false, + "key": "xkaggmfnaa", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "hlhsn0qacz", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{Table1.selectedRow.link || \"\"}}" + }, + { + "widgetName": "Text19", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 63.0, + "bottomRow": 67.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "States", + "key": "r0yrfpzmtn", + "rightColumn": 14.0, + "textAlign": "LEFT", + "widgetId": "5vtar11iru", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "edit_states_select", + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 67.0, + "bottomRow": 71.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.states}}", + "animateLoading": true, + "parentColumnSpace": 5.87890625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{Configs.states}}", + "placeholderText": "Select state(s)", + "isDisabled": false, + "key": "lmf0nxzr5a", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "qemq1k1zhf", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton9", + "onClick": "{{IssueManager.createGithubIssue()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + + ], + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 4.78515625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 52.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "6o86hsevdn", + "rightColumn": 63.0, + "iconName": "cube-add", + "widgetId": "uj3oiub9lt", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton10", + "onClick": "{{remove_github_issue.run().then(() => fetch_issues.run())}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isVisible" + } + ], + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 47.0, + "bottomRow": 51.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 4.78515625, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 31.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "isDisabled": false, + "key": "66ba61jgdc", + "rightColumn": 38.0, + "iconName": "remove", + "widgetId": "ria4v9jmjk", + "isVisible": "{{!!Table1.selectedRow.github_issue_id}}", + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "edit_label_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + } + ], + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 43.0, + "bottomRow": 47.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET_V2", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.labels.map((label) => {\n return {\n\t label: label,\n\t value: label\n }\n})}}", + "animateLoading": true, + "parentColumnSpace": 16.3125, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{GithubManager.getLabels()}}", + "placeholderText": "Select label(s)", + "isDisabled": false, + "key": "5rw0979hv0", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "ufwxmsi8gy", + "isVisible": true, + "version": 1.0, + "parentId": "devkwyks4k", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{fetch_labels.run({ filterText: edit_label_select.filterText })}}" + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "tabName": "Details", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "devkwyks4k", + "isVisible": true, + "version": 1.0, + "parentId": "n316autef7", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "key": "5hk6y4h4e6", + "rightColumn": 64.0, + "widgetId": "n316autef7", + "defaultTab": "Details", + "onTabSelected": "{{Tabs1.selectedTab === \"Upvotes\" ? fetch_comments.run() : undefined}}", + "shouldShowTabs": true, + "tabsObj": { + "tab2": { + "label": "Details", + "id": "tab2", + "widgetId": "devkwyks4k", + "isVisible": true, + "index": 0.0 + }, + "tab1": { + "label": "Upvotes", + "id": "tab1", + "widgetId": "e05q08c1nq", + "isVisible": true, + "index": 1.0 + } + }, + "isVisible": "{{!!Table1.selectedRow.id}}", + "version": 3.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "FilePicker1", + "displayName": "FilePicker", + "iconSVG": "/static/media/icon.7c5ad9c3.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "allowedFileTypes": [ + + ], + "type": "FILE_PICKER_WIDGET_V2", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 59.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "vhc66isyeb", + "isRequired": false, + "rightColumn": 64.0, + "isDefaultClickDisabled": true, + "widgetId": "bitkgcu3n8", + "defaultSelectedFiles": [ + + ], + "isVisible": false, + "label": "Select Files", + "maxFileSize": "5", + "version": 1.0, + "fileDataType": "Text", + "parentId": "0", + "selectedFiles": [ + + ], + "renderMode": "CANVAS", + "isLoading": false, + "files": [ + + ], + "maxNumFiles": 1.0 + }, + { + "boxShadow": "NONE", + "widgetName": "AddIssue", + "onClick": "{{showModal('add_issue_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 9.8095703125, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 44.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 47.0, + "iconName": "add", + "widgetId": "11kdci9jhn", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "SHARP", + "buttonVariant": "TERTIARY", + "boxShadowColor": "" + }, + { + "widgetName": "add_issue_modal", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.4975978e.svg", + "topRow": 90.0, + "bottomRow": 114.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 14.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "Canvas3", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 720.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 694.0, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "children": [ + { + "widgetName": "label_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + } + ], + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET_V2", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "", + "animateLoading": true, + "parentColumnSpace": 16.3125, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{GithubManager.getLabels()}}", + "placeholderText": "Select label(s)", + "isDisabled": false, + "key": "5rw0979hv0", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "ankv8zz1xp", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{fetch_labels.run({ filterText: label_select.filterText })}}" + }, + { + "widgetName": "Text19Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 45.0, + "bottomRow": 49.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "States", + "key": "r0yrfpzmtn", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "i9kgqmx0tz", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "states_select", + "displayName": "MultiSelect", + "iconSVG": "/static/media/icon.a3495809.svg", + "labelText": "", + "topRow": 45.0, + "bottomRow": 49.0, + "parentRowSpace": 10.0, + "type": "MULTI_SELECT_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "{{Table1.selectedRow.states}}", + "animateLoading": true, + "parentColumnSpace": 5.87890625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "defaultOptionValue" + } + ], + "options": "{{Configs.states}}", + "placeholderText": "Select state(s)", + "isDisabled": false, + "key": "lmf0nxzr5a", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "qawnxpxdix", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "Text5Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 16.0, + "bottomRow": 20.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Title", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "2mh922944s", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "title_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 16.0, + "bottomRow": 20.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "glfkj7n61g", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{GithubManager.getSelectedGithubIssue()?.title || \"\"}}" + }, + { + "widgetName": "Text6Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 21.0, + "bottomRow": 25.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Description", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "tx9h5i8ovw", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "description_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 21.0, + "bottomRow": 29.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "zyoraxqcrl", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "xp8otc7k1c", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Text7Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 6.0, + "bottomRow": 10.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "Type", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "xa5lprgkkr", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "type_select", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 6.0, + "bottomRow": 10.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Configs.type}}", + "placeholderText": "Select Type", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "jw4tgzde1z", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "Text8Copy", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 35.0, + "bottomRow": 39.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Labels", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "483a8ji8wb", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text9Copy", + "dynamicPropertyPathList": [ + { + "key": "isVisible" + } + ], + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 11.0, + "bottomRow": 15.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "isVisible" + } + ], + "text": "Github Issue", + "key": "fzyz91gt8q", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "cj7wnbg01q", + "isVisible": "{{type_select.selectedOptionValue === \"Feature\" || type_select.selectedOptionValue === \"Bug\"}}", + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "add_issue_select", + "isFilterable": true, + "dynamicPropertyPathList": [ + { + "key": "onFilterUpdate" + }, + { + "key": "isVisible" + } + ], + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 11.0, + "bottomRow": 15.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": true, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onFilterUpdate" + } + ], + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "options" + }, + { + "key": "isVisible" + } + ], + "options": "{{GithubManager.getIssues()}}", + "placeholderText": "Search Github Issues", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "mle8h2yllt", + "isVisible": "{{type_select.selectedOptionValue === \"Feature\" || type_select.selectedOptionValue === \"Bug\"}}", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "onFilterUpdate": "{{GithubManager.searchIssues(add_issue_select.filterText)}}" + }, + { + "widgetName": "Text10", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "text": "New Issue", + "key": "fzyz91gt8q", + "rightColumn": 28.0, + "textAlign": "LEFT", + "widgetId": "240nwl18xx", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "HEADING1" + }, + { + "widgetName": "Button2", + "onClick": "{{closeModal('add_issue_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 63.0, + "bottomRow": 67.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 26.0, + "dynamicBindingPathList": [ + + ], + "text": "Close", + "isDisabled": false, + "key": "oz6v5ujks3", + "rightColumn": 38.0, + "isDefaultClickDisabled": true, + "widgetId": "qk4c4nfb1q", + "buttonStyle": "PRIMARY", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "SECONDARY" + }, + { + "widgetName": "Button3", + "onClick": "{{IssueManager.create_issue()}}", + "buttonColor": "#2E3D49", + "dynamicPropertyPathList": [ + { + "key": "onClick" + }, + { + "key": "isDisabled" + } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 63.0, + "bottomRow": 67.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 38.0, + "dynamicBindingPathList": [ + { + "key": "isDisabled" + } + ], + "text": "Confirm", + "isDisabled": "{{!link_input.isValid || !type_select.isValid || !title_input.text || IssueManager.getAssignedLabels(label_select.selectedOptionValues).length == 0}}", + "key": "oz6v5ujks3", + "rightColumn": 63.0, + "isDefaultClickDisabled": true, + "widgetId": "mhnwwl1t95", + "buttonStyle": "PRIMARY_BUTTON", + "isVisible": true, + "version": 1.0, + "recaptchaType": "V3", + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY" + }, + { + "boxShadow": "NONE", + "widgetName": "IconButton5", + "onClick": "{{closeModal('add_issue_modal')}}", + "buttonColor": "#2E3D49", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 57.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "1b5hj6tv0b", + "rightColumn": 64.0, + "iconName": "cross", + "widgetId": "6tvffrozwj", + "isVisible": true, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "CIRCLE", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "Text13", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 30.0, + "bottomRow": 34.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Issue Link", + "key": "w50usn0v9g", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "w91q3a6doy", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "link_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 30.0, + "bottomRow": 34.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Discord / Github / Discourse / Intercom msg URL", + "isDisabled": false, + "key": "iqxzeop4oc", + "isRequired": true, + "rightColumn": 63.0, + "widgetId": "erhs9rotun", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{add_issue_select.selectedOptionValue ? \n\"https://github.com/appsmithorg/appsmith/issues/\" + GithubManager.getSelectedGithubIssue()?.issue_number : \"\"}}" + }, + { + "widgetName": "answer_input", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 40.0, + "bottomRow": 44.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "type": "INPUT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "resetOnSubmit": true, + "leftColumn": 17.0, + "dynamicBindingPathList": [ + + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "Documentation / Example app URL", + "isDisabled": false, + "key": "iqxzeop4oc", + "isRequired": false, + "rightColumn": 63.0, + "widgetId": "335stzmyk5", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "" + }, + { + "widgetName": "Text16", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 40.0, + "bottomRow": 44.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + + ], + "text": "Answer Link", + "key": "w50usn0v9g", + "rightColumn": 17.0, + "textAlign": "RIGHT", + "widgetId": "h9drw49jnw", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "8tzkaielld", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + } + ], + "isDisabled": false, + "key": "6u4x0kf3h8", + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "8tzkaielld", + "isVisible": true, + "version": 1.0, + "parentId": "rxoie5b5j5", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "key": "9ppzbhlnqc", + "height": 694.0, + "rightColumn": 38.0, + "detachFromLayout": true, + "widgetId": "rxoie5b5j5", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "width": 456.0 + }, + { + "boxShadow": "NONE", + "widgetName": "RefreshIssues", + "onClick": "{{IssueManager.fetchIssues()}}", + "buttonColor": "#2E3D49", + "displayName": "Icon Button", + "iconSVG": "/static/media/icon.1a0c634a.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 9.8095703125, + "dynamicTriggerPathList": [ + { + "key": "onClick" + } + ], + "leftColumn": 41.0, + "dynamicBindingPathList": [ + + ], + "isDisabled": false, + "key": "35uqmnh3wt", + "rightColumn": 44.0, + "iconName": "refresh", + "widgetId": "pu0p8ahn8i", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "SHARP", + "buttonVariant": "TERTIARY" + }, + { + "widgetName": "sort_select", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "GITHUB", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 20.3125, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 30.0, + "dynamicBindingPathList": [ + + ], + "options": "[\n {\n \"label\": \"Most Github Votes\",\n \"value\": \"GITHUB\"\n },\n {\n \"label\": \"Most Upvotes\",\n \"value\": \"VOTES\"\n },\n\t{\n \"label\": \"Most Commentors\",\n \"value\": \"COMMENTORS\"\n },\n\t{\n \"label\": \"Most Recent\",\n \"value\": \"RECENT\"\n }\n]", + "placeholderText": "Select option", + "isDisabled": false, + "key": "at2ne0v8x9", + "isRequired": true, + "rightColumn": 41.0, + "widgetId": "ra23cq4tyo", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{fetch_issues.run()}}" + }, + { + "widgetName": "type_filter", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "GREEN", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 6.4140625, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 23.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Configs.type}}", + "placeholderText": "Type", + "isDisabled": false, + "key": "p2g6q7uu0o", + "isRequired": false, + "rightColumn": 30.0, + "widgetId": "eznbmvwewn", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{IssueManager.fetchIssues()}}" + }, + { + "widgetName": "status_filter", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 14.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Configs.states}}", + "placeholderText": "States", + "isDisabled": false, + "key": "52qeg2r9uo", + "isRequired": false, + "rightColumn": 23.0, + "widgetId": "sinxumk3m3", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{IssueManager.fetchIssues()}}" + }, + { + "widgetName": "pod_filter", + "isFilterable": false, + "displayName": "Select", + "iconSVG": "/static/media/icon.bd99caba.svg", + "labelText": "", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "DROP_DOWN_WIDGET", + "serverSideFiltering": false, + "hideCard": false, + "defaultOptionValue": "", + "selectionType": "SINGLE_SELECT", + "animateLoading": true, + "parentColumnSpace": 5.5732421875, + "dynamicTriggerPathList": [ + { + "key": "onOptionChange" + } + ], + "leftColumn": 7.0, + "dynamicBindingPathList": [ + { + "key": "options" + } + ], + "options": "{{Utils.getPodLabels()}}", + "placeholderText": "Pods", + "isDisabled": false, + "key": "qjixxicfzt", + "isRequired": false, + "rightColumn": 14.0, + "widgetId": "ajzvz766xg", + "isVisible": true, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "onOptionChange": "{{IssueManager.fetchIssues()}}" + }, + { + "multiRowSelection": false, + "onSort": "", + "isVisibleDownload": false, + "iconSVG": "/static/media/icon.db8a9cbd.svg", + "topRow": 5.0, + "isSortable": false, + "onPageChange": "{{fetch_issues.run()}}", + "type": "TABLE_WIDGET", + "animateLoading": true, + "dynamicBindingPathList": [ + { + "key": "tableData" + }, + { + "key": "primaryColumns.unique_commentors.computedValue" + }, + { + "key": "primaryColumns.total_reactions.computedValue" + }, + { + "key": "primaryColumns.upvote_id.computedValue" + }, + { + "key": "primaryColumns.count.computedValue" + }, + { + "key": "primaryColumns.link.computedValue" + }, + { + "key": "primaryColumns.answer.isCellVisible" + }, + { + "key": "primaryColumns.state.computedValue" + }, + { + "key": "primaryColumns.type.computedValue" + }, + { + "key": "primaryColumns.labels.computedValue" + }, + { + "key": "primaryColumns.description.computedValue" + }, + { + "key": "primaryColumns.title.computedValue" + }, + { + "key": "primaryColumns.created_at.computedValue" + }, + { + "key": "primaryColumns.author.computedValue" + }, + { + "key": "primaryColumns.github_issue_id.computedValue" + }, + { + "key": "primaryColumns.id.computedValue" + }, + { + "key": "primaryColumns.states.computedValue" + }, + { + "key": "primaryColumns.updated_at.computedValue" + }, + { + "key": "derivedColumns.customColumn2.computedValue" + }, + { + "key": "primaryColumns.customColumn2.computedValue" + } + ], + "leftColumn": 0.0, + "delimiter": ",", + "isVisibleFilters": true, + "isVisible": true, + "enableClientSideSearch": true, + "version": 3.0, + "totalRecordsCount": 0.0, + "isLoading": false, + "onSearchTextChanged": "{{fetch_issues.run()}}", + "columnSizeMap": { + "task": 245.0, + "step": 62.0, + "status": 75.0, + "id": 61.0, + "type": 88.0, + "title": 590.0, + "date": 101.0, + "created_at": 150.0, + "count": 69.00000000000001, + "customColumn1": 91.0, + "answer": 91.0, + "total_reactions": 60.0, + "unique_commentors": 144.0, + "states": 155.0, + "customColumn2": 77.0, + "state": 111.0, + "link": 188.0, + "description": 187.0, + "author": 157.0, + "github_issue_id": 163.0 + }, + "widgetName": "Table1", + "defaultPageSize": 0.0, + "columnOrder": [ + "type", + "title", + "customColumn2", + "total_reactions", + "unique_commentors", + "count", + "answer", + "customColumn1", + "states", + "upvote_id", + "id", + "github_issue_id", + "author", + "created_at", + "description", + "labels", + "state", + "link", + "updated_at" + ], + "dynamicPropertyPathList": [ + { + "key": "primaryColumns.answer.onClick" + }, + { + "key": "primaryColumns.answer.isCellVisible" + } + ], + "displayName": "Table", + "bottomRow": 89.0, + "parentRowSpace": 10.0, + "defaultSelectedRow": "0", + "hideCard": false, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [ + { + "key": "primaryColumns.customColumn1.onClick" + }, + { + "key": "onRowSelected" + }, + { + "key": "onPageChange" + }, + { + "key": "onSearchTextChanged" + }, + { + "key": "onSort" + }, + { + "key": "primaryColumns.answer.onClick" + } + ], + "primaryColumns": { + "customColumn1": { + "index": 7.0, + "width": 150.0, + "id": "customColumn1", + "columnType": "iconButton", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "UpVote", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.customColumn1))}}", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#38AFF4", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "buttonLabel": "{{Table1.sanitizedTableData.map((currentRow) => ( 'Upvote'))}}", + "iconName": "caret-up", + "borderRadius": "ROUNDED", + "buttonVariant": "SECONDARY", + "onClick": "{{showModal('upvote_modal')}}", + "horizontalAlignment": "LEFT", + "textSize": "PARAGRAPH" + }, + "id": { + "index": 0.0, + "width": 150.0, + "id": "id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "id", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.id))}}" + }, + "github_issue_id": { + "index": 1.0, + "width": 150.0, + "id": "github_issue_id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "github_issue_id", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.github_issue_id))}}" + }, + "author": { + "index": 2.0, + "width": 150.0, + "id": "author", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "author", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.author))}}" + }, + "created_at": { + "index": 3.0, + "width": 150.0, + "id": "created_at", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "created_at", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.created_at))}}" + }, + "title": { + "index": 4.0, + "width": 150.0, + "id": "title", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Title", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.title))}}" + }, + "description": { + "index": 5.0, + "width": 150.0, + "id": "description", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "description", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.description))}}" + }, + "labels": { + "index": 6.0, + "width": 150.0, + "id": "labels", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "labels", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.labels))}}" + }, + "type": { + "index": 7.0, + "width": 150.0, + "id": "type", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Type", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.type))}}" + }, + "state": { + "index": 8.0, + "width": 150.0, + "id": "state", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "state", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.state))}}" + }, + "answer": { + "index": 9.0, + "width": 150.0, + "id": "answer", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "iconButton", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": "{{Table1.sanitizedTableData.map((currentRow) => ( !!currentRow.answer))}}", + "isDerived": false, + "label": "Answer", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.answer))}}", + "iconName": "duplicate", + "buttonVariant": "TERTIARY", + "buttonColor": "#2E3D49", + "onClick": "{{copyToClipboard(currentRow.answer); showAlert('Copied');}}" + }, + "link": { + "index": 11.0, + "width": 150.0, + "id": "link", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "link", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.link))}}" + }, + "count": { + "index": 12.0, + "width": 150.0, + "id": "count", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "number", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Votes", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.count))}}" + }, + "upvote_id": { + "index": 13.0, + "width": 150.0, + "id": "upvote_id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "upvote_id", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.upvote_id))}}" + }, + "total_reactions": { + "index": 14.0, + "width": 150.0, + "id": "total_reactions", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "+1", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.total_reactions))}}" + }, + "unique_commentors": { + "index": 15.0, + "width": 150.0, + "id": "unique_commentors", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "Commentors", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.unique_commentors))}}" + }, + "states": { + "index": 16.0, + "width": 150.0, + "id": "states", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "States", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.states))}}" + }, + "updated_at": { + "index": 16.0, + "width": 150.0, + "id": "updated_at", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": false, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "updated_at", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.updated_at))}}" + }, + "customColumn2": { + "index": 18.0, + "width": 150.0, + "id": "customColumn2", + "horizontalAlignment": "LEFT", + "columnType": "text", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "Status", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( Configs.getTitleState(currentRow.states)))}}", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#03B365", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "textSize": "PARAGRAPH" + } + }, + "onRowSelected": "{{resetWidget(\"Tabs1\")}}", + "key": "tr3pdljkm8", + "derivedColumns": { + "customColumn1": { + "index": 7.0, + "width": 150.0, + "id": "customColumn1", + "columnType": "iconButton", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "UpVote", + "computedValue": "", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#38AFF4", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "buttonLabel": "{{Table1.sanitizedTableData.map((currentRow) => ( 'Upvote'))}}", + "iconName": "caret-up", + "borderRadius": "ROUNDED", + "buttonVariant": "PRIMARY", + "horizontalAlignment": "LEFT", + "textSize": "PARAGRAPH" + }, + "customColumn2": { + "index": 18.0, + "width": 150.0, + "id": "customColumn2", + "horizontalAlignment": "LEFT", + "columnType": "text", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": true, + "label": "Status", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( Configs.getTitleState(currentRow.states)))}}", + "buttonStyle": "rgb(3, 179, 101)", + "buttonLabelColor": "#FFFFFF", + "buttonColor": "#03B365", + "menuColor": "#03B365", + "labelColor": "#FFFFFF", + "textSize": "PARAGRAPH" + } + }, + "rightColumn": 44.0, + "textSize": "PARAGRAPH", + "widgetId": "zsilqrkvkw", + "tableData": "{{IssueManager.getIssueData()}}", + "label": "Data", + "searchKey": "", + "parentId": "0", + "serverSidePaginationEnabled": true, + "renderMode": "CANVAS", + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "verticalAlignment": "CENTER" + }, + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 16.71875, + "dynamicTriggerPathList": [ + + ], + "leftColumn": 0.0, + "dynamicBindingPathList": [ + + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "🗓 Issues", + "key": "t8e7qdq1ol", + "rightColumn": 7.0, + "textAlign": "LEFT", + "widgetId": "yyqsgarlj7", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "HEADING1" + } + ] + }, + "layoutOnLoadActions": [ + [ + { + "id": "Issues_search_github_issues", + "name": "search_github_issues", + "confirmBeforeExecute": false, + "pluginType": "DB", + "jsonPathKeys": [ + "\"%\" + this.params.searchText + \"%\"" + ], + "timeoutInMillisecond": 10000 + }, + { + "id": "Issues_fetch_label_config", + "name": "fetch_label_config", + "confirmBeforeExecute": false, + "pluginType": "API", + "jsonPathKeys": [ + + ], + "timeoutInMillisecond": 10000 + } + ], + [ + { + "id": "Issues_fetch_comments", + "name": "fetch_comments", + "confirmBeforeExecute": false, + "pluginType": "DB", + "jsonPathKeys": [ + "Table1.selectedRow.id" + ], + "timeoutInMillisecond": 10000 + } + ], + [ + { + "id": "Issues_fetch_labels", + "name": "fetch_labels", + "confirmBeforeExecute": false, + "pluginType": "API", + "jsonPathKeys": [ + + ], + "timeoutInMillisecond": 10000 + }, + { + "id": "Issues_fetch_issues", + "name": "fetch_issues", + "confirmBeforeExecute": false, + "pluginType": "DB", + "jsonPathKeys": [ + "appsmith.URL.queryParams.id ? \" and global_issues.id=\" + appsmith.URL.queryParams.id: \"\"", + "type_filter.selectedOptionValue && type_filter.selectedOptionValue !== \"ALL\" ? \"and global_issues.type ='\" + type_filter.selectedOptionValue + \"'\" : \"\"", + "\"%\" + Table1.searchText + \"%\"", + "(Table1.pageNo - 1) * Table1.pageSize", + "Table1.pageSize", + "status_filter.selectedOptionValue && status_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + status_filter.selectedOptionValue + \"' =ANY(global_issues.states)\" : \"\"", + "pod_filter.selectedOptionValue && pod_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + pod_filter.selectedOptionValue + \"'=ANY(global_issues.labels)\" : \"\"", + "sort_select.selectedOptionValue === \"GITHUB\" ? \"total_reactions desc, count desc, upvote_id desc\" : sort_select.selectedOptionValue === \"VOTES\" ? \"count desc, upvote_id desc, total_reactions desc\" : sort_select.selectedOptionValue === \"COMMENTORS\" ? \"unique_commentors desc, total_reactions desc, count desc, upvote_id desc\" : \"updated_at desc\"" + ], + "timeoutInMillisecond": 10000 + } + ] + ], + "new": false + } + ], + "userPermissions": [ + + ], + "isHidden": false + }, + "new": true + } + ], + "publishedDefaultPageName": "Issues", + "unpublishedDefaultPageName": "Issues", + "actionList": [ + { + "id": "Issues_fetch_label_config", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623765542e5d3f189d0c3c2d", + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "fetch_label_config", + "datasource": { + "userPermissions": [ + + ], + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { + "url": "https://hook.integromat.com" + }, + "invalids": [ + + ], + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/3yepr9ekaott9io115jl2lifd5z469s9", + "headers": [ + + ], + "encodeParamsToggle": true, + "queryParameters": [ + + ], + "httpMethod": "GET", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ], + "formData": { + "apiContentType": "none" + } + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_label_config" + }, + "publishedAction": { + "name": "fetch_label_config", + "datasource": { + "userPermissions": [ + + ], + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { + "url": "https://hook.integromat.com" + }, + "invalids": [ + + ], + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/3yepr9ekaott9io115jl2lifd5z469s9", + "headers": [ + + ], + "encodeParamsToggle": true, + "queryParameters": [ + + ], + "httpMethod": "GET", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ], + "formData": { + "apiContentType": "none" + } + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_label_config" + }, + "new": false + }, + { + "id": "Issues_Utils.getPodLabels", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623765f12e5d3f189d0c3c35", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getPodLabels", + "fullyQualifiedName": "Utils.getPodLabels", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn Object.keys(fetch_label_config.data.runners[0].issue.labels)\n\t\t\t.map((pod) => { \n\t\t\t\treturn {\n\t\t\t\t\tlabel: pod,\n\t\t\t\t\tvalue: pod\n\t\t\t\t}\n\t\t\t});\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn Object.keys(fetch_label_config.data.runners[0].issue.labels)\n\t\t\t.map((pod) => { \n\t\t\t\treturn {\n\t\t\t\t\tlabel: pod,\n\t\t\t\t\tvalue: pod\n\t\t\t\t}\n\t\t\t});\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getPodLabels" + }, + "publishedAction": { + "name": "getPodLabels", + "fullyQualifiedName": "Utils.getPodLabels", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn Object.keys(fetch_label_config.data.runners[0].issue.labels)\n\t\t\t.map((pod) => { \n\t\t\t\treturn {\n\t\t\t\t\tlabel: pod,\n\t\t\t\t\tvalue: pod\n\t\t\t\t}\n\t\t\t});\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn Object.keys(fetch_label_config.data.runners[0].issue.labels)\n\t\t\t.map((pod) => { \n\t\t\t\treturn {\n\t\t\t\t\tlabel: pod,\n\t\t\t\t\tvalue: pod\n\t\t\t\t}\n\t\t\t});\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getPodLabels" + }, + "new": false + }, + { + "id": "Issues_Utils.getConfig", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_6237662e2e5d3f189d0c3c37", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getConfig", + "fullyQualifiedName": "Utils.getConfig", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn fetch_label_config.data;\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn fetch_label_config.data;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getConfig" + }, + "publishedAction": { + "name": "getConfig", + "fullyQualifiedName": "Utils.getConfig", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn fetch_label_config.data;\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn fetch_label_config.data;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getConfig" + }, + "new": false + }, + { + "id": "Issues_Utils.checkIsPod", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_6237662e2e5d3f189d0c3c38", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "checkIsPod", + "fullyQualifiedName": "Utils.checkIsPod", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(label) => {\n\t\treturn fetch_label_config.data.runners[0].issue.labels[label] !== undefined\n\t}", + "jsArguments": [ + { + "name": "label" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(label) => {\n\t\treturn fetch_label_config.data.runners[0].issue.labels[label] !== undefined\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.checkIsPod" + }, + "publishedAction": { + "name": "checkIsPod", + "fullyQualifiedName": "Utils.checkIsPod", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(label) => {\n\t\treturn fetch_label_config.data.runners[0].issue.labels[label] !== undefined\n\t}", + "jsArguments": [ + { + "name": "label" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(label) => {\n\t\treturn fetch_label_config.data.runners[0].issue.labels[label] !== undefined\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.checkIsPod" + }, + "new": false + }, + { + "id": "Issues_Utils.getLabelsForPod", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623766812e5d3f189d0c3c3d", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getLabelsForPod", + "fullyQualifiedName": "Utils.getLabelsForPod", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(pod) => {\n\t\treturn fetch_label_config.data.runners[0]\n\t\t\t.issue.labels[pod].conditions.map((label) => \n\t\t\t\t\tfetch_label_config.data.labels[label.label])\n\t\t\t.filter((label) => label !== undefined)\n\t}", + "jsArguments": [ + { + "name": "pod" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(pod) => {\n\t\treturn fetch_label_config.data.runners[0]\n\t\t\t.issue.labels[pod].conditions.map((label) => \n\t\t\t\t\tfetch_label_config.data.labels[label.label])\n\t\t\t.filter((label) => label !== undefined)\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getLabelsForPod" + }, + "publishedAction": { + "name": "getLabelsForPod", + "fullyQualifiedName": "Utils.getLabelsForPod", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(pod) => {\n\t\treturn fetch_label_config.data.runners[0]\n\t\t\t.issue.labels[pod].conditions.map((label) => \n\t\t\t\t\tfetch_label_config.data.labels[label.label])\n\t\t\t.filter((label) => label !== undefined)\n\t}", + "jsArguments": [ + { + "name": "pod" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(pod) => {\n\t\treturn fetch_label_config.data.runners[0]\n\t\t\t.issue.labels[pod].conditions.map((label) => \n\t\t\t\t\tfetch_label_config.data.labels[label.label])\n\t\t\t.filter((label) => label !== undefined)\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getLabelsForPod" + }, + "new": false + }, + { + "id": "Issues_Utils.getPodForLabel", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623766592e5d3f189d0c3c3b", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getPodForLabel", + "fullyQualifiedName": "Utils.getPodForLabel", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(label = \"New JS Function\") => {\n\t\tconst labels = fetch_label_config.data.runners[0].issue.labels;\n\t\tconst pods = Utils.getPodLabels().map((pod) => pod.label);\n\t\tlet foundPod;\n\t\tpods.map((podLabel) => {\n\t\t\tconst foundLabel = labels[podLabel].conditions.find((condition) => {\n\t\t\t\treturn condition.label === label && podLabel !== label\n\t\t\t})\n\t\t\tif (foundLabel) {\n\t\t\t\tfoundPod = podLabel\n\t\t\t}\n\t\t});\n\t\treturn foundPod;\n\t}", + "jsArguments": [ + { + "name": "label" + }, + { + "name": "", + "value": "" + }, + { + "name": "\"New" + }, + { + "name": "JS" + }, + { + "name": "Function\"" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(label = \"New JS Function\") => {\n\t\tconst labels = fetch_label_config.data.runners[0].issue.labels;\n\t\tconst pods = Utils.getPodLabels().map((pod) => pod.label);\n\t\tlet foundPod;\n\t\tpods.map((podLabel) => {\n\t\t\tconst foundLabel = labels[podLabel].conditions.find((condition) => {\n\t\t\t\treturn condition.label === label && podLabel !== label\n\t\t\t})\n\t\t\tif (foundLabel) {\n\t\t\t\tfoundPod = podLabel\n\t\t\t}\n\t\t});\n\t\treturn foundPod;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getPodForLabel" + }, + "publishedAction": { + "name": "getPodForLabel", + "fullyQualifiedName": "Utils.getPodForLabel", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(label = \"New JS Function\") => {\n\t\tconst labels = fetch_label_config.data.runners[0].issue.labels;\n\t\tconst pods = Utils.getPodLabels().map((pod) => pod.label);\n\t\tlet foundPod;\n\t\tpods.map((podLabel) => {\n\t\t\tconst foundLabel = labels[podLabel].conditions.find((condition) => {\n\t\t\t\treturn condition.label === label && podLabel !== label\n\t\t\t})\n\t\t\tif (foundLabel) {\n\t\t\t\tfoundPod = podLabel\n\t\t\t}\n\t\t});\n\t\treturn foundPod;\n\t}", + "jsArguments": [ + { + "name": "label" + }, + { + "name": "", + "value": "" + }, + { + "name": "\"New" + }, + { + "name": "JS" + }, + { + "name": "Function\"" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(label = \"New JS Function\") => {\n\t\tconst labels = fetch_label_config.data.runners[0].issue.labels;\n\t\tconst pods = Utils.getPodLabels().map((pod) => pod.label);\n\t\tlet foundPod;\n\t\tpods.map((podLabel) => {\n\t\t\tconst foundLabel = labels[podLabel].conditions.find((condition) => {\n\t\t\t\treturn condition.label === label && podLabel !== label\n\t\t\t})\n\t\t\tif (foundLabel) {\n\t\t\t\tfoundPod = podLabel\n\t\t\t}\n\t\t});\n\t\treturn foundPod;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.getPodForLabel" + }, + "new": false + }, + { + "id": "Issues_Utils.csvToArr", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623766812e5d3f189d0c3c3e", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "csvToArr", + "fullyQualifiedName": "Utils.csvToArr", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\t//const csvRows = FilePicker1.files[1].data.split(\"\\n\");\n\t\t//const objArr = [];\n\t\t//const headers = csvRows[0].split(',');\n\t\t\t//for(let i = 1; i < csvRows.length; i++) {\n\t\t\t\t//const rowObj = {};\n\t\t\t\t//objArr.push(rowObj);\n\t\t\t\t//const rowArr = csvRows[i].split(',');\n\t\t\t\t//rowArr.forEach((val, index) => {\n\t\t\t\t//rowObj[headers[index]] = val;\n\t\t\t\t//});\n\t\t\t//}\n\t\t//return objArr;\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\t//const csvRows = FilePicker1.files[1].data.split(\"\\n\");\n\t\t//const objArr = [];\n\t\t//const headers = csvRows[0].split(',');\n\t\t\t//for(let i = 1; i < csvRows.length; i++) {\n\t\t\t\t//const rowObj = {};\n\t\t\t\t//objArr.push(rowObj);\n\t\t\t\t//const rowArr = csvRows[i].split(',');\n\t\t\t\t//rowArr.forEach((val, index) => {\n\t\t\t\t//rowObj[headers[index]] = val;\n\t\t\t\t//});\n\t\t\t//}\n\t\t//return objArr;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.csvToArr" + }, + "publishedAction": { + "name": "csvToArr", + "fullyQualifiedName": "Utils.csvToArr", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Utils", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\t//const csvRows = FilePicker1.files[1].data.split(\"\\n\");\n\t\t//const objArr = [];\n\t\t//const headers = csvRows[0].split(',');\n\t\t\t//for(let i = 1; i < csvRows.length; i++) {\n\t\t\t\t//const rowObj = {};\n\t\t\t\t//objArr.push(rowObj);\n\t\t\t\t//const rowArr = csvRows[i].split(',');\n\t\t\t\t//rowArr.forEach((val, index) => {\n\t\t\t\t//rowObj[headers[index]] = val;\n\t\t\t\t//});\n\t\t\t//}\n\t\t//return objArr;\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\t//const csvRows = FilePicker1.files[1].data.split(\"\\n\");\n\t\t//const objArr = [];\n\t\t//const headers = csvRows[0].split(',');\n\t\t\t//for(let i = 1; i < csvRows.length; i++) {\n\t\t\t\t//const rowObj = {};\n\t\t\t\t//objArr.push(rowObj);\n\t\t\t\t//const rowArr = csvRows[i].split(',');\n\t\t\t\t//rowArr.forEach((val, index) => {\n\t\t\t\t//rowObj[headers[index]] = val;\n\t\t\t\t//});\n\t\t\t//}\n\t\t//return objArr;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Utils.csvToArr" + }, + "new": false + }, + { + "id": "Issues_IssueManager.create_issue", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62382c40cb09660cd0f703bf", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "create_issue", + "fullyQualifiedName": "IssueManager.create_issue", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\tconst labels = IssueManager.getAssignedLabels(label_select.selectedOptionValues);\n\t\tadd_new_issue.run(() => {\n\t\t\t\tfetch_issues.run(() => {\n\t\t\t\t\tresetWidget('add_issue_modal', true);\n\t\t\t\t\tcloseModal('add_issue_modal');\n\t\t\t\t});\n\t\t}, undefined, { labels: labels })\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\tconst labels = IssueManager.getAssignedLabels(label_select.selectedOptionValues);\n\t\tadd_new_issue.run(() => {\n\t\t\t\tfetch_issues.run(() => {\n\t\t\t\t\tresetWidget('add_issue_modal', true);\n\t\t\t\t\tcloseModal('add_issue_modal');\n\t\t\t\t});\n\t\t}, undefined, { labels: labels })\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.create_issue" + }, + "publishedAction": { + "name": "create_issue", + "fullyQualifiedName": "IssueManager.create_issue", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\tconst labels = IssueManager.getAssignedLabels(label_select.selectedOptionValues);\n\t\tadd_new_issue.run(() => {\n\t\t\t\tfetch_issues.run(() => {\n\t\t\t\t\tresetWidget('add_issue_modal', true);\n\t\t\t\t\tcloseModal('add_issue_modal');\n\t\t\t\t});\n\t\t}, undefined, { labels: labels })\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\tconst labels = IssueManager.getAssignedLabels(label_select.selectedOptionValues);\n\t\tadd_new_issue.run(() => {\n\t\t\t\tfetch_issues.run(() => {\n\t\t\t\t\tresetWidget('add_issue_modal', true);\n\t\t\t\t\tcloseModal('add_issue_modal');\n\t\t\t\t});\n\t\t}, undefined, { labels: labels })\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.create_issue" + }, + "new": false + }, + { + "id": "Issues_add_new_comment", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62382bb0cb09660cd0f703b7", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "add_new_comment", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "INSERT INTO issue_upvote\n (link, comment, author, created_at, issue_id, id)\nVALUES\n (\n '{{ comment_link_input.text }}',\n '{{ comment_input.text }}',\n\t\t'{{ appsmith.user.email }}',\n\t\tnow(),\n\t\t{{Table1.selectedRow.id}},\n\t\t(SELECT max(id) + 1\nFROM public.\"issue_upvote\")\n );", + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id", + "comment_input.text", + "appsmith.user.email", + "comment_link_input.text" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "add_new_comment" + }, + "publishedAction": { + "name": "add_new_comment", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "INSERT INTO issue_upvote\n (link, comment, author, created_at, issue_id, id)\nVALUES\n (\n '{{ comment_link_input.text }}',\n '{{ comment_input.text }}',\n\t\t'{{ appsmith.user.email }}',\n\t\tnow(),\n\t\t{{Table1.selectedRow.id}},\n\t\t(SELECT max(id) + 1\nFROM public.\"issue_upvote\")\n );", + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id", + "comment_input.text", + "appsmith.user.email", + "comment_link_input.text" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "add_new_comment" + }, + "new": false + }, + { + "id": "Issues_IssueManager.getAssignedLabels", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62382c40cb09660cd0f703c3", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getAssignedLabels", + "fullyQualifiedName": "IssueManager.getAssignedLabels", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(allLabels = label_select.selectedOptionValues) => {\n\t\tconst labels = allLabels.filter((label) => {\n\t\t\treturn Utils.checkIsPod(label) !== true;\n\t\t}); \n\t\tconst podMap = {};\n\t\tlabels.map((label) => {\n\t\t\tconst pod = Utils.getPodForLabel(label);\n\t\t\tif (pod)\n\t\t\t\tpodMap[pod] = true;\n\t\t});\n\t\treturn [...Object.keys(podMap), ...labels];\n\t}", + "jsArguments": [ + { + "name": "allLabels" + }, + { + "name": "", + "value": "" + }, + { + "name": "label_select.selectedOptionValues" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(allLabels = label_select.selectedOptionValues) => {\n\t\tconst labels = allLabels.filter((label) => {\n\t\t\treturn Utils.checkIsPod(label) !== true;\n\t\t}); \n\t\tconst podMap = {};\n\t\tlabels.map((label) => {\n\t\t\tconst pod = Utils.getPodForLabel(label);\n\t\t\tif (pod)\n\t\t\t\tpodMap[pod] = true;\n\t\t});\n\t\treturn [...Object.keys(podMap), ...labels];\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.getAssignedLabels" + }, + "publishedAction": { + "name": "getAssignedLabels", + "fullyQualifiedName": "IssueManager.getAssignedLabels", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(allLabels = label_select.selectedOptionValues) => {\n\t\tconst labels = allLabels.filter((label) => {\n\t\t\treturn Utils.checkIsPod(label) !== true;\n\t\t}); \n\t\tconst podMap = {};\n\t\tlabels.map((label) => {\n\t\t\tconst pod = Utils.getPodForLabel(label);\n\t\t\tif (pod)\n\t\t\t\tpodMap[pod] = true;\n\t\t});\n\t\treturn [...Object.keys(podMap), ...labels];\n\t}", + "jsArguments": [ + { + "name": "allLabels" + }, + { + "name": "", + "value": "" + }, + { + "name": "label_select.selectedOptionValues" + } + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(allLabels = label_select.selectedOptionValues) => {\n\t\tconst labels = allLabels.filter((label) => {\n\t\t\treturn Utils.checkIsPod(label) !== true;\n\t\t}); \n\t\tconst podMap = {};\n\t\tlabels.map((label) => {\n\t\t\tconst pod = Utils.getPodForLabel(label);\n\t\t\tif (pod)\n\t\t\t\tpodMap[pod] = true;\n\t\t});\n\t\treturn [...Object.keys(podMap), ...labels];\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.getAssignedLabels" + }, + "new": false + }, + { + "id": "Issues_IssueManager.getIssueData", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62382c40cb09660cd0f703c2", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getIssueData", + "fullyQualifiedName": "IssueManager.getIssueData", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn fetch_issues.data.map((issue) => {\n\t\t\tif (issue.upvote_id > 0)\n\t\t\t\tissue.count = issue.count + 1;\n\t\t\treturn { type: issue.type, title: issue.title, total_reactions: issue.total_reactions, unique_commentors: issue.unique_commentors, upvote_id: issue.upvote_id ,...issue};\n\t\t});\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn fetch_issues.data.map((issue) => {\n\t\t\tif (issue.upvote_id > 0)\n\t\t\t\tissue.count = issue.count + 1;\n\t\t\treturn { type: issue.type, title: issue.title, total_reactions: issue.total_reactions, unique_commentors: issue.unique_commentors, upvote_id: issue.upvote_id ,...issue};\n\t\t});\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.getIssueData" + }, + "publishedAction": { + "name": "getIssueData", + "fullyQualifiedName": "IssueManager.getIssueData", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn fetch_issues.data.map((issue) => {\n\t\t\tif (issue.upvote_id > 0)\n\t\t\t\tissue.count = issue.count + 1;\n\t\t\treturn { type: issue.type, title: issue.title, total_reactions: issue.total_reactions, unique_commentors: issue.unique_commentors, upvote_id: issue.upvote_id ,...issue};\n\t\t});\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn fetch_issues.data.map((issue) => {\n\t\t\tif (issue.upvote_id > 0)\n\t\t\t\tissue.count = issue.count + 1;\n\t\t\treturn { type: issue.type, title: issue.title, total_reactions: issue.total_reactions, unique_commentors: issue.unique_commentors, upvote_id: issue.upvote_id ,...issue};\n\t\t});\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.getIssueData" + }, + "new": false + }, + { + "id": "Issues_IssueManager.fetchIssues", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62382c40cb09660cd0f703cf", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "fetchIssues", + "fullyQualifiedName": "IssueManager.fetchIssues", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\tfetch_issues.run();\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\tfetch_issues.run();\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.fetchIssues" + }, + "publishedAction": { + "name": "fetchIssues", + "fullyQualifiedName": "IssueManager.fetchIssues", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\tfetch_issues.run();\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\tfetch_issues.run();\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.fetchIssues" + }, + "new": false + }, + { + "id": "Issues_add_new_issue", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62382cf9cb09660cd0f703db", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "add_new_issue", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "INSERT INTO global_issues\n (title, description, github_issue_id, author, created_at, labels, type, answer, link, states, state, id)\nVALUES\n (\n '{{ title_input.text }}',\n '{{ description_input.text }}',\n {{ add_issue_select.selectedOptionValue }},\n\t\t'{{ appsmith.user.email }}',\n\t\tnow(),\n\t\t'{{ \"{\" + (this.params.labels ?? []).join(\",\") + \"}\" }}',\n\t\t'{{ type_select.selectedOptionValue }}',\n\t\t'{{answer_input.text}}',\n\t\t'{{link_input.text}}',\n\t\t'{{\"{\" + states_select.selectedOptionValues.join(\",\") + \"}\"}}',\n\t\t'Opened',\n\t\t(SELECT max(id) + 1 FROM public.\"global_issues\")\n );", + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "answer_input.text", + "description_input.text", + "add_issue_select.selectedOptionValue", + "appsmith.user.email", + "\"{\" + (this.params.labels ?? []).join(\",\") + \"}\"", + "\"{\" + states_select.selectedOptionValues.join(\",\") + \"}\"", + "type_select.selectedOptionValue", + "title_input.text", + "link_input.text" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "add_new_issue" + }, + "publishedAction": { + "name": "add_new_issue", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "INSERT INTO global_issues\n (title, description, github_issue_id, author, created_at, labels, type, answer, link, states, state, id)\nVALUES\n (\n '{{ title_input.text }}',\n '{{ description_input.text }}',\n {{ add_issue_select.selectedOptionValue }},\n\t\t'{{ appsmith.user.email }}',\n\t\tnow(),\n\t\t'{{ \"{\" + (this.params.labels ?? []).join(\",\") + \"}\" }}',\n\t\t'{{ type_select.selectedOptionValue }}',\n\t\t'{{answer_input.text}}',\n\t\t'{{link_input.text}}',\n\t\t'{{\"{\" + states_select.selectedOptionValues.join(\",\") + \"}\"}}',\n\t\t'Opened',\n\t\t(SELECT max(id) + 1 FROM public.\"global_issues\")\n );", + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "answer_input.text", + "description_input.text", + "add_issue_select.selectedOptionValue", + "appsmith.user.email", + "\"{\" + (this.params.labels ?? []).join(\",\") + \"}\"", + "\"{\" + states_select.selectedOptionValues.join(\",\") + \"}\"", + "type_select.selectedOptionValue", + "title_input.text", + "link_input.text" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "add_new_issue" + }, + "new": false + }, + { + "id": "Issues_fetch_comments", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623850eacb09660cd0f703ff", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "fetch_comments", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "select * from issue_upvote where issue_id = {{Table1.selectedRow.id}}" + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_comments" + }, + "publishedAction": { + "name": "fetch_comments", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "select * from issue_upvote where issue_id = {{Table1.selectedRow.id}}" + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_comments" + }, + "new": false + }, + { + "id": "Issues_fetch_issues", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62383bb7cb09660cd0f703e5", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "fetch_issues", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "select global_issues.*, count(global_issues.id), count(issue_upvote.id) as upvote_id, COALESCE (github_issues.total_reactions, 0) as total_reactions, COALESCE(github_issues.unique_commentors,0) as unique_commentors, GREATEST(MAX(issue_upvote.created_at), MAX(global_issues.created_at)) as updated_at from global_issues left join github_issues on github_issues.id = global_issues.github_issue_id left join issue_upvote on global_issues.id = issue_upvote.issue_id where global_issues.title ilike '{{ \"%\" + Table1.searchText + \"%\" }}' {{appsmith.URL.queryParams.id ? \" and global_issues.id=\" + appsmith.URL.queryParams.id: \"\"}} and global_issues.state != 'DELETED' {{ type_filter.selectedOptionValue && type_filter.selectedOptionValue !== \"ALL\" ? \"and global_issues.type ='\" + type_filter.selectedOptionValue + \"'\" : \"\" }} {{ pod_filter.selectedOptionValue && pod_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + pod_filter.selectedOptionValue + \"'=ANY(global_issues.labels)\" : \"\" }} \n{{ status_filter.selectedOptionValue && status_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + status_filter.selectedOptionValue + \"' =ANY(global_issues.states)\" : \"\" }} group by global_issues.id, github_issues.id, global_issues.github_issue_id, global_issues.author, global_issues.created_at, global_issues.title, global_issues.description, global_issues.labels, global_issues.type, global_issues.state, global_issues.answer, global_issues.link, global_issues.states, github_issues.total_reactions, github_issues.unique_commentors order by {{sort_select.selectedOptionValue === \"GITHUB\" ? \"total_reactions desc, count desc, upvote_id desc\" : sort_select.selectedOptionValue === \"VOTES\" ? \"count desc, upvote_id desc, total_reactions desc\" : sort_select.selectedOptionValue === \"COMMENTORS\" ? \"unique_commentors desc, total_reactions desc, count desc, upvote_id desc\" : \"updated_at desc\" }} offset {{(Table1.pageNo - 1) * Table1.pageSize}} limit {{Table1.pageSize}}", + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "appsmith.URL.queryParams.id ? \" and global_issues.id=\" + appsmith.URL.queryParams.id: \"\"", + "type_filter.selectedOptionValue && type_filter.selectedOptionValue !== \"ALL\" ? \"and global_issues.type ='\" + type_filter.selectedOptionValue + \"'\" : \"\"", + "\"%\" + Table1.searchText + \"%\"", + "(Table1.pageNo - 1) * Table1.pageSize", + "Table1.pageSize", + "status_filter.selectedOptionValue && status_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + status_filter.selectedOptionValue + \"' =ANY(global_issues.states)\" : \"\"", + "pod_filter.selectedOptionValue && pod_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + pod_filter.selectedOptionValue + \"'=ANY(global_issues.labels)\" : \"\"", + "sort_select.selectedOptionValue === \"GITHUB\" ? \"total_reactions desc, count desc, upvote_id desc\" : sort_select.selectedOptionValue === \"VOTES\" ? \"count desc, upvote_id desc, total_reactions desc\" : sort_select.selectedOptionValue === \"COMMENTORS\" ? \"unique_commentors desc, total_reactions desc, count desc, upvote_id desc\" : \"updated_at desc\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_issues" + }, + "publishedAction": { + "name": "fetch_issues", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "select global_issues.*, count(global_issues.id), count(issue_upvote.id) as upvote_id, COALESCE (github_issues.total_reactions, 0) as total_reactions, COALESCE(github_issues.unique_commentors,0) as unique_commentors, GREATEST(MAX(issue_upvote.created_at), MAX(global_issues.created_at)) as updated_at from global_issues left join github_issues on github_issues.id = global_issues.github_issue_id left join issue_upvote on global_issues.id = issue_upvote.issue_id where global_issues.title ilike '{{ \"%\" + Table1.searchText + \"%\" }}' {{appsmith.URL.queryParams.id ? \" and global_issues.id=\" + appsmith.URL.queryParams.id: \"\"}} and global_issues.state != 'DELETED' {{ type_filter.selectedOptionValue && type_filter.selectedOptionValue !== \"ALL\" ? \"and global_issues.type ='\" + type_filter.selectedOptionValue + \"'\" : \"\" }} {{ pod_filter.selectedOptionValue && pod_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + pod_filter.selectedOptionValue + \"'=ANY(global_issues.labels)\" : \"\" }} \n{{ status_filter.selectedOptionValue && status_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + status_filter.selectedOptionValue + \"' =ANY(global_issues.states)\" : \"\" }} group by global_issues.id, github_issues.id, global_issues.github_issue_id, global_issues.author, global_issues.created_at, global_issues.title, global_issues.description, global_issues.labels, global_issues.type, global_issues.state, global_issues.answer, global_issues.link, global_issues.states, github_issues.total_reactions, github_issues.unique_commentors order by {{sort_select.selectedOptionValue === \"GITHUB\" ? \"total_reactions desc, count desc, upvote_id desc\" : sort_select.selectedOptionValue === \"VOTES\" ? \"count desc, upvote_id desc, total_reactions desc\" : sort_select.selectedOptionValue === \"COMMENTORS\" ? \"unique_commentors desc, total_reactions desc, count desc, upvote_id desc\" : \"updated_at desc\" }} offset {{(Table1.pageNo - 1) * Table1.pageSize}} limit {{Table1.pageSize}}", + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "appsmith.URL.queryParams.id ? \" and global_issues.id=\" + appsmith.URL.queryParams.id: \"\"", + "type_filter.selectedOptionValue && type_filter.selectedOptionValue !== \"ALL\" ? \"and global_issues.type ='\" + type_filter.selectedOptionValue + \"'\" : \"\"", + "\"%\" + Table1.searchText + \"%\"", + "(Table1.pageNo - 1) * Table1.pageSize", + "Table1.pageSize", + "status_filter.selectedOptionValue && status_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + status_filter.selectedOptionValue + \"' =ANY(global_issues.states)\" : \"\"", + "pod_filter.selectedOptionValue && pod_filter.selectedOptionValue !== \"ALL\" ? \"and '\" + pod_filter.selectedOptionValue + \"'=ANY(global_issues.labels)\" : \"\"", + "sort_select.selectedOptionValue === \"GITHUB\" ? \"total_reactions desc, count desc, upvote_id desc\" : sort_select.selectedOptionValue === \"VOTES\" ? \"count desc, upvote_id desc, total_reactions desc\" : sort_select.selectedOptionValue === \"COMMENTORS\" ? \"unique_commentors desc, total_reactions desc, count desc, upvote_id desc\" : \"updated_at desc\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_issues" + }, + "new": false + }, + { + "id": "Issues_fetch_labels", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62389caf2d7f921bb707cf4b", + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "fetch_labels", + "datasource": { + "userPermissions": [ + + ], + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { + "url": "https://mock-api.appsmith.com" + }, + "invalids": [ + + ], + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/echo/post", + "headers": [ + { + "key": "content-type", + "value": "application/json" + } + ], + "encodeParamsToggle": true, + "queryParameters": [ + + ], + "body": "{\n \"total_count\": 16,\n \"incomplete_results\": false,\n \"items\": [\n {\n \"id\": 3393754279,\n \"node_id\": \"LA_kwDOEHNVHc7KSJSn\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/New%20Widget\",\n \"name\": \"New Widget\",\n \"color\": \"be4cf2\",\n \"default\": false,\n \"description\": \"A request for a new widget\",\n \"score\": 1\n },\n {\n \"id\": 2730904585,\n \"node_id\": \"MDU6TGFiZWwyNzMwOTA0NTg1\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Epic\",\n \"name\": \"Epic\",\n \"color\": \"3E4B9E\",\n \"default\": false,\n \"description\": \"A zenhub epic that describes a project\",\n \"score\": 1\n },\n {\n \"id\": 2768358578,\n \"node_id\": \"MDU6TGFiZWwyNzY4MzU4NTc4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Task\",\n \"name\": \"Task\",\n \"color\": \"085630\",\n \"default\": false,\n \"description\": \"A simple Todo\",\n \"score\": 1\n },\n {\n \"id\": 2640225158,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjI1MTU4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Medium%20effort\",\n \"name\": \"Medium effort\",\n \"color\": \"D31156\",\n \"default\": false,\n \"description\": \"Something that'll take more than a week but less than a month to build\",\n \"score\": 1\n },\n {\n \"id\": 2384759598,\n \"node_id\": \"MDU6TGFiZWwyMzg0NzU5NTk4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/High\",\n \"name\": \"High\",\n \"color\": \"c94d14\",\n \"default\": false,\n \"description\": \"This issue blocks a user from building or impacts a lot of users\",\n \"score\": 1\n },\n {\n \"id\": 2184776572,\n \"node_id\": \"MDU6TGFiZWwyMTg0Nzc2NTcy\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Dependencies\",\n \"name\": \"Dependencies\",\n \"color\": \"0366d6\",\n \"default\": false,\n \"description\": \"Pull requests that update a dependency file\",\n \"score\": 1\n },\n {\n \"id\": 3684243954,\n \"node_id\": \"LA_kwDOEHNVHc7bmRny\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/New%20JS%20Function\",\n \"name\": \"New JS Function\",\n \"color\": \"8e8aa4\",\n \"default\": false,\n \"description\": \"Issues related to adding a JS Function\",\n \"score\": 1\n },\n {\n \"id\": 2640223895,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjIzODk1\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Low%20effort\",\n \"name\": \"Low effort\",\n \"color\": \"8B59F0\",\n \"default\": false,\n \"description\": \"Something that'll take a few days to build\",\n \"score\": 1\n },\n {\n \"id\": 2640221594,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjIxNTk0\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Quick%20effort\",\n \"name\": \"Quick effort\",\n \"color\": \"95ED65\",\n \"default\": false,\n \"description\": \"Something that'll take a few hours to build\",\n \"score\": 1\n },\n {\n \"id\": 2640225928,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjI1OTI4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/High%20effort\",\n \"name\": \"High effort\",\n \"color\": \"A7E87B\",\n \"default\": false,\n \"description\": \"Something that'll take more than a month to build\",\n \"score\": 1\n },\n {\n \"id\": 2484384496,\n \"node_id\": \"MDU6TGFiZWwyNDg0Mzg0NDk2\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Needs%20Tests\",\n \"name\": \"Needs Tests\",\n \"color\": \"8ee263\",\n \"default\": false,\n \"description\": \"Needs automated tests to assert a feature/bug fix\",\n \"score\": 1\n },\n {\n \"id\": 2482077195,\n \"node_id\": \"MDU6TGFiZWwyNDgyMDc3MTk1\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Query%20Editor\",\n \"name\": \"Query Editor\",\n \"color\": \"8887af\",\n \"default\": false,\n \"description\": \"The section where a user can write DB queries.\",\n \"score\": 1\n },\n {\n \"id\": 3012242710,\n \"node_id\": \"MDU6TGFiZWwzMDEyMjQyNzEw\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/skip-changelog\",\n \"name\": \"skip-changelog\",\n \"color\": \"06086F\",\n \"default\": false,\n \"description\": \"Adding this label to a PR prevents it from being listed in the changelog\",\n \"score\": 1\n },\n {\n \"id\": 2384760942,\n \"node_id\": \"MDU6TGFiZWwyMzg0NzYwOTQy\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Low\",\n \"name\": \"Low\",\n \"color\": \"79e53b\",\n \"default\": false,\n \"description\": \"An issue that is neither critical nor breaks a user flow\",\n \"score\": 1\n },\n {\n \"id\": 3949573096,\n \"node_id\": \"LA_kwDOEHNVHc7rabPo\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Support\",\n \"name\": \"Support\",\n \"color\": \"f6ff4d\",\n \"default\": false,\n \"description\": \"Issues created by the A-force team to address user queries\",\n \"score\": 1\n },\n {\n \"id\": 3596711146,\n \"node_id\": \"LA_kwDOEHNVHc7WYXTq\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Old%20App%20Issues\",\n \"name\": \"Old App Issues\",\n \"color\": \"87ab18\",\n \"default\": false,\n \"description\": \"Issues related to apps old apps a few weeks old and app issues in stale browser session\",\n \"score\": 1\n }\n ]\n}", + "httpMethod": "POST", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ], + "formData": { + "apiContentType": "none" + } + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_labels" + }, + "publishedAction": { + "name": "fetch_labels", + "datasource": { + "userPermissions": [ + + ], + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { + "url": "https://mock-api.appsmith.com" + }, + "invalids": [ + + ], + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/echo/post", + "headers": [ + { + "key": "content-type", + "value": "application/json" + } + ], + "encodeParamsToggle": true, + "queryParameters": [ + + ], + "body": "{\n \"total_count\": 16,\n \"incomplete_results\": false,\n \"items\": [\n {\n \"id\": 3393754279,\n \"node_id\": \"LA_kwDOEHNVHc7KSJSn\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/New%20Widget\",\n \"name\": \"New Widget\",\n \"color\": \"be4cf2\",\n \"default\": false,\n \"description\": \"A request for a new widget\",\n \"score\": 1\n },\n {\n \"id\": 2730904585,\n \"node_id\": \"MDU6TGFiZWwyNzMwOTA0NTg1\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Epic\",\n \"name\": \"Epic\",\n \"color\": \"3E4B9E\",\n \"default\": false,\n \"description\": \"A zenhub epic that describes a project\",\n \"score\": 1\n },\n {\n \"id\": 2768358578,\n \"node_id\": \"MDU6TGFiZWwyNzY4MzU4NTc4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Task\",\n \"name\": \"Task\",\n \"color\": \"085630\",\n \"default\": false,\n \"description\": \"A simple Todo\",\n \"score\": 1\n },\n {\n \"id\": 2640225158,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjI1MTU4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Medium%20effort\",\n \"name\": \"Medium effort\",\n \"color\": \"D31156\",\n \"default\": false,\n \"description\": \"Something that'll take more than a week but less than a month to build\",\n \"score\": 1\n },\n {\n \"id\": 2384759598,\n \"node_id\": \"MDU6TGFiZWwyMzg0NzU5NTk4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/High\",\n \"name\": \"High\",\n \"color\": \"c94d14\",\n \"default\": false,\n \"description\": \"This issue blocks a user from building or impacts a lot of users\",\n \"score\": 1\n },\n {\n \"id\": 2184776572,\n \"node_id\": \"MDU6TGFiZWwyMTg0Nzc2NTcy\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Dependencies\",\n \"name\": \"Dependencies\",\n \"color\": \"0366d6\",\n \"default\": false,\n \"description\": \"Pull requests that update a dependency file\",\n \"score\": 1\n },\n {\n \"id\": 3684243954,\n \"node_id\": \"LA_kwDOEHNVHc7bmRny\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/New%20JS%20Function\",\n \"name\": \"New JS Function\",\n \"color\": \"8e8aa4\",\n \"default\": false,\n \"description\": \"Issues related to adding a JS Function\",\n \"score\": 1\n },\n {\n \"id\": 2640223895,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjIzODk1\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Low%20effort\",\n \"name\": \"Low effort\",\n \"color\": \"8B59F0\",\n \"default\": false,\n \"description\": \"Something that'll take a few days to build\",\n \"score\": 1\n },\n {\n \"id\": 2640221594,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjIxNTk0\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Quick%20effort\",\n \"name\": \"Quick effort\",\n \"color\": \"95ED65\",\n \"default\": false,\n \"description\": \"Something that'll take a few hours to build\",\n \"score\": 1\n },\n {\n \"id\": 2640225928,\n \"node_id\": \"MDU6TGFiZWwyNjQwMjI1OTI4\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/High%20effort\",\n \"name\": \"High effort\",\n \"color\": \"A7E87B\",\n \"default\": false,\n \"description\": \"Something that'll take more than a month to build\",\n \"score\": 1\n },\n {\n \"id\": 2484384496,\n \"node_id\": \"MDU6TGFiZWwyNDg0Mzg0NDk2\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Needs%20Tests\",\n \"name\": \"Needs Tests\",\n \"color\": \"8ee263\",\n \"default\": false,\n \"description\": \"Needs automated tests to assert a feature/bug fix\",\n \"score\": 1\n },\n {\n \"id\": 2482077195,\n \"node_id\": \"MDU6TGFiZWwyNDgyMDc3MTk1\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Query%20Editor\",\n \"name\": \"Query Editor\",\n \"color\": \"8887af\",\n \"default\": false,\n \"description\": \"The section where a user can write DB queries.\",\n \"score\": 1\n },\n {\n \"id\": 3012242710,\n \"node_id\": \"MDU6TGFiZWwzMDEyMjQyNzEw\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/skip-changelog\",\n \"name\": \"skip-changelog\",\n \"color\": \"06086F\",\n \"default\": false,\n \"description\": \"Adding this label to a PR prevents it from being listed in the changelog\",\n \"score\": 1\n },\n {\n \"id\": 2384760942,\n \"node_id\": \"MDU6TGFiZWwyMzg0NzYwOTQy\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Low\",\n \"name\": \"Low\",\n \"color\": \"79e53b\",\n \"default\": false,\n \"description\": \"An issue that is neither critical nor breaks a user flow\",\n \"score\": 1\n },\n {\n \"id\": 3949573096,\n \"node_id\": \"LA_kwDOEHNVHc7rabPo\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Support\",\n \"name\": \"Support\",\n \"color\": \"f6ff4d\",\n \"default\": false,\n \"description\": \"Issues created by the A-force team to address user queries\",\n \"score\": 1\n },\n {\n \"id\": 3596711146,\n \"node_id\": \"LA_kwDOEHNVHc7WYXTq\",\n \"url\": \"https://api.github.com/repos/appsmithorg/appsmith/labels/Old%20App%20Issues\",\n \"name\": \"Old App Issues\",\n \"color\": \"87ab18\",\n \"default\": false,\n \"description\": \"Issues related to apps old apps a few weeks old and app issues in stale browser session\",\n \"score\": 1\n }\n ]\n}", + "httpMethod": "POST", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ], + "formData": { + "apiContentType": "none" + } + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "fetch_labels" + }, + "new": false + }, + { + "id": "Issues_GithubManager.getLabels", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62389d702d7f921bb707cf53", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getLabels", + "fullyQualifiedName": "GithubManager.getLabels", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_GithubManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn fetch_labels.data.body.items.filter((label) => {\n\t\t\treturn !label.name.includes('Pod');\n\t\t}).map((item) => {\n\t\t\treturn { label: item.name, value: item.name } \n\t\t}); \n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn fetch_labels.data.body.items.filter((label) => {\n\t\t\treturn !label.name.includes('Pod');\n\t\t}).map((item) => {\n\t\t\treturn { label: item.name, value: item.name } \n\t\t}); \n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "GithubManager.getLabels" + }, + "publishedAction": { + "name": "getLabels", + "fullyQualifiedName": "GithubManager.getLabels", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_GithubManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn fetch_labels.data.body.items.filter((label) => {\n\t\t\treturn !label.name.includes('Pod');\n\t\t}).map((item) => {\n\t\t\treturn { label: item.name, value: item.name } \n\t\t}); \n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn fetch_labels.data.body.items.filter((label) => {\n\t\t\treturn !label.name.includes('Pod');\n\t\t}).map((item) => {\n\t\t\treturn { label: item.name, value: item.name } \n\t\t}); \n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "GithubManager.getLabels" + }, + "new": false + }, + { + "id": "Issues_search_github_issues", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62389e1e2d7f921bb707cf55", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "search_github_issues", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "select * from github_issues where title ilike {{ \"%\" + this.params.searchText + \"%\" }} or issue_number ::text ilike {{ \"%\" + this.params.searchText + \"%\" }}", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "\"%\" + this.params.searchText + \"%\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "search_github_issues" + }, + "publishedAction": { + "name": "search_github_issues", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "select * from github_issues where title ilike {{ \"%\" + this.params.searchText + \"%\" }} or issue_number ::text ilike {{ \"%\" + this.params.searchText + \"%\" }}", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "\"%\" + this.params.searchText + \"%\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "search_github_issues" + }, + "new": false + }, + { + "id": "Issues_IssueManager.addComment", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62394b6837307a6b1cf05f23", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "addComment", + "fullyQualifiedName": "IssueManager.addComment", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\tadd_new_comment.run(() => {\n\t\t\tfetch_comments.run();\n\t\t\tupdate_issue_labels.run(() => \n\t\t\t\tfetch_issues.run());\n\t\t\tcloseModal('upvote_modal');\n\t\t\tresetWidget('upvote_modal', true);\n\t\t});\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\tadd_new_comment.run(() => {\n\t\t\tfetch_comments.run();\n\t\t\tupdate_issue_labels.run(() => \n\t\t\t\tfetch_issues.run());\n\t\t\tcloseModal('upvote_modal');\n\t\t\tresetWidget('upvote_modal', true);\n\t\t});\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.addComment" + }, + "publishedAction": { + "name": "addComment", + "fullyQualifiedName": "IssueManager.addComment", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\tadd_new_comment.run(() => {\n\t\t\tfetch_comments.run();\n\t\t\tupdate_issue_labels.run(() => \n\t\t\t\tfetch_issues.run());\n\t\t\tcloseModal('upvote_modal');\n\t\t\tresetWidget('upvote_modal', true);\n\t\t});\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\tadd_new_comment.run(() => {\n\t\t\tfetch_comments.run();\n\t\t\tupdate_issue_labels.run(() => \n\t\t\t\tfetch_issues.run());\n\t\t\tcloseModal('upvote_modal');\n\t\t\tresetWidget('upvote_modal', true);\n\t\t});\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.addComment" + }, + "new": false + }, + { + "id": "Issues_GithubManager.getSelectedGithubIssue", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_6239d1a8a11e927e2cfc8276", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getSelectedGithubIssue", + "fullyQualifiedName": "GithubManager.getSelectedGithubIssue", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_GithubManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn search_github_issues.data.find((issue) => issue.id == add_issue_select.selectedOptionValue);\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn search_github_issues.data.find((issue) => issue.id == add_issue_select.selectedOptionValue);\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "GithubManager.getSelectedGithubIssue" + }, + "publishedAction": { + "name": "getSelectedGithubIssue", + "fullyQualifiedName": "GithubManager.getSelectedGithubIssue", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_GithubManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn search_github_issues.data.find((issue) => issue.id == add_issue_select.selectedOptionValue);\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn search_github_issues.data.find((issue) => issue.id == add_issue_select.selectedOptionValue);\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "GithubManager.getSelectedGithubIssue" + }, + "new": false + }, + { + "id": "Issues_update_issue", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_6239d7e9a11e927e2cfc8278", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "update_issue", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "update global_issues set \ntitle = {{edit_title_input.text}}, \ndescription = {{edit_description_input.text}},\ntype = {{edit_type_input.selectedOptionValue}},\nlabels = {{ \"{\" + this.params.labels.join(\",\") + \"}\" }}::text[],\nanswer = {{edit_answer_input.text}},\ngithub_issue_id = {{edit_issue_select.selectedOptionValue || Table1.selectedRow.github_issue_id}},\nlink = {{edit_link_input.text}},\nstates = {{\"{\" + edit_states_select.selectedOptionValues.join(\",\") + \"}\"}}::text[] where id = {{Table1.selectedRow.id}}", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "edit_title_input.text", + "edit_description_input.text", + "edit_type_input.selectedOptionValue", + "edit_answer_input.text", + "edit_issue_select.selectedOptionValue || Table1.selectedRow.github_issue_id", + "Table1.selectedRow.id", + "\"{\" + this.params.labels.join(\",\") + \"}\"", + "edit_link_input.text", + "\"{\" + edit_states_select.selectedOptionValues.join(\",\") + \"}\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "update_issue" + }, + "publishedAction": { + "name": "update_issue", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "update global_issues set \ntitle = {{edit_title_input.text}}, \ndescription = {{edit_description_input.text}},\ntype = {{edit_type_input.selectedOptionValue}},\nlabels = {{ \"{\" + this.params.labels.join(\",\") + \"}\" }}::text[],\nanswer = {{edit_answer_input.text}},\ngithub_issue_id = {{edit_issue_select.selectedOptionValue || Table1.selectedRow.github_issue_id}},\nlink = {{edit_link_input.text}},\nstates = {{\"{\" + edit_states_select.selectedOptionValues.join(\",\") + \"}\"}}::text[] where id = {{Table1.selectedRow.id}}", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "edit_title_input.text", + "edit_description_input.text", + "edit_type_input.selectedOptionValue", + "edit_answer_input.text", + "edit_issue_select.selectedOptionValue || Table1.selectedRow.github_issue_id", + "Table1.selectedRow.id", + "\"{\" + this.params.labels.join(\",\") + \"}\"", + "edit_link_input.text", + "\"{\" + edit_states_select.selectedOptionValues.join(\",\") + \"}\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "update_issue" + }, + "new": false + }, + { + "id": "Issues_Configs.getTitleState", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_6239488837307a6b1cf05f1f", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getTitleState", + "fullyQualifiedName": "Configs.getTitleState", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Configs", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(states) => {\n\t\treturn states ? states.map((state) => Configs.statesMap[state]?.icon + \" \").join(\" \") : \"\"\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(states) => {\n\t\treturn states ? states.map((state) => Configs.statesMap[state]?.icon + \" \").join(\" \") : \"\"\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Configs.getTitleState" + }, + "publishedAction": { + "name": "getTitleState", + "fullyQualifiedName": "Configs.getTitleState", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_Configs", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "(states) => {\n\t\treturn states ? states.map((state) => Configs.statesMap[state]?.icon + \" \").join(\" \") : \"\"\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "(states) => {\n\t\treturn states ? states.map((state) => Configs.statesMap[state]?.icon + \" \").join(\" \") : \"\"\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "Configs.getTitleState" + }, + "new": false + }, + { + "id": "Issues_delete_issue", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_6239ce9ba11e927e2cfc8274", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "delete_issue", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "update global_issues set state = 'DELETED' where id = {{Table1.selectedRow.id.toString()}}" + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id.toString()" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "delete_issue" + }, + "publishedAction": { + "name": "delete_issue", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "update global_issues set state = 'DELETED' where id = {{Table1.selectedRow.id.toString()}}" + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id.toString()" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "delete_issue" + }, + "new": false + }, + { + "id": "Issues_IssueManager.delete", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623a10fba11e927e2cfc8284", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "delete", + "fullyQualifiedName": "IssueManager.delete", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "async () => {\n\t\tawait delete_issue.run(() => fetch_issues.run());\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "async () => {\n\t\tawait delete_issue.run(() => fetch_issues.run());\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.delete" + }, + "publishedAction": { + "name": "delete", + "fullyQualifiedName": "IssueManager.delete", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "async () => {\n\t\tawait delete_issue.run(() => fetch_issues.run());\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "async () => {\n\t\tawait delete_issue.run(() => fetch_issues.run());\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.delete" + }, + "new": false + }, + { + "id": "Issues_GithubManager.getIssues", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62389edb2d7f921bb707cf57", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "getIssues", + "fullyQualifiedName": "GithubManager.getIssues", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_GithubManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn search_github_issues.data.map((item) => {\n\t\t\treturn {\n\t\t\t\tlabel: item.title,\n\t\t\t\tvalue: item.id + \"\"\n\t\t\t}\n\t\t})\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn search_github_issues.data.map((item) => {\n\t\t\treturn {\n\t\t\t\tlabel: item.title,\n\t\t\t\tvalue: item.id + \"\"\n\t\t\t}\n\t\t})\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "GithubManager.getIssues" + }, + "publishedAction": { + "name": "getIssues", + "fullyQualifiedName": "GithubManager.getIssues", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_GithubManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\treturn search_github_issues.data.map((item) => {\n\t\t\treturn {\n\t\t\t\tlabel: item.title,\n\t\t\t\tvalue: item.id + \"\"\n\t\t\t}\n\t\t})\n\t}", + "jsArguments": [ + + ], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "() => {\n\t\treturn search_github_issues.data.map((item) => {\n\t\t\treturn {\n\t\t\t\tlabel: item.title,\n\t\t\t\tvalue: item.id + \"\"\n\t\t\t}\n\t\t})\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "GithubManager.getIssues" + }, + "new": false + }, + { + "id": "Issues_IssueManager.update", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_6239dff0a11e927e2cfc827a", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "update", + "fullyQualifiedName": "IssueManager.update", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "async () => {\n\t\tconst labels = IssueManager.getAssignedLabels(edit_label_select.selectedOptionValues);\n\t\tawait update_issue.run({ labels: labels });\n\t\tawait fetch_issues.run();\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "async () => {\n\t\tconst labels = IssueManager.getAssignedLabels(edit_label_select.selectedOptionValues);\n\t\tawait update_issue.run({ labels: labels });\n\t\tawait fetch_issues.run();\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.update" + }, + "publishedAction": { + "name": "update", + "fullyQualifiedName": "IssueManager.update", + "datasource": { + "userPermissions": [ + + ], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [ + + ], + "isValid": true, + "new": true + }, + "pageId": "Issues", + "collectionId": "Issues_IssueManager", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "async () => {\n\t\tconst labels = IssueManager.getAssignedLabels(edit_label_select.selectedOptionValues);\n\t\tawait update_issue.run({ labels: labels });\n\t\tawait fetch_issues.run();\n\t}", + "jsArguments": [ + + ], + "isAsync": true + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "async () => {\n\t\tconst labels = IssueManager.getAssignedLabels(edit_label_select.selectedOptionValues);\n\t\tawait update_issue.run({ labels: labels });\n\t\tawait fetch_issues.run();\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "IssueManager.update" + }, + "new": false + }, + { + "id": "Issues_update_issue_labels", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62394b3e37307a6b1cf05f21", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "update_issue_labels", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "update global_issues set \nlabels = {{ \"{\" + IssueManager.getAssignedLabels(upvote_label_select.selectedOptionValues) + \"}\" }}::text[]\n where id = {{Table1.selectedRow.id}}", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id", + "\"{\" + IssueManager.getAssignedLabels(upvote_label_select.selectedOptionValues) + \"}\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "update_issue_labels" + }, + "publishedAction": { + "name": "update_issue_labels", + "datasource": { + "id": "AForceDB", + "userPermissions": [ + + ], + "pluginId": "postgres-plugin", + "messages": [ + + ], + "isValid": true, + "new": false + }, + "pageId": "Issues", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "update global_issues set \nlabels = {{ \"{\" + IssueManager.getAssignedLabels(upvote_label_select.selectedOptionValues) + \"}\" }}::text[]\n where id = {{Table1.selectedRow.id}}", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [ + + ], + "messages": [ + + ], + "jsonPathKeys": [ + "Table1.selectedRow.id", + "\"{\" + IssueManager.getAssignedLabels(upvote_label_select.selectedOptionValues) + \"}\"" + ], + "confirmBeforeExecute": false, + "userPermissions": [ + + ], + "validName": "update_issue_labels" + }, + "new": false + } + ], + "actionCollectionList": [ + { + "id": "Issues_Utils", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623765e92e5d3f189d0c3c33", + "unpublishedCollection": { + "name": "Utils", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\tgetPodLabels: () => {\n\t\treturn Object.keys(fetch_label_config.data.runners[0].issue.labels)\n\t\t\t.map((pod) => { \n\t\t\t\treturn {\n\t\t\t\t\tlabel: pod,\n\t\t\t\t\tvalue: pod\n\t\t\t\t}\n\t\t\t});\n\t},\n\tcheckIsPod: (label) => {\n\t\treturn fetch_label_config.data.runners[0].issue.labels[label] !== undefined\n\t},\n\tgetConfig: () => {\n\t\treturn fetch_label_config.data;\n\t},\n\tgetPodForLabel: (label = \"New JS Function\") => {\n\t\tconst labels = fetch_label_config.data.runners[0].issue.labels;\n\t\tconst pods = this.getPodLabels().map((pod) => pod.label);\n\t\tlet foundPod;\n\t\tpods.map((podLabel) => {\n\t\t\tconst foundLabel = labels[podLabel].conditions.find((condition) => {\n\t\t\t\treturn condition.label === label && podLabel !== label\n\t\t\t})\n\t\t\tif (foundLabel) {\n\t\t\t\tfoundPod = podLabel\n\t\t\t}\n\t\t});\n\t\treturn foundPod;\n\t},\n\tgetLabelsForPod: (pod) => {\n\t\treturn fetch_label_config.data.runners[0]\n\t\t\t.issue.labels[pod].conditions.map((label) => \n\t\t\t\t\tfetch_label_config.data.labels[label.label])\n\t\t\t.filter((label) => label !== undefined)\n\t},\n\tcsvToArr: () => {\n\t\t//const csvRows = FilePicker1.files[1].data.split(\"\\n\");\n\t\t//const objArr = [];\n\t\t//const headers = csvRows[0].split(',');\n\t\t\t//for(let i = 1; i < csvRows.length; i++) {\n\t\t\t\t//const rowObj = {};\n\t\t\t\t//objArr.push(rowObj);\n\t\t\t\t//const rowArr = csvRows[i].split(',');\n\t\t\t\t//rowArr.forEach((val, index) => {\n\t\t\t\t//rowObj[headers[index]] = val;\n\t\t\t\t//});\n\t\t\t//}\n\t\t//return objArr;\n\t}\n}", + "variables": [ + + ] + }, + "publishedCollection": { + "name": "Utils", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\tgetPodLabels: () => {\n\t\treturn Object.keys(fetch_label_config.data.runners[0].issue.labels)\n\t\t\t.map((pod) => { \n\t\t\t\treturn {\n\t\t\t\t\tlabel: pod,\n\t\t\t\t\tvalue: pod\n\t\t\t\t}\n\t\t\t});\n\t},\n\tcheckIsPod: (label) => {\n\t\treturn fetch_label_config.data.runners[0].issue.labels[label] !== undefined\n\t},\n\tgetConfig: () => {\n\t\treturn fetch_label_config.data;\n\t},\n\tgetPodForLabel: (label = \"New JS Function\") => {\n\t\tconst labels = fetch_label_config.data.runners[0].issue.labels;\n\t\tconst pods = this.getPodLabels().map((pod) => pod.label);\n\t\tlet foundPod;\n\t\tpods.map((podLabel) => {\n\t\t\tconst foundLabel = labels[podLabel].conditions.find((condition) => {\n\t\t\t\treturn condition.label === label && podLabel !== label\n\t\t\t})\n\t\t\tif (foundLabel) {\n\t\t\t\tfoundPod = podLabel\n\t\t\t}\n\t\t});\n\t\treturn foundPod;\n\t},\n\tgetLabelsForPod: (pod) => {\n\t\treturn fetch_label_config.data.runners[0]\n\t\t\t.issue.labels[pod].conditions.map((label) => \n\t\t\t\t\tfetch_label_config.data.labels[label.label])\n\t\t\t.filter((label) => label !== undefined)\n\t},\n\tcsvToArr: () => {\n\t\t//const csvRows = FilePicker1.files[1].data.split(\"\\n\");\n\t\t//const objArr = [];\n\t\t//const headers = csvRows[0].split(',');\n\t\t\t//for(let i = 1; i < csvRows.length; i++) {\n\t\t\t\t//const rowObj = {};\n\t\t\t\t//objArr.push(rowObj);\n\t\t\t\t//const rowArr = csvRows[i].split(',');\n\t\t\t\t//rowArr.forEach((val, index) => {\n\t\t\t\t//rowObj[headers[index]] = val;\n\t\t\t\t//});\n\t\t\t//}\n\t\t//return objArr;\n\t}\n}", + "variables": [ + + ] + }, + "new": false + }, + { + "id": "Issues_Configs", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_623763562e5d3f189d0c3c2b", + "unpublishedCollection": { + "name": "Configs", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\ttype: [\n\t\t{\n\t\t\tlabel: \"All\",\n\t\t\tvalue: \"ALL\"\n\t\t}, \n\t\t{\n\t\t\tlabel: \"Feature\",\n\t\t\tvalue: \"Feature\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Bug\",\n\t\t\tvalue: \"Bug\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Question\",\n\t\t\tvalue: \"Question\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Troubleshooting\",\n\t\t\tvalue: \"Troubleshooting\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Suggestion\",\n\t\t\tvalue: \"Suggestion\"\n\t\t}\n\t],\n\tpods: [\n\t\t{\n\t\t\tlabel: \"All\",\n\t\t\tvalue: \"ALL\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"App Viewers Pod\",\n\t\t\tvalue: \"App Viewers Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"UI Builders Pod\",\n\t\t\tvalue: \"UI Builders Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Team Managers Pod\",\n\t\t\tvalue: \"Team Managers Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"FE Coders Pod\",\n\t\t\tvalue: \"FE Coders Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"BE Coders Pod\",\n\t\t\tvalue: \"BE Coders Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"New Developers Pod\",\n\t\t\tvalue: \"New Developers Pod\"\n\t\t}\n\t],\n\tstatus: [\n\t\t{\n\t\t\tlabel: \"Opened\",\n\t\t\tvalue: \"Opened\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Solved\",\n\t\t\tvalue: \"Solved\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Communicated to user\",\n\t\t\tvalue: \"Communicated to user\"\n\t\t}\n\t],\n\tstatesMap: {\n\t\t[\"Needs Documentation\"]: {\n\t\t\tlabel: \"Needs Docs\",\n\t\t\tvalue: \"Needs Documentation\",\n\t\t\ticon: \"❓📑\",\n\t\t\torder: 1\n\t\t},\n\t\t[\"Documented\"]: {\n\t\t\tlabel: \"Documented\",\n\t\t\tvalue: \"Documented\",\n\t\t\ticon: \"📑\",\n\t\t\torder: 2\n\t\t},\n\t\t[\"Needs App\"]: {\n\t\t\tlabel: \"Needs App\",\n\t\t\tvalue: \"Needs App\",\n\t\t\ticon: \"❓💻\",\n\t\t\torder: 3\n\t\t},\n\t\t[\"App Built\"]: {\n\t\t\tlabel: \"App Built\",\n\t\t\tvalue: \"App Built\",\n\t\t\ticon: \"💻\",\n\t\t\torder: 4\n\t\t},\n\t\t[\"Needs Product\"]: {\n\t\t\tlabel: \"Needs Product\",\n\t\t\tvalue: \"Needs Product\",\n\t\t\ticon: \"❓🧩\",\n\t\t\torder: 5\n\t\t},\n\t\t[\"Product Solved\"]: {\n\t\t\tlabel: \"Product Solved\",\n\t\t\tvalue: \"Product Solved\",\n\t\t\ticon: \"🧩\",\n\t\t\torder: 6\n\t\t},\n\t},\n\tstates: [ { label: \"All\", value: \"ALL\" }, ...Object.values(this.statesMap)],\n\tgetTitleState: (states) => {\n\t\treturn states ? states.map((state) => this.statesMap[state]?.icon + \" \").join(\" \") : \"\"\n\t}\n}", + "variables": [ + { + "name": "type", + "value": [ + { + "label": "All", + "value": "ALL" + }, + { + "label": "Feature", + "value": "Feature" + }, + { + "label": "Bug", + "value": "Bug" + }, + { + "label": "Question", + "value": "Question" + }, + { + "label": "Troubleshooting", + "value": "Troubleshooting" + }, + { + "label": "Suggestion", + "value": "Suggestion" + } + ] + }, + { + "name": "pods", + "value": [ + { + "label": "All", + "value": "ALL" + }, + { + "label": "App Viewers Pod", + "value": "App Viewers Pod" + }, + { + "label": "UI Builders Pod", + "value": "UI Builders Pod" + }, + { + "label": "Team Managers Pod", + "value": "Team Managers Pod" + }, + { + "label": "FE Coders Pod", + "value": "FE Coders Pod" + }, + { + "label": "BE Coders Pod", + "value": "BE Coders Pod" + }, + { + "label": "New Developers Pod", + "value": "New Developers Pod" + } + ] + }, + { + "name": "status", + "value": [ + { + "label": "Opened", + "value": "Opened" + }, + { + "label": "Solved", + "value": "Solved" + }, + { + "label": "Communicated to user", + "value": "Communicated to user" + } + ] + }, + { + "name": "statesMap", + "value": { + "Needs Documentation": { + "label": "Needs Docs", + "value": "Needs Documentation", + "icon": "❓📑", + "order": 1.0 + }, + "Documented": { + "label": "Documented", + "value": "Documented", + "icon": "📑", + "order": 2.0 + }, + "Needs App": { + "label": "Needs App", + "value": "Needs App", + "icon": "❓💻", + "order": 3.0 + }, + "App Built": { + "label": "App Built", + "value": "App Built", + "icon": "💻", + "order": 4.0 + }, + "Needs Product": { + "label": "Needs Product", + "value": "Needs Product", + "icon": "❓🧩", + "order": 5.0 + }, + "Product Solved": { + "label": "Product Solved", + "value": "Product Solved", + "icon": "🧩", + "order": 6.0 + } + } + }, + { + "name": "states", + "value": [ + { + "label": "All", + "value": "ALL" + }, + { + "label": "Needs Docs", + "value": "Needs Documentation", + "icon": "❓📑", + "order": 1.0 + }, + { + "label": "Documented", + "value": "Documented", + "icon": "📑", + "order": 2.0 + }, + { + "label": "Needs App", + "value": "Needs App", + "icon": "❓💻", + "order": 3.0 + }, + { + "label": "App Built", + "value": "App Built", + "icon": "💻", + "order": 4.0 + }, + { + "label": "Needs Product", + "value": "Needs Product", + "icon": "❓🧩", + "order": 5.0 + }, + { + "label": "Product Solved", + "value": "Product Solved", + "icon": "🧩", + "order": 6.0 + } + ] + } + ] + }, + "publishedCollection": { + "name": "Configs", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\ttype: [\n\t\t{\n\t\t\tlabel: \"All\",\n\t\t\tvalue: \"ALL\"\n\t\t}, \n\t\t{\n\t\t\tlabel: \"Feature\",\n\t\t\tvalue: \"Feature\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Bug\",\n\t\t\tvalue: \"Bug\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Question\",\n\t\t\tvalue: \"Question\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Troubleshooting\",\n\t\t\tvalue: \"Troubleshooting\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Suggestion\",\n\t\t\tvalue: \"Suggestion\"\n\t\t}\n\t],\n\tpods: [\n\t\t{\n\t\t\tlabel: \"All\",\n\t\t\tvalue: \"ALL\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"App Viewers Pod\",\n\t\t\tvalue: \"App Viewers Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"UI Builders Pod\",\n\t\t\tvalue: \"UI Builders Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Team Managers Pod\",\n\t\t\tvalue: \"Team Managers Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"FE Coders Pod\",\n\t\t\tvalue: \"FE Coders Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"BE Coders Pod\",\n\t\t\tvalue: \"BE Coders Pod\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"New Developers Pod\",\n\t\t\tvalue: \"New Developers Pod\"\n\t\t}\n\t],\n\tstatus: [\n\t\t{\n\t\t\tlabel: \"Opened\",\n\t\t\tvalue: \"Opened\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Solved\",\n\t\t\tvalue: \"Solved\"\n\t\t},\n\t\t{\n\t\t\tlabel: \"Communicated to user\",\n\t\t\tvalue: \"Communicated to user\"\n\t\t}\n\t],\n\tstatesMap: {\n\t\t[\"Needs Documentation\"]: {\n\t\t\tlabel: \"Needs Docs\",\n\t\t\tvalue: \"Needs Documentation\",\n\t\t\ticon: \"❓📑\",\n\t\t\torder: 1\n\t\t},\n\t\t[\"Documented\"]: {\n\t\t\tlabel: \"Documented\",\n\t\t\tvalue: \"Documented\",\n\t\t\ticon: \"📑\",\n\t\t\torder: 2\n\t\t},\n\t\t[\"Needs App\"]: {\n\t\t\tlabel: \"Needs App\",\n\t\t\tvalue: \"Needs App\",\n\t\t\ticon: \"❓💻\",\n\t\t\torder: 3\n\t\t},\n\t\t[\"App Built\"]: {\n\t\t\tlabel: \"App Built\",\n\t\t\tvalue: \"App Built\",\n\t\t\ticon: \"💻\",\n\t\t\torder: 4\n\t\t},\n\t\t[\"Needs Product\"]: {\n\t\t\tlabel: \"Needs Product\",\n\t\t\tvalue: \"Needs Product\",\n\t\t\ticon: \"❓🧩\",\n\t\t\torder: 5\n\t\t},\n\t\t[\"Product Solved\"]: {\n\t\t\tlabel: \"Product Solved\",\n\t\t\tvalue: \"Product Solved\",\n\t\t\ticon: \"🧩\",\n\t\t\torder: 6\n\t\t},\n\t},\n\tstates: [ { label: \"All\", value: \"ALL\" }, ...Object.values(this.statesMap)],\n\tgetTitleState: (states) => {\n\t\treturn states ? states.map((state) => this.statesMap[state]?.icon + \" \").join(\" \") : \"\"\n\t}\n}", + "variables": [ + { + "name": "type", + "value": [ + { + "label": "All", + "value": "ALL" + }, + { + "label": "Feature", + "value": "Feature" + }, + { + "label": "Bug", + "value": "Bug" + }, + { + "label": "Question", + "value": "Question" + }, + { + "label": "Troubleshooting", + "value": "Troubleshooting" + }, + { + "label": "Suggestion", + "value": "Suggestion" + } + ] + }, + { + "name": "pods", + "value": [ + { + "label": "All", + "value": "ALL" + }, + { + "label": "App Viewers Pod", + "value": "App Viewers Pod" + }, + { + "label": "UI Builders Pod", + "value": "UI Builders Pod" + }, + { + "label": "Team Managers Pod", + "value": "Team Managers Pod" + }, + { + "label": "FE Coders Pod", + "value": "FE Coders Pod" + }, + { + "label": "BE Coders Pod", + "value": "BE Coders Pod" + }, + { + "label": "New Developers Pod", + "value": "New Developers Pod" + } + ] + }, + { + "name": "status", + "value": [ + { + "label": "Opened", + "value": "Opened" + }, + { + "label": "Solved", + "value": "Solved" + }, + { + "label": "Communicated to user", + "value": "Communicated to user" + } + ] + }, + { + "name": "statesMap", + "value": { + "Needs Documentation": { + "label": "Needs Docs", + "value": "Needs Documentation", + "icon": "❓📑", + "order": 1.0 + }, + "Documented": { + "label": "Documented", + "value": "Documented", + "icon": "📑", + "order": 2.0 + }, + "Needs App": { + "label": "Needs App", + "value": "Needs App", + "icon": "❓💻", + "order": 3.0 + }, + "App Built": { + "label": "App Built", + "value": "App Built", + "icon": "💻", + "order": 4.0 + }, + "Needs Product": { + "label": "Needs Product", + "value": "Needs Product", + "icon": "❓🧩", + "order": 5.0 + }, + "Product Solved": { + "label": "Product Solved", + "value": "Product Solved", + "icon": "🧩", + "order": 6.0 + } + } + }, + { + "name": "states", + "value": [ + { + "label": "All", + "value": "ALL" + }, + { + "label": "Needs Docs", + "value": "Needs Documentation", + "icon": "❓📑", + "order": 1.0 + }, + { + "label": "Documented", + "value": "Documented", + "icon": "📑", + "order": 2.0 + }, + { + "label": "Needs App", + "value": "Needs App", + "icon": "❓💻", + "order": 3.0 + }, + { + "label": "App Built", + "value": "App Built", + "icon": "💻", + "order": 4.0 + }, + { + "label": "Needs Product", + "value": "Needs Product", + "icon": "❓🧩", + "order": 5.0 + }, + { + "label": "Product Solved", + "value": "Product Solved", + "icon": "🧩", + "order": 6.0 + } + ] + } + ] + }, + "new": false + }, + { + "id": "Issues_IssueManager", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62382c35cb09660cd0f703bd", + "unpublishedCollection": { + "name": "IssueManager", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\tgetAssignedLabels: (allLabels = label_select.selectedOptionValues) => {\n\t\tconst labels = allLabels.filter((label) => {\n\t\t\treturn Utils.checkIsPod(label) !== true;\n\t\t}); \n\t\tconst podMap = {};\n\t\tlabels.map((label) => {\n\t\t\tconst pod = Utils.getPodForLabel(label);\n\t\t\tif (pod)\n\t\t\t\tpodMap[pod] = true;\n\t\t});\n\t\treturn [...Object.keys(podMap), ...labels];\n\t}, \n\tcreate_issue: () => {\n\t\tconst labels = this.getAssignedLabels(label_select.selectedOptionValues);\n\t\tadd_new_issue.run(() => {\n\t\t\t\tfetch_issues.run(() => {\n\t\t\t\t\tresetWidget('add_issue_modal', true);\n\t\t\t\t\tcloseModal('add_issue_modal');\n\t\t\t\t});\n\t\t}, undefined, { labels: labels })\n\t},\n\tfetchIssues: () => {\n\t\tfetch_issues.run();\n\t},\n\tgetIssueData: () => {\n\t\treturn fetch_issues.data.map((issue) => {\n\t\t\tif (issue.upvote_id > 0)\n\t\t\t\tissue.count = issue.count + 1;\n\t\t\treturn { type: issue.type, title: issue.title, total_reactions: issue.total_reactions, unique_commentors: issue.unique_commentors, upvote_id: issue.upvote_id ,...issue};\n\t\t});\n\t},\n\taddComment: () => {\n\t\tadd_new_comment.run(() => {\n\t\t\tfetch_comments.run();\n\t\t\tupdate_issue_labels.run(() => \n\t\t\t\tfetch_issues.run());\n\t\t\tcloseModal('upvote_modal');\n\t\t\tresetWidget('upvote_modal', true);\n\t\t});\n\t},\n\tupdate: async () => {\n\t\tconst labels = this.getAssignedLabels(edit_label_select.selectedOptionValues);\n\t\tawait update_issue.run({ labels: labels });\n\t\tawait fetch_issues.run();\n\t},\n\tdelete: async () => {\n\t\tawait delete_issue.run(() => fetch_issues.run());\n\t}\n}", + "variables": [ + + ] + }, + "publishedCollection": { + "name": "IssueManager", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\tgetAssignedLabels: (allLabels = label_select.selectedOptionValues) => {\n\t\tconst labels = allLabels.filter((label) => {\n\t\t\treturn Utils.checkIsPod(label) !== true;\n\t\t}); \n\t\tconst podMap = {};\n\t\tlabels.map((label) => {\n\t\t\tconst pod = Utils.getPodForLabel(label);\n\t\t\tif (pod)\n\t\t\t\tpodMap[pod] = true;\n\t\t});\n\t\treturn [...Object.keys(podMap), ...labels];\n\t}, \n\tcreate_issue: () => {\n\t\tconst labels = this.getAssignedLabels(label_select.selectedOptionValues);\n\t\tadd_new_issue.run(() => {\n\t\t\t\tfetch_issues.run(() => {\n\t\t\t\t\tresetWidget('add_issue_modal', true);\n\t\t\t\t\tcloseModal('add_issue_modal');\n\t\t\t\t});\n\t\t}, undefined, { labels: labels })\n\t},\n\tfetchIssues: () => {\n\t\tfetch_issues.run();\n\t},\n\tgetIssueData: () => {\n\t\treturn fetch_issues.data.map((issue) => {\n\t\t\tif (issue.upvote_id > 0)\n\t\t\t\tissue.count = issue.count + 1;\n\t\t\treturn { type: issue.type, title: issue.title, total_reactions: issue.total_reactions, unique_commentors: issue.unique_commentors, upvote_id: issue.upvote_id ,...issue};\n\t\t});\n\t},\n\taddComment: () => {\n\t\tadd_new_comment.run(() => {\n\t\t\tfetch_comments.run();\n\t\t\tupdate_issue_labels.run(() => \n\t\t\t\tfetch_issues.run());\n\t\t\tcloseModal('upvote_modal');\n\t\t\tresetWidget('upvote_modal', true);\n\t\t});\n\t},\n\tupdate: async () => {\n\t\tconst labels = this.getAssignedLabels(edit_label_select.selectedOptionValues);\n\t\tawait update_issue.run({ labels: labels });\n\t\tawait fetch_issues.run();\n\t},\n\tdelete: async () => {\n\t\tawait delete_issue.run(() => fetch_issues.run());\n\t}\n}", + "variables": [ + + ] + }, + "new": false + }, + { + "id": "Issues_GithubManager", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "623762992e5d3f189d0c3c23_62389d692d7f921bb707cf51", + "unpublishedCollection": { + "name": "GithubManager", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\tgetLabels: () => {\n\t\treturn fetch_labels.data.body.items.filter((label) => {\n\t\t\treturn !label.name.includes('Pod');\n\t\t}).map((item) => {\n\t\t\treturn { label: item.name, value: item.name } \n\t\t}); \n\t}, \n\tgetIssues: () => {\n\t\treturn search_github_issues.data.map((item) => {\n\t\t\treturn {\n\t\t\t\tlabel: item.title,\n\t\t\t\tvalue: item.id + \"\"\n\t\t\t}\n\t\t})\n\t},\n\tgetSelectedGithubIssue: () => {\n\t\treturn search_github_issues.data.find((issue) => issue.id == add_issue_select.selectedOptionValue);\n\t}\n}", + "variables": [ + + ] + }, + "publishedCollection": { + "name": "GithubManager", + "pageId": "Issues", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [ + + ], + "archivedActionIds": [ + + ], + "actions": [ + + ], + "archivedActions": [ + + ], + "body": "export default {\n\tgetLabels: () => {\n\t\treturn fetch_labels.data.body.items.filter((label) => {\n\t\t\treturn !label.name.includes('Pod');\n\t\t}).map((item) => {\n\t\t\treturn { label: item.name, value: item.name } \n\t\t}); \n\t}, \n\tgetIssues: () => {\n\t\treturn search_github_issues.data.map((item) => {\n\t\t\treturn {\n\t\t\t\tlabel: item.title,\n\t\t\t\tvalue: item.id + \"\"\n\t\t\t}\n\t\t})\n\t},\n\tgetSelectedGithubIssue: () => {\n\t\treturn search_github_issues.data.find((issue) => issue.id == add_issue_select.selectedOptionValue);\n\t}\n}", + "variables": [ + + ] + }, + "new": false + } + ], + "invisibleActionFields": { + "Issues_Utils.getConfig": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_IssueManager.fetchIssues": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_Utils.checkIsPod": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_IssueManager.create_issue": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_GithubManager.getSelectedGithubIssue": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_GithubManager.getIssues": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_fetch_label_config": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_fetch_comments": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_fetch_labels": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_IssueManager.getAssignedLabels": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_update_issue_labels": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_Utils.csvToArr": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_update_issue": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_IssueManager.addComment": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_IssueManager.update": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_Utils.getLabelsForPod": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_Utils.getPodForLabel": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_search_github_issues": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_IssueManager.delete": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_IssueManager.getIssueData": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_GithubManager.getLabels": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_fetch_issues": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_add_new_comment": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_delete_issue": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_add_new_issue": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_Utils.getPodLabels": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + }, + "Issues_Configs.getTitleState": { + "unpublishedUserSetOnLoad": false, + "publishedUserSetOnLoad": false + } + }, + "editModeTheme": { + "name": "Classic", + "displayName": "Classic", + "new": true, + "isSystemTheme": true + }, + "publishedTheme": { + "name": "Classic", + "displayName": "Classic", + "new": true, + "isSystemTheme": true + }, + "publishedLayoutmongoEscapedWidgets": { + }, + "unpublishedLayoutmongoEscapedWidgets": { + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/ConcreteHouse.jpg b/app/client/cypress/fixtures/ConcreteHouse.jpg new file mode 100644 index 0000000000..73b8f51d18 Binary files /dev/null and b/app/client/cypress/fixtures/ConcreteHouse.jpg differ diff --git a/app/client/cypress/fixtures/apiParallelDsl.json b/app/client/cypress/fixtures/apiParallelDsl.json index 99aa0de135..350ab8d81c 100644 --- a/app/client/cypress/fixtures/apiParallelDsl.json +++ b/app/client/cypress/fixtures/apiParallelDsl.json @@ -2,91 +2,713 @@ "dsl": { "widgetName": "MainContainer", "backgroundColor": "none", - "rightColumn": 776, + "rightColumn": 647, "snapColumns": 64, "detachFromLayout": true, "widgetId": "0", "topRow": 0, - "bottomRow": 1290, + "bottomRow": 1070, "containerStyle": "none", - "snapRows": 125, + "snapRows": 104, "parentRowSpace": 1, "type": "CANVAS_WIDGET", "canExtend": true, - "version": 46, - "minHeight": 1292, + "version": 53, + "minHeight": 1050, "parentColumnSpace": 1, - "dynamicBindingPathList": [ - - ], + "dynamicBindingPathList": [], "leftColumn": 0, "children": [ { - "widgetName": "Button1", - "onClick": "{{CatImage.run();\nCatFacts.run();\nDogImage.run();\nDogFacts.run();}}", - "buttonColor": "#03B365", - "dynamicPropertyPathList": [ + "template": { + "Image1Copy": { + "widgetName": "Image1Copy", + "displayName": "Image", + "iconSVG": "/static/media/icon.52d8fb96.svg", + "topRow": 1, + "bottomRow": 19, + "parentRowSpace": 10, + "type": "IMAGE_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 10.935302734375, + "dynamicTriggerPathList": [], + "imageShape": "RECTANGLE", + "leftColumn": 1, + "dynamicBindingPathList": [ + { + "key": "image" + } + ], + "defaultImage": "https://assets.appsmith.com/widgets/default.png", + "key": "k7gqsx8va7", + "image": "{{List1.listData.map((currentItem) => currentItem.image)}}", + "rightColumn": 13, + "objectFit": "contain", + "widgetId": "6xs9n3qas8", + "logBlackList": { + "isVisible": true, + "defaultImage": true, + "imageShape": true, + "maxZoomLevel": true, + "enableRotation": true, + "enableDownload": true, + "objectFit": true, + "image": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1, + "parentId": "ukkqmnxanx", + "renderMode": "CANVAS", + "isLoading": false, + "maxZoomLevel": 1, + "enableDownload": false, + "enableRotation": false + }, + "Canvas1": { + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0, + "bottomRow": 390, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "dropDisabled": true, + "openParentPropertyPane": true, + "minHeight": 400, + "noPad": true, + "parentColumnSpace": 1, + "leftColumn": 0, + "children": [ + "mno4dkclkn" + ], + "key": "st5e69fis5", + "rightColumn": 472.125, + "detachFromLayout": true, + "widgetId": "i7op8tv8mv", + "containerStyle": "none", + "isVisible": true, + "version": 1, + "parentId": "lkyh2v8k8s", + "renderMode": "CANVAS", + "isLoading": false + }, + "Container1": { + "boxShadow": "NONE", + "widgetName": "Container1", + "borderColor": "transparent", + "disallowCopy": true, + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3.svg", + "topRow": 0, + "bottomRow": 22, + "dragDisabled": true, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "openParentPropertyPane": true, + "isDeletable": false, + "animateLoading": true, + "leftColumn": 0, + "children": [ + "ukkqmnxanx" + ], + "borderWidth": "0", + "key": "c509lus1x5", + "disablePropertyPane": true, + "backgroundColor": "white", + "rightColumn": 64, + "widgetId": "mno4dkclkn", + "containerStyle": "card", + "isVisible": true, + "version": 1, + "parentId": "i7op8tv8mv", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "0" + }, + "Canvas2": { + "widgetName": "Canvas2", + "detachFromLayout": true, + "displayName": "Canvas", + "widgetId": "ukkqmnxanx", + "containerStyle": "none", + "topRow": 0, + "bottomRow": 210, + "parentRowSpace": 1, + "isVisible": true, + "type": "CANVAS_WIDGET", + "canExtend": false, + "version": 1, + "hideCard": true, + "parentId": "mno4dkclkn", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 1, + "leftColumn": 0, + "children": [ + "6xs9n3qas8", + "ii4kp8uzl9", + "bx88oni4aa" + ], + "key": "st5e69fis5" + }, + "Text1": { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 1, + "bottomRow": 5, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 10.935302734375, + "dynamicTriggerPathList": [], + "leftColumn": 14, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "{{List1.listData.map((currentItem) => 'Drink Name: ' + currentItem.name)}}", + "key": "pwuql7fds3", + "rightColumn": 40, + "textAlign": "LEFT", + "widgetId": "ii4kp8uzl9", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "truncateButtonColor": true, + "widgetName": true, + "shouldScroll": true, + "shouldTruncate": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1, + "parentId": "ukkqmnxanx", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + "Text2": { + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 5, + "bottomRow": 19, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 10.935302734375, + "dynamicTriggerPathList": [], + "leftColumn": 14, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "{{List1.listData.map((currentItem) => currentItem.instruction)}}", + "key": "pwuql7fds3", + "rightColumn": 62, + "textAlign": "LEFT", + "widgetId": "bx88oni4aa", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "truncateButtonColor": true, + "widgetName": true, + "shouldScroll": true, + "shouldTruncate": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1, + "parentId": "ukkqmnxanx", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + } + }, + "widgetName": "List1", + "listData": "{{CocktailDB.data.drinks.map(item => {\n\treturn {\n\t\timage: item.strDrinkThumb,\n\t\tname: item.strDrink,\n\t\tinstruction: item.strInstructions\n\t}\n})}}", + "isCanvas": true, + "displayName": "List", + "iconSVG": "/static/media/icon.9925ee17.svg", + "topRow": 29, + "bottomRow": 104, + "parentRowSpace": 10, + "type": "LIST_WIDGET", + "hideCard": false, + "gridGap": 0, + "animateLoading": true, + "parentColumnSpace": 19.671875, + "dynamicTriggerPathList": [], + "leftColumn": 12, + "dynamicBindingPathList": [ { - "key": "onClick" + "key": "template.Text1.text" + }, + { + "key": "listData" + }, + { + "key": "template.Image1Copy.image" + }, + { + "key": "template.Text2.text" + }, + { + "key": "template.Image1Copy.image" + }, + { + "key": "template.Text1.text" + }, + { + "key": "template.Text2.text" } ], + "gridType": "vertical", + "enhancements": true, + "children": [ + { + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0, + "bottomRow": 390, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "dropDisabled": true, + "openParentPropertyPane": true, + "minHeight": 400, + "noPad": true, + "parentColumnSpace": 1, + "leftColumn": 0, + "children": [ + { + "boxShadow": "NONE", + "widgetName": "Container1", + "borderColor": "transparent", + "disallowCopy": true, + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3.svg", + "topRow": 0, + "bottomRow": 22, + "dragDisabled": true, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "openParentPropertyPane": true, + "isDeletable": false, + "animateLoading": true, + "leftColumn": 0, + "children": [ + { + "widgetName": "Canvas2", + "detachFromLayout": true, + "displayName": "Canvas", + "widgetId": "ukkqmnxanx", + "containerStyle": "none", + "topRow": 0, + "bottomRow": 210, + "parentRowSpace": 1, + "isVisible": true, + "type": "CANVAS_WIDGET", + "canExtend": false, + "version": 1, + "hideCard": true, + "parentId": "mno4dkclkn", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 1, + "leftColumn": 0, + "children": [ + { + "widgetName": "Image1Copy", + "displayName": "Image", + "iconSVG": "/static/media/icon.52d8fb96.svg", + "topRow": 1, + "bottomRow": 19, + "parentRowSpace": 10, + "type": "IMAGE_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 10.935302734375, + "dynamicTriggerPathList": [], + "imageShape": "RECTANGLE", + "leftColumn": 1, + "dynamicBindingPathList": [ + { + "key": "image" + } + ], + "defaultImage": "https://assets.appsmith.com/widgets/default.png", + "key": "k7gqsx8va7", + "image": "{{currentItem.image}}", + "rightColumn": 13, + "objectFit": "contain", + "widgetId": "6xs9n3qas8", + "logBlackList": { + "isVisible": true, + "defaultImage": true, + "imageShape": true, + "maxZoomLevel": true, + "enableRotation": true, + "enableDownload": true, + "objectFit": true, + "image": true, + "widgetName": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "version": 1, + "parentId": "ukkqmnxanx", + "renderMode": "CANVAS", + "isLoading": false, + "maxZoomLevel": 1, + "enableDownload": false, + "enableRotation": false + }, + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 1, + "bottomRow": 5, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 10.935302734375, + "dynamicTriggerPathList": [], + "leftColumn": 14, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "Drink Name: {{currentItem.name}}", + "key": "pwuql7fds3", + "rightColumn": 40, + "textAlign": "LEFT", + "widgetId": "ii4kp8uzl9", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "truncateButtonColor": true, + "widgetName": true, + "shouldScroll": true, + "shouldTruncate": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1, + "parentId": "ukkqmnxanx", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 5, + "bottomRow": 19, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 10.935302734375, + "dynamicTriggerPathList": [], + "leftColumn": 14, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "{{currentItem.instruction}}", + "key": "pwuql7fds3", + "rightColumn": 62, + "textAlign": "LEFT", + "widgetId": "bx88oni4aa", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "truncateButtonColor": true, + "widgetName": true, + "shouldScroll": true, + "shouldTruncate": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1, + "parentId": "ukkqmnxanx", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + } + ], + "key": "st5e69fis5" + } + ], + "borderWidth": "0", + "key": "c509lus1x5", + "disablePropertyPane": true, + "backgroundColor": "white", + "rightColumn": 64, + "widgetId": "mno4dkclkn", + "containerStyle": "card", + "isVisible": true, + "version": 1, + "parentId": "i7op8tv8mv", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "0" + } + ], + "key": "st5e69fis5", + "rightColumn": 472.125, + "detachFromLayout": true, + "widgetId": "i7op8tv8mv", + "containerStyle": "none", + "isVisible": true, + "version": 1, + "parentId": "lkyh2v8k8s", + "renderMode": "CANVAS", + "isLoading": false + } + ], + "privateWidgets": { + "Image1Copy": true, + "Text1": true, + "Text2": true + }, + "key": "zh4de7als8", + "backgroundColor": "transparent", + "rightColumn": 53, + "itemBackgroundColor": "#FFFFFF", + "widgetId": "lkyh2v8k8s", + "isVisible": true, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false + }, + { + "widgetName": "Button1", + "buttonColor": "#03B365", "displayName": "Button", "iconSVG": "/static/media/icon.cca02633.svg", - "topRow": 18, - "bottomRow": 22, + "topRow": 3, + "bottomRow": 7, "parentRowSpace": 10, "type": "BUTTON_WIDGET", "hideCard": false, - "parentColumnSpace": 16.921875, + "animateLoading": true, + "parentColumnSpace": 19.671875, "dynamicTriggerPathList": [ { "key": "onClick" } ], - "leftColumn": 24, - "dynamicBindingPathList": [ - - ], - "text": "Get Facts!", + "leftColumn": 25, + "dynamicBindingPathList": [], + "text": "Invoke APIs!", "isDisabled": false, - "key": "lys38w8oo5", - "rightColumn": 40, + "key": "f4fix3idzp", + "rightColumn": 41, "isDefaultClickDisabled": true, - "widgetId": "4q03mtvedv", - "recaptchaV2": false, + "widgetId": "c552h69exh", "isVisible": true, + "recaptchaType": "V3", "version": 1, "parentId": "0", "renderMode": "CANVAS", "isLoading": false, - "buttonVariant": "PRIMARY" + "buttonVariant": "PRIMARY", + "placement": "CENTER", + "onClick": "{{CatImage.run();\nDogImage.run();\nNumberFact.run();\nCocktailDB.run()}}", + "dynamicPropertyPathList": [ + { + "key": "onClick" + } + ] }, { "widgetName": "Image1", "displayName": "Image", "iconSVG": "/static/media/icon.52d8fb96.svg", - "topRow": 24, - "bottomRow": 41, + "topRow": 9, + "bottomRow": 28, "parentRowSpace": 10, "type": "IMAGE_WIDGET", "hideCard": false, - "parentColumnSpace": 16.921875, - "dynamicTriggerPathList": [ - - ], + "animateLoading": true, + "parentColumnSpace": 19.671875, + "dynamicTriggerPathList": [], "imageShape": "RECTANGLE", - "leftColumn": 11, + "leftColumn": 12, "dynamicBindingPathList": [ { "key": "image" } ], "defaultImage": "https://assets.appsmith.com/widgets/default.png", - "key": "khcxwti5gq", + "key": "k7gqsx8va7", "image": "{{CatImage.data[0].url}}", - "rightColumn": 31, - "objectFit": "cover", - "widgetId": "t9b2aacss5", + "rightColumn": 24, + "objectFit": "contain", + "widgetId": "14dy28sgfl", "isVisible": true, "version": 1, "parentId": "0", @@ -100,28 +722,27 @@ "widgetName": "Image2", "displayName": "Image", "iconSVG": "/static/media/icon.52d8fb96.svg", - "topRow": 24, - "bottomRow": 41, + "topRow": 9, + "bottomRow": 28, "parentRowSpace": 10, "type": "IMAGE_WIDGET", "hideCard": false, - "parentColumnSpace": 16.921875, - "dynamicTriggerPathList": [ - - ], + "animateLoading": true, + "parentColumnSpace": 19.671875, + "dynamicTriggerPathList": [], "imageShape": "RECTANGLE", - "leftColumn": 33, + "leftColumn": 25, "dynamicBindingPathList": [ { "key": "image" } ], "defaultImage": "https://assets.appsmith.com/widgets/default.png", - "key": "khcxwti5gq", + "key": "k7gqsx8va7", "image": "{{DogImage.data.message}}", - "rightColumn": 54, - "objectFit": "cover", - "widgetId": "v4iy6l1z9x", + "rightColumn": 37, + "objectFit": "contain", + "widgetId": "ctl1a3f5iq", "isVisible": true, "version": 1, "parentId": "0", @@ -132,65 +753,34 @@ "enableRotation": false }, { - "widgetName": "Text1", + "widgetName": "Text3", "displayName": "Text", "iconSVG": "/static/media/icon.97c59b52.svg", - "topRow": 45, - "bottomRow": 65, + "topRow": 9, + "bottomRow": 28, "parentRowSpace": 10, "type": "TEXT_WIDGET", "hideCard": false, - "parentColumnSpace": 16.921875, - "dynamicTriggerPathList": [ - - ], - "leftColumn": 6, + "animateLoading": true, + "parentColumnSpace": 19.671875, + "dynamicTriggerPathList": [], + "leftColumn": 38, "dynamicBindingPathList": [ { "key": "text" } ], - "text": "{{CatFacts.data.text}}", - "key": "7tipkwe4lq", - "rightColumn": 31, + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "Number fact for you: {{NumberFact.data}}", + "key": "pwuql7fds3", + "rightColumn": 53, "textAlign": "CENTER", - "widgetId": "d5shcrpvxp", + "widgetId": "mvtnucnzf7", "isVisible": true, - "fontStyle": "ITALIC,BOLD", - "textColor": "#231F20", - "version": 1, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "fontSize": "PARAGRAPH" - }, - { - "widgetName": "Text2", - "displayName": "Text", - "iconSVG": "/static/media/icon.97c59b52.svg", - "topRow": 45, - "bottomRow": 65, - "parentRowSpace": 10, - "type": "TEXT_WIDGET", - "hideCard": false, - "parentColumnSpace": 16.921875, - "dynamicTriggerPathList": [ - - ], - "leftColumn": 33, - "dynamicBindingPathList": [ - { - "key": "text" - } - ], - "text": "{{DogFacts.data.text}}", - "key": "7tipkwe4lq", - "rightColumn": 59, - "textAlign": "CENTER", - "widgetId": "sqllxxccb7", - "isVisible": true, - "fontStyle": "BOLD,ITALIC", + "fontStyle": "BOLD", "textColor": "#231F20", + "shouldScroll": false, "version": 1, "parentId": "0", "renderMode": "CANVAS", diff --git a/app/client/cypress/fixtures/datasources.json b/app/client/cypress/fixtures/datasources.json index 8c92bd6cbe..a1eb147212 100644 --- a/app/client/cypress/fixtures/datasources.json +++ b/app/client/cypress/fixtures/datasources.json @@ -46,4 +46,4 @@ "mockDatabasePassword": "LimitedAccess123#", "readonly":"readonly", "authenticatedApiUrl": "https://fakeapi.com" -} +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/listwidgetdsl.json b/app/client/cypress/fixtures/listwidgetdsl.json index f34952103f..f568a4c832 100644 --- a/app/client/cypress/fixtures/listwidgetdsl.json +++ b/app/client/cypress/fixtures/listwidgetdsl.json @@ -172,7 +172,7 @@ "type": "LIST_WIDGET", "isLoading": false, "parentColumnSpace": 57.875, - "parentRowSpace": 10, + "parentRowSpace": 40, "leftColumn": 4, "rightColumn": 12, "topRow": 2, diff --git a/app/client/cypress/fixtures/multiPartFormDataDsl.json b/app/client/cypress/fixtures/multiPartFormDataDsl.json new file mode 100644 index 0000000000..948bcfeb9b --- /dev/null +++ b/app/client/cypress/fixtures/multiPartFormDataDsl.json @@ -0,0 +1,93 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 539, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1320, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 53, + "minHeight": 1292, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "FilePicker1", + "dynamicPropertyPathList": [], + "displayName": "FilePicker", + "iconSVG": "/static/media/icon.7c5ad9c3.svg", + "topRow": 19, + "bottomRow": 23, + "parentRowSpace": 10, + "allowedFileTypes": [], + "type": "FILE_PICKER_WIDGET_V2", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 16.921875, + "dynamicTriggerPathList": [ + { + "key": "onFilesSelected" + } + ], + "leftColumn": 24, + "dynamicBindingPathList": [], + "isDisabled": false, + "key": "p3l7kkj73w", + "onFilesSelected": "", + "isRequired": false, + "rightColumn": 40, + "isDefaultClickDisabled": true, + "widgetId": "fa9qrs8i86", + "isVisible": true, + "label": "Select Files", + "maxFileSize": 5, + "version": 1, + "fileDataType": "Base64", + "parentId": "0", + "selectedFiles": [], + "renderMode": "CANVAS", + "isLoading": false, + "files": [], + "maxNumFiles": 1 + }, + { + "widgetName": "Image1", + "displayName": "Image", + "iconSVG": "/static/media/icon.52d8fb96.svg", + "topRow": 26, + "bottomRow": 71, + "parentRowSpace": 10, + "type": "IMAGE_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 16.921875, + "dynamicTriggerPathList": [], + "imageShape": "RECTANGLE", + "leftColumn": 18, + "dynamicBindingPathList": [], + "defaultImage": "", + "key": "tfm5uqw4f4", + "image": "", + "rightColumn": 46, + "objectFit": "contain", + "widgetId": "m59cig84vv", + "isVisible": true, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "maxZoomLevel": 1, + "enableDownload": false, + "enableRotation": false + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/testdata.json b/app/client/cypress/fixtures/testdata.json index f857b9b246..74ab4b92dd 100644 --- a/app/client/cypress/fixtures/testdata.json +++ b/app/client/cypress/fixtures/testdata.json @@ -137,5 +137,9 @@ "apiContentTypeForm": "tab--FORM_URLENCODED", "apiContentTypeMultiPart": "tab--MULTIPART_FORM_DATA", "noBodyErrorMessageDiv": "#NoBodyMessageDiv", - "noBodyErrorMessage": "This request does not have a body" + "noBodyErrorMessage": "This request does not have a body", + "v2Key": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI", + "v3Key": "6LcnzQgfAAAAAMwMlQLppqx7STvZ6pZJoDMXti8k", + "invalidKey": "abc123", + "errorMsg": "Google Re-Captcha token generation failed! Please check the Re-captcha site key." } diff --git a/app/client/cypress/index.ts b/app/client/cypress/index.ts index 28696d4f7d..c891a3cb4b 100644 --- a/app/client/cypress/index.ts +++ b/app/client/cypress/index.ts @@ -1,4 +1,5 @@ import "cypress-xpath"; +import "cypress-file-upload"; // data: string; // cy.fixture("example").then(function (data) { diff --git a/app/client/cypress/integration/Smoke_TestSuite/Application/AForceMigration_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/Application/AForceMigration_Spec.ts new file mode 100644 index 0000000000..113008cea3 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/Application/AForceMigration_Spec.ts @@ -0,0 +1,564 @@ +/// +import { ObjectsRegistry } from "../../../support/Objects/Registry"; + +let homePage = ObjectsRegistry.HomePage, + dataSources = ObjectsRegistry.DataSources, + table = ObjectsRegistry.Table, + agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor; + +describe("AForce - Community Issues page validations", function () { + + let reconnect = true, selectedRow: number; + it("1. Import application json and validate headers", () => { + + homePage.ImportApp("AForceMigrationExport.json", reconnect) + if (reconnect) + dataSources.ReconnectDataSourcePostgres("AForceDB") + //Validate table is not empty! + table.WaitUntilTableLoad() + //Validating order of header columns! + table.AssertTableHeaderOrder("TypeTitleStatus+1CommentorsVotesAnswerUpVoteStatesupvote_ididgithub_issue_idauthorcreated_atdescriptionlabelsstatelinkupdated_at") + //Validating hidden columns: + table.AssertHiddenColumns(['States', 'upvote_id', 'id', 'github_issue_id', 'author', 'created_at', 'description', 'labels', 'state', 'link', 'updated_at']) + + }); + + it("2. Validate table navigation with Server Side pagination enabled with Default selected row", () => { + ee.expandCollapseEntity("WIDGETS") + ee.SelectEntityByName("Table1") + agHelper.AssertExistingToggleState("serversidepagination", 'checked') + + agHelper.EvaluateExistingPropertyFieldValue("Default Selected Row") + .then($selectedRow => { + selectedRow = Number($selectedRow); + table.AssertSelectedRow(selectedRow) + }); + + agHelper.DeployApp() + table.WaitUntilTableLoad() + + //Verify hidden columns are infact hidden in deployed app! + table.AssertTableHeaderOrder("TypeTitleStatus+1CommentorsVotesAnswerUpVote")//from case #1 + + table.AssertSelectedRow(selectedRow)//Assert default selected row + + table.AssertPageNumber(1); + table.NavigateToNextPage()//page 2 + agHelper.Sleep(3000)//wait for table navigation to take effect! + table.WaitUntilTableLoad() + table.AssertSelectedRow(selectedRow) + + + table.NavigateToNextPage()//page 3 + agHelper.Sleep(3000)//wait for table navigation to take effect! + table.WaitForTableEmpty()//page 3 + table.NavigateToPreviousPage()//page 2 + agHelper.Sleep(3000)//wait for table navigation to take effect! + table.WaitUntilTableLoad() + table.AssertSelectedRow(selectedRow) + + table.NavigateToPreviousPage()//page 1 + agHelper.Sleep(3000)//wait for table navigation to take effect! + table.WaitUntilTableLoad() + table.AssertSelectedRow(selectedRow) + table.AssertPageNumber(1); + + }) + + it("3. Validate table navigation with Server Side pagination disabled with Default selected row selection", () => { + + agHelper.NavigateBacktoEditor() + table.WaitUntilTableLoad() + ee.expandCollapseEntity("WIDGETS") + ee.SelectEntityByName("Table1") + agHelper.ToggleOnOrOff('serversidepagination', 'Off') + agHelper.DeployApp() + table.WaitUntilTableLoad() + table.AssertPageNumber(1, 'Off'); + table.AssertSelectedRow(selectedRow) + agHelper.NavigateBacktoEditor() + table.WaitUntilTableLoad() + ee.SelectEntityByName("Table1") + agHelper.ToggleOnOrOff('serversidepagination', 'On') + + }); + + it("4. Change Default selected row in table and verify", () => { + + jsEditor.EnterJSContext("defaultselectedrow", "1", true) + agHelper.DeployApp() + table.WaitUntilTableLoad() + table.AssertPageNumber(1); + table.AssertSelectedRow(1) + table.NavigateToNextPage()//page 2 + table.AssertPageNumber(2); + table.AssertSelectedRow(1) + agHelper.NavigateBacktoEditor() + table.WaitUntilTableLoad() + + }); + + // it("4. Verify Default search text in table as per 'Default Search Text' property set", () => { + + // }); + + // it.skip("5. Validate Search table with Client Side Search enabled & disabled", () => { + + // }) + + // it.skip("6. Validate Filter table", () => { + + // }) + + // it.skip("7. Validate Filter table", () => { + + // }) + + // it.skip("8. Validate Updating issue from Details tab", () => { + + // }) + + // it.skip("9. Validate Adding a New issue from Add Modal", () => { + + + // }) + + // it.skip("10. Validate Deleting the newly created issue", () => { + + + // //Validating Id column sorting happens as Datatype is Number in app! + // cy.xpath( + // "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='id']", + // ) + // .click() + // .wait(2000); + + // cy.readTabledataPublish("0", "1").then((cellData) => { + // expect(cellData).to.be.equal("100"); + // }); + + // cy.readTabledataPublish("1", "1").then((cellData) => { + // expect(cellData).to.be.equal("99"); + // }); + + // cy.readTabledataPublish("2", "1").then((cellData) => { + // expect(cellData).to.be.equal("98"); + // }); + + // //Revert the Id column sorting! + // cy.xpath( + // "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='id']", + // ) + // .click() + // .wait(2000); + + // cy.readTabledataPublish("0", "1").then((cellData) => { + // expect(cellData).to.be.equal("1"); + // }); + + // cy.readTabledataPublish("1", "1").then((cellData) => { + // expect(cellData).to.be.equal("2"); + // }); + + // cy.readTabledataPublish("2", "1").then((cellData) => { + // expect(cellData).to.be.equal("3"); + // }); + + // //Validating image column is present: + // cy.getTableDataSelector("0", "10").then((selector) => { + // cy.get(selector + " div") + // .invoke("attr", "class") + // .then((classes) => { + // cy.log("classes are:" + classes); + // expect(classes).to.eq("image-cell"); + // }); + // }); + + // //Card Number mapping to text widget! + // cy.isSelectRow(2); + // cy.wait(2500); //time for table row select to reflect! + // cy.readTabledataPublish("2", "0").then((cardNumber) => { + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]") + // .eq(1) + // .invoke("text") + // .then((cardNo) => { + // var format = /^\d{4}-\d{4}-\d{4}(-\d{4})?$/; + // expect(cardNumber).match(format); + // expect(cardNumber).to.be.equal(cardNo); + // }); + // }); + + // //Address mapping to text widget! + // cy.readTabledataPublish("2", "4").then((address) => { + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") + // .eq(1) + // .invoke("text") + // .then((addr) => { + // expect(address.replace(/\r?\n|\r/, "")).to.eq(addr); + // }); + // }); + + // //Validating Available limit column computation maintained! + // cy.readTabledataPublish("2", "16").then((availLimit) => { + // cy.readTabledataPublish("2", "13").then((creditLimit) => { + // cy.readTabledataPublish("2", "14").then((outstanding) => { + // expect(Number(availLimit)).to.eq(creditLimit - outstanding); + // }); + // }); + // }); + + // //Validating State button click & binding & text widget mapping! + // cy.getTableDataSelector("2", "15").then((selector) => { + // cy.get(selector + " button.bp3-button") + // .click() + // .wait(3000); + + // cy.waitUntil( + // () => + // cy + // .xpath("//div[contains(@class, ' t--widget-textwidget')][2]", { + // timeout: 30000, + // }) + // .eq(0) + // .should("contain.text", "State:"), + // { + // errorMsg: "Execute call did not complete evn after 10 secs", + // timeout: 20000, + // interval: 1000, + // }, + // ).then(() => cy.wait(500)); + + // cy.get(selector + " button span") + // .invoke("text") + // .then((statetxt) => { + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") + // .eq(0) + // .invoke("text") + // .then((txtWidtxt) => { + // cy.log("statetxt is:" + statetxt); + // let text = + // statetxt == "Activate" ? "State:Inactive" : "State:Active"; + // expect(text).to.eq(txtWidtxt); + // }); + // }); + // }); + + // //Validating Image URL click & navigation! + // cy.getTableDataSelector("2", "19").then((selector) => { + // // Stubbing window.open to open in the same tab + // cy.window().then((window) => { + // cy.stub(window, "open").callsFake((url) => { + // window.location.href = url; //.substring(1); + // window.location.target = "_self"; + // }); + // }); + + // cy.get(selector + " span.bp3-popover-target span") + // .invoke("text") + // .then((url) => { + // cy.get(selector + " span.bp3-popover-target") + // .click() + // .wait(2000); + // cy.wait("@postExecute"); + // cy.url().should("contain", url); + // cy.go(-1); + // }); + // }); + + // // cy.wait(4000); + // // cy.get("div.tableWrap").should("be.visible"); //wait for page load! + + // cy.waitUntil( + // () => cy.get("div.tableWrap", { timeout: 30000 }).should("be.visible"), + // { + // errorMsg: "Page is not loaded evn after 10 secs", + // timeout: 30000, + // interval: 2000, + // }, + // ).then(() => cy.wait(1000)); //wait for page load! + + // cy.isSelectRow(2); //as aft refresh row selection is also gone + // cy.getTableDataSelector("2", "18").then((selector) => { + // cy.get(selector + " button") + // .click() + // .wait(1000); + + // cy.xpath( + // "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='AddcreditLimit']/parent::a", + // ) + // .click() + // .wait(2000); + + // cy.waitUntil( + // () => + // cy + // .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .should("contain.text", "CreditLimit:"), + // { + // errorMsg: "Execute call did not complete evn after 10 secs", + // timeout: 20000, + // interval: 1000, + // }, + // ).then(() => cy.wait(500)); //allow time for n/w to finish + + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .invoke("text") + // .then((addreduce) => { + // expect(addreduce).to.eq("CreditLimit:Add"); + // }); + // }); + + // //Manu Btn validation: - 2nd menu item + // cy.getTableDataSelector("2", "18").then((selector) => { + // cy.get(selector + " button") + // .click() + // .wait(1000); + + // cy.xpath( + // "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='Reducecreditlimit']/parent::a", + // ) + // .click() + // .wait(2000); + + // cy.waitUntil( + // () => + // cy + // .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .should("contain.text", "CreditLimit:"), + // { + // errorMsg: "Execute call did not complete evn after 10 secs", + // timeout: 20000, + // interval: 1000, + // }, + // ).then(() => cy.wait(500)); //allow time for n/w to finish + + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .invoke("text") + // .then((addreduce) => { + // expect(addreduce).to.eq("CreditLimit:Reduce"); + // }); + // }); + + // //Another row! + // //Card Number mapping to text widget! + // cy.isSelectRow(4); + // cy.wait(2500); //time for table row select to reflect! + // cy.readTabledataPublish("4", "0").then((cardNumber) => { + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]") + // .eq(1) + // .invoke("text") + // .then((cardNo) => { + // var format = /^\d{4}-\d{4}-\d{4}(-\d{4})?$/; + // expect(cardNumber).match(format); + // expect(cardNumber).to.be.equal(cardNo); + // }); + // }); + + // //Address mapping to text widget! + // cy.readTabledataPublish("4", "4").then((address) => { + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") + // .eq(1) + // .invoke("text") + // .then((addr) => { + // expect(address.replace(/\r?\n|\r/, "")).to.eq(addr); + // }); + // }); + + // //Validating Available limit column computation maintained! + // cy.readTabledataPublish("4", "16").then((availLimit) => { + // cy.readTabledataPublish("4", "13").then((creditLimit) => { + // cy.readTabledataPublish("4", "14").then((outstanding) => { + // expect(Number(availLimit)).to.eq(creditLimit - outstanding); + // }); + // }); + // }); + + // //Validating State button click & binding & text widget mapping! + // cy.getTableDataSelector("4", "15").then((selector) => { + // cy.get(selector + " button.bp3-button") + // .click() + // .wait(2000); + + // cy.waitUntil( + // () => + // cy + // .xpath("//div[contains(@class, ' t--widget-textwidget')][2]", { + // timeout: 30000, + // }) + // .eq(0) + // .should("contain.text", "State:"), + // { + // errorMsg: "Execute call did not complete evn after 10 secs", + // timeout: 20000, + // interval: 1000, + // }, + // ).then(() => cy.wait(500)); + + // cy.get(selector + " button span") + // .invoke("text") + // .then((statetxt) => { + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") + // .eq(0) + // .invoke("text") + // .then((txtWidtxt) => { + // cy.log("statetxt is:" + statetxt); + // let text = + // statetxt == "Activate" ? "State:Inactive" : "State:Active"; + // expect(text).to.eq(txtWidtxt); + // }); + // }); + // }); + + // //Validating Image URL click & navigation! + // cy.getTableDataSelector("4", "19").then((selector) => { + // // Stubbing window.open to open in the same tab + // cy.window().then((window) => { + // cy.stub(window, "open").callsFake((url) => { + // window.location.href = url; //.substring(1); + // window.location.target = "_self"; + // }); + // }); + + // cy.get(selector + " span.bp3-popover-target span") + // .invoke("text") + // .then((url) => { + // cy.get(selector + " span.bp3-popover-target") + // .click() + // .wait(2000); + // cy.wait("@postExecute"); + // cy.url().should("contain", url); + // cy.go(-1); + // }); + // }); + + // //cy.wait(4000); + // //cy.get("div.tableWrap").should("be.visible"); + + // cy.waitUntil( + // () => cy.get("div.tableWrap", { timeout: 30000 }).should("be.visible"), + // { + // errorMsg: "Page is not loaded evn after 10 secs", + // timeout: 30000, + // interval: 2000, + // }, + // ).then(() => cy.wait(1000)); //wait for page load! + + // //Manu Btn validation: - 1st menu item + // cy.isSelectRow(4); //as aft refresh row selection is also gone + // cy.getTableDataSelector("4", "18").then((selector) => { + // cy.get(selector + " button") + // .click() + // .wait(1000); + + // cy.xpath( + // "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='AddcreditLimit']/parent::a", + // ) + // .click() + // .wait(2000); //allow time for n/w to finish + + // cy.waitUntil( + // () => + // cy + // .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .should("contain.text", "CreditLimit:"), + // { + // errorMsg: "Execute call did not complete evn after 10 secs", + // timeout: 20000, + // interval: 1000, + // }, + // ).then(() => cy.wait(500)); //allow time for n/w to finish + + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .invoke("text") + // .then((addreduce) => { + // expect(addreduce).to.eq("CreditLimit:Add"); + // }); + // }); + + // //Manu Btn validation: - 2nd menu item + // cy.getTableDataSelector("4", "18").then((selector) => { + // cy.get(selector + " button") + // .click() + // .wait(1000); + + // cy.xpath( + // "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='Reducecreditlimit']/parent::a", + // ) + // .click() + // .wait(2000); //allow time for n/w to finish + + // cy.waitUntil( + // () => + // cy + // .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .should("contain.text", "CreditLimit:"), + // { + // errorMsg: "Execute call did not complete evn after 10 secs", + // timeout: 20000, + // interval: 1000, + // }, + // ).then(() => cy.wait(500)); //allow time for n/w to finish + + // cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { + // timeout: 30000, + // }) + // .eq(0) + // .invoke("text") + // .then((addreduce) => { + // expect(addreduce).to.eq("CreditLimit:Reduce"); + // }); + // }); + // }); + + // //Page 2 Validations: + + // cy.selectEntityByName("Change color and font"); + // cy.selectEntityByName("WIDGETS"); + // cy.selectEntityByName("Table1"); + + // cy.get(widgetsPage.bold) + // .invoke("attr", "aria-selected") + // .then((sel) => expect(Boolean(sel)).to.be.true); + // cy.get(widgetsPage.centerAlign) + // .eq(0) + // .invoke("attr", "aria-selected") + // .then((sel) => expect(Boolean(sel)).to.be.true); //Text align + // cy.get(widgetsPage.centerAlign) + // .eq(1) + // .invoke("attr", "aria-selected") + // .then((sel) => expect(Boolean(sel)).to.be.true); //Vertical align + // cy.get(widgetsPage.textColor) + // .first() + // .invoke("attr", "value") + // .should("contain", "#2E3D49"); + // cy.get(`${widgetsPage.cellBackground} input`) + // .first() + // .invoke("attr", "value") + // .should("contain", "#FFC13D"); + // cy.get(widgetsPage.selectedTextSize).should("have.text", "24px"); + + //}); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_all_sidebar_actions_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_ContextMenu_spec.js similarity index 64% rename from app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_all_sidebar_actions_spec.js rename to app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_ContextMenu_spec.js index cb3e4c51bb..f352d4bcea 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_all_sidebar_actions_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_ContextMenu_spec.js @@ -1,36 +1,26 @@ const commonlocators = require("../../../../locators/commonlocators.json"); const testdata = require("../../../../fixtures/testdata.json"); const apiwidget = require("../../../../locators/apiWidgetslocator.json"); -const { - AggregateHelper, -} = require("../../../../support/Pages/AggregateHelper"); -const helper = new AggregateHelper(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +let ee = ObjectsRegistry.EntityExplorer; describe("API Panel Test Functionality ", function() { it("Test API copy/Move/delete feature", function() { - cy.log("Login Successful"); cy.Createpage("SecondPage"); cy.NavigateToAPI_Panel(); - cy.log("Navigation to API Panel screen successful"); cy.CreateAPI("FirstAPI"); cy.enterDatasourceAndPath(testdata.baseUrl, "{{ '/random' }}"); - cy.log("Creation of FirstAPI Action successful"); - helper.ActionContextMenuByEntityName( - "FirstAPI", - "Copy to page", - "SecondPage", - ); + cy.assertPageSave(); + cy.get("body").click(0, 0); + ee.expandCollapseEntity("QUERIES/JS"); + ee.ActionContextMenuByEntityName("FirstAPI", "Copy to page", "SecondPage"); // click on learn how link cy.get(".t--learn-how-apis-link").click(); // this should open in a global search modal cy.get(commonlocators.globalSearchModal); cy.get("body").click(0, 0); - helper.ActionContextMenuByEntityName( - "FirstAPICopy", - "Move to page", - "Page1", - ); + ee.ActionContextMenuByEntityName("FirstAPICopy", "Move to page", "Page1"); cy.wait(2000); cy.get(".t--entity-name") .contains("FirstAPICopy") diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_MultiPart_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_MultiPart_Spec.ts new file mode 100644 index 0000000000..f60173df56 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_MultiPart_Spec.ts @@ -0,0 +1,136 @@ +import { ObjectsRegistry } from "../../../../support/Objects/Registry" + +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + apiPage = ObjectsRegistry.ApiPage, + locator = ObjectsRegistry.CommonLocators; + +describe("Validate API request body panel", () => { + it("1. Check whether input and type dropdown selector exist when multi-part is selected", () => { + apiPage.CreateApi("FirstAPI", 'POST'); + apiPage.SelectAPITab('Body') + apiPage.SelectSubTab('FORM_URLENCODED') + apiPage.CheckElementPresence(apiPage._bodyKey(0)) + apiPage.CheckElementPresence(apiPage._bodyValue(0)) + apiPage.SelectSubTab('MULTIPART_FORM_DATA') + apiPage.CheckElementPresence(apiPage._bodyKey(0)) + apiPage.CheckElementPresence(apiPage._bodyTypeDropdown) + apiPage.CheckElementPresence(apiPage._bodyValue(0)) + agHelper.ActionContextMenuWithInPane('Delete') + }); + + it("2. Checks whether No body error message is shown when None API body content type is selected", function () { + apiPage.CreateApi("FirstAPI", 'GET'); + apiPage.SelectAPITab('Body') + apiPage.SelectSubTab('NONE') + cy.get(apiPage._noBodyMessageDiv).contains(apiPage._noBodyMessage); + agHelper.ActionContextMenuWithInPane('Delete') + }); + + it("3. Checks whether header content type is being changed when FORM_URLENCODED API body content type is selected", function () { + apiPage.CreateApi("FirstAPI", 'POST'); + apiPage.ValidateHeaderParams({ + key: "content-type", + value: "application/json", + }); + apiPage.SelectAPITab('Body') + apiPage.SelectSubTab('FORM_URLENCODED') + apiPage.ValidateHeaderParams({ + key: "content-type", + value: "application/x-www-form-urlencoded", + }); + agHelper.ActionContextMenuWithInPane('Delete') + }); + + it("4. Checks whether header content type is being changed when MULTIPART_FORM_DATA API body content type is selected", function () { + apiPage.CreateApi("FirstAPI", 'POST'); + apiPage.ValidateHeaderParams({ + key: "content-type", + value: "application/json", + }); + apiPage.SelectAPITab('Body') + apiPage.SelectSubTab('MULTIPART_FORM_DATA') + apiPage.ValidateHeaderParams({ + key: "content-type", + value: "multipart/form-data", + }); + agHelper.ActionContextMenuWithInPane('Delete') + }); + + it("5. Checks whether content type 'FORM_URLENCODED' is preserved when user selects None API body content type", function () { + apiPage.CreateApi("FirstAPI", 'POST'); + apiPage.SelectAPITab('Body') + apiPage.SelectSubTab('FORM_URLENCODED') + apiPage.SelectSubTab('NONE') + apiPage.ValidateHeaderParams({ + key: "content-type", + value: "application/x-www-form-urlencoded", + }); + agHelper.ActionContextMenuWithInPane('Delete') + }); + + it("6. Checks whether content type 'MULTIPART_FORM_DATA' is preserved when user selects None API body content type", function () { + apiPage.CreateApi("FirstAPI", 'POST'); + apiPage.SelectAPITab('Body') + apiPage.SelectSubTab('MULTIPART_FORM_DATA') + apiPage.SelectSubTab('NONE') + apiPage.ValidateHeaderParams({ + key: "content-type", + value: "multipart/form-data", + }); + agHelper.ActionContextMenuWithInPane('Delete') + }); + + it("7. Checks MultiPart form data for a File Type upload", () => { + let imageNameToUpload = "ConcreteHouse.jpg"; + cy.fixture('multiPartFormDataDsl').then((val: any) => { + agHelper.AddDsl(val) + }); + + apiPage.CreateAndFillApi('https://api.cloudinary.com/v1_1/appsmithautomationcloud/image/upload?upload_preset=fbbhg4xu', 'CloudinaryUploadApi', 'POST') + apiPage.EnterBodyFormData('MULTIPART_FORM_DATA', 'file', '{{FilePicker1.files[0]}}', 'File') + + jsEditor.CreateJSObject(`export default { + myVar1: [], + myVar2: {}, + upload: async () => { + await CloudinaryUploadApi.run().then(()=> showAlert('Image uploaded to Cloudinary successfully', 'success')).catch(err => showAlert(err.message, 'error')); + await resetWidget('FilePicker1', true); + } + }`, true, true, false); + + ee.expandCollapseEntity("WIDGETS")//to expand widgets + ee.SelectEntityByName("FilePicker1"); + jsEditor.EnterJSContext('onfilesselected', `{{JSObject1.upload()}}`, true, true); + + ee.SelectEntityByName("Image1"); + jsEditor.EnterJSContext('image', '{{CloudinaryUploadApi.data.url}}') + + agHelper.ClickButton('Select Files'); + agHelper.UploadFile(imageNameToUpload) + agHelper.ValidateToastMessage("Image uploaded to Cloudinary successfully") + agHelper.Sleep() + cy.xpath(apiPage._imageSrc).find('img') + .invoke('attr', 'src').then($src => { + expect($src).not.eq("https://assets.appsmith.com/widgets/default.png") + }) + apiPage.CheckElementPresence(locator._spanButton('Select Files'))//verifying if reset! + + }); + + it("8. Checks MultiPart form data for a Array Type upload results in API error", () => { + let imageNameToUpload = "AAAFlowerVase.jpeg"; + ee.expandCollapseEntity("QUERIES/JS")//to expand widgets + ee.SelectEntityByName("CloudinaryUploadApi"); + apiPage.EnterBodyFormData('MULTIPART_FORM_DATA', 'file', '{{FilePicker1.files[0]}}', 'Array', true) + ee.SelectEntityByName("FilePicker1"); + agHelper.ClickButton('Select Files'); + agHelper.UploadFile(imageNameToUpload, false) + agHelper.ValidateToastMessage("CloudinaryUploadApi failed to execute") + apiPage.CheckElementPresence(locator._spanButton('Select Files'))//verifying if reset! + agHelper.AssertDebugError("Execution failed with status 400 BAD_REQUEST", '{"error":{"message":"Unsupported source URL: {\\"type\\":\\"image/jpeg\\"') + + }); + +}); \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_Multipart_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_Multipart_spec.js deleted file mode 100644 index 6e26458eb6..0000000000 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_Multipart_spec.js +++ /dev/null @@ -1,68 +0,0 @@ -const testdata = require("../../../../fixtures/testdata.json"); -const apiwidget = require("../../../../locators/apiWidgetslocator.json"); -import apiEditor from "../../../../locators/ApiEditor"; - -describe("API Panel request body", function() { - it("Check whether input and type dropdown selector exist when multi-part is selected", function() { - cy.NavigateToAPI_Panel(); - cy.CreateAPI("FirstAPI"); - - cy.SelectAction(testdata.postAction); - - cy.contains(apiEditor.bodyTab).click(); - cy.get(`[data-cy=${testdata.apiContentTypeForm}]`).click(); - cy.get(`[data-cy=${testdata.apiContentTypeMultiPart}]`).click(); - - cy.get(apiwidget.formEncoded).should("be.visible"); - cy.get(apiwidget.multipartTypeDropdown).should("be.visible"); - cy.DeleteAPI(); - }); - - it("Checks whether No body error message is shown when None API body content type is selected", function() { - cy.NavigateToAPI_Panel(); - cy.CreateAPI("FirstAPI"); - - cy.SelectAction(testdata.getAction); - - cy.contains(apiEditor.bodyTab).click(); - cy.get(`[data-cy=${testdata.apiContentTypeNone}]`).click(); - cy.get(testdata.noBodyErrorMessageDiv).should("exist"); - cy.get(testdata.noBodyErrorMessageDiv).contains( - testdata.noBodyErrorMessage, - ); - cy.DeleteAPI(); - }); - - it("Checks whether header content type is being changed when FORM_URLENCODED API body content type is selected", function() { - cy.NavigateToAPI_Panel(); - cy.CreateAPI("FirstAPI"); - - cy.SelectAction(testdata.postAction); - - cy.contains(apiEditor.bodyTab).click({ force: true }); - cy.get(`[data-cy=${testdata.apiContentTypeForm}]`).click(); - cy.contains(apiEditor.headersTab).click({ force: true }); - - cy.get(apiwidget.headerKey).contains(testdata.headerKey.toLowerCase()); - cy.get(apiwidget.headerValue).contains(testdata.apiFormDataHeaderValue); - - cy.DeleteAPI(); - }); - - it("Checks whether content type is preserved when user selects None API body content type", function() { - cy.NavigateToAPI_Panel(); - cy.CreateAPI("FirstAPI"); - - cy.SelectAction(testdata.postAction); - - cy.contains(apiEditor.bodyTab).click({ force: true }); - cy.get(`[data-cy=${testdata.apiContentTypeForm}]`).click({ force: true }); - cy.get(`[data-cy=${testdata.apiContentTypeNone}]`).click({ force: true }); - cy.contains(apiEditor.headersTab).click({ force: true }); - - cy.get(apiwidget.headerKey).contains(testdata.headerKey.toLowerCase()); - cy.get(apiwidget.headerValue).contains(testdata.apiFormDataHeaderValue); - - cy.DeleteAPI(); - }); -}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/BindButton_Text_WithRecaptcha_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/BindButton_Text_WithRecaptcha_spec.js index 58a27a3fdf..ae9b194ad3 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/BindButton_Text_WithRecaptcha_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/BindButton_Text_WithRecaptcha_spec.js @@ -35,4 +35,145 @@ describe("Binding the Button widget with Text widget using Recpatcha v3", functi cy.get(".t--draggable-textwidget .bp3-ui-text").should("be.visible"); cy.get(".t--draggable-textwidget .bp3-ui-text").should("have.value", ""); }); + + /* This test to be enabled once the product bug is fixed + it("Validate the Button binding with Text Widget with Recaptcha Token with invalid key before using valid key", function() { + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.testCodeMirrorLast(testdata.invalidKey) + cy.SearchEntityandOpen("Text1"); + cy.get(".t--draggable-textwidget span").last().invoke('text').then((x) => { + cy.log(x); + expect(x).to.be.empty; + }) + cy.SearchEntityandOpen("Button1"); + cy.get(".t--property-control-googlerecaptchaversion .bp3-popover-target") + .last() + .should("be.visible") + .click({ force: true }); + cy.get(".t--dropdown-option:contains('reCAPTCHA v2')").click({ + force: true, + }); + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.get(".t--toast-action span").should("have.text",testdata.errorMsg) + cy.SearchEntityandOpen("Text1"); + cy.wait(3000); + cy.get(".t--draggable-textwidget span").last().invoke('text').then((x) => { + cy.log(x); + expect(x).to.be.empty; + }) + }); +*/ + it("Validate the Button binding with Text Widget with Recaptcha Token with v2Key", function() { + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.testCodeMirrorLast(testdata.v2Key); + cy.SearchEntityandOpen("Text1"); + cy.get(".t--draggable-textwidget span") + .last() + .invoke("text") + .then((x) => { + cy.log(x); + expect(x).to.be.empty; + }); + cy.SearchEntityandOpen("Button1"); + cy.get(".t--property-control-googlerecaptchaversion .bp3-popover-target") + .last() + .should("be.visible") + .click({ force: true }); + cy.get(".t--dropdown-option:contains('reCAPTCHA v2')").click({ + force: true, + }); + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.SearchEntityandOpen("Text1"); + cy.wait(3000); + cy.get(".t--draggable-textwidget span") + .last() + .invoke("text") + .then((x) => { + cy.log(x); + expect(x).not.to.be.empty; + }); + }); + + it("Validate the Button binding with Text Widget with Recaptcha Token with v3Key", function() { + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.testCodeMirrorLast(testdata.v3Key); + cy.SearchEntityandOpen("Text1"); + cy.get(".t--draggable-textwidget span") + .last() + .invoke("text") + .then((x) => { + cy.log(x); + expect(x).not.to.be.empty; + }); + cy.SearchEntityandOpen("Button1"); + cy.get(".t--property-control-googlerecaptchaversion .bp3-popover-target") + .last() + .should("be.visible") + .click({ force: true }); + cy.get(".t--dropdown-option:contains('reCAPTCHA v2')").click({ + force: true, + }); + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.SearchEntityandOpen("Text1"); + cy.wait(3000); + cy.get(".t--draggable-textwidget span") + .last() + .invoke("text") + .then((x) => { + cy.log(x); + expect(x).not.to.be.empty; + }); + }); + + /* This test to be enabled once the product bug is fixed + + it("Validate the Button binding with Text Widget with Recaptcha Token with invalid key", function() { + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.testCodeMirrorLast(testdata.invalidKey) + cy.SearchEntityandOpen("Text1"); + cy.get(".t--draggable-textwidget span").last().invoke('text').then((x) => { + cy.log(x); + expect(x).not.to.be.empty; + }) + cy.SearchEntityandOpen("Button1"); + cy.get(".t--property-control-googlerecaptchaversion .bp3-popover-target") + .last() + .should("be.visible") + .click({ force: true }); + cy.get(".t--dropdown-option:contains('reCAPTCHA v2')").click({ + force: true, + }); + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.SearchEntityandOpen("Text1"); + cy.wait(3000); + cy.get(".t--draggable-textwidget span").last().invoke('text').then((x) => { + cy.log(x); + expect(x).not.to.be.empty; + }) + }); + */ }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts index 257ae1e40b..4ba32c21ad 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts @@ -1,10 +1,9 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry" -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const locator = new CommonLocators(); +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators; describe("Validate Create Api and Bind to Table widget via JSObject", () => { before(() => { @@ -15,9 +14,9 @@ describe("Validate Create Api and Bind to Table widget via JSObject", () => { it("1. Bind Input widget with JSObject", function () { jsEditor.CreateJSObject('return "Success";', false); - agHelper.expandCollapseEntity("WIDGETS")//to expand widgets - agHelper.expandCollapseEntity("Form1") - agHelper.SelectEntityByName("Input2") + ee.expandCollapseEntity("WIDGETS")//to expand widgets + ee.expandCollapseEntity("Form1") + ee.SelectEntityByName("Input2") cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext("defaulttext", "{{" + jsObjName + ".myFun1()}}") }); @@ -33,8 +32,8 @@ describe("Validate Create Api and Bind to Table widget via JSObject", () => { it.skip("2. Bug 10284, 11529 - Verify timeout issue with running JS Objects", function () { jsEditor.CreateJSObject('return "Success";', true); - agHelper.expandCollapseEntity("Form1") - agHelper.SelectEntityByName("Input2") + ee.expandCollapseEntity("Form1") + ee.SelectEntityByName("Input2") cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext("defaulttext", "{{" + jsObjName + ".myFun1()}}") }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToListWidget_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToListWidget_Spec.ts index ec09a87398..ca5351ea34 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToListWidget_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToListWidget_Spec.ts @@ -1,14 +1,12 @@ -import { ApiPage } from "../../../../support/Pages/ApiPage"; -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; - -const apiPage = new ApiPage(); -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const locator = new CommonLocators(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry" let dataSet: any, valueToTest: any, jsName: any; +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators, + apiPage = ObjectsRegistry.ApiPage; + describe("Validate Create Api and Bind to Table widget via JSObject", () => { before(() => { @@ -38,8 +36,8 @@ describe("Validate Create Api and Bind to Table widget via JSObject", () => { }); it("2. Validate the Api data is updated on List widget", function () { - agHelper.expandCollapseEntity("WIDGETS")//to expand widgets - agHelper.SelectEntityByName("List1"); + ee.expandCollapseEntity("WIDGETS")//to expand widgets + ee.SelectEntityByName("List1"); jsEditor.EnterJSContext("items", "{{" + jsName as string + ".myFun1()}}") cy.get(locator._textWidget).should("have.length", 8); cy.get(locator._textWidget) @@ -61,8 +59,8 @@ describe("Validate Create Api and Bind to Table widget via JSObject", () => { it("3. Validate the List widget ", function () { agHelper.NavigateBacktoEditor() - agHelper.expandCollapseEntity("WIDGETS")//to expand widgets - agHelper.SelectEntityByName("List1"); + ee.expandCollapseEntity("WIDGETS")//to expand widgets + ee.SelectEntityByName("List1"); jsEditor.EnterJSContext("itemspacing\\(px\\)", "50") cy.get(locator._textWidget).should("have.length", 6); cy.get(locator._textWidget) diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/LoadashBasic_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/LoadashBasic_Spec.ts index 4cbd75f208..9c6483ccf0 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/LoadashBasic_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/LoadashBasic_Spec.ts @@ -1,12 +1,10 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; - -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const locator = new CommonLocators(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry" let dataSet: any; +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators; describe("Loadash basic test with input Widget", () => { @@ -21,16 +19,16 @@ describe("Loadash basic test with input Widget", () => { }); it("1. Input widget test with default value for atob method", () => { - agHelper.expandCollapseEntity("WIDGETS") - agHelper.SelectEntityByName("Input1") + ee.expandCollapseEntity("WIDGETS") + ee.SelectEntityByName("Input1") jsEditor.EnterJSContext("defaulttext", dataSet.defaultInputBinding + "}}"); - agHelper.ValidateNetworkCallRespPut('@updateLayout') + agHelper.ValidateNetworkStatus('@updateLayout') }); it("2. Input widget test with default value for btoa method", function () { - agHelper.SelectEntityByName("Input2") + ee.SelectEntityByName("Input2") jsEditor.EnterJSContext("defaulttext", dataSet.loadashInput + "}}"); - agHelper.ValidateNetworkCallRespPut('@updateLayout') + agHelper.ValidateNetworkStatus('@updateLayout') }); it("3. Publish and validate the data displayed in input widgets value for aToB and bToa", function () { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/MomentBasic_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/MomentBasic_Spec.ts index 96d348542a..55e064dd5a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/MomentBasic_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/MomentBasic_Spec.ts @@ -1,12 +1,10 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; - -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const locator = new CommonLocators(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry" let dataSet: any; +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators; describe("Validate basic binding of Input widget to Input widget", () => { @@ -21,16 +19,16 @@ describe("Validate basic binding of Input widget to Input widget", () => { }); it("1. Input widget test with default value from another Input widget", () => { - agHelper.expandCollapseEntity("WIDGETS") - agHelper.SelectEntityByName("Input1") + ee.expandCollapseEntity("WIDGETS") + ee.SelectEntityByName("Input1") jsEditor.EnterJSContext("defaulttext", dataSet.defaultInputBinding + "}}"); - agHelper.ValidateNetworkCallRespPut('@updateLayout') + agHelper.ValidateNetworkStatus('@updateLayout') }); it("2. Binding second input widget with first input widget and validating", function () { - agHelper.SelectEntityByName("Input2") + ee.SelectEntityByName("Input2") jsEditor.EnterJSContext("defaulttext", dataSet.momentInput + "}}"); - agHelper.ValidateNetworkCallRespPut('@updateLayout') + agHelper.ValidateNetworkStatus('@updateLayout') }); it("3. Publish widget and validate the data displayed in input widgets", function () { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts index 611689957b..d10a93455c 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts @@ -1,12 +1,10 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; -import { ApiPage } from "../../../../support/Pages/ApiPage"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry" -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const locator = new CommonLocators(); -const apiPage = new ApiPage(); +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators, + apiPage = ObjectsRegistry.ApiPage; describe("Validate basic operations on Entity explorer JSEditor structure", () => { @@ -15,22 +13,20 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = cy.fixture('promisesBtnDsl').then((val: any) => { agHelper.AddDsl(val) }); - agHelper.expandCollapseEntity("WIDGETS")//to expand widgets - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS")//to expand widgets + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext('onclick', "{{storeValue('date', Date()).then(() => showAlert(appsmith.store.date))}}", true, true); agHelper.ClickButton('Submit') cy.log("Date is:" + date) - cy.get(locator._toastMsg) - .should("have.length", 1) - .should("contain.text", date); - }) + agHelper.ValidateToastMessage(date) + }); it("2. Verify resolve & chaining via direct Promises", () => { cy.fixture("promisesBtnDsl").then((val: any) => { agHelper.AddDsl(val); }); - agHelper.expandCollapseEntity("WIDGETS"); - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS"); + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", `{{ @@ -43,9 +39,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = }).catch(err => { showAlert(err, 'error') }); }}`, true, true); agHelper.ClickButton('Submit') - cy.get(locator._toastMsg) - .should("have.length", 1) - .should("contain.text", "We are on planet Earth"); + agHelper.ValidateToastMessage('We are on planet Earth') }); it("3. Verify Async Await in direct Promises", () => { @@ -61,8 +55,8 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = key: "name", value: "{{this.params.country}}", }); // verifies Bug 10055 - agHelper.expandCollapseEntity("WIDGETS"); - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS"); + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", `{{(async function(){ @@ -93,8 +87,8 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = "https://source.unsplash.com/collection/8439505", "Christmas", ); - agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS"); //to expand widgets + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", `{{ @@ -107,7 +101,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = true, true, ); - agHelper.SelectEntityByName("Image1"); + ee.SelectEntityByName("Image1"); jsEditor.EnterJSContext("image", `{{Christmas.data}}`, true); agHelper.WaitUntilEleDisappear( locator._toastMsg, @@ -126,15 +120,13 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = apiPage.CreateAndFillApi("https://favqs.com/api/qotd", "InspiringQuotes"); jsEditor.CreateJSObject(`const user = 'You'; return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " is " + JSON.stringify(res.quote.body), 'success') }).catch(() => showAlert("Unable to fetch quote for " + user, 'warning'))`); - agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS"); //to expand widgets + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext('onclick', "{{" + jsObjName + ".myFun1()}}", true, true); }) agHelper.ClickButton("Submit"); - cy.get(locator._toastMsg) - .should("have.length", 1) - .should("contain.text", "Today's quote for You"); + agHelper.ValidateToastMessage("Today's quote for You") }); it("6. Verify Promise.race via direct Promises", () => { @@ -143,8 +135,8 @@ return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + us }); apiPage.CreateAndFillApi("https://api.agify.io?name={{this.params.person}}", "Agify") apiPage.ValidateQueryParams({ key: "name", value: "{{this.params.person}}" }); // verifies Bug 10055 - agHelper.expandCollapseEntity("WIDGETS") - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS") + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext('onclick', `{{ Promise.race([Agify.run({ person: 'Melinda' }), Agify.run({ person: 'Trump' })]).then((res) => { showAlert('Winner is ' + JSON.stringify(res.name), 'success') }) }} `, true, true); agHelper.ClickButton('Submit') cy.get(locator._toastMsg).should("have.length", 1).contains(/Melinda|Trump/g) @@ -158,8 +150,8 @@ return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + us "https://api.jikan.moe/v3/search/anime?q={{this.params.name}}", "GetAnime", ); - agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets - agHelper.SelectEntityByName("List1"); + ee.expandCollapseEntity("WIDGETS"); //to expand widgets + ee.SelectEntityByName("List1"); jsEditor.EnterJSContext( "items", `[{ @@ -183,7 +175,7 @@ return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + us locator._toastMsg, "will be executed automatically on page load", ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", `{{ @@ -207,8 +199,8 @@ return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + us cy.fixture('promisesBtnDsl').then((val: any) => { agHelper.AddDsl(val) }); - agHelper.expandCollapseEntity("WIDGETS")//to expand widgets - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS")//to expand widgets + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext('onclick', `{{ (function () { let agifyy = []; @@ -221,7 +213,7 @@ return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + us })() }} `, true, true); agHelper.ClickButton('Submit') - cy.get(locator._toastMsg).should("have.length", 1).should("have.text", "cat,dog,camel,rabbit,rat") + agHelper.ValidateToastMessage("cat,dog,camel,rabbit,rat") }); it("9. Bug 10150: Verify Promise.all via JSObjects", () => { @@ -240,9 +232,9 @@ showAlert("Running all api's", "warning"); return Promise.all(allFuncs).then(() => showAlert("Wonderful! all apis executed", "success")).catch(() => showAlert("Please check your api's again", "error")); `) - agHelper.expandCollapseEntity("WIDGETS") + ee.expandCollapseEntity("WIDGETS") - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext('onclick', "{{storeValue('date', Date()).then(() => { showAlert(appsmith.store.date, 'success'); return " + jsObjName + ".myFun1()})}}", true, true); }); @@ -275,8 +267,8 @@ showAlert("Wonderful! all apis executed", "success")).catch(() => showAlert("Ple return Promise.any([this.func2(), this.func3(), this.func1()]).then((value) => showAlert("Resolved promise is:" + value)) } }`, true, true) - agHelper.expandCollapseEntity('WIDGETS') - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity('WIDGETS') + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext('onclick', "{{" + jsObjName + ".runAny()}}", true, true); }); @@ -291,8 +283,8 @@ showAlert("Wonderful! all apis executed", "success")).catch(() => showAlert("Ple cy.fixture("promisesBtnDsl").then((dsl: any) => { agHelper.AddDsl(dsl); }); - agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS"); //to expand widgets + ee.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", "{{resetWidget('Input1').then(() => showAlert(Input1.text))}}", @@ -302,10 +294,7 @@ showAlert("Wonderful! all apis executed", "success")).catch(() => showAlert("Ple agHelper.DeployApp(); cy.get(locator._inputWidgetInDeployed).type("Update value"); agHelper.ClickButton("Submit"); - cy.get(locator._toastMsg) - .should("have.length", 1) - .should("contain.text", "Test"); - + agHelper.ValidateToastMessage("Test") agHelper.NavigateBacktoEditor() }) @@ -316,12 +305,12 @@ showAlert("Wonderful! all apis executed", "success")).catch(() => showAlert("Ple }); jsEditor.CreateJSObject(`const user = 'You'; InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " is " + JSON.stringify(res.quote.body), 'success') }).catch(() => showAlert("Unable to fetch quote for " + user, 'warning'))`); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext('onclick', "{{" + jsObjName + ".myFun1()}}", true, true); }); agHelper.ClickButton('Submit') - cy.get(locator._toastMsg).should("have.length", 1).should("contain.text", "Today's quote for You"); + agHelper.ValidateToastMessage("Today's quote for You") }); }) diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/aTobAndbToaBasic_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/aTobAndbToaBasic_Spec.ts index e1d3b8a6e2..b1d9e86486 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/aTobAndbToaBasic_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/aTobAndbToaBasic_Spec.ts @@ -1,13 +1,11 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; - -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const locator = new CommonLocators(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry" let dataSet: any; - +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators; + describe("Validate basic binding of Input widget to Input widget", () => { before(() => { @@ -21,16 +19,16 @@ describe("Validate basic binding of Input widget to Input widget", () => { }); it("1. Input widget test with default value for atob method", () => { - agHelper.expandCollapseEntity("WIDGETS") - agHelper.SelectEntityByName("Input1") + ee.expandCollapseEntity("WIDGETS") + ee.SelectEntityByName("Input1") jsEditor.EnterJSContext("defaulttext", dataSet.atobInput + "}}"); - agHelper.ValidateNetworkCallRespPut('@updateLayout') + agHelper.ValidateNetworkStatus('@updateLayout') }); it("2. Input widget test with default value for btoa method", function () { - agHelper.SelectEntityByName("Input2") + ee.SelectEntityByName("Input2") jsEditor.EnterJSContext("defaulttext", dataSet.btoaInput + "}}"); - agHelper.ValidateNetworkCallRespPut('@updateLayout') + agHelper.ValidateNetworkStatus('@updateLayout') }); it("3. Publish and validate the data displayed in input widgets value for aToB and bToa", function () { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js index aadc2436a5..1995c9ba5b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js @@ -66,6 +66,7 @@ describe("Comments", function() { .its("length") .should("eq", 2); }); + it("Completing comments tour adds bot comment in first thread", function() { cy.generateUUID().then((uid) => { cy.Signup(`${uid}@appsmithtest.com`, uid); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts index 42ad725063..0598455a93 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts @@ -1,12 +1,10 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; - -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const locator = new CommonLocators(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry" let dataSet: any, dsl: any; +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators; describe("Input widget test with default value from chart datapoint", () => { @@ -21,14 +19,14 @@ describe("Input widget test with default value from chart datapoint", () => { }); it("1. Input widget test with default value from another Input widget", () => { - agHelper.expandCollapseEntity("WIDGETS") - agHelper.SelectEntityByName("Input1") + ee.expandCollapseEntity("WIDGETS") + ee.SelectEntityByName("Input1") jsEditor.EnterJSContext("defaulttext", dataSet.bindChartData + "}}"); - agHelper.ValidateNetworkCallRespPut('@updateLayout') + agHelper.ValidateNetworkStatus('@updateLayout') }); it("2. Chart with datapoint feature validation", function () { - agHelper.SelectEntityByName("Chart1") + ee.SelectEntityByName("Chart1") agHelper.SelectPropertiesDropDown("ondatapointclick", "Show message") agHelper.EnterActionValue("Message", dataSet.bindingDataPoint) agHelper.XpathNClick("(//*[local-name()='rect'])[13]") @@ -40,7 +38,7 @@ describe("Input widget test with default value from chart datapoint", () => { }) it("3. Chart with seriesTitle feature validation", function () { - agHelper.SelectEntityByName("Input2") + ee.SelectEntityByName("Input2") jsEditor.EnterJSContext("defaulttext", dataSet.bindingSeriesTitle + "}}"); cy.get(locator._inputWidget).last().should("have.value", dsl.dsl.children[0].chartData[0].seriesName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts index 8b1f0d9aca..de5c2ee9e5 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts @@ -1,19 +1,19 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry" -const agHelper = new AggregateHelper(); -const locator = new CommonLocators(); +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + locator = ObjectsRegistry.CommonLocators; describe("DocumentViewer Widget Functionality", () => { it("1. Add new DocumentViewer and verify in canvas", () => { - agHelper.DragDropWidgetNVerify("documentviewerwidget", 300, 300); + ee.DragDropWidgetNVerify("documentviewerwidget", 300, 300); }); it("2. Modify visibility & Publish app & verify", () => { - agHelper.NavigateToExplorer(); - agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets - agHelper.SelectEntityByName("DocumentViewer1"); - agHelper.ToggleOrDisable("visible", false); + ee.NavigateToSwitcher('explorer') + ee.expandCollapseEntity("WIDGETS"); //to expand widgets + ee.SelectEntityByName("DocumentViewer1"); + agHelper.ToggleOnOrOff("visible", 'Off'); agHelper.DeployApp(); cy.get(locator._widgetInDeployed("documentviewerwidget")).should( "not.exist", @@ -22,9 +22,9 @@ describe("DocumentViewer Widget Functionality", () => { }); it("3. Change visibility & Publish app & verify again", () => { - agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets - agHelper.SelectEntityByName("DocumentViewer1"); - agHelper.ToggleOrDisable("visible"); + ee.expandCollapseEntity("WIDGETS"); //to expand widgets + ee.SelectEntityByName("DocumentViewer1"); + agHelper.ToggleOnOrOff("visible", 'On'); agHelper.DeployApp(); cy.get(locator._widgetInDeployed("documentviewerwidget")).should("exist"); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js index 1e8acf9016..79f7f556dc 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js @@ -1,11 +1,9 @@ const explorer = require("../../../../locators/explorerlocators.json"); +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +let ee = ObjectsRegistry.EntityExplorer; + const firstApiName = "First"; const secondApiName = "Second"; -const { - AggregateHelper, -} = require("../../../../support/Pages/AggregateHelper"); - -const helper = new AggregateHelper(); describe("Api Naming conflict on a page test", function() { it("expects actions on the same page cannot have identical names", function() { @@ -17,7 +15,7 @@ describe("Api Naming conflict on a page test", function() { // create another API cy.NavigateToAPI_Panel(); cy.CreateAPI(secondApiName); - helper.expandCollapseEntity("QUERIES/JS", true); + ee.expandCollapseEntity("QUERIES/JS", true); // try to rename one of the APIs with an existing API name cy.get(`.t--entity-item:contains(${secondApiName})`).within(() => { cy.get(".t--context-menu").click({ force: true }); @@ -46,11 +44,11 @@ describe("Api Naming conflict on different pages test", function() { cy.log("Login Successful"); // create a new API cy.CreateAPI(firstApiName); - helper.expandCollapseEntity("QUERIES/JS", true); + ee.expandCollapseEntity("QUERIES/JS", true); // create a new page and an API on that page cy.Createpage("Page2"); cy.CreateAPI(firstApiName); - helper.expandCollapseEntity("QUERIES/JS", true); + ee.expandCollapseEntity("QUERIES/JS", true); cy.get(".t--entity-name") .contains(firstApiName) .should("exist"); @@ -73,7 +71,7 @@ describe("Api Naming conflict on different pages test", function() { describe("Entity Naming conflict test", function() { it("expects JS objects and actions to not have identical names on the same page.", function() { cy.log("Login Successful"); - helper.expandCollapseEntity("QUERIES/JS", true); + ee.expandCollapseEntity("QUERIES/JS", true); // create JS object and name it cy.createJSObject('return "Hello World";'); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js index 9f54a68721..75eafebe86 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js @@ -4,9 +4,9 @@ const datasource = require("../../../../locators/DatasourcesEditor.json"); const apiwidget = require("../../../../locators/apiWidgetslocator.json"); const commonlocators = require("../../../../locators/commonlocators.json"); const pages = require("../../../../locators/Pages.json"); -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -const AHelper = new AggregateHelper(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +let ee = ObjectsRegistry.EntityExplorer; const pageid = "MyPage"; let datasourceName; @@ -93,7 +93,7 @@ describe("Entity explorer tests related to query and datasource", function() { cy.EvaluateCurrentValue("select * from users"); cy.get(".t--action-name-edit-field").click({ force: true }); - AHelper.ActionContextMenuByEntityName("Query1", "Show Bindings"); + ee.ActionContextMenuByEntityName("Query1", "Show Bindings"); cy.get(apiwidget.propertyList).then(function($lis) { expect($lis).to.have.length(5); expect($lis.eq(0)).to.contain("{{Query1.isLoading}}"); @@ -102,9 +102,9 @@ describe("Entity explorer tests related to query and datasource", function() { expect($lis.eq(3)).to.contain("{{Query1.run()}}"); expect($lis.eq(4)).to.contain("{{Query1.clear()}}"); }); - AHelper.ActionContextMenuByEntityName("Query1", "Edit Name"); + ee.ActionContextMenuByEntityName("Query1", "Edit Name"); cy.EditApiNameFromExplorer("MyQuery"); - AHelper.ActionContextMenuByEntityName("MyQuery", "Move to page", pageid); + ee.ActionContextMenuByEntityName("MyQuery", "Move to page", pageid); cy.get(".t--entity-name") .contains("MyQuery") .click(); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Delete_Undo_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Delete_Undo_spec.js index 2981e68874..7dba62e0ec 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Delete_Undo_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Delete_Undo_spec.js @@ -1,9 +1,6 @@ -const testdata = require("../../../../fixtures/testdata.json"); const apiwidget = require("../../../../locators/apiWidgetslocator.json"); -const explorer = require("../../../../locators/explorerlocators.json"); const commonlocators = require("../../../../locators/commonlocators.json"); const formWidgetsPage = require("../../../../locators/FormWidgets.json"); -const publish = require("../../../../locators/publishWidgetspage.json"); const dsl = require("../../../../fixtures/formWidgetdsl.json"); const pageid = "MyPage"; diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Paste_Delete_Undo_Keyboard_Event_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Paste_Delete_Undo_Keyboard_Event_spec.js index 32c0d49938..1694445d80 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Paste_Delete_Undo_Keyboard_Event_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_Copy_Paste_Delete_Undo_Keyboard_Event_spec.js @@ -2,9 +2,9 @@ const apiwidget = require("../../../../locators/apiWidgetslocator.json"); const commonlocators = require("../../../../locators/commonlocators.json"); const formWidgetsPage = require("../../../../locators/FormWidgets.json"); const dsl = require("../../../../fixtures/formWithInputdsl.json"); -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; -const AgHelper = new AggregateHelper(); +let ee = ObjectsRegistry.EntityExplorer; const pageid = "MyPage"; before(() => { @@ -42,9 +42,9 @@ describe("Test Suite to validate copy/delete/undo functionalites", function() { 200, ); cy.get("body").type(`{${modifierKey}}z`); - AgHelper.expandCollapseEntity("WIDGETS"); - AgHelper.expandCollapseEntity("FormTest"); - AgHelper.ActionContextMenuByEntityName("FormTestCopy", "Show Bindings"); + ee.expandCollapseEntity("WIDGETS"); + ee.expandCollapseEntity("FormTest"); + ee.ActionContextMenuByEntityName("FormTestCopy", "Show Bindings"); cy.get(apiwidget.propertyList).then(function($lis) { expect($lis).to.have.length(2); expect($lis.eq(0)).to.contain("{{FormTestCopy.isVisible}}"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js index 5714c66c7d..e2877c5e94 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js @@ -9,7 +9,7 @@ describe("Phone input widget - ", () => { cy.addDsl(dsl); }); - it("Add new dropdown widget", () => { + it("1. Add new dropdown widget", () => { cy.get(explorer.addWidget).click(); cy.dragAndDropToCanvas(widgetName, { x: 300, y: 300 }); cy.get(`.t--widget-${widgetName}`).should("exist"); @@ -21,7 +21,7 @@ describe("Phone input widget - ", () => { ); }); - it("should check for the format and dialCode", () => { + it("2. Should check for the format and dialCode", () => { cy.get(`.t--widget-${widgetName} input`).clear(); cy.wait(500); cy.get(`.t--widget-${widgetName} input`).type("9999999999"); @@ -80,7 +80,7 @@ describe("Phone input widget - ", () => { cy.get(".t--input-country-code-change").should("contain", "🇮🇳+91"); }); - it("should check that widget input resets on submit", () => { + it("3. Should check that widget input resets on submit", () => { cy.openPropertyPane("textwidget"); cy.updateCodeInput( ".t--property-control-text", @@ -94,9 +94,11 @@ describe("Phone input widget - ", () => { cy.addSuccessMessage("Submitted!!"); cy.get(widgetInput).clear(); - cy.wait(300); - cy.get(widgetInput).type("1234567890"); - cy.wait(300); + cy.wait(500); + cy.get(widgetInput) + .click() + .type("1234567890"); + cy.wait(500); cy.get(".t--widget-textwidget").should("contain", "1234567890:1234567890"); cy.get(widgetInput).type("{enter}"); cy.wait(300); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js index 674e8ab21e..454ad9504a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js @@ -5,10 +5,9 @@ const pages = require("../../../../locators/Pages.json"); const testdata = require("../../../../fixtures/testdata.json"); describe("Rest Bugs tests", function() { - //Skipping until api endpoint fixed - it.skip("Bug 5550: Not able to run APIs in parallel", function() { + it("Bug 5550: Not able to run APIs in parallel", function() { cy.addDsl(dslParallel); - cy.wait(5000); //settling time for dsl! + cy.wait(8000); //settling time for dsl! cy.get(".bp3-spinner").should("not.exist"); //Api 1 @@ -20,56 +19,90 @@ describe("Rest Bugs tests", function() { //Api 2 cy.NavigateToAPI_Panel(); - cy.CreateAPI("CatFacts"); - cy.enterDatasource( - "https://cat-fact.herokuapp.com/facts/random?animal_type=cat", - ); - cy.assertPageSave(); - - cy.get("body").click(0, 0); - - //Api 3 - cy.NavigateToAPI_Panel(); cy.CreateAPI("DogImage"); cy.enterDatasource("https://dog.ceo/api/breeds/image/random"); cy.assertPageSave(); //important - needed for autosave of API before running cy.get("body").click(0, 0); + //Api 3 + cy.NavigateToAPI_Panel(); + cy.CreateAPI("NumberFact"); + cy.enterDatasource("http://numbersapi.com/random/math"); + cy.assertPageSave(); + cy.get("body").click(0, 0); + //Api 4 cy.NavigateToAPI_Panel(); - cy.CreateAPI("DogFacts"); + cy.CreateAPI("CocktailDB"); cy.enterDatasource( - "https://cat-fact.herokuapp.com/facts/random?animal_type=dog", + "https://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita", ); cy.assertPageSave(); cy.get("body").click(0, 0); - cy.contains(commonlocators.entityName, "Page1").click({ force: true }); - cy.clickButton("Get Facts!"); + cy.contains(commonlocators.entityName, "Page1") + .click({ force: true }) + .wait(2000); + cy.clickButton("Invoke APIs!"); cy.wait(12000); // for all api calls to complete! - cy.wait("@postExecute", { timeout: 8000 }).then(({ response }) => { - expect(response.body.data.isExecutionSuccess).to.eq(true); - expect(response.body.data.body[0].url.length).to.be.above(0); - }); + //Cat Image + cy.xpath("//img/parent::div") + .eq(0) + .find("img") + .invoke("attr", "src") + .then(($src) => { + expect($src).not.eq("https://assets.appsmith.com/widgets/default.png"); + expect($src).contains("cat"); + }); - cy.wait("@postExecute", { timeout: 8000 }).then(({ response }) => { - expect(response.body.data.isExecutionSuccess).to.eq(true); - expect(response.body.data.body.type).to.eq("cat"); - }); + // cy.wait("@postExecute").then(({ response }) => { + // expect(response.body.data.isExecutionSuccess).to.eq(true); + // expect(response.body.data.body[0].url.length).to.be.above(0); //Cat image + // }); - cy.wait("@postExecute", { timeout: 8000 }).then(({ response }) => { - expect(response.body.data.isExecutionSuccess).to.eq(true); - expect(response.body.data.body.message.length).to.be.above(0); - }); + // cy.wait("@postExecute", { timeout: 8000 }).then(({ response }) => { + // expect(response.body.data.isExecutionSuccess).to.eq(true); + // expect(response.body.data.body.message.length).to.be.above(0); //Dog Image + // }); - cy.wait("@postExecute", { timeout: 8000 }).then(({ response }) => { - //cy.log("Response is :"+ JSON.stringify(response.body)) + //Dog Image + cy.xpath("//img/parent::div") + .eq(1) + .find("img") + .invoke("attr", "src") + .then(($src) => { + expect($src).not.eq("https://assets.appsmith.com/widgets/default.png"); + expect($src).contains("dog"); + }); - expect(response.body.data.isExecutionSuccess).to.eq(true); - expect(response.body.data.body.type).to.eq("dog"); - }); + // cy.wait("@postExecute", { timeout: 8000 }).then(({ response }) => { + // expect(response.body.data.isExecutionSuccess).to.eq(true); + // expect(response.body.data.body.length).to.be.above(0); //Number fact + // }); + + cy.get(".t--draggable-textwidget") + .eq(0) + .invoke("text") + .then(($txt) => expect($txt).to.have.length.greaterThan(25)); + + // cy.wait("@postExecute", { timeout: 8000 }).then(({ response }) => { + // //cy.log("Response is :"+ JSON.stringify(response.body)) + // expect(response.body.data.isExecutionSuccess).to.eq(true); + // expect(response.body.data.request.url.length).to.be.above(0); //Cocktail + // }); + + //Cocktail DB + + cy.xpath("//img/parent::div") + .eq(2) + .find("img") + .invoke("attr", "src") + .then(($src) => { + expect($src).not.eq("https://assets.appsmith.com/widgets/default.png"); + expect($src).contains("cocktail"); + }); //Spread to check later! // cy.wait(['@postExecute', '@postExecute', '@postExecute', '@postExecute'], { timeout: 8000 }).spread( diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js index 9dfcaa9bc0..3ed80c6448 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js @@ -1,8 +1,11 @@ const apiwidget = require("../../../../locators/apiWidgetslocator.json"); const datasourceFormData = require("../../../../fixtures/datasources.json"); +const datasourceEditor = require("../../../../locators/DatasourcesEditor.json"); describe("Authenticated API Datasource", function() { - it("Can create New Authentication API datasource", function() { + const URL = datasourceFormData["authenticatedApiUrl"]; + + it("1. Bug: 12045 - No Blank screen diplay after New Authentication API datasource creation", function() { cy.NavigateToAPI_Panel(); cy.get(apiwidget.createAuthApiDatasource).click({ force: true }); cy.wait("@createDatasource").should( @@ -10,9 +13,17 @@ describe("Authenticated API Datasource", function() { "response.body.responseMeta.status", 201, ); + cy.renameDatasource("FakeAuthenticatedApi"); cy.fillAuthenticatedAPIForm(); cy.saveDatasource(); - const URL = datasourceFormData["authenticatedApiUrl"]; cy.contains(URL); }); + + it("2. Bug: 12045 - No Blank screen diplay after editing/opening existing Authentication API datasource", function() { + cy.xpath("//span[text()='EDIT']/parent::a").click(); + cy.get(datasourceEditor.url).type("/users"); + cy.saveDatasource(); + cy.contains(URL + "/users"); + cy.deleteDatasource("FakeAuthenticatedApi"); + }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_API_Pane_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_API_Pane_spec.js index db7943e4b0..5afce1c76a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_API_Pane_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_API_Pane_spec.js @@ -3,9 +3,8 @@ const apiwidget = require("../../../../locators/apiWidgetslocator.json"); const explorer = require("../../../../locators/explorerlocators.json"); const pageid = "MyPage"; -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; - -const AHelper = new AggregateHelper(); +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +let ee = ObjectsRegistry.EntityExplorer; describe("Entity explorer API pane related testcases", function() { it("Empty Message validation for Widgets/API/Queries", function() { @@ -33,7 +32,7 @@ describe("Entity explorer API pane related testcases", function() { ); cy.ResponseStatusCheck(testdata.successStatusCode); cy.CheckAndUnfoldEntityItem("QUERIES/JS"); - AHelper.ActionContextMenuByEntityName("FirstAPI", "Show Bindings"); + ee.ActionContextMenuByEntityName("FirstAPI", "Show Bindings"); cy.get(apiwidget.propertyList).then(function($lis) { expect($lis).to.have.length(5); expect($lis.eq(0)).to.contain("{{FirstAPI.isLoading}}"); @@ -49,14 +48,14 @@ describe("Entity explorer API pane related testcases", function() { cy.get(".t--entity-name") .contains("Page1") .click(); - AHelper.ActionContextMenuByEntityName("FirstAPI", "Edit Name"); + ee.ActionContextMenuByEntityName("FirstAPI", "Edit Name"); cy.EditApiNameFromExplorer("SecondAPI"); cy.xpath(apiwidget.popover) .last() .should("be.hidden") .invoke("show") .click({ force: true }); - AHelper.ActionContextMenuByEntityName("SecondAPI", "Move to page", pageid); + ee.ActionContextMenuByEntityName("SecondAPI", "Move to page", pageid); cy.get(".t--entity-name") .contains("SecondAPI") .should("exist"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js index 79f5a4c62c..56934298f1 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js @@ -1,8 +1,9 @@ const queryLocators = require("../../../../locators/QueryEditor.json"); const datasource = require("../../../../locators/DatasourcesEditor.json"); const apiwidget = require("../../../../locators/apiWidgetslocator.json"); -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -const agHelper = new AggregateHelper(); + +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +let ee = ObjectsRegistry.EntityExplorer; const pageid = "MyPage"; let updatedName; @@ -55,7 +56,7 @@ describe("Entity explorer tests related to copy query", function() { datasourceName = httpResponse.response.body.data.name; cy.CheckAndUnfoldEntityItem("QUERIES/JS"); - agHelper.ActionContextMenuByEntityName("Query1", "Show Bindings"); + ee.ActionContextMenuByEntityName("Query1", "Show Bindings"); cy.get(apiwidget.propertyList).then(function($lis) { expect($lis).to.have.length(5); expect($lis.eq(0)).to.contain("{{Query1.isLoading}}"); @@ -71,13 +72,13 @@ describe("Entity explorer tests related to copy query", function() { cy.get(".t--entity-name") .contains("Page1") .click({ force: true }); - agHelper.ActionContextMenuByEntityName("Query1", "Copy to page", pageid); + ee.ActionContextMenuByEntityName("Query1", "Copy to page", pageid); cy.CheckAndUnfoldEntityItem("QUERIES/JS"); cy.get(".t--entity-name") .contains("Query1") .click({ force: true }); cy.runQuery(); - agHelper.ActionContextMenuByEntityName("Query1", "Show Bindings"); + ee.ActionContextMenuByEntityName("Query1", "Show Bindings"); cy.get(apiwidget.propertyList).then(function($lis) { expect($lis.eq(0)).to.contain("{{Query1.isLoading}}"); expect($lis.eq(1)).to.contain("{{Query1.data}}"); @@ -100,11 +101,7 @@ describe("Entity explorer tests related to copy query", function() { cy.CheckAndUnfoldEntityItem("QUERIES/JS"); cy.EditEntityNameByDoubleClick(datasourceName, updatedName); cy.wait(1000); - agHelper.ActionContextMenuByEntityName( - updatedName, - "Delete", - "Are you sure?", - ); + ee.ActionContextMenuByEntityName(updatedName, "Delete", "Are you sure?"); cy.wait(1000); //This is check to make sure if a datasource is active 409 cy.wait("@deleteDatasource").should( @@ -116,6 +113,6 @@ describe("Entity explorer tests related to copy query", function() { cy.get(".t--entity-name") .contains("Query1") .click(); - agHelper.ActionContextMenuByEntityName("Query1", "Delete", "Are you sure?"); + ee.ActionContextMenuByEntityName("Query1", "Delete", "Are you sure?"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/EditorContextMenu_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/JSEditorContextMenu_Spec.ts similarity index 56% rename from app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/EditorContextMenu_Spec.ts rename to app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/JSEditorContextMenu_Spec.ts index dd8702c3f7..8c0a802f5c 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/EditorContextMenu_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/JSEditorContextMenu_Spec.ts @@ -1,27 +1,27 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry" -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); +let agHelper = ObjectsRegistry.AggregateHelper, + ee = ObjectsRegistry.EntityExplorer, + jsEditor = ObjectsRegistry.JSEditor; describe("Validate basic operations on Entity explorer JSEditor structure", () => { const pageId = "Page1"; it("1. Validate JSObject creation & Run", () => { jsEditor.CreateJSObject('return "Hello World";'); - agHelper.expandCollapseEntity("QUERIES/JS"); - agHelper.ValidateEntityPresenceInExplorer("JSObject1"); + ee.expandCollapseEntity("QUERIES/JS"); + ee.AssertEntityPresenceInExplorer("JSObject1"); jsEditor.validateDefaultJSObjProperties("JSObject1"); }); it("2. Validate Rename JSObject from Form Header", function() { jsEditor.RenameJSObjFromForm("RenamedJSObject"); - agHelper.ValidateEntityPresenceInExplorer("RenamedJSObject"); + ee.AssertEntityPresenceInExplorer("RenamedJSObject"); jsEditor.validateDefaultJSObjProperties("RenamedJSObject"); }); it("3. Validate Copy JSObject", function() { - agHelper.ActionContextMenuByEntityName( + ee.ActionContextMenuByEntityName( "RenamedJSObject", "Copy to page", pageId, @@ -31,40 +31,40 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = "response.body.responseMeta.status", 201, ); - agHelper.ValidateEntityPresenceInExplorer("RenamedJSObjectCopy"); + ee.AssertEntityPresenceInExplorer("RenamedJSObjectCopy"); jsEditor.validateDefaultJSObjProperties("RenamedJSObjectCopy"); }); it("4. Validate Rename JSObject from Entity Explorer", function() { jsEditor.RenameJSObjFromExplorer("RenamedJSObject", "ExplorerRenamed"); - agHelper.ValidateEntityPresenceInExplorer("ExplorerRenamed"); + ee.AssertEntityPresenceInExplorer("ExplorerRenamed"); jsEditor.validateDefaultJSObjProperties("ExplorerRenamed"); }); it("5. Validate Move JSObject", function() { const newPageId = "Page2"; agHelper.AddNewPage(); - agHelper.ValidateEntityPresenceInExplorer(newPageId); - agHelper.SelectEntityByName(pageId); - agHelper.expandCollapseEntity("QUERIES/JS"); - agHelper.ActionContextMenuByEntityName( + ee.AssertEntityPresenceInExplorer(newPageId); + ee.SelectEntityByName(pageId); + ee.expandCollapseEntity("QUERIES/JS"); + ee.ActionContextMenuByEntityName( "RenamedJSObjectCopy", "Move to page", newPageId, ); - agHelper.SelectEntityByName(newPageId); - agHelper.ValidateEntityPresenceInExplorer("RenamedJSObjectCopy"); + ee.SelectEntityByName(newPageId); + ee.AssertEntityPresenceInExplorer("RenamedJSObjectCopy"); jsEditor.validateDefaultJSObjProperties("RenamedJSObjectCopy"); }); it("6. Validate Deletion of JSObject", function() { - agHelper.SelectEntityByName(pageId); - agHelper.expandCollapseEntity("QUERIES/JS"); - agHelper.ActionContextMenuByEntityName( + ee.SelectEntityByName(pageId); + ee.expandCollapseEntity("QUERIES/JS"); + ee.ActionContextMenuByEntityName( "ExplorerRenamed", "Delete", "Are you sure?", ); - agHelper.ValidateEntityAbsenceInExplorer("ExplorerRenamed"); + ee.AssertEntityAbsenceInExplorer("ExplorerRenamed"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts index 81acdbeefd..994196b2af 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts @@ -1,13 +1,12 @@ -import { ApiPage } from "../../../../support/Pages/ApiPage"; -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { HomePage } from "../../../../support/Pages/HomePage"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry" -const apiPage = new ApiPage(); -const agHelper = new AggregateHelper(); -const homePage = new HomePage(); +let dsl: any; +let agHelper = ObjectsRegistry.AggregateHelper, + homePage = ObjectsRegistry.HomePage, + ee = ObjectsRegistry.EntityExplorer, + apiPage = ObjectsRegistry.ApiPage; describe("Layout OnLoad Actions tests", function() { - let dsl: any; before(() => { cy.fixture("onPageLoadActionsDsl").then((val: any) => { dsl = val; @@ -16,8 +15,8 @@ describe("Layout OnLoad Actions tests", function() { it("1. Bug 8595: OnPageLoad execution - when No api to run on Pageload", function() { agHelper.AddDsl(dsl); - agHelper.SelectEntityByName("WIDGETS"); - agHelper.SelectEntityByName("Page1"); + ee.SelectEntityByName("WIDGETS"); + ee.SelectEntityByName("Page1"); cy.url().then((url) => { const pageid = url.split("/")[4]?.split("-").pop(); cy.log(pageid + "page id"); @@ -55,8 +54,8 @@ describe("Layout OnLoad Actions tests", function() { apiPage.CreateAndFillApi("https://api.genderize.io", "Genderize"); apiPage.EnterParams("name", "{{RandomUser.data.results[0].name.first}}"); apiPage.RunAPI(); - agHelper.SelectEntityByName("WIDGETS"); - agHelper.SelectEntityByName("Page1"); + ee.SelectEntityByName("WIDGETS"); + ee.SelectEntityByName("Page1"); cy.url().then((url) => { const pageid = url.split("/")[4]?.split("-").pop(); @@ -132,8 +131,8 @@ describe("Layout OnLoad Actions tests", function() { value: "{{RandomUser.data.results[0].name.first}}", }); // verifies Bug 10055 apiPage.RunAPI(); - agHelper.SelectEntityByName("WIDGETS"); - agHelper.SelectEntityByName("Page1"); + ee.SelectEntityByName("WIDGETS"); + ee.SelectEntityByName("Page1"); cy.url().then((url) => { const pageid = url.split("/")[4]?.split("-").pop(); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/MemberRoles_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/MemberRoles_Spec.ts index c7ebde0cef..f3e9a119ac 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/MemberRoles_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/MemberRoles_Spec.ts @@ -1,13 +1,10 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { HomePage } from "../../../../support/Pages/HomePage"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry" -const agHelper = new AggregateHelper(); -const homePage = new HomePage(); +let orgid: any, appid: any; +let agHelper = ObjectsRegistry.AggregateHelper, + homePage = ObjectsRegistry.HomePage; describe("Create new org and invite user & validate all roles", () => { - let orgid: any; - let appid: any; - it("1. Create new Organization, Share with a user from UI & verify", () => { homePage.NavigateToHome() agHelper.GenerateUUID() diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts index 94f2d5cade..ab2ef1c76e 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts @@ -1,12 +1,12 @@ -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; -import { JSEditor } from "../../../../support/Pages/JSEditor"; -import { DataSources } from "../../../../support/Pages/DataSources"; -import { CommonLocators } from "../../../../support/Objects/CommonLocators"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry" -const agHelper = new AggregateHelper(); -const jsEditor = new JSEditor(); -const dataSources = new DataSources(); -const locator = new CommonLocators(); +let guid: any; +let agHelper = ObjectsRegistry.AggregateHelper, + dataSources = ObjectsRegistry.DataSources, + jsEditor = ObjectsRegistry.JSEditor, + locator = ObjectsRegistry.CommonLocators, + ee = ObjectsRegistry.EntityExplorer, + table = ObjectsRegistry.Table; describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", () => { before(() => { @@ -15,10 +15,8 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", }); }); - let guid: any; - - it("1. With Optional chaining : {{ this?.params?.condition }}", function() { - agHelper.NavigateToDSCreateNew(); + it("1. With Optional chaining : {{ this?.params?.condition }}", function () { + dataSources.NavigateToDSCreateNew(); dataSources.CreatePlugIn("PostgreSQL"); dataSources.FillPostgresDSForm(); agHelper.GenerateUUID(); @@ -37,8 +35,8 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params1.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); }); - agHelper.expandCollapseEntity("WIDGETS"); - agHelper.SelectEntityByName("Button1"); + ee.expandCollapseEntity("WIDGETS"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -47,12 +45,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params1.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("8"); }); @@ -61,12 +59,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("7"); }); }); - it("2. With Optional chaining : {{ (function() { return this?.params?.condition })() }}", function() { + it("2. With Optional chaining : {{ (function() { return this?.params?.condition })() }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params2"); @@ -77,7 +75,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params2.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -86,12 +84,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params2.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("7"); }); @@ -100,12 +98,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("9"); }); }); - it("3. With Optional chaining : {{ (() => { return this?.params?.condition })() }}", function() { + it("3. With Optional chaining : {{ (() => { return this?.params?.condition })() }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params3"); @@ -116,7 +114,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params3.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -125,12 +123,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params3.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("9"); }); @@ -139,12 +137,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("8"); }); }); - it("4. With Optional chaining : {{ this?.params.condition }}", function() { + it("4. With Optional chaining : {{ this?.params.condition }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params4"); @@ -155,7 +153,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params4.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -164,12 +162,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params4.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("8"); }); @@ -178,12 +176,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("7"); }); }); - it("5. With Optional chaining : {{ (function() { return this?.params.condition })() }}", function() { + it("5. With Optional chaining : {{ (function() { return this?.params.condition })() }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params5"); @@ -194,7 +192,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params5.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -203,12 +201,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params5.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("7"); }); @@ -217,12 +215,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("9"); }); }); - it("6. With Optional chaining : {{ (() => { return this?.params.condition })() }}", function() { + it("6. With Optional chaining : {{ (() => { return this?.params.condition })() }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params6"); @@ -233,7 +231,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params6.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -242,12 +240,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params6.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("9"); }); @@ -256,12 +254,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("8"); }); }); - it("7. With No Optional chaining : {{ this.params.condition }}", function() { + it("7. With No Optional chaining : {{ this.params.condition }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params7"); @@ -272,7 +270,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params7.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -281,12 +279,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params7.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("8"); }); @@ -295,12 +293,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("7"); }); }); - it("8. With No Optional chaining : {{ (function() { return this.params.condition })() }}", function() { + it("8. With No Optional chaining : {{ (function() { return this.params.condition })() }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params8"); @@ -311,7 +309,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params8.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -320,12 +318,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params8.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("7"); }); @@ -334,12 +332,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("9"); }); }); - it("9. With No Optional chaining : {{ (() => { return this.params.condition })() }}", function() { + it("9. With No Optional chaining : {{ (() => { return this.params.condition })() }}", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params9"); @@ -350,7 +348,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params9.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -359,12 +357,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params9.data}}"); agHelper.ClickButton("Submit"); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("9"); }); @@ -373,12 +371,12 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("8"); }); }); - it("10. With Optional chaining : {{ this?.params?.condition }} && no optional paramter passed", function() { + it("10. With Optional chaining : {{ this?.params?.condition }} && no optional paramter passed", function () { dataSources.NavigateToActiveDSQueryPane(guid); agHelper.GetNClick(dataSources._templateMenu); agHelper.RenameWithInPane("Params10"); @@ -389,7 +387,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params10.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); - agHelper.SelectEntityByName("Button1"); + ee.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( "onclick", @@ -398,7 +396,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", true, ); }); - agHelper.SelectEntityByName("Table1"); + ee.SelectEntityByName("Table1"); jsEditor.EnterJSContext("tabledata", "{{Params10.data}}"); //When No selected option passed @@ -408,7 +406,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", agHelper.ClickButton("Submit"); agHelper.Sleep(2000); agHelper.ValidateNetworkExecutionSuccess("@postExecute"); - agHelper.ReadTableRowColumnData(0, 0).then((cellData) => { + table.ReadTableRowColumnData(0, 0).then((cellData) => { expect(cellData).to.be.equal("7"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js index 9fb7646585..d7107481c2 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js @@ -2,10 +2,10 @@ const queryLocators = require("../../../../locators/QueryEditor.json"); const generatePage = require("../../../../locators/GeneratePage.json"); const datasource = require("../../../../locators/DatasourcesEditor.json"); import homePage from "../../../../locators/HomePage"; -import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +let ee = ObjectsRegistry.EntityExplorer; let datasourceName; -const agHelper = new AggregateHelper(); describe("Create a query with a mongo datasource, run, save and then delete the query", function() { beforeEach(() => { @@ -228,7 +228,7 @@ describe("Create a query with a mongo datasource, run, save and then delete the it("9. Bug 7399: Validate Form based & Raw command based templates", function() { let id; - agHelper.expandCollapseEntity(`${datasourceName}`); + ee.expandCollapseEntity(`${datasourceName}`); cy.xpath(queryLocators.listingAndReviewContext) .invoke("show") .click({ force: true }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js index 3690481daa..45f925f5ab 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js @@ -400,7 +400,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", //Verifying Searching File from UI cy.xpath(queryLocators.searchFilefield) .type("CRUD") - .wait(500); //for search to finish + .wait(7000); //for search to finish expect( cy.xpath( "//div[@data-cy='overlay-comments-wrapper']//span[text()='CRUDNewPageFile']", diff --git a/app/client/cypress/manual_TestSuite/CommentedScriptFiles/AForceMigration_Spec.ts b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/AForceMigration_Spec.ts deleted file mode 100644 index 4e412fc32f..0000000000 --- a/app/client/cypress/manual_TestSuite/CommentedScriptFiles/AForceMigration_Spec.ts +++ /dev/null @@ -1,507 +0,0 @@ -// const widgetsPage = require("../../../locators/Widgets.json"); -// import homePage from "../../locators/HomePage"; - -// describe("Migration Validate", function () { -// it("1. Import application and Validate Migration on pageload", function () { -// // import application -// cy.get(homePage.homeIcon).click(); -// cy.get(homePage.optionsIcon) -// .first() -// .click(); -// cy.get(homePage.orgImportAppOption).click({ force: true }); -// cy.get(homePage.orgImportAppModal).should("be.visible"); -// cy.xpath(homePage.uploadLogo) -// .attachFile("TableMigrationAppExported.json") -// .wait(500); -// cy.get(homePage.orgImportAppButton) -// .trigger("click") -// .wait(500); -// cy.get(homePage.orgImportAppModal).should("not.exist"); - -// cy.wait("@importNewApplication").then((interception) => { -// let appId = interception.response.body.data.id; -// let defaultPage = interception.response.body.data.pages.find( -// (eachPage) => !!eachPage.isDefault, -// ); - -// cy.get(homePage.toastMessage).should( -// "contain", -// "Application imported successfully", -// ); - -// //Renaming imported app! -// const uuid = () => Cypress._.random(0, 1e4); -// const name = uuid(); -// cy.wait(2000); -// cy.get(homePage.applicationName) -// .clear() -// .type(`app${name}`); -// cy.wrap(`app${name}`).as("appname"); -// cy.wait(2000); - -// // Validating data binding for the imported application - Page1 - -// //Validating Latitude & Longitude are hidden columns: -// cy.xpath( -// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='latitude']/parent::div/parent::div", -// ) -// .invoke("attr", "class") -// .then((classes) => { -// cy.log("classes are:" + classes); -// expect(classes).includes("hidden-header"); -// }); - -// cy.xpath( -// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='longitude']/parent::div/parent::div", -// ) -// .invoke("attr", "class") -// .then((classes) => { -// cy.log("classes are:" + classes); -// expect(classes).includes("hidden-header"); -// }); - -// //Validating order of header row! -// cy.xpath( -// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]", -// ) -// .invoke("text") -// .then((x) => { -// expect(x).to.eq( -// "Card NumberidNameاسمaddress住所PhoneemailCompanyjobimagessnPin CodeCreditLimitOutstandingStateAvailable LimitCard TypeChange Credit limitimageURLlatitudelongitude", -// ); -// cy.log("header set is:" + x); -// }); - -// //Validating Id column sorting happens as Datatype is Number in app! -// cy.xpath( -// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='id']", -// ) -// .click() -// .wait(2000); - -// cy.readTabledataPublish("0", "1").then((cellData) => { -// expect(cellData).to.be.equal("100"); -// }); - -// cy.readTabledataPublish("1", "1").then((cellData) => { -// expect(cellData).to.be.equal("99"); -// }); - -// cy.readTabledataPublish("2", "1").then((cellData) => { -// expect(cellData).to.be.equal("98"); -// }); - -// //Revert the Id column sorting! -// cy.xpath( -// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='id']", -// ) -// .click() -// .wait(2000); - -// cy.readTabledataPublish("0", "1").then((cellData) => { -// expect(cellData).to.be.equal("1"); -// }); - -// cy.readTabledataPublish("1", "1").then((cellData) => { -// expect(cellData).to.be.equal("2"); -// }); - -// cy.readTabledataPublish("2", "1").then((cellData) => { -// expect(cellData).to.be.equal("3"); -// }); - -// //Validating image column is present: -// cy.getTableDataSelector("0", "10").then((selector) => { -// cy.get(selector + " div") -// .invoke("attr", "class") -// .then((classes) => { -// cy.log("classes are:" + classes); -// expect(classes).to.eq("image-cell"); -// }); -// }); - -// //Card Number mapping to text widget! -// cy.isSelectRow(2); -// cy.wait(2500); //time for table row select to reflect! -// cy.readTabledataPublish("2", "0").then((cardNumber) => { -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]") -// .eq(1) -// .invoke("text") -// .then((cardNo) => { -// var format = /^\d{4}-\d{4}-\d{4}(-\d{4})?$/; -// expect(cardNumber).match(format); -// expect(cardNumber).to.be.equal(cardNo); -// }); -// }); - -// //Address mapping to text widget! -// cy.readTabledataPublish("2", "4").then((address) => { -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") -// .eq(1) -// .invoke("text") -// .then((addr) => { -// expect(address.replace(/\r?\n|\r/, "")).to.eq(addr); -// }); -// }); - -// //Validating Available limit column computation maintained! -// cy.readTabledataPublish("2", "16").then((availLimit) => { -// cy.readTabledataPublish("2", "13").then((creditLimit) => { -// cy.readTabledataPublish("2", "14").then((outstanding) => { -// expect(Number(availLimit)).to.eq(creditLimit - outstanding); -// }); -// }); -// }); - -// //Validating State button click & binding & text widget mapping! -// cy.getTableDataSelector("2", "15").then((selector) => { -// cy.get(selector + " button.bp3-button") -// .click() -// .wait(3000); - -// cy.waitUntil( -// () => -// cy -// .xpath("//div[contains(@class, ' t--widget-textwidget')][2]", { -// timeout: 30000, -// }) -// .eq(0) -// .should("contain.text", "State:"), -// { -// errorMsg: "Execute call did not complete evn after 10 secs", -// timeout: 20000, -// interval: 1000, -// }, -// ).then(() => cy.wait(500)); - -// cy.get(selector + " button span") -// .invoke("text") -// .then((statetxt) => { -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") -// .eq(0) -// .invoke("text") -// .then((txtWidtxt) => { -// cy.log("statetxt is:" + statetxt); -// let text = -// statetxt == "Activate" ? "State:Inactive" : "State:Active"; -// expect(text).to.eq(txtWidtxt); -// }); -// }); -// }); - -// //Validating Image URL click & navigation! -// cy.getTableDataSelector("2", "19").then((selector) => { -// // Stubbing window.open to open in the same tab -// cy.window().then((window) => { -// cy.stub(window, "open").callsFake((url) => { -// window.location.href = url; //.substring(1); -// window.location.target = "_self"; -// }); -// }); - -// cy.get(selector + " span.bp3-popover-target span") -// .invoke("text") -// .then((url) => { -// cy.get(selector + " span.bp3-popover-target") -// .click() -// .wait(2000); -// cy.wait("@postExecute"); -// cy.url().should("contain", url); -// cy.go(-1); -// }); -// }); - -// // cy.wait(4000); -// // cy.get("div.tableWrap").should("be.visible"); //wait for page load! - -// cy.waitUntil( -// () => cy.get("div.tableWrap", { timeout: 30000 }).should("be.visible"), -// { -// errorMsg: "Page is not loaded evn after 10 secs", -// timeout: 30000, -// interval: 2000, -// }, -// ).then(() => cy.wait(1000)); //wait for page load! - -// cy.isSelectRow(2); //as aft refresh row selection is also gone -// cy.getTableDataSelector("2", "18").then((selector) => { -// cy.get(selector + " button") -// .click() -// .wait(1000); - -// cy.xpath( -// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='AddcreditLimit']/parent::a", -// ) -// .click() -// .wait(2000); - -// cy.waitUntil( -// () => -// cy -// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .should("contain.text", "CreditLimit:"), -// { -// errorMsg: "Execute call did not complete evn after 10 secs", -// timeout: 20000, -// interval: 1000, -// }, -// ).then(() => cy.wait(500)); //allow time for n/w to finish - -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .invoke("text") -// .then((addreduce) => { -// expect(addreduce).to.eq("CreditLimit:Add"); -// }); -// }); - -// //Manu Btn validation: - 2nd menu item -// cy.getTableDataSelector("2", "18").then((selector) => { -// cy.get(selector + " button") -// .click() -// .wait(1000); - -// cy.xpath( -// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='Reducecreditlimit']/parent::a", -// ) -// .click() -// .wait(2000); - -// cy.waitUntil( -// () => -// cy -// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .should("contain.text", "CreditLimit:"), -// { -// errorMsg: "Execute call did not complete evn after 10 secs", -// timeout: 20000, -// interval: 1000, -// }, -// ).then(() => cy.wait(500)); //allow time for n/w to finish - -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .invoke("text") -// .then((addreduce) => { -// expect(addreduce).to.eq("CreditLimit:Reduce"); -// }); -// }); - -// //Another row! -// //Card Number mapping to text widget! -// cy.isSelectRow(4); -// cy.wait(2500); //time for table row select to reflect! -// cy.readTabledataPublish("4", "0").then((cardNumber) => { -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]") -// .eq(1) -// .invoke("text") -// .then((cardNo) => { -// var format = /^\d{4}-\d{4}-\d{4}(-\d{4})?$/; -// expect(cardNumber).match(format); -// expect(cardNumber).to.be.equal(cardNo); -// }); -// }); - -// //Address mapping to text widget! -// cy.readTabledataPublish("4", "4").then((address) => { -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") -// .eq(1) -// .invoke("text") -// .then((addr) => { -// expect(address.replace(/\r?\n|\r/, "")).to.eq(addr); -// }); -// }); - -// //Validating Available limit column computation maintained! -// cy.readTabledataPublish("4", "16").then((availLimit) => { -// cy.readTabledataPublish("4", "13").then((creditLimit) => { -// cy.readTabledataPublish("4", "14").then((outstanding) => { -// expect(Number(availLimit)).to.eq(creditLimit - outstanding); -// }); -// }); -// }); - -// //Validating State button click & binding & text widget mapping! -// cy.getTableDataSelector("4", "15").then((selector) => { -// cy.get(selector + " button.bp3-button") -// .click() -// .wait(2000); - -// cy.waitUntil( -// () => -// cy -// .xpath("//div[contains(@class, ' t--widget-textwidget')][2]", { -// timeout: 30000, -// }) -// .eq(0) -// .should("contain.text", "State:"), -// { -// errorMsg: "Execute call did not complete evn after 10 secs", -// timeout: 20000, -// interval: 1000, -// }, -// ).then(() => cy.wait(500)); - -// cy.get(selector + " button span") -// .invoke("text") -// .then((statetxt) => { -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") -// .eq(0) -// .invoke("text") -// .then((txtWidtxt) => { -// cy.log("statetxt is:" + statetxt); -// let text = -// statetxt == "Activate" ? "State:Inactive" : "State:Active"; -// expect(text).to.eq(txtWidtxt); -// }); -// }); -// }); - -// //Validating Image URL click & navigation! -// cy.getTableDataSelector("4", "19").then((selector) => { -// // Stubbing window.open to open in the same tab -// cy.window().then((window) => { -// cy.stub(window, "open").callsFake((url) => { -// window.location.href = url; //.substring(1); -// window.location.target = "_self"; -// }); -// }); - -// cy.get(selector + " span.bp3-popover-target span") -// .invoke("text") -// .then((url) => { -// cy.get(selector + " span.bp3-popover-target") -// .click() -// .wait(2000); -// cy.wait("@postExecute"); -// cy.url().should("contain", url); -// cy.go(-1); -// }); -// }); - -// //cy.wait(4000); -// //cy.get("div.tableWrap").should("be.visible"); - -// cy.waitUntil( -// () => cy.get("div.tableWrap", { timeout: 30000 }).should("be.visible"), -// { -// errorMsg: "Page is not loaded evn after 10 secs", -// timeout: 30000, -// interval: 2000, -// }, -// ).then(() => cy.wait(1000)); //wait for page load! - -// //Manu Btn validation: - 1st menu item -// cy.isSelectRow(4); //as aft refresh row selection is also gone -// cy.getTableDataSelector("4", "18").then((selector) => { -// cy.get(selector + " button") -// .click() -// .wait(1000); - -// cy.xpath( -// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='AddcreditLimit']/parent::a", -// ) -// .click() -// .wait(2000); //allow time for n/w to finish - -// cy.waitUntil( -// () => -// cy -// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .should("contain.text", "CreditLimit:"), -// { -// errorMsg: "Execute call did not complete evn after 10 secs", -// timeout: 20000, -// interval: 1000, -// }, -// ).then(() => cy.wait(500)); //allow time for n/w to finish - -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .invoke("text") -// .then((addreduce) => { -// expect(addreduce).to.eq("CreditLimit:Add"); -// }); -// }); - -// //Manu Btn validation: - 2nd menu item -// cy.getTableDataSelector("4", "18").then((selector) => { -// cy.get(selector + " button") -// .click() -// .wait(1000); - -// cy.xpath( -// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='Reducecreditlimit']/parent::a", -// ) -// .click() -// .wait(2000); //allow time for n/w to finish - -// cy.waitUntil( -// () => -// cy -// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .should("contain.text", "CreditLimit:"), -// { -// errorMsg: "Execute call did not complete evn after 10 secs", -// timeout: 20000, -// interval: 1000, -// }, -// ).then(() => cy.wait(500)); //allow time for n/w to finish - -// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { -// timeout: 30000, -// }) -// .eq(0) -// .invoke("text") -// .then((addreduce) => { -// expect(addreduce).to.eq("CreditLimit:Reduce"); -// }); -// }); -// }); - -// //Page 2 Validations: - -// cy.selectEntityByName("Change color and font"); -// cy.selectEntityByName("WIDGETS"); -// cy.selectEntityByName("Table1"); - -// cy.get(widgetsPage.bold) -// .invoke("attr", "aria-selected") -// .then((sel) => expect(Boolean(sel)).to.be.true); -// cy.get(widgetsPage.centerAlign) -// .eq(0) -// .invoke("attr", "aria-selected") -// .then((sel) => expect(Boolean(sel)).to.be.true); //Text align -// cy.get(widgetsPage.centerAlign) -// .eq(1) -// .invoke("attr", "aria-selected") -// .then((sel) => expect(Boolean(sel)).to.be.true); //Vertical align -// cy.get(widgetsPage.textColor) -// .first() -// .invoke("attr", "value") -// .should("contain", "#2E3D49"); -// cy.get(`${widgetsPage.cellBackground} input`) -// .first() -// .invoke("attr", "value") -// .should("contain", "#FFC13D"); -// cy.get(widgetsPage.selectedTextSize).should("have.text", "24px"); -// }); -// }); diff --git a/app/client/cypress/plugins/index.js b/app/client/cypress/plugins/index.js index 4353f59b02..a7312082d9 100644 --- a/app/client/cypress/plugins/index.js +++ b/app/client/cypress/plugins/index.js @@ -57,6 +57,12 @@ module.exports = (on, config) => { return launchOptions; } + if (browser.name === "electron") { + // && browser.isHeadless) { + launchOptions.preferences.fullscreen = true; + launchOptions.preferences.darkTheme = true; + } + return launchOptions; }); diff --git a/app/client/cypress/support/Objects/CommonLocators.ts b/app/client/cypress/support/Objects/CommonLocators.ts index 3d9b0642d0..17b69d12e4 100644 --- a/app/client/cypress/support/Objects/CommonLocators.ts +++ b/app/client/cypress/support/Objects/CommonLocators.ts @@ -1,13 +1,10 @@ export class CommonLocators { - _addNewDataSource = ".datasources .t--entity-add-btn" - _integrationCreateNew = "[data-cy=t--tab-CREATE_NEW]" _loading = "#loading" + _spinner = ".bp3-spinner" _queryName = ".t--action-name-edit-field span" _queryNameTxt = ".t--action-name-edit-field input" _dsName = ".t--edit-datasource-name span" _dsNameTxt = ".t--edit-datasource-name input" - _homeIcon = ".t--appsmith-logo" - _homePageAppCreateBtn = ".t--applications-container .createnew" _saveStatusSuccess = ".t--save-status-success" _codeMirrorTextArea = ".CodeMirror textarea" _codeMirrorCode = ".CodeMirror-code" @@ -24,10 +21,20 @@ export class CommonLocators { _newPage = ".pages .t--entity-add-btn" _toastMsg = ".t--toast-action" _empty = "span[name='no-response']" + _contextMenuInPane = "span[name='context-menu']" + _visibleTextDiv = (divText: string) => "//div[text()='" + divText + "']" _openWidget = ".widgets .t--entity-add-btn" _dropHere = "#comment-overlay-wrapper-0" _activeTab = "span:contains('Active')" _createQuery = ".t--create-query" + _crossBtn = "span.cancel-icon" + _createNew = ".t--entity-add-btn.group.files" + _uploadFiles = "div.uppy-Dashboard-AddFiles input" + _uploadBtn = "button.uppy-StatusBar-actionBtn--upload" + _debuggerIcon = ".t--debugger svg" + _errorTab = "[data-cy=t--tab-ERROR]" + _debugErrorMsg = ".t--debugger-message" + _debuggerLabel = "span.debugger-label" _entityNameInExplorer = (entityNameinLeftSidebar: string) => "//div[contains(@class, 't--entity-name')][text()='" + entityNameinLeftSidebar + "']" _expandCollapseArrow = (entityNameinLeftSidebar: string) => "//div[text()='" + entityNameinLeftSidebar + "']/ancestor::div/preceding-sibling::a[contains(@class, 't--entity-collapse-toggle')]" _entityProperties = (entityNameinLeftSidebar: string) => "//div[text()='" + entityNameinLeftSidebar + "']/ancestor::div[contains(@class, 't--entity-item')]/following-sibling::div//div[contains(@class, 't--entity-property')]//code" @@ -45,13 +52,11 @@ export class CommonLocators { _widgetInCanvas = (widgetType: string) => `.t--draggable-${widgetType}` _widgetInDeployed = (widgetType: string) => `.t--widget-${widgetType}` _propertyToggle = (controlToToggle: string) => ".t--property-control-" + controlToToggle + " input[type='checkbox']" + _propertyToggleValue = (controlToToggle: string) => "//div[contains(@class, 't--property-control-" + controlToToggle + "')]//input[@type='checkbox']/parent::label" _openNavigationTab = (tabToOpen: string) => `#switcher--${tabToOpen}` _selectWidgetDropdown = (widgetType: string) => "//div[contains(@class, 't--draggable-" + widgetType + "')]//button" - _createNewPlgin = (pluginName: string) => ".t--plugin-name:contains('" + pluginName + "')" _inputFieldByName = (fieldName: string) => "//p[text()='" + fieldName + "']/parent::label/following-sibling::div" + _existingFieldValueByName = (fieldName: string) => "//label[text()='" + fieldName + "']/ancestor::div//div[contains(@class,'CodeMirror-code')]" _evaluatedCurrentValue = "div:last-of-type .t--CodeEditor-evaluatedValue > div:last-of-type pre" - _tableRowColumn = (rowNum: number, colNum: number) => `.t--widget-tablewidget .tbody .td[data-rowindex=${rowNum}][data-colindex=${colNum}] div div` - _crossBtn = "span.cancel-icon" - _createNew = ".t--entity-add-btn.group.files" } diff --git a/app/client/cypress/support/Objects/Registry.ts b/app/client/cypress/support/Objects/Registry.ts new file mode 100644 index 0000000000..6096886218 --- /dev/null +++ b/app/client/cypress/support/Objects/Registry.ts @@ -0,0 +1,75 @@ +import { AggregateHelper } from "../Pages/AggregateHelper"; +import { JSEditor } from "../Pages/JSEditor"; +import { EntityExplorer } from "../Pages/EntityExplorer"; +import { CommonLocators } from "./CommonLocators"; +import { ApiPage } from "../Pages/ApiPage"; +import { HomePage } from "../Pages/HomePage"; +import { DataSources } from "../Pages/DataSources"; +import { Table } from "../Pages/Table"; + +export class ObjectsRegistry { + + private static aggregateHelper__: AggregateHelper; + static get AggregateHelper(): AggregateHelper { + if (ObjectsRegistry.aggregateHelper__ === undefined) { + ObjectsRegistry.aggregateHelper__ = new AggregateHelper() + } + return ObjectsRegistry.aggregateHelper__; + } + + private static jsEditor__: JSEditor; + static get JSEditor(): JSEditor { + if (ObjectsRegistry.jsEditor__ === undefined) { + ObjectsRegistry.jsEditor__ = new JSEditor() + } + return ObjectsRegistry.jsEditor__; + } + + private static commonLocators__: CommonLocators; + static get CommonLocators(): CommonLocators { + if (ObjectsRegistry.commonLocators__ === undefined) { + ObjectsRegistry.commonLocators__ = new CommonLocators() + } + return ObjectsRegistry.commonLocators__; + } + + private static entityExplorer__: EntityExplorer; + static get EntityExplorer(): EntityExplorer { + if (ObjectsRegistry.entityExplorer__ === undefined) { + ObjectsRegistry.entityExplorer__ = new EntityExplorer() + } + return ObjectsRegistry.entityExplorer__; + } + + private static apiPage__: ApiPage; + static get ApiPage(): ApiPage { + if (ObjectsRegistry.apiPage__ === undefined) { + ObjectsRegistry.apiPage__ = new ApiPage() + } + return ObjectsRegistry.apiPage__; + } + + private static homePage__: HomePage; + static get HomePage(): HomePage { + if (ObjectsRegistry.homePage__ === undefined) { + ObjectsRegistry.homePage__ = new HomePage() + } + return ObjectsRegistry.homePage__; + } + + private static dataSources__: DataSources; + static get DataSources(): DataSources { + if (ObjectsRegistry.dataSources__ === undefined) { + ObjectsRegistry.dataSources__ = new DataSources() + } + return ObjectsRegistry.dataSources__; + } + + private static table__: Table; + static get Table(): Table { + if (ObjectsRegistry.table__ === undefined) { + ObjectsRegistry.table__ = new Table() + } + return ObjectsRegistry.table__; + } +} \ No newline at end of file diff --git a/app/client/cypress/support/Pages/AggregateHelper.ts b/app/client/cypress/support/Pages/AggregateHelper.ts index 91e60db36b..a54f597ca7 100644 --- a/app/client/cypress/support/Pages/AggregateHelper.ts +++ b/app/client/cypress/support/Pages/AggregateHelper.ts @@ -1,9 +1,8 @@ import 'cypress-wait-until'; const uuid = require("uuid"); -import { CommonLocators } from "../Objects/CommonLocators"; - -const locator = new CommonLocators(); +import { ObjectsRegistry } from '../Objects/Registry'; export class AggregateHelper { + private locator = ObjectsRegistry.CommonLocators; public AddDsl(dsl: string) { let currentURL; @@ -29,20 +28,7 @@ export class AggregateHelper { }); }); this.Sleep(5000)//settling time for dsl - } - - public NavigateToDSCreateNew() { - this.NavigateToDSAdd() - cy.get(locator._integrationCreateNew) - .should("be.visible") - .click({ force: true }); - cy.get(locator._loading).should("not.exist"); - } - - public NavigateToDSAdd() { - cy.get(locator._addNewDataSource).last().scrollIntoView() - .should("be.visible") - .click({ force: true }); + cy.get(this.locator._loading).should("not.exist");//Checks the spinner is gone & dsl loaded! } public StartServerAndRoutes() { @@ -52,8 +38,8 @@ export class AggregateHelper { } public RenameWithInPane(renameVal: string, query = true) { - let name = query ? locator._queryName : locator._dsName; - let text = query ? locator._queryNameTxt : locator._dsNameTxt; + let name = query ? this.locator._queryName : this.locator._dsName; + let text = query ? this.locator._queryNameTxt : this.locator._dsNameTxt; cy.get(name).click({ force: true }); cy.get(text) .clear({ force: true }) @@ -62,30 +48,14 @@ export class AggregateHelper { .blur(); } - public WaitAutoSave() { + public AssertAutoSave() { // wait for save query to trigger & n/w call to finish occuring - cy.get(locator._saveStatusSuccess, { timeout: 40000 }).should("exist"); - } - - public SelectEntityByName(entityNameinLeftSidebar: string) { - cy.xpath(locator._entityNameInExplorer(entityNameinLeftSidebar), { timeout: 30000 }) - .last() - .click({ multiple: true }) - this.Sleep() - } - - public NavigateToExplorer() { - cy.get(locator._openNavigationTab('explorer')).click() - } - - public ValidateEntityPresenceInExplorer(entityNameinLeftSidebar: string) { - cy.xpath(locator._entityNameInExplorer(entityNameinLeftSidebar)) - .should("have.length", 1); + cy.get(this.locator._saveStatusSuccess, { timeout: 40000 }).should("exist"); } public ValidateCodeEditorContent(selector: string, contentToValidate: any) { cy.get(selector).within(() => { - cy.get(locator._codeMirrorCode).should("have.text", contentToValidate); + cy.get(this.locator._codeMirrorCode).should("have.text", contentToValidate); }); } @@ -94,31 +64,21 @@ export class AggregateHelper { cy.intercept("POST", "/api/v1/applications/publish/*").as("publishApp"); // Wait before publish this.Sleep(2000) - this.WaitAutoSave() + this.AssertAutoSave() // Stubbing window.open to open in the same tab cy.window().then((window) => { cy.stub(window, "open").callsFake((url) => { window.location.href = Cypress.config().baseUrl + url.substring(1); }); }); - cy.get(locator._publishButton).click(); - cy.wait("@publishApp"); + cy.get(this.locator._publishButton).click(); cy.log("Pagename: " + localStorage.getItem("PageName")); - } - - public expandCollapseEntity(entityName: string, expand = true) { - cy.xpath(locator._expandCollapseArrow(entityName)).invoke('attr', 'name').then((arrow) => { - if (expand && arrow == 'arrow-right') - cy.xpath(locator._expandCollapseArrow(entityName)).trigger('click', { multiple: true }).wait(1000); - else if (!expand && arrow == 'arrow-down') - cy.xpath(locator._expandCollapseArrow(entityName)).trigger('click', { multiple: true }).wait(1000); - else - this.Sleep() - }) + cy.wait("@publishApp").its("request.url").should("not.contain", "edit") + //cy.wait('@publishApp').wait('@publishApp') //waitng for 2 calls to complete } public AddNewPage() { - cy.get(locator._newPage) + cy.get(this.locator._newPage) .first() .click(); cy.wait("@createPage").should( @@ -128,8 +88,14 @@ export class AggregateHelper { ); } + public ValidateToastMessage(text: string, length = 1, index = 1) { + cy.get(this.locator._toastMsg) + .should("have.length", length) + .should("contain.text", text); + } + public ClickButton(btnVisibleText: string) { - cy.xpath(locator._spanButton(btnVisibleText)) + cy.xpath(this.locator._spanButton(btnVisibleText)) .scrollIntoView() .click({ force: true }); } @@ -148,22 +114,22 @@ export class AggregateHelper { }); } - public WaitUntilEleDisappear(selector: string, msgToCheckforDisappearance: string, timeout = 1000) { + public WaitUntilEleDisappear(selector: string, msgToCheckforDisappearance: string) { cy.waitUntil(() => cy.get(selector).contains(msgToCheckforDisappearance).should("have.length", 0), { errorMsg: msgToCheckforDisappearance + " did not disappear", timeout: 5000, interval: 1000 - }).then(() => this.Sleep(timeout)) + }).then(() => this.Sleep()) } - public WaitUntilEleAppear(selector: string, timeout = 500) { + public WaitUntilEleAppear(selector: string) { cy.waitUntil(() => cy.get(selector, { timeout: 50000 }).should("have.length.greaterThan", 0), { errorMsg: "Element did not appear", timeout: 5000, interval: 1000 - }).then(() => this.Sleep(timeout)) + }).then(() => this.Sleep(500)) } public ValidateNetworkExecutionSuccess(aliasName: string, expectedRes = true) { @@ -174,15 +140,15 @@ export class AggregateHelper { ) } - public ValidateNetworkStatus(aliasName: string, expectedRes = 200) { + public ValidateNetworkDataSuccess(aliasName: string, expectedRes = true) { cy.wait(aliasName).should( "have.nested.property", - "response.body.responseMeta.status", + "response.body.data.success", expectedRes, ) } - public ValidateNetworkCallRespPut(aliasName: string, expectedStatus = 200) { + public ValidateNetworkStatus(aliasName: string, expectedStatus = 200) { cy.wait(aliasName).should( "have.nested.property", "response.body.responseMeta.status", @@ -191,24 +157,24 @@ export class AggregateHelper { } public SelectPropertiesDropDown(endp: string, ddOption: string,) { - cy.xpath(locator._selectPropDropdown(endp)) + cy.xpath(this.locator._selectPropDropdown(endp)) .first() .scrollIntoView() .click() - cy.get(locator._dropDownValue(ddOption)).click() + cy.get(this.locator._dropDownValue(ddOption)).click() } public SelectDropDown(endp: string, ddOption: string,) { - cy.xpath(locator._selectWidgetDropdown(endp)) + cy.xpath(this.locator._selectWidgetDropdown(endp)) .first() .scrollIntoView() .click() - cy.get(locator._selectOptionValue(ddOption)).click({ force: true }) + cy.get(this.locator._selectOptionValue(ddOption)).click({ force: true }) this.Sleep(2000) } public EnterActionValue(actionName: string, value: string, paste = true) { - cy.xpath(locator._actionTextArea(actionName)) + cy.xpath(this.locator._actionTextArea(actionName)) .first() .focus() .type("{uparrow}", { force: true }) @@ -216,7 +182,7 @@ export class AggregateHelper { cy.focused().then(($cm: any) => { if ($cm.contents != "") { cy.log("The field is not empty"); - cy.xpath(locator._actionTextArea(actionName)) + cy.xpath(this.locator._actionTextArea(actionName)) .first() .click({ force: true }) .focused() @@ -225,7 +191,7 @@ export class AggregateHelper { }); } this.Sleep() - cy.xpath(locator._actionTextArea(actionName)) + cy.xpath(this.locator._actionTextArea(actionName)) .first() .then((el: any) => { const input = cy.get(el); @@ -238,7 +204,7 @@ export class AggregateHelper { }); } }); - this.WaitAutoSave() + this.AssertAutoSave() }) } @@ -253,36 +219,29 @@ export class AggregateHelper { cy.get(selector).click({ force: true }); } - public DragDropWidgetNVerify(widgetType: string, x: number, y: number) { - cy.get(locator._openNavigationTab('widgets')).click({ force: true }) - this.Sleep() - cy.get(locator._widgetPageIcon(widgetType)).first() - .trigger("dragstart", { force: true }) - .trigger("mousemove", x, y, { force: true }); - cy.get(locator._dropHere) - .trigger("mousemove", x, y, { eventConstructor: "MouseEvent" }) - .trigger("mousemove", x, y, { eventConstructor: "MouseEvent" }) - .trigger("mouseup", x, y, { eventConstructor: "MouseEvent" }); - this.WaitAutoSave()//settling time for widget on canvas! - cy.get(locator._widgetInCanvas(widgetType)).should('exist') - } - - public ToggleOrDisable(propertyName: string, check = true) { - if (check) { - cy.get(locator._propertyToggle(propertyName)) + public ToggleOnOrOff(propertyName: string, toggle: 'On' | 'Off') { + if (toggle == 'On') { + cy.get(this.locator._propertyToggle(propertyName)) .check({ force: true }) .should("be.checked"); } else { - cy.get(locator._propertyToggle(propertyName)) + cy.get(this.locator._propertyToggle(propertyName)) .uncheck({ force: true }) .should("not.checked"); } - this.WaitAutoSave() + this.AssertAutoSave() + } + + public AssertExistingToggleState(propertyName: string, toggle: 'checked' | 'unchecked') { + cy.xpath(this.locator._propertyToggleValue(propertyName)).invoke("attr", "class") + .then((classes) => { + expect(classes).includes(toggle); + }); } public NavigateBacktoEditor() { - cy.get(locator._backToEditor).click({ force: true }); + cy.get(this.locator._backToEditor).click({ force: true }); this.Sleep(2000) } @@ -293,54 +252,27 @@ export class AggregateHelper { } public GetObjectName() { - //cy.get(locator._queryName).invoke("text").then((text) => cy.wrap(text).as("queryName")); or below syntax - return cy.get(locator._queryName).invoke("text"); + //cy.get(this.locator._queryName).invoke("text").then((text) => cy.wrap(text).as("queryName")); or below syntax + return cy.get(this.locator._queryName).invoke("text"); } public Sleep(timeout = 1000) { cy.wait(timeout) } - public NavigateToHome() { - cy.get(locator._homeIcon).click({ force: true }); - this.Sleep(3000); - cy.wait("@applications"); - cy.get(locator._homePageAppCreateBtn) - .should("be.visible") - .should("be.enabled"); - } - - public CreateNewApplication() { - cy.get(locator._homePageAppCreateBtn).click({ force: true }); - cy.wait("@createNewApplication").should( - "have.nested.property", - "response.body.responseMeta.status", - 201, - ); - } - - public ActionContextMenuByEntityName( - entityNameinLeftSidebar: string, - action = "Delete", - subAction = "") { - this.Sleep(); - cy.xpath(locator._contextMenu(entityNameinLeftSidebar)) - .last() - .click({ force: true }); - cy.xpath(locator._contextMenuItem(action)) - .click({ force: true }) - this.Sleep(500) + public ActionContextMenuWithInPane(action: 'Copy to page' | 'Move to page' | 'Delete', subAction = "") { + cy.get(this.locator._contextMenuInPane).click() + cy.xpath(this.locator._visibleTextDiv(action)).should('be.visible').click() + if (action == 'Delete') { + cy.xpath(this.locator._visibleTextDiv('Are you sure?')).click() + this.ValidateNetworkStatus("@deleteAction"); + } if (subAction) { - cy.xpath(locator._contextMenuItem(subAction)) - .click({ force: true }) + cy.xpath(this.locator._visibleTextDiv(subAction)).click() this.Sleep(500) } } - public ValidateEntityAbsenceInExplorer(entityNameinLeftSidebar: string) { - cy.xpath(locator._entityNameInExplorer(entityNameinLeftSidebar)).should('not.exist'); - } - public TypeValueNValidate(valueToType: string, fieldName = "") { this.EnterValue(valueToType, fieldName) this.VerifyEvaluatedValue(valueToType); @@ -348,11 +280,11 @@ export class AggregateHelper { public EnterValue(valueToType: string, fieldName = "") { if (fieldName) { - cy.xpath(locator._inputFieldByName(fieldName)).then(($field: any) => { + cy.xpath(this.locator._inputFieldByName(fieldName)).then(($field: any) => { this.UpdateCodeInput($field, valueToType); }); } else { - cy.get(locator._codeEditorTarget).then(($field: any) => { + cy.get(this.locator._codeEditorTarget).then(($field: any) => { this.UpdateCodeInput($field, valueToType); }); } @@ -373,11 +305,11 @@ export class AggregateHelper { public VerifyEvaluatedValue(currentValue: string) { this.Sleep(3000); - cy.get(locator._evaluatedCurrentValue) + cy.get(this.locator._evaluatedCurrentValue) .first() .should("be.visible") .should("not.have.text", "undefined"); - cy.get(locator._evaluatedCurrentValue) + cy.get(this.locator._evaluatedCurrentValue) .first() .click({ force: true }) .then(($text) => { @@ -385,7 +317,47 @@ export class AggregateHelper { }); } - public ReadTableRowColumnData(rowNum: number, colNum: number) { - return cy.get(locator._tableRowColumn(rowNum, colNum)).invoke("text"); + public EvaluateExistingPropertyFieldValue(fieldName = "", currentValue = "") { + let toValidate = false; + if (currentValue) toValidate = true; + if (fieldName) { + cy.xpath(this.locator._existingFieldValueByName(fieldName)).eq(0).click(); + } else { + cy.xpath(this.locator._codeMirrorCode).click(); + } + this.Sleep(3000); //Increasing wait time to evaluate non-undefined values + const val = cy + .get(this.locator._evaluatedCurrentValue) + .first() + .should("be.visible") + .invoke("text"); + if (toValidate) expect(val).to.eq(currentValue); + return val; + } + + public UploadFile(fixtureName: string, execStat = true) { + cy.get(this.locator._uploadFiles).attachFile(fixtureName).wait(1000); + cy.get(this.locator._uploadBtn).click().wait(3000); + this.ValidateNetworkExecutionSuccess("@postExecute", execStat); + } + + public AssertDebugError(label: string, messgae: string) { + cy.get(this.locator._debuggerIcon) + .should("be.visible") + .click({ force: true }); + cy.get(this.locator._errorTab) + .should("be.visible") + .click({ force: true }); + cy.get(this.locator._debuggerLabel).eq(0) + .invoke("text") + .then(($text) => { + expect($text).to.eq(label); + }); + cy.get(this.locator._debugErrorMsg).eq(0) + .invoke("text") + .then(($text) => { + expect($text).contains(messgae); + }); + } } \ No newline at end of file diff --git a/app/client/cypress/support/Pages/ApiPage.ts b/app/client/cypress/support/Pages/ApiPage.ts index 8294c48ac6..2a7081fa5a 100644 --- a/app/client/cypress/support/Pages/ApiPage.ts +++ b/app/client/cypress/support/Pages/ApiPage.ts @@ -1,10 +1,7 @@ -import { AggregateHelper } from "./AggregateHelper"; -import { CommonLocators } from "../Objects/CommonLocators"; - -const agHelper = new AggregateHelper(); -const locator = new CommonLocators() - +import { ObjectsRegistry } from "../Objects/Registry" export class ApiPage { + public agHelper = ObjectsRegistry.AggregateHelper + public locator = ObjectsRegistry.CommonLocators; private _createapi = ".t--createBlankApiCard" private _resourceUrl = ".t--dataSourceField" @@ -12,22 +9,32 @@ export class ApiPage { private _headerValue = (index: number) => ".t--actionConfiguration\\.headers\\[0\\]\\.value\\." + index + "" private _paramKey = (index: number) => ".t--actionConfiguration\\.queryParameters\\[0\\]\\.key\\." + index + "" private _paramValue = (index: number) => ".t--actionConfiguration\\.queryParameters\\[0\\]\\.value\\." + index + "" - private _paramsTab = "//li//span[text()='Params']" + _bodyKey = (index: number) => ".t--actionConfiguration\\.bodyFormData\\[0\\]\\.key\\." + index + "" + _bodyValue = (index: number) => ".t--actionConfiguration\\.bodyFormData\\[0\\]\\.value\\." + index + "" + _bodyTypeDropdown = "//span[text()='Type'][@class='bp3-button-text']/parent::button" private _apiRunBtn = ".t--apiFormRunBtn" private _queryTimeout = "//input[@name='actionConfiguration.timeoutInMillisecond']" - private _apiTab = (tabValue: string) => "span:contains('" + tabValue + "')" _responseBody = ".CodeMirror-code span.cm-string.cm-property" private _blankAPI = "span:contains('New Blank API')" + private _apiVerbDropdown = ".t--apiFormHttpMethod" + private _verbToSelect = (verb: string) => "//div[contains(@class, 't--dropdown-option')]//span[contains(text(),'" + verb + "')]" + private _bodySubTab = (subTab: string) => `[data-cy='tab--${subTab}']` + _visibleTextSpan = (spanText: string) => "//span[text()='" + spanText + "']" + _visibleTextDiv = (divText: string) => "//div[text()='" + divText + "']" + _noBodyMessageDiv = "#NoBodyMessageDiv" + _noBodyMessage = "This request does not have a body" + _imageSrc = "//img/parent::div" + private _trashDelete = "span[name='delete']" - CreateAndFillApi(url: string, apiname: string = "", queryTimeout = 30000) { - cy.get(locator._createNew).click({ force: true }); + CreateApi(apiName: string = "", apiVerb: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' = 'GET',) { + cy.get(this.locator._createNew).click({ force: true }); cy.get(this._blankAPI).click({ force: true }); - agHelper.ValidateNetworkStatus("@createNewApi", 201) + this.agHelper.ValidateNetworkStatus("@createNewApi", 201) // cy.get("@createNewApi").then((response: any) => { // expect(response.response.body.responseMeta.success).to.eq(true); - // cy.get(agHelper._actionName) + // cy.get(this.agHelper._actionName) // .click() // .invoke("text") // .then((text) => { @@ -36,12 +43,18 @@ export class ApiPage { // }); // }); // to check if Api1 = Api1 when Create Api invoked - if (apiname) - agHelper.RenameWithInPane(apiname) + if (apiName) + this.agHelper.RenameWithInPane(apiName) cy.get(this._resourceUrl).should("be.visible"); + if (apiVerb != 'GET') + this.SelectAPIVerb(apiVerb) + } + + CreateAndFillApi(url: string, apiname: string = "", apiVerb: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' = 'GET', queryTimeout = 30000) { + this.CreateApi(apiname, apiVerb) this.EnterURL(url) - agHelper.WaitAutoSave() - agHelper.Sleep(2000);// Added because api name edit takes some time to reflect in api sidebar after the call passes. + this.agHelper.AssertAutoSave() + this.agHelper.Sleep(2000);// Added because api name edit takes some time to reflect in api sidebar after the call passes. cy.get(this._apiRunBtn).should("not.be.disabled"); this.SetAPITimeout(queryTimeout) } @@ -51,58 +64,103 @@ export class ApiPage { .first() .click({ force: true }) .type(url, { parseSpecialCharSequences: false }); - agHelper.WaitAutoSave() + this.agHelper.AssertAutoSave() } EnterHeader(hKey: string, hValue: string) { - cy.get(this._apiTab('Headers')).eq(0).should('be.visible').click(); + this.SelectAPITab('Headers'); cy.get(this._headerKey(0)) .first() .click({ force: true }) - .type(hKey, { parseSpecialCharSequences: false }); + .type(hKey, { parseSpecialCharSequences: false }) + .type("{esc}"); cy.get(this._headerValue(0)) .first() .click({ force: true }) - .type(hValue, { parseSpecialCharSequences: false }); - agHelper.WaitAutoSave() + .type(hValue, { parseSpecialCharSequences: false }) + .type("{esc}"); + this.agHelper.AssertAutoSave() } EnterParams(pKey: string, pValue: string) { - cy.xpath(this._paramsTab) - .should("be.visible") - .click({ force: true }); + this.SelectAPITab('Params') cy.get(this._paramKey(0)) .first() .click({ force: true }) - .type(pKey, { parseSpecialCharSequences: false }); + .type(pKey, { parseSpecialCharSequences: false }) + .type("{esc}"); cy.get(this._paramValue(0)) .first() .click({ force: true }) - .type(pValue, { parseSpecialCharSequences: false }); - agHelper.WaitAutoSave() + .type(pValue, { parseSpecialCharSequences: false }) + .type("{esc}"); + this.agHelper.AssertAutoSave() + } + + EnterBodyFormData(subTab: 'FORM_URLENCODED' | 'MULTIPART_FORM_DATA', bKey: string, bValue: string, type = "", toTrash = false) { + this.SelectAPITab('Body') + this.SelectSubTab(subTab) + if (toTrash) + { + cy.get(this._trashDelete).click() + cy.xpath(this._visibleTextSpan('Add more')).click() + } + cy.get(this._bodyKey(0)) + .first() + .click({ force: true }) + .type(bKey, { parseSpecialCharSequences: false }) + .type("{esc}"); + if (type) { + cy.xpath(this._bodyTypeDropdown).eq(0).click() + cy.xpath(this._visibleTextDiv(type)).click() + } + cy.get(this._bodyValue(0)) + .first() + .click({ force: true }) + .type(bValue, { parseSpecialCharSequences: false }) + .type("{esc}"); + + this.agHelper.AssertAutoSave() } RunAPI() { cy.get(this._apiRunBtn).click({ force: true }); - agHelper.ValidateNetworkExecutionSuccess("@postExecute") + this.agHelper.ValidateNetworkExecutionSuccess("@postExecute") } SetAPITimeout(timeout: number) { - cy.get(this._apiTab('Settings')).click(); + this.SelectAPITab('Settings'); cy.xpath(this._queryTimeout) .clear() .type(timeout.toString()); + this.SelectAPITab('Headers'); + } - cy.get(this._apiTab('Headers')).eq(0).click(); + SelectAPITab(tabName: 'Headers' | 'Params' | 'Body' | 'Pagination' | 'Authentication' | 'Settings') { + cy.xpath(this._visibleTextSpan(tabName)).should('be.visible').eq(0).click(); + } + + SelectSubTab(subTabName: 'NONE' | 'JSON' | 'FORM_URLENCODED' | 'MULTIPART_FORM_DATA' | 'RAW') { + cy.get(this._bodySubTab(subTabName)).eq(0).should('be.visible').click(); + } + + public CheckElementPresence(selector: string) { + if (selector.startsWith("//")) + cy.xpath(selector).should('be.visible') + else + cy.get(selector).should('be.visible') } ValidateQueryParams(param: { key: string; value: string; }) { - cy.xpath(this._paramsTab) - .should("be.visible") - .click({ force: true }); + this.SelectAPITab('Params') + this.agHelper.ValidateCodeEditorContent(this._paramKey(0), param.key) + this.agHelper.ValidateCodeEditorContent(this._paramValue(0), param.value) + } - agHelper.ValidateCodeEditorContent(this._paramKey(0), param.key) - agHelper.ValidateCodeEditorContent(this._paramValue(0), param.value) + ValidateHeaderParams(header: { key: string; value: string; }) { + this.SelectAPITab('Headers') + this.agHelper.ValidateCodeEditorContent(this._headerKey(0), header.key) + this.agHelper.ValidateCodeEditorContent(this._headerValue(0), header.value) } ReadApiResponsebyKey(key: string) { @@ -117,4 +175,9 @@ export class ApiPage { cy.wrap(apiResp).as("apiResp") }); } -} + + public SelectAPIVerb(verb: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH') { + cy.get(this._apiVerbDropdown).click() + cy.xpath(this._verbToSelect(verb)).should('be.visible').click() + } +} \ No newline at end of file diff --git a/app/client/cypress/support/Pages/DataSources.ts b/app/client/cypress/support/Pages/DataSources.ts index de509cb854..66d8fc4432 100644 --- a/app/client/cypress/support/Pages/DataSources.ts +++ b/app/client/cypress/support/Pages/DataSources.ts @@ -1,12 +1,13 @@ -import { CommonLocators } from "../Objects/CommonLocators"; import datasourceFormData from "../../fixtures/datasources.json"; -import { AggregateHelper } from "./AggregateHelper"; - -const agHelper = new AggregateHelper(); -const locator = new CommonLocators(); - +import { ObjectsRegistry } from "../Objects/Registry" export class DataSources { + private agHelper = ObjectsRegistry.AggregateHelper + private locator = ObjectsRegistry.CommonLocators; + + private _dsCreateNewTab = "[data-cy=t--tab-CREATE_NEW]" + private _addNewDataSource = ".datasources .t--entity-add-btn" + private _createNewPlgin = (pluginName: string) => ".t--plugin-name:contains('" + pluginName + "')" private _host = "input[name='datasourceConfiguration.endpoints[0].host']" private _port = "input[name='datasourceConfiguration.endpoints[0].port']" private _databaseName = "input[name='datasourceConfiguration.authentication.databaseName']" @@ -17,9 +18,27 @@ export class DataSources { private _saveDs = ".t--save-datasource" private _datasourceCard = ".t--datasource" _templateMenu = ".t--template-menu" + _visibleTextSpan = (spanText: string) => "//span[contains(text(),'" + spanText + "')]" + _dropdownTitle = (ddTitle: string) => "//p[contains(text(),'" + ddTitle + "')]/parent::label/following-sibling::div/div/div" + _reconnectModal = "div.reconnect-datasource-modal" + _activeDSListReconnectModal = (dbName: string) => "//div[contains(@class, 't--ds-list')]//span[text()='" + dbName + "']" + + public NavigateToDSAdd() { + cy.get(this._addNewDataSource).last().scrollIntoView() + .should("be.visible") + .click({ force: true }); + } public CreatePlugIn(pluginName: string) { - cy.get(locator._createNewPlgin(pluginName)).click(); + cy.get(this._createNewPlgin(pluginName)).click(); + } + + public NavigateToDSCreateNew() { + this.NavigateToDSAdd() + cy.get(this._dsCreateNewTab) + .should("be.visible") + .click({ force: true }); + cy.get(this.locator._loading).should("not.exist"); } public FillPostgresDSForm(shouldAddTrailingSpaces = false) { @@ -40,32 +59,52 @@ export class DataSources { public TestDatasource(expectedRes = true) { cy.get(this._testDs).click(); - cy.wait("@testDatasource").should( - "have.nested.property", - "response.body.data.success", - expectedRes, - ); + this.agHelper.ValidateNetworkDataSuccess("@testDatasource", expectedRes) } public SaveDatasource() { cy.get(this._saveDs).click(); - cy.wait("@saveDatasource") - .then((xhr) => { - cy.log(JSON.stringify(xhr.response!.body)); - }).should("have.nested.property", "response.body.responseMeta.status", 200); + this.agHelper.ValidateNetworkStatus("@saveDatasource", 200) + + // cy.wait("@saveDatasource") + // .then((xhr) => { + // cy.log(JSON.stringify(xhr.response!.body)); + // }).should("have.nested.property", "response.body.responseMeta.status", 200); } public NavigateToActiveDSQueryPane(datasourceName: string) { - agHelper.NavigateToDSAdd() - agHelper.GetNClick(locator._activeTab) + this.NavigateToDSAdd() + this.agHelper.GetNClick(this.locator._activeTab) cy.get(this._datasourceCard) .contains(datasourceName) .scrollIntoView() .should("be.visible") .closest(this._datasourceCard) .within(() => { - cy.get(locator._createQuery).click({ force: true }); + cy.get(this.locator._createQuery).click({ force: true }); }) - agHelper.Sleep(2000); //for the CreateQuery page to load + this.agHelper.Sleep(2000); //for the CreateQuery page to load } + + + public ValidateNSelectDropdown(ddTitle: string, currentValue = "", newValue = "") { + let toChange = false; + if (currentValue) + cy.xpath(this._visibleTextSpan(currentValue)).scrollIntoView().should("be.visible", currentValue + " dropdown value not present") + if (newValue) toChange = true; + if (toChange) { + cy.xpath(this._dropdownTitle(ddTitle)).click(); //to expand the dropdown + cy.xpath(this._visibleTextSpan(newValue)).last().click({ force: true }); //to select the new value + } + } + + public ReconnectDataSourcePostgres(dbName: string) { + cy.get(this._reconnectModal).should('exist') + cy.xpath(this._activeDSListReconnectModal("PostgreSQL")).should('be.visible') + cy.xpath(this._activeDSListReconnectModal(dbName)).should('be.visible')//.click() + this.ValidateNSelectDropdown("Connection Mode", "", "Read / Write") + this.FillPostgresDSForm() + cy.get(this._saveDs).click(); + } + } \ No newline at end of file diff --git a/app/client/cypress/support/Pages/EntityExplorer.ts b/app/client/cypress/support/Pages/EntityExplorer.ts new file mode 100644 index 0000000000..ca9614967e --- /dev/null +++ b/app/client/cypress/support/Pages/EntityExplorer.ts @@ -0,0 +1,67 @@ +import { ObjectsRegistry } from "../Objects/Registry" + +export class EntityExplorer { + + public agHelper = ObjectsRegistry.AggregateHelper + public locator = ObjectsRegistry.CommonLocators; + + public SelectEntityByName(entityNameinLeftSidebar: string) { + cy.xpath(this.locator._entityNameInExplorer(entityNameinLeftSidebar), { timeout: 30000 }) + .last() + .click({ multiple: true }) + this.agHelper.Sleep() + } + + public NavigateToSwitcher(navigationTab: 'explorer' | 'widgets') { + cy.get(this.locator._openNavigationTab(navigationTab)).click() + } + + public AssertEntityPresenceInExplorer(entityNameinLeftSidebar: string) { + cy.xpath(this.locator._entityNameInExplorer(entityNameinLeftSidebar)) + .should("have.length", 1); + } + + public AssertEntityAbsenceInExplorer(entityNameinLeftSidebar: string) { + cy.xpath(this.locator._entityNameInExplorer(entityNameinLeftSidebar)).should('not.exist'); + } + + public expandCollapseEntity(entityName: string, expand = true) { + cy.xpath(this.locator._expandCollapseArrow(entityName)).invoke('attr', 'name').then((arrow) => { + if (expand && arrow == 'arrow-right') + cy.xpath(this.locator._expandCollapseArrow(entityName)).trigger('click', { multiple: true }).wait(1000); + else if (!expand && arrow == 'arrow-down') + cy.xpath(this.locator._expandCollapseArrow(entityName)).trigger('click', { multiple: true }).wait(1000); + else + this.agHelper.Sleep() + }) + } + + public ActionContextMenuByEntityName(entityNameinLeftSidebar: string, action = "Delete", subAction = "") { + this.agHelper.Sleep(); + cy.xpath(this.locator._contextMenu(entityNameinLeftSidebar)) + .last() + .click({ force: true }); + cy.xpath(this.locator._contextMenuItem(action)) + .click({ force: true }) + this.agHelper.Sleep(500) + if (subAction) { + cy.xpath(this.locator._contextMenuItem(subAction)) + .click({ force: true }) + this.agHelper.Sleep(500) + } + } + + public DragDropWidgetNVerify(widgetType: string, x: number, y: number) { + this.NavigateToSwitcher('widgets') + this.agHelper.Sleep() + cy.get(this.locator._widgetPageIcon(widgetType)).first() + .trigger("dragstart", { force: true }) + .trigger("mousemove", x, y, { force: true }); + cy.get(this.locator._dropHere) + .trigger("mousemove", x, y, { eventConstructor: "MouseEvent" }) + .trigger("mousemove", x, y, { eventConstructor: "MouseEvent" }) + .trigger("mouseup", x, y, { eventConstructor: "MouseEvent" }); + this.agHelper.AssertAutoSave()//settling time for widget on canvas! + cy.get(this.locator._widgetInCanvas(widgetType)).should('exist') + } +} diff --git a/app/client/cypress/support/Pages/HomePage.ts b/app/client/cypress/support/Pages/HomePage.ts index a63eb8b6e0..f2090afa05 100644 --- a/app/client/cypress/support/Pages/HomePage.ts +++ b/app/client/cypress/support/Pages/HomePage.ts @@ -1,11 +1,9 @@ -import { AggregateHelper } from "./AggregateHelper"; -import { CommonLocators } from "../Objects/CommonLocators"; - -const agHelper = new AggregateHelper(); -const locator = new CommonLocators(); - +import { ObjectsRegistry } from "../Objects/Registry" export class HomePage { + private agHelper = ObjectsRegistry.AggregateHelper; + private locator = ObjectsRegistry.CommonLocators; + private _username = "input[name='username']" private _password = "input[name='password']" private _submitBtn = "button[type='submit']" @@ -39,11 +37,13 @@ export class HomePage { private _userRoleDropDown = (email: string, role: string) => "//td[text()='" + email + "']/following-sibling::td//span[text()='" + role + "']" //private _userRoleDropDown = (email: string) => "//td[text()='" + email + "']/following-sibling::td" private _leaveOrgConfirmModal = ".t--member-delete-confirmation-modal" + private _orgImportAppModal = ".t--import-application-modal" private _leaveOrgConfirmButton = "[data - cy= t--org-leave - button]" private _lastOrgInHomePage = "//div[contains(@class, 't--org-section')][last()]//span/span" _editPageLanding = "//h2[text()='Drag and drop a widget here']" _usersEmailList = "[data-colindex='1']" - + private _orgImport = "[data-cy=t--org-import-app]" + private _uploadFile = "//div/form/input" public CreateNewOrg(orgNewName: string) { let oldName: string = "" @@ -52,7 +52,7 @@ export class HomePage { .first() .click({ force: true }); cy.wait("@createOrg") - agHelper.Sleep(2000) + this.agHelper.Sleep(2000) cy.xpath(this._lastOrgInHomePage).first().then($ele => { oldName = $ele.text(); cy.log("oldName is : " + oldName); @@ -69,7 +69,7 @@ export class HomePage { cy.get(this._renameOrgInput) .should("be.visible") .type(newOrgName.concat("{enter}")); - agHelper.Sleep(2000) + this.agHelper.Sleep(2000) cy.wait("@updateOrganization").should( "have.nested.property", "response.body.responseMeta.status", @@ -101,9 +101,9 @@ export class HomePage { .click({ force: true }) .type(email); cy.xpath(this._selectRole).first().click({ force: true }); - agHelper.Sleep(500) + this.agHelper.Sleep(500) cy.xpath(this._userRole(role)).click({ force: true }); - agHelper.ClickButton('Invite') + this.agHelper.ClickButton('Invite') cy.wait("@mockPostInvite") .its("request.headers") .should("have.property", "origin", "Cypress"); @@ -117,21 +117,17 @@ export class HomePage { public NavigateToHome() { cy.get(this._homeIcon).click({ force: true }); - agHelper.Sleep(3000) + this.agHelper.Sleep(3000) + //cy.wait("@applications"); this randomly fails & introduces flakyness hence commenting! cy.get(this._homePageAppCreateBtn).should("be.visible").should("be.enabled"); } public CreateNewApplication() { cy.get(this._homePageAppCreateBtn).first().click({ force: true }) - cy.wait("@createNewApplication").should( - "have.nested.property", - "response.body.responseMeta.status", - 201, - ); - cy.get(locator._loading).should("not.exist"); + this.agHelper.ValidateNetworkStatus("@createNewApplication", 201) + cy.get(this.locator._loading).should("not.exist"); } - //Maps to CreateAppForOrg in command.js public CreateAppInOrg(orgName: string, appname: string) { cy.xpath(this._newOrganizationCreateNewApp(orgName)) @@ -143,8 +139,8 @@ export class HomePage { "response.body.responseMeta.status", 201, ); - cy.get(locator._loading).should("not.exist"); - agHelper.Sleep(2000) + cy.get(this.locator._loading).should("not.exist"); + this.agHelper.Sleep(2000) this.RenameApplication(appname) cy.get(this._buildFromScratchActionCard).click(); cy.wait("@updateApplication").should( @@ -170,11 +166,11 @@ export class HomePage { //Maps to LogOut in command.js public LogOutviaAPI() { cy.request("POST", "/api/v1/logout"); - agHelper.Sleep()//for logout to complete! + this.agHelper.Sleep()//for logout to complete! } public LogintoApp(uname: string, pswd: string, role: 'App Viewer' | 'Developer' | 'Administrator' = 'Administrator') { - agHelper.Sleep() //waiting for window to load + this.agHelper.Sleep() //waiting for window to load cy.window().its("store").invoke("dispatch", { type: "LOGOUT_USER_INIT" }); cy.wait("@postLogout"); cy.visit("/user/login"); @@ -182,16 +178,16 @@ export class HomePage { cy.get(this._password).type(pswd); cy.get(this._submitBtn).click(); cy.wait("@getUser"); - agHelper.Sleep(3000) + this.agHelper.Sleep(3000) if (role != 'App Viewer') cy.get(this._homePageAppCreateBtn).should("be.visible").should("be.enabled"); } public FilterApplication(appName: string, orgId: string) { cy.get(this._searchInput).type(appName); - agHelper.Sleep(2000) + this.agHelper.Sleep(2000) cy.get(this._appContainer).contains(orgId); - cy.xpath(locator._spanButton('Share')) + cy.xpath(this.locator._spanButton('Share')) .first() .should("be.visible") } @@ -202,7 +198,7 @@ export class HomePage { .should("be.visible") .first() .click(); - cy.get(locator._loading).should("not.exist"); + cy.get(this.locator._loading).should("not.exist"); cy.wait("@getPagesForViewApp").should( "have.nested.property", "response.body.responseMeta.status", @@ -249,7 +245,7 @@ export class HomePage { "response.body.responseMeta.status", 200, ); - agHelper.Sleep(2500)//wait for members page to load! + this.agHelper.Sleep(2500)//wait for members page to load! } public UpdateUserRoleInOrg(orgName: string, email: string, currentRole: string, newRole: string) { @@ -257,9 +253,27 @@ export class HomePage { cy.xpath(this._userRoleDropDown(email, currentRole)).first().trigger('click'); //cy.xpath(this._userRoleDropDown(email)).first().click({force: true}); cy.get(this._visibleTextSpan(newRole)).last().click({ force: true }); - agHelper.Sleep() + this.agHelper.Sleep() this.NavigateToHome() } + + public ImportApp(fixtureJson: string, reconnect = false) { + cy.get(this._homeIcon).click(); + cy.get(this._optionsIcon).first().click(); + cy.get(this._orgImport).click({ force: true }); + cy.get(this._orgImportAppModal).should("be.visible"); + cy.xpath(this._uploadFile).attachFile(fixtureJson).wait(500); + cy.get(this._orgImportAppModal).should("not.exist"); + if (!reconnect) { + this.AssertImport() + } + } + + public AssertImport() { + this.agHelper.ValidateToastMessage("Application imported successfully") + this.agHelper.Sleep(5000)//for imported app to settle! + cy.get(this.locator._loading).should("not.exist"); + } } diff --git a/app/client/cypress/support/Pages/JSEditor.ts b/app/client/cypress/support/Pages/JSEditor.ts index be8fd5040c..a174c4eb04 100644 --- a/app/client/cypress/support/Pages/JSEditor.ts +++ b/app/client/cypress/support/Pages/JSEditor.ts @@ -1,63 +1,64 @@ -import { AggregateHelper } from "./AggregateHelper"; -import { CommonLocators } from "../Objects/CommonLocators"; -import apiwidget from "../../locators/apiWidgetslocator.json"; - -const agHelper = new AggregateHelper(); -const locator = new CommonLocators(); - +import { ObjectsRegistry } from "../Objects/Registry" export class JSEditor { + + public agHelper = ObjectsRegistry.AggregateHelper + public locator = ObjectsRegistry.CommonLocators; + public ee = ObjectsRegistry.EntityExplorer; + private _runButton = "//li//*[local-name() = 'svg' and @class='run-button']"; private _jsObjName = ".t--js-action-name-edit-field span"; private _jsObjTxt = ".t--js-action-name-edit-field input"; private _newJSobj = "span:contains('New JS Object')" private _bindingsClose = ".t--entity-property-close" + private _propertyList = ".t--entity-property" + public NavigateToJSEditor() { - cy.get(locator._createNew) + cy.get(this.locator._createNew) .last() .click({ force: true }); cy.get(this._newJSobj).click({ force: true }); - //cy.waitUntil(() => cy.get(locator._toastMsg).should('not.be.visible')) // fails sometimes - agHelper.WaitUntilEleDisappear(locator._toastMsg, 'created successfully', 1000) + //cy.waitUntil(() => cy.get(this.locator._toastMsg).should('not.be.visible')) // fails sometimes + this.agHelper.WaitUntilEleDisappear(this.locator._toastMsg, 'created successfully') } - public CreateJSObject(JSCode: string, paste = true, completeReplace = false) { + public CreateJSObject(JSCode: string, paste = true, completeReplace = false, toRun = true) { this.NavigateToJSEditor(); if (!completeReplace) { - cy.get(locator._codeMirrorTextArea) + cy.get(this.locator._codeMirrorTextArea) .first() .focus() .type("{downarrow}{downarrow}{downarrow}{downarrow} ") } else { - cy.get(locator._codeMirrorTextArea) - .first() - .focus() - .type("{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}") - .type("{shift}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}", { force: true }) - .type("{backspace}",{ force: true }); + cy.get(this.locator._codeMirrorTextArea) + .first() + .focus() + .type("{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}") + .type("{shift}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}", { force: true }) + .type("{backspace}", { force: true }); // .type("{uparrow}", { force: true }) // .type("{ctrl}{shift}{downarrow}", { force: true }) // .type("{del}",{ force: true }); - // cy.get(locator._codeEditorTarget).contains('export').click().closest(locator._codeEditorTarget) + // cy.get(this.locator._codthis.eeditorTarget).contains('export').click().closest(this.locator._codthis.eeditorTarget) // .type("{uparrow}", { force: true }) // .type("{ctrl}{shift}{downarrow}", { force: true }) // .type("{backspace}",{ force: true }); //.type("{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow} ") - } + } - cy.get(locator._codeMirrorTextArea) + cy.get(this.locator._codeMirrorTextArea) .first() .then((el: any) => { const input = cy.get(el); if (paste) { //input.invoke("val", value); - agHelper.Paste(el, JSCode) + this.agHelper.Paste(el, JSCode) } else { input.type(JSCode, { parseSpecialCharSequences: false, delay: 150 @@ -65,34 +66,36 @@ export class JSEditor { } }); - agHelper.WaitAutoSave()//Ample wait due to open bug # 10284 - agHelper.Sleep(5000)//Ample wait due to open bug # 10284 + this.agHelper.AssertAutoSave()//Ample wait due to open bug # 10284 + this.agHelper.Sleep(5000)//Ample wait due to open bug # 10284 - //clicking 1 times & waits for 3 second for result to be populated! - Cypress._.times(1, () => { - cy.xpath(this._runButton) - .first() - .click() - .wait(3000) - }) - cy.get(locator._empty).should('not.exist') - cy.get(locator._toastMsg).should("have.length", 0) + if (toRun) { + //clicking 1 times & waits for 3 second for result to be populated! + Cypress._.times(1, () => { + cy.xpath(this._runButton) + .first() + .click() + .wait(3000) + }) + cy.get(this.locator._empty).should('not.exist') + cy.get(this.locator._toastMsg).should("have.length", 0) + } this.GetJSObjectName() } public EnterJSContext(endp: string, value: string, paste = true, toToggleOnJS = false) { if (toToggleOnJS) { - cy.get(locator._jsToggle(endp)) + cy.get(this.locator._jsToggle(endp)) .invoke("attr", "class") .then((classes: any) => { if (!classes.includes("is-active")) { - cy.get(locator._jsToggle(endp)) + cy.get(this.locator._jsToggle(endp)) .first() .click({ force: true }); } }); } - cy.get(locator._propertyControl + endp + " " + locator._codeMirrorTextArea) + cy.get(this.locator._propertyControl + endp + " " + this.locator._codeMirrorTextArea) .first() .focus() .type("{uparrow}", { force: true }) @@ -102,7 +105,7 @@ export class JSEditor { cy.focused().then(($cm: any) => { if ($cm.contents != "") { cy.log("The field is not empty"); - cy.get(locator._propertyControl + endp + " " + locator._codeMirrorTextArea) + cy.get(this.locator._propertyControl + endp + " " + this.locator._codeMirrorTextArea) .first() .click({ force: true }) .focused() @@ -110,14 +113,14 @@ export class JSEditor { force: true, }); } - agHelper.Sleep() - cy.get(locator._propertyControl + endp + " " + locator._codeMirrorTextArea) + this.agHelper.Sleep() + cy.get(this.locator._propertyControl + endp + " " + this.locator._codeMirrorTextArea) .first() .then((el: any) => { const input = cy.get(el); if (paste) { //input.invoke("val", value); - agHelper.Paste(el, value) + this.agHelper.Paste(el, value) } else { input.type(value, { parseSpecialCharSequences: false, @@ -125,7 +128,7 @@ export class JSEditor { } }); }); - agHelper.WaitAutoSave()//Allowing time for Evaluate value to capture value + this.agHelper.AssertAutoSave()//Allowing time for Evaluate value to capture value } public RenameJSObjFromForm(renameVal: string) { @@ -135,16 +138,16 @@ export class JSEditor { .type(renameVal, { force: true }) .should("have.value", renameVal) .blur(); - agHelper.Sleep(); //allowing time for name change to reflect in EntityExplorer + this.agHelper.Sleep(); //allowing time for name change to reflect in EntityExplorer } public RenameJSObjFromExplorer(entityName: string, renameVal: string) { - agHelper.ActionContextMenuByEntityName("RenamedJSObject", "Edit Name"); - cy.xpath(locator._entityNameEditing(entityName)).type( + this.ee.ActionContextMenuByEntityName("RenamedJSObject", "Edit Name"); + cy.xpath(this.locator._entityNameEditing(entityName)).type( renameVal + "{enter}", ); - agHelper.ValidateEntityPresenceInExplorer(renameVal); - agHelper.Sleep(); //allowing time for name change to reflect in EntityExplorer + this.ee.AssertEntityPresenceInExplorer(renameVal); + this.agHelper.Sleep(); //allowing time for name change to reflect in EntityExplorer } public GetJSObjectName() { @@ -153,8 +156,8 @@ export class JSEditor { } public validateDefaultJSObjProperties(jsObjName: string) { - agHelper.ActionContextMenuByEntityName(jsObjName, "Show Bindings"); - cy.get(apiwidget.propertyList).then(function ($lis) { + this.ee.ActionContextMenuByEntityName(jsObjName, "Show Bindings"); + cy.get(this._propertyList).then(function ($lis) { expect($lis).to.have.length(4); expect($lis.eq(0).text()).to.be.oneOf([ "{{" + jsObjName + ".myFun2()}}", diff --git a/app/client/cypress/support/Pages/Table.ts b/app/client/cypress/support/Pages/Table.ts new file mode 100644 index 0000000000..ecb8a2f37e --- /dev/null +++ b/app/client/cypress/support/Pages/Table.ts @@ -0,0 +1,106 @@ +import { ObjectsRegistry } from "../Objects/Registry" + +export class Table { + public agHelper = ObjectsRegistry.AggregateHelper + public locator = ObjectsRegistry.CommonLocators + + private _tableWrap = "//div[@class='tableWrap']" + private _tableHeader = this._tableWrap + "//div[@class='thead']//div[@class='tr'][1]" + private _columnHeader = (columnName: string) => this._tableWrap + "//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='" + columnName + "']/parent::div/parent::div" + private _nextPage = ".t--widget-tablewidget .t--table-widget-next-page" + private _previousPage = ".t--widget-tablewidget .t--table-widget-prev-page" + private _pageNumber = ".t--widget-tablewidget .page-item" + private _pageNumberServerSideOff = ".t--widget-tablewidget .t--table-widget-page-input input" + _tableRowColumn = (rowNum: number, colNum: number) => `.t--widget-tablewidget .tbody .td[data-rowindex=${rowNum}][data-colindex=${colNum}] div div` + _tableEmptyColumnData = `.t--widget-tablewidget .tbody .td` //selected-row + _tableSelectedRow = this._tableWrap + "//div[contains(@class, 'tbody')]//div[contains(@class, 'selected-row')]/div" + + + public WaitUntilTableLoad() { + // cy.waitUntil(() => cy.xpath(this._table, { timeout: 80000 }).should('be.visible'), + // { + // errorMsg: "Element did not appear", + // timeout: 10000, + // interval: 2000 + // }).then(() => this.agHelper.Sleep(500)) + + // this.ReadTableRowColumnData(0, 0).then((cellData) => { + // expect(cellData).not.empty; + // }); + + cy.waitUntil(() => this.ReadTableRowColumnData(0, 0).then(cellData => expect(cellData).not.empty), + { + errorMsg: "Table is not populated", + timeout: 10000, + interval: 2000 + }).then(() => this.agHelper.Sleep(500)) + } + + public WaitForTableEmpty() { + cy.waitUntil(() => cy.get(this._tableEmptyColumnData).children().should("have.length", 0), + { + errorMsg: "Table is populated when not expected", + timeout: 10000, + interval: 2000 + }).then(() => this.agHelper.Sleep(500)) + } + + public AssertTableHeaderOrder(expectedOrder: string) { + cy.xpath(this._tableHeader).invoke("text").then((x) => { + expect(x).to.eq(expectedOrder); + }); + } + + public ReadTableRowColumnData(rowNum: number, colNum: number) { + return cy.get(this._tableRowColumn(rowNum, colNum), { timeout: 80000 }).invoke("text"); + } + + public AssertHiddenColumns(columnNames: string[]) { + columnNames.forEach($header => { + cy.xpath(this._columnHeader($header)) + .invoke("attr", "class") + .then((classes) => { + expect(classes).includes("hidden-header"); + }); + }) + } + + public NavigateToNextPage() { + let curPageNo: number; + cy.get(this._pageNumber).invoke('text').then($currentPageNo => + curPageNo = Number($currentPageNo)) + cy.get(this._nextPage).click() + cy.get(this._pageNumber).invoke('text').then($newPageNo => + expect(Number($newPageNo)).to.eq(curPageNo + 1)) + } + + public NavigateToPreviousPage() { + let curPageNo: number; + cy.get(this._pageNumber).invoke('text').then($currentPageNo => + curPageNo = Number($currentPageNo)) + cy.get(this._previousPage).click() + cy.get(this._pageNumber).invoke('text').then($newPageNo => + expect(Number($newPageNo)).to.eq(curPageNo - 1)) + } + + public AssertPageNumber(pageNo: number, serverSide: 'Off' | 'On' = 'On') { + if (serverSide == 'On') + cy.get(this._pageNumber).should('have.text', Number(pageNo)) + else { + cy.get(this._pageNumberServerSideOff).should('have.value', Number(pageNo)) + cy.get(this._previousPage).should("have.attr", 'disabled') + cy.get(this._nextPage).should("have.attr", 'disabled') + } + if (pageNo == 1) + cy.get(this._previousPage).should("have.attr", 'disabled') + } + + public AssertSelectedRow(rowNum: number = 0) { + cy.xpath(this._tableSelectedRow) + .invoke("attr", "data-rowindex") + .then($rowIndex => { + expect(Number($rowIndex)).to.eq(rowNum); + }); + } + +} \ No newline at end of file diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 7c2bb0170c..753535b5ac 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -479,7 +479,7 @@ Cypress.Commands.add("LogintoApp", (uname, pword) => { cy.visit("/user/login"); cy.get(loginPage.username).should("be.visible"); cy.get(loginPage.username).type(uname); - cy.get(loginPage.password).type(pword); + cy.get(loginPage.password).type(pword, { log: false }); cy.get(loginPage.submitBtn).click(); cy.wait("@getUser"); cy.wait(3000); @@ -889,7 +889,8 @@ Cypress.Commands.add("enterDatasource", (datasource) => { cy.get(apiwidget.resourceUrl) .first() .click({ force: true }) - .type(datasource, { parseSpecialCharSequences: false }); + .type(datasource, { parseSpecialCharSequences: false }) + .type("{esc}}"); }); Cypress.Commands.add("changeZoomLevel", (zoomValue) => { diff --git a/app/client/src/assets/icons/widget/alert.svg b/app/client/src/assets/icons/widget/alert.svg deleted file mode 100644 index 71eeb2297a..0000000000 --- a/app/client/src/assets/icons/widget/alert.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/audio-recorder.svg b/app/client/src/assets/icons/widget/audio-recorder.svg deleted file mode 100755 index 85d23c1773..0000000000 --- a/app/client/src/assets/icons/widget/audio-recorder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/audio.svg b/app/client/src/assets/icons/widget/audio.svg deleted file mode 100644 index d6069c08b0..0000000000 --- a/app/client/src/assets/icons/widget/audio.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/button-group.svg b/app/client/src/assets/icons/widget/button-group.svg deleted file mode 100644 index 93e175d443..0000000000 --- a/app/client/src/assets/icons/widget/button-group.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/button.svg b/app/client/src/assets/icons/widget/button.svg deleted file mode 100644 index 6246b31269..0000000000 --- a/app/client/src/assets/icons/widget/button.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/camera.svg b/app/client/src/assets/icons/widget/camera.svg deleted file mode 100755 index 4057fae9ac..0000000000 --- a/app/client/src/assets/icons/widget/camera.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/chart.svg b/app/client/src/assets/icons/widget/chart.svg deleted file mode 100644 index 10b7930eb1..0000000000 --- a/app/client/src/assets/icons/widget/chart.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/checkbox-group.svg b/app/client/src/assets/icons/widget/checkbox-group.svg deleted file mode 100755 index 431fada640..0000000000 --- a/app/client/src/assets/icons/widget/checkbox-group.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/checkbox.svg b/app/client/src/assets/icons/widget/checkbox.svg deleted file mode 100644 index 3c20df48ff..0000000000 --- a/app/client/src/assets/icons/widget/checkbox.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/circular-progress.svg b/app/client/src/assets/icons/widget/circular-progress.svg deleted file mode 100644 index d50c9e22b1..0000000000 --- a/app/client/src/assets/icons/widget/circular-progress.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/app/client/src/assets/icons/widget/collapse.svg b/app/client/src/assets/icons/widget/collapse.svg deleted file mode 100644 index 8cbcb11329..0000000000 --- a/app/client/src/assets/icons/widget/collapse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/container.svg b/app/client/src/assets/icons/widget/container.svg deleted file mode 100644 index e7d9792336..0000000000 --- a/app/client/src/assets/icons/widget/container.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/currencyInput.svg b/app/client/src/assets/icons/widget/currencyInput.svg deleted file mode 100644 index 7da986a933..0000000000 --- a/app/client/src/assets/icons/widget/currencyInput.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/app/client/src/assets/icons/widget/datepicker.svg b/app/client/src/assets/icons/widget/datepicker.svg deleted file mode 100644 index caea05bfd4..0000000000 --- a/app/client/src/assets/icons/widget/datepicker.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/divider.svg b/app/client/src/assets/icons/widget/divider.svg deleted file mode 100644 index db2cc65c08..0000000000 --- a/app/client/src/assets/icons/widget/divider.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/dropdown.svg b/app/client/src/assets/icons/widget/dropdown.svg deleted file mode 100644 index 12f5d912e4..0000000000 --- a/app/client/src/assets/icons/widget/dropdown.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/embed.svg b/app/client/src/assets/icons/widget/embed.svg deleted file mode 100755 index 75d04fae11..0000000000 --- a/app/client/src/assets/icons/widget/embed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/filepicker.svg b/app/client/src/assets/icons/widget/filepicker.svg deleted file mode 100644 index cf5335aadd..0000000000 --- a/app/client/src/assets/icons/widget/filepicker.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/form.svg b/app/client/src/assets/icons/widget/form.svg deleted file mode 100644 index 88b4c3e2e9..0000000000 --- a/app/client/src/assets/icons/widget/form.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/icon-button.svg b/app/client/src/assets/icons/widget/icon-button.svg deleted file mode 100755 index af9416caab..0000000000 --- a/app/client/src/assets/icons/widget/icon-button.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/image.svg b/app/client/src/assets/icons/widget/image.svg deleted file mode 100644 index 395ba51c3d..0000000000 --- a/app/client/src/assets/icons/widget/image.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/input.svg b/app/client/src/assets/icons/widget/input.svg deleted file mode 100644 index 889009e70e..0000000000 --- a/app/client/src/assets/icons/widget/input.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/json-form.svg b/app/client/src/assets/icons/widget/json-form.svg deleted file mode 100644 index 885be38088..0000000000 --- a/app/client/src/assets/icons/widget/json-form.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/app/client/src/assets/icons/widget/list.svg b/app/client/src/assets/icons/widget/list.svg deleted file mode 100644 index 1818ca0370..0000000000 --- a/app/client/src/assets/icons/widget/list.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/location picker.svg b/app/client/src/assets/icons/widget/location picker.svg deleted file mode 100644 index 254038ecd5..0000000000 --- a/app/client/src/assets/icons/widget/location picker.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/client/src/assets/icons/widget/location-picker.svg b/app/client/src/assets/icons/widget/location-picker.svg deleted file mode 100644 index 68150b62e1..0000000000 --- a/app/client/src/assets/icons/widget/location-picker.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/map-chart.svg b/app/client/src/assets/icons/widget/map-chart.svg deleted file mode 100755 index 543938a355..0000000000 --- a/app/client/src/assets/icons/widget/map-chart.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/map.svg b/app/client/src/assets/icons/widget/map.svg deleted file mode 100755 index b199275976..0000000000 --- a/app/client/src/assets/icons/widget/map.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/menu-button.svg b/app/client/src/assets/icons/widget/menu-button.svg deleted file mode 100755 index 22abf1ed77..0000000000 --- a/app/client/src/assets/icons/widget/menu-button.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/menu.svg b/app/client/src/assets/icons/widget/menu.svg deleted file mode 100755 index 6f87aa9903..0000000000 --- a/app/client/src/assets/icons/widget/menu.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/modal.svg b/app/client/src/assets/icons/widget/modal.svg deleted file mode 100644 index 1f67b24e84..0000000000 --- a/app/client/src/assets/icons/widget/modal.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/multi-tree-select.svg b/app/client/src/assets/icons/widget/multi-tree-select.svg deleted file mode 100644 index 7a89adeb59..0000000000 --- a/app/client/src/assets/icons/widget/multi-tree-select.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/multiselect.svg b/app/client/src/assets/icons/widget/multiselect.svg deleted file mode 100644 index 65d9822b1d..0000000000 --- a/app/client/src/assets/icons/widget/multiselect.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/phoneInput.svg b/app/client/src/assets/icons/widget/phoneInput.svg deleted file mode 100644 index 189182612a..0000000000 --- a/app/client/src/assets/icons/widget/phoneInput.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/app/client/src/assets/icons/widget/plus.svg b/app/client/src/assets/icons/widget/plus.svg deleted file mode 100644 index ca280afea0..0000000000 --- a/app/client/src/assets/icons/widget/plus.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/progressbar-icon.svg b/app/client/src/assets/icons/widget/progressbar-icon.svg deleted file mode 100644 index a61c2afb7d..0000000000 --- a/app/client/src/assets/icons/widget/progressbar-icon.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/client/src/assets/icons/widget/radio.svg b/app/client/src/assets/icons/widget/radio.svg deleted file mode 100644 index eb82ce4707..0000000000 --- a/app/client/src/assets/icons/widget/radio.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/rating.svg b/app/client/src/assets/icons/widget/rating.svg deleted file mode 100644 index f26f77728d..0000000000 --- a/app/client/src/assets/icons/widget/rating.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/rich-text.svg b/app/client/src/assets/icons/widget/rich-text.svg deleted file mode 100644 index fc9ce1022c..0000000000 --- a/app/client/src/assets/icons/widget/rich-text.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/single-tree-select.svg b/app/client/src/assets/icons/widget/single-tree-select.svg deleted file mode 100644 index 12f5d912e4..0000000000 --- a/app/client/src/assets/icons/widget/single-tree-select.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/slash.svg b/app/client/src/assets/icons/widget/slash.svg deleted file mode 100644 index e32936f698..0000000000 --- a/app/client/src/assets/icons/widget/slash.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/statbox.svg b/app/client/src/assets/icons/widget/statbox.svg deleted file mode 100644 index 9039aac210..0000000000 --- a/app/client/src/assets/icons/widget/statbox.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/switch-group.svg b/app/client/src/assets/icons/widget/switch-group.svg deleted file mode 100755 index c3990e16db..0000000000 --- a/app/client/src/assets/icons/widget/switch-group.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/switch.svg b/app/client/src/assets/icons/widget/switch.svg deleted file mode 100644 index bb51734a86..0000000000 --- a/app/client/src/assets/icons/widget/switch.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/table.svg b/app/client/src/assets/icons/widget/table.svg deleted file mode 100644 index fa8091c0e0..0000000000 --- a/app/client/src/assets/icons/widget/table.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/tabs.svg b/app/client/src/assets/icons/widget/tabs.svg deleted file mode 100644 index 89d70ee6f3..0000000000 --- a/app/client/src/assets/icons/widget/tabs.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/text.svg b/app/client/src/assets/icons/widget/text.svg deleted file mode 100644 index be8c0c7589..0000000000 --- a/app/client/src/assets/icons/widget/text.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/assets/icons/widget/video.svg b/app/client/src/assets/icons/widget/video.svg deleted file mode 100644 index 077b0a5628..0000000000 --- a/app/client/src/assets/icons/widget/video.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/client/src/components/ads/formFields/RedirectUrlForm.test.tsx b/app/client/src/components/ads/formFields/RedirectUrlForm.test.tsx new file mode 100644 index 0000000000..f0993a144c --- /dev/null +++ b/app/client/src/components/ads/formFields/RedirectUrlForm.test.tsx @@ -0,0 +1,41 @@ +import { render, screen } from "test/testUtils"; +import React from "react"; +import { RedirectUrlReduxForm } from "./RedirectUrlForm"; + +let container: any = null; + +const useSelector = jest.fn(); +const values = { + helpText: "some helper text", + value: "/link-to-be-copied", +}; +useSelector.mockReturnValue(values); + +function renderComponent() { + render( + , + ); +} + +describe("Redirect URL Form", () => { + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("is rendered", () => { + renderComponent(); + window.prompt = jest.fn(); + const fieldTitle = screen.getAllByText(/Redirect URL/); + expect(fieldTitle).toBeDefined(); + const inputEl = document.querySelector("input"); + const value = `${window.location.origin}/link-to-be-copied`; + expect(inputEl?.value).toBeDefined(); + expect(inputEl?.value).toEqual(value); + expect(inputEl?.hasAttribute("disabled")); + expect(inputEl?.hasAttribute("iscopy")).toEqual(true); + const copyIcon = document.querySelector(".copy-icon") as HTMLElement; + expect(copyIcon).toBeDefined(); + copyIcon?.click(); + }); +}); diff --git a/app/client/src/components/ads/formFields/RedirectUrlForm.tsx b/app/client/src/components/ads/formFields/RedirectUrlForm.tsx index 9cc1b46abb..4fe34738c3 100644 --- a/app/client/src/components/ads/formFields/RedirectUrlForm.tsx +++ b/app/client/src/components/ads/formFields/RedirectUrlForm.tsx @@ -13,6 +13,8 @@ import { createMessage, REDIRECT_URL_TOOLTIP, } from "@appsmith/constants/messages"; +import { REDIRECT_URL_FORM } from "constants/forms"; +import { Colors } from "constants/Colors"; const HelpIcon = HelpIcons.HELP_ICON; @@ -34,7 +36,7 @@ const HeaderWrapper = styled.div` cursor: pointer; svg { border-radius: 50%; - border: 1px solid #858282; + border: 1px solid ${Colors.GREY_7}; padding: 1px; } } @@ -81,7 +83,7 @@ function RedirectUrlForm( > @@ -102,6 +104,6 @@ function RedirectUrlForm( } export const RedirectUrlReduxForm = reduxForm({ - form: "Redirect URL", + form: REDIRECT_URL_FORM, touchOnBlur: true, })(RedirectUrlForm); diff --git a/app/client/src/components/ads/formFields/UneditableField.test.tsx b/app/client/src/components/ads/formFields/UneditableField.test.tsx new file mode 100644 index 0000000000..af8c443200 --- /dev/null +++ b/app/client/src/components/ads/formFields/UneditableField.test.tsx @@ -0,0 +1,71 @@ +import { render } from "test/testUtils"; +import React from "react"; +import UneditableField from "./UneditableField"; +import { REDIRECT_URL_FORM } from "constants/forms"; +import { reduxForm } from "redux-form"; + +let container: any = null; +const setting = { + id: "SETTING_UNEDITABLE_FIELD_ID", + name: "SETTING_UNEDITABLE_FIELD_ID", + category: "test category", + helpText: "some helper text", + label: "test label", +}; + +const clickHandler = jest.fn(); + +function renderComponent() { + function UneditableFieldComponent() { + return ( + + ); + } + const Parent = reduxForm({ + validate: () => { + return {}; + }, + form: REDIRECT_URL_FORM, + touchOnBlur: true, + })(UneditableFieldComponent); + + render(, { + initialState: { + form: { + [REDIRECT_URL_FORM]: { + values: { + "uneditable-field": "value to be copied", + }, + }, + }, + }, + }); +} + +describe("Uneditabled Field", () => { + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("is rendered", () => { + renderComponent(); + window.prompt = jest.fn(); + const inputEl = document.querySelector("input"); + const value = `value to be copied`; + expect(inputEl?.value).toBeDefined(); + expect(inputEl?.value).toEqual(value); + expect(inputEl?.hasAttribute("disabled")); + expect(inputEl?.hasAttribute("iscopy")).toEqual(true); + const copyIcon = document.querySelector(".copy-icon") as HTMLElement; + expect(copyIcon).toBeDefined(); + copyIcon?.click(); + }); +}); diff --git a/app/client/src/components/ads/formFields/UneditableField.tsx b/app/client/src/components/ads/formFields/UneditableField.tsx index a2d3276b5f..37eb3f3e1e 100644 --- a/app/client/src/components/ads/formFields/UneditableField.tsx +++ b/app/client/src/components/ads/formFields/UneditableField.tsx @@ -8,7 +8,9 @@ import InputComponent, { InputType } from "../TextInput"; import { Intent } from "constants/DefaultTheme"; import { Colors } from "constants/Colors"; import styled from "styled-components"; -import { ReactComponent as CopyIcon } from "assets/icons/menu/copy-snippet.svg"; +import { HelpIcons } from "icons/HelpIcons"; + +const CopyIcon = HelpIcons.COPY_ICON; const Label = styled.div` font-size: 14px; @@ -24,11 +26,8 @@ const InputCopyWrapper = styled.div` width: 40rem; } - svg { + .copy-icon { margin-left: 12px; - cursor: pointer; - position: absolute; - right: -24px; } `; @@ -45,6 +44,8 @@ const renderComponent = ( {componentProps.iscopy === "true" && ( componentProps.handleCopy(componentProps.input.value) diff --git a/app/client/src/components/editorComponents/Debugger/hooks/useGetEntityInfo.tsx b/app/client/src/components/editorComponents/Debugger/hooks/useGetEntityInfo.tsx index f160c37324..a6a09d8868 100644 --- a/app/client/src/components/editorComponents/Debugger/hooks/useGetEntityInfo.tsx +++ b/app/client/src/components/editorComponents/Debugger/hooks/useGetEntityInfo.tsx @@ -1,11 +1,7 @@ import { isStoredDatasource } from "entities/Action"; import { ENTITY_TYPE } from "entities/AppsmithConsole"; import { isEqual, keyBy } from "lodash"; -import { - getPluginIcon, - getWidgetIcon, - jsIcon, -} from "pages/Editor/Explorer/ExplorerIcons"; +import { getPluginIcon, jsIcon } from "pages/Editor/Explorer/ExplorerIcons"; import { useMemo, useCallback } from "react"; import { AppState } from "reducers"; import { getFilteredErrors } from "selectors/debuggerSelectors"; @@ -13,6 +9,8 @@ import { getAction, getDatasource } from "selectors/entitiesSelector"; import { useSelector } from "react-redux"; import { isAction, isJSAction, isWidget } from "workers/evaluationUtils"; import { doesEntityHaveErrors } from "../helpers"; +import React from "react"; +import WidgetIcon from "pages/Editor/Explorer/Widgets/WidgetIcon"; export const useGetEntityInfo = (name: string) => { const entity = useSelector((state: AppState) => state.evaluations.tree[name]); @@ -33,7 +31,7 @@ export const useGetEntityInfo = (name: string) => { const getEntityInfo = useCallback(() => { if (isWidget(entity)) { - const icon = getWidgetIcon(entity.type); + const icon = ; const hasError = doesEntityHaveErrors(entity.widgetId, debuggerErrors); return { diff --git a/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx b/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx index 3c2e9665ce..e351777cc7 100644 --- a/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx +++ b/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx @@ -19,7 +19,6 @@ import { } from "./utils"; import SearchContext from "./GlobalSearchContext"; import { - getWidgetIcon, getPluginIcon, homePageIcon, pageIcon, @@ -32,6 +31,7 @@ import { AppState } from "reducers"; import { keyBy, noop } from "lodash"; import { getPageList } from "selectors/editorSelectors"; import { PluginType } from "entities/Action"; +import WidgetIcon from "pages/Editor/Explorer/Widgets/WidgetIcon"; const DocumentIcon = HelpIcons.DOCUMENT; @@ -181,14 +181,13 @@ function WidgetItem(props: { const title = getItemTitle(item); const pageName = usePageName(item.pageId); const subText = `${pageName}`; - return ( <> - {getWidgetIcon(type)} + diff --git a/app/client/src/components/editorComponents/form/fields/StyledFormComponents.tsx b/app/client/src/components/editorComponents/form/fields/StyledFormComponents.tsx index 3a90d64a55..41a914292d 100644 --- a/app/client/src/components/editorComponents/form/fields/StyledFormComponents.tsx +++ b/app/client/src/components/editorComponents/form/fields/StyledFormComponents.tsx @@ -33,7 +33,7 @@ font-size: 12px; //Styled help text, intended to be used with Form Fields const FormInputHelperText = styled.p<{ addMarginTop?: string }>` - color: #858282; + color: ${Colors.GREY_7}; font-style: normal; font-weight: normal; font-size: 12px; diff --git a/app/client/src/constants/forms.ts b/app/client/src/constants/forms.ts index 7584fbabba..e678fecea9 100644 --- a/app/client/src/constants/forms.ts +++ b/app/client/src/constants/forms.ts @@ -35,3 +35,4 @@ export const WELCOME_FORM_CUSTOM_USECASE_FIELD_NAME = "custom_useCase"; export const SETTINGS_FORM_NAME = "SettingsForm"; export const WELCOME_NON_SUPER_FORM_NAME = "WelcomeNonSuperSetupForm"; +export const REDIRECT_URL_FORM = "RedirectURLForm"; diff --git a/app/client/src/icons/HelpIcons.tsx b/app/client/src/icons/HelpIcons.tsx index ac0fed452b..c641a8d292 100644 --- a/app/client/src/icons/HelpIcons.tsx +++ b/app/client/src/icons/HelpIcons.tsx @@ -7,6 +7,7 @@ import DocumentIcon from "remixicon-react/FileTextFillIcon"; import HelpIcon from "remixicon-react/QuestionMarkIcon"; import DiscordIcon from "remixicon-react/DiscordFillIcon"; import OpenLinkIcon from "remixicon-react/ShareBoxLineIcon"; +import FileCopyLineIcon from "remixicon-react/FileCopyLineIcon"; /* eslint-disable react/display-name */ @@ -53,6 +54,11 @@ export const HelpIcons: { ), + COPY_ICON: (props: IconProps) => ( + + + + ), }; export type HelpIconName = keyof typeof HelpIcons; diff --git a/app/client/src/icons/WidgetIcons.test.tsx b/app/client/src/icons/WidgetIcons.test.tsx deleted file mode 100644 index ef91c74382..0000000000 --- a/app/client/src/icons/WidgetIcons.test.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from "react"; -import { WidgetIcons } from "./WidgetIcons"; -import { render, screen } from "@testing-library/react"; - -import { ThemeProvider, theme } from "constants/DefaultTheme"; - -const ListWidgetIcon = WidgetIcons["LIST_WIDGET"]; - -describe("WidgetIcons", () => { - it("checks widget icon for list widget", () => { - render( - - - , - ); - - const input = screen.queryByTestId("list-widget-icon"); - expect(input).toBeTruthy(); - }); -}); diff --git a/app/client/src/icons/WidgetIcons.tsx b/app/client/src/icons/WidgetIcons.tsx deleted file mode 100644 index 73a86d6149..0000000000 --- a/app/client/src/icons/WidgetIcons.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import React, { JSXElementConstructor } from "react"; -import styled from "styled-components"; - -import { Colors } from "constants/Colors"; -import { IconProps, IconWrapper } from "constants/IconConstants"; -import { ReactComponent as SpinnerIcon } from "assets/icons/widget/alert.svg"; -import { ReactComponent as ButtonIcon } from "assets/icons/widget/button.svg"; -import { ReactComponent as CollapseIcon } from "assets/icons/widget/collapse.svg"; -import { ReactComponent as ContainerIcon } from "assets/icons/widget/container.svg"; -import { ReactComponent as DatePickerIcon } from "assets/icons/widget/datepicker.svg"; -import { ReactComponent as TableIcon } from "assets/icons/widget/table.svg"; -import { ReactComponent as VideoIcon } from "assets/icons/widget/video.svg"; -import { ReactComponent as DropDownIcon } from "assets/icons/widget/dropdown.svg"; -import { ReactComponent as MultiSelectIcon } from "assets/icons/widget/multiselect.svg"; -import { ReactComponent as MultiSelectV2Icon } from "assets/icons/widget/multiselect.svg"; -import { ReactComponent as CheckboxIcon } from "assets/icons/widget/checkbox.svg"; -import { ReactComponent as RadioGroupIcon } from "assets/icons/widget/radio.svg"; -import { ReactComponent as InputIcon } from "assets/icons/widget/input.svg"; -import { ReactComponent as SwitchIcon } from "assets/icons/widget/switch.svg"; -import { ReactComponent as TextIcon } from "assets/icons/widget/text.svg"; -import { ReactComponent as ImageIcon } from "assets/icons/widget/image.svg"; -import { ReactComponent as FilePickerIcon } from "assets/icons/widget/filepicker.svg"; -import { ReactComponent as TabsIcon } from "assets/icons/widget/tabs.svg"; -import { ReactComponent as RichTextEditorIcon } from "assets/icons/widget/rich-text.svg"; -import { ReactComponent as ChartIcon } from "assets/icons/widget/chart.svg"; -import { ReactComponent as FormIcon } from "assets/icons/widget/form.svg"; -import { ReactComponent as MapIcon } from "assets/icons/widget/map.svg"; -import { ReactComponent as ModalIcon } from "assets/icons/widget/modal.svg"; -import { ReactComponent as ListIcon } from "assets/icons/widget/list.svg"; -import { ReactComponent as RatingIcon } from "assets/icons/widget/rating.svg"; -import { ReactComponent as EmbedIcon } from "assets/icons/widget/embed.svg"; -import { ReactComponent as DividerIcon } from "assets/icons/widget/divider.svg"; -import { ReactComponent as MenuButtonIcon } from "assets/icons/widget/menu-button.svg"; -import { ReactComponent as MultiTreeSelectIcon } from "assets/icons/widget/multi-tree-select.svg"; -import { ReactComponent as SingleTreeSelectIcon } from "assets/icons/widget/single-tree-select.svg"; -import { ReactComponent as IconButtonIcon } from "assets/icons/widget/icon-button.svg"; -import { ReactComponent as StatboxIcon } from "assets/icons/widget/statbox.svg"; -import { ReactComponent as CheckboxGroupIcon } from "assets/icons/widget/checkbox-group.svg"; -import { ReactComponent as AudioRecorderIcon } from "assets/icons/widget/audio-recorder.svg"; -import { ReactComponent as AudioIcon } from "assets/icons/widget/audio.svg"; -import { ReactComponent as ButtonGroupIcon } from "assets/icons/widget/button-group.svg"; -import { ReactComponent as ProgressBarIcon } from "assets/icons/widget/progressbar-icon.svg"; -import { ReactComponent as SwitchGroupIcon } from "assets/icons/widget/switch-group.svg"; -import { ReactComponent as CameraIcon } from "assets/icons/widget/camera.svg"; -import { ReactComponent as MapChartIcon } from "assets/icons/widget/map-chart.svg"; -import { ReactComponent as PhoneInput } from "assets/icons/widget/phoneInput.svg"; -import { ReactComponent as CurrencyInput } from "assets/icons/widget/currencyInput.svg"; -import { ReactComponent as CircularProgressIcon } from "assets/icons/widget/circular-progress.svg"; -import { ReactComponent as JSONFormIcon } from "assets/icons/widget/json-form.svg"; - -/* eslint-disable react/display-name */ - -const StyledIconWrapper = styled(IconWrapper)` - svg { - path { - fill: ${Colors.CHARCOAL} !important; - } - } -`; - -export const WidgetIcons: { - [id: string]: JSXElementConstructor; -} = { - SPINNER_WIDGET: (props: IconProps) => ( - - - - ), - BUTTON_WIDGET: (props: IconProps) => ( - - - - ), - CHECKBOX_WIDGET: (props: IconProps) => ( - - - - ), - COLLAPSE_WIDGET: (props: IconProps) => ( - - - - ), - CONTAINER_WIDGET: (props: IconProps) => ( - - - - ), - DATE_PICKER_WIDGET2: (props: IconProps) => ( - - - - ), - TABLE_WIDGET: (props: IconProps) => ( - - - - ), - VIDEO_WIDGET: (props: IconProps) => ( - - - - ), - DROP_DOWN_WIDGET: (props: IconProps) => ( - - - - ), - MULTI_SELECT_WIDGET: (props: IconProps) => ( - - - - ), - SELECT_WIDGET: (props: IconProps) => ( - - - - ), - MULTI_SELECT_WIDGET_V2: (props: IconProps) => ( - - - - ), - RADIO_GROUP_WIDGET: (props: IconProps) => ( - - - - ), - INPUT_WIDGET: (props: IconProps) => ( - - - - ), - INPUT_WIDGET_V2: (props: IconProps) => ( - - - - ), - RICH_TEXT_EDITOR_WIDGET: (props: IconProps) => ( - - - - ), - SWITCH_WIDGET: (props: IconProps) => ( - - - - ), - TEXT_WIDGET: (props: IconProps) => ( - - - - ), - IMAGE_WIDGET: (props: IconProps) => ( - - - - ), - FILE_PICKER_WIDGET_V2: (props: IconProps) => ( - - - - ), - TABS_WIDGET: (props: IconProps) => ( - - - - ), - CHART_WIDGET: (props: IconProps) => ( - - - - ), - FORM_WIDGET: (props: IconProps) => ( - - - - ), - MAP_WIDGET: (props: IconProps) => ( - - - - ), - MODAL_WIDGET: (props: IconProps) => ( - - - - ), - FORM_BUTTON_WIDGET: (props: IconProps) => ( - - - - ), - LIST_WIDGET: (props: IconProps) => ( - - - - ), - RATE_WIDGET: (props: IconProps) => ( - - - - ), - IFRAME_WIDGET: (props: IconProps) => ( - - - - ), - DIVIDER_WIDGET: (props: IconProps) => ( - - - - ), - MENU_BUTTON_WIDGET: (props: IconProps) => ( - - - - ), - SINGLE_SELECT_TREE_WIDGET: (props: IconProps) => ( - - - - ), - MULTI_SELECT_TREE_WIDGET: (props: IconProps) => ( - - - - ), - ICON_BUTTON_WIDGET: (props: IconProps) => ( - - - - ), - STATBOX_WIDGET: (props: IconProps) => ( - - - - ), - CHECKBOX_GROUP_WIDGET: (props: IconProps) => ( - - - - ), - AUDIO_RECORDER_WIDGET: (props: IconProps) => ( - - - - ), - AUDIO_WIDGET: (props: IconProps) => ( - - - - ), - BUTTON_GROUP_WIDGET: (props: IconProps) => ( - - - - ), - PROGRESSBAR_WIDGET: (props: IconProps) => ( - - - - ), - SWITCH_GROUP_WIDGET: (props: IconProps) => ( - - - - ), - CAMERA_WIDGET: (props: IconProps) => ( - - - - ), - MAP_CHART_WIDGET: (props: IconProps) => ( - - - - ), - PHONE_INPUT_WIDGET: (props: IconProps) => ( - - - - ), - CURRENCY_INPUT_WIDGET: (props: IconProps) => ( - - - - ), - CIRCULAR_PROGRESS_WIDGET: (props: IconProps) => ( - - - - ), - JSON_FORM_WIDGET: (props: IconProps) => ( - - - - ), -}; - -export type WidgetIcon = typeof WidgetIcons[keyof typeof WidgetIcons]; diff --git a/app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx b/app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx index ae65943216..2e58701b40 100644 --- a/app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx +++ b/app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx @@ -534,21 +534,29 @@ class DatasourceRestAPIEditor extends React.Component< {this.renderAuthFields()} {this.renderSelfSignedCertificateFields()} - - - this.save( - redirectAuthorizationCode(pageId, datasourceId, PluginType.API), - ) - } - size="small" - text={isAuthorized ? "Save and Re-Authorize" : "Save and Authorize"} - /> - + {formData.authType && formData.authType === AuthType.OAuth2 && ( + + + this.save( + redirectAuthorizationCode( + pageId, + datasourceId, + PluginType.API, + ), + ) + } + size="small" + text={ + isAuthorized ? "Save and Re-Authorize" : "Save and Authorize" + } + /> + + )} ); }; diff --git a/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx b/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx index ff6fb0da5c..74da518721 100644 --- a/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx +++ b/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx @@ -1,8 +1,6 @@ import React, { ReactNode } from "react"; import { MenuIcons } from "icons/MenuIcons"; import { Colors } from "constants/Colors"; -import { WidgetType } from "constants/WidgetConstants"; -import { WidgetIcons } from "icons/WidgetIcons"; import { Plugin } from "api/PluginApi"; import ImageAlt from "assets/images/placeholder-image.svg"; import styled from "styled-components"; @@ -151,13 +149,6 @@ export const DATASOURCE_FIELD_ICONS_MAP: Record = { [FOREIGN_KEY]: foreignKeyIcon, }; -export const getWidgetIcon = (type: WidgetType) => { - const WidgetIcon = WidgetIcons[type]; - if (WidgetIcon) - return ; - return null; -}; - const PluginIcon = styled.img` height: ${ENTITY_ICON_SIZE}px; width: ${ENTITY_ICON_SIZE}px; diff --git a/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx b/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx index d771dd37bf..799390f88a 100644 --- a/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx +++ b/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx @@ -4,12 +4,12 @@ import { WidgetProps } from "widgets/BaseWidget"; import { WidgetType } from "constants/WidgetConstants"; import { useSelector } from "react-redux"; import { AppState } from "reducers"; -import { getWidgetIcon } from "../ExplorerIcons"; import WidgetContextMenu from "./WidgetContextMenu"; import { updateWidgetName } from "actions/propertyPaneActions"; import { CanvasStructure } from "reducers/uiReducers/pageCanvasStructureReducer"; import { getSelectedWidget, getSelectedWidgets } from "selectors/ui"; import { useNavigateToWidget } from "./useNavigateToWidget"; +import WidgetIcon from "./WidgetIcon"; export type WidgetTree = WidgetProps & { children?: WidgetTree[] }; @@ -80,6 +80,7 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => { const widgetsToExpand = useSelector( (state: AppState) => state.ui.widgetDragResize.selectedWidgetAncestry, ); + const icon = ; const shouldExpand = widgetsToExpand.includes(props.widgetId); @@ -129,7 +130,7 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => { contextMenu={showContextMenu && contextMenu} entityId={props.widgetId} highlight={lastSelectedWidget === props.widgetId} - icon={getWidgetIcon(props.widgetType)} + icon={icon} isDefaultExpanded={ shouldExpand || (!!props.searchKeyword && !!props.childWidgets) || diff --git a/app/client/src/pages/Editor/Explorer/Widgets/WidgetIcon.tsx b/app/client/src/pages/Editor/Explorer/Widgets/WidgetIcon.tsx new file mode 100644 index 0000000000..6e1dae2c12 --- /dev/null +++ b/app/client/src/pages/Editor/Explorer/Widgets/WidgetIcon.tsx @@ -0,0 +1,26 @@ +import { IconWrapper } from "constants/IconConstants"; +import { WidgetType } from "constants/WidgetConstants"; +import React from "react"; +import { useSelector } from "react-redux"; +import { getWidgetConfigs } from "selectors/editorSelectors"; +import { ENTITY_ICON_SIZE } from "../ExplorerIcons"; + +function WidgetIcon(props: { + type: WidgetType; + width?: number; + height?: number; +}) { + const { height = ENTITY_ICON_SIZE, type, width = ENTITY_ICON_SIZE } = props; + const widgetConfig = useSelector(getWidgetConfigs); + if (!type) return null; + const svg = widgetConfig.config[type].iconSVG; + if (svg) + return ( + + + + ); + return null; +} + +export default WidgetIcon; diff --git a/app/client/src/pages/Editor/GuidedTour/TourCompletionMessage.tsx b/app/client/src/pages/Editor/GuidedTour/TourCompletionMessage.tsx index d90b9fc96f..c0a3c58c06 100644 --- a/app/client/src/pages/Editor/GuidedTour/TourCompletionMessage.tsx +++ b/app/client/src/pages/Editor/GuidedTour/TourCompletionMessage.tsx @@ -21,6 +21,7 @@ import { RATING_TITLE, } from "@appsmith/constants/messages"; import { getTypographyByKey } from "constants/DefaultTheme"; +import { Colors } from "constants/Colors"; import { builderURL } from "RouteBuilder"; const Container = styled.div` @@ -124,7 +125,7 @@ function CongratulationsView() { emptySymbol={ diff --git a/app/client/src/pages/Settings/DisconnectService.test.tsx b/app/client/src/pages/Settings/DisconnectService.test.tsx new file mode 100644 index 0000000000..01ef8b162e --- /dev/null +++ b/app/client/src/pages/Settings/DisconnectService.test.tsx @@ -0,0 +1,48 @@ +import { render, screen } from "test/testUtils"; +import React from "react"; +import { DisconnectService } from "./DisconnectService"; +import { + createMessage, + DISCONNECT_AUTH_METHOD, + DISCONNECT_CONFIRMATION, +} from "@appsmith/constants/messages"; + +let container: any = null; +const buttonClickHandler = jest.fn(); + +const useSelector = jest.fn(); +const values = { + subHeader: "some subheader value", + warning: "some warning", +}; +useSelector.mockReturnValue(values); + +function renderComponent() { + render( + buttonClickHandler()} + subHeader={values.subHeader} + warning={values.warning} + />, + ); +} + +describe("Disconnect Service", () => { + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("is rendered", () => { + renderComponent(); + const disconnectBtn = screen.queryAllByTestId("disconnect-service-button"); + expect(disconnectBtn).toHaveLength(1); + expect(disconnectBtn[0].textContent).toEqual( + createMessage(DISCONNECT_AUTH_METHOD), + ); + disconnectBtn[0].click(); + expect(disconnectBtn[0].textContent).toEqual( + createMessage(DISCONNECT_CONFIRMATION), + ); + }); +}); diff --git a/app/client/src/pages/Settings/DisconnectService.tsx b/app/client/src/pages/Settings/DisconnectService.tsx index da8cb81de5..1933746159 100644 --- a/app/client/src/pages/Settings/DisconnectService.tsx +++ b/app/client/src/pages/Settings/DisconnectService.tsx @@ -61,6 +61,7 @@ export function DisconnectService(props: { {props.subHeader} warnDisconnectAuth ? props.disconnect() : setWarnDisconnectAuth(true) } diff --git a/app/client/src/pages/Settings/FormGroup/Accordion.test.tsx b/app/client/src/pages/Settings/FormGroup/Accordion.test.tsx new file mode 100644 index 0000000000..8a84b42d99 --- /dev/null +++ b/app/client/src/pages/Settings/FormGroup/Accordion.test.tsx @@ -0,0 +1,86 @@ +import { render, screen } from "test/testUtils"; +import React from "react"; +import { + SettingTypes, + SettingSubtype, +} from "@appsmith/pages/AdminSettings/config/types"; +import Accordion from "./Accordion"; +import { SETTINGS_FORM_NAME } from "constants/forms"; +import { reduxForm } from "redux-form"; + +let container: any = null; +const setting = { + id: "SETTING_TOGGLE_ID", + name: "SETTING_TOGGLE_ID", + category: "test category", + subCategory: "test sub category", + controlType: SettingTypes.ACCORDION, + label: "test accordion label", + advanced: [ + { + id: "SETTING_TEXT_INPUT_ID", + name: "SETTING_TEXT_INPUT_ID", + category: "test input category", + subCategory: "test input sub category", + controlType: SettingTypes.TEXTINPUT, + controlSubType: SettingSubtype.TEXT, + label: "test input label", + }, + ], +}; + +function renderComponent() { + function ToggleComponent() { + return ( + + ); + } + const Parent = reduxForm({ + validate: () => { + return {}; + }, + form: SETTINGS_FORM_NAME, + touchOnBlur: true, + })(ToggleComponent); + + render(, { + initialState: { + form: { + [SETTINGS_FORM_NAME]: { + values: { + [setting.advanced[0].id]: false, + }, + }, + }, + }, + }); +} + +describe("Accordion", () => { + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("is rendered", () => { + renderComponent(); + expect(screen.getAllByText(/test accordion label/)).toBeDefined(); + expect(document.querySelector("hr")).toBeDefined(); + expect(document.querySelector("[name='expand-more']")).toBeDefined(); + expect(screen.queryByTestId("admin-settings-group-wrapper")).toBeFalsy(); + }); + + it("is open", () => { + renderComponent(); + expect(document.querySelector("hr")).toBeDefined(); + expect(document.querySelector("[name='expand-more']")).toBeDefined(); + document.querySelector("hr")?.click(); + expect(document.querySelector("[name='expand-less']")).toBeDefined(); + expect(screen.queryByTestId("admin-settings-group-wrapper")).toBeDefined(); + }); +}); diff --git a/app/client/src/pages/Settings/FormGroup/TagInputField.test.tsx b/app/client/src/pages/Settings/FormGroup/TagInputField.test.tsx new file mode 100644 index 0000000000..345282c80e --- /dev/null +++ b/app/client/src/pages/Settings/FormGroup/TagInputField.test.tsx @@ -0,0 +1,71 @@ +import { render, screen } from "test/testUtils"; +import React from "react"; +import { SettingTypes } from "@appsmith/pages/AdminSettings/config/types"; +import TagInputField from "./TagInputField"; +import { SETTINGS_FORM_NAME } from "constants/forms"; +import { reduxForm } from "redux-form"; + +let container: any = null; +const setting = { + id: "SETTING_TAG_INPUT_ID", + name: "SETTING_TAG_INPUT_ID", + category: "test category", + controlType: SettingTypes.TAGINPUT, + label: "test label", +}; + +function renderComponent() { + function TagInputFieldComponent() { + return ( + + ); + } + const Parent = reduxForm({ + validate: () => { + return {}; + }, + form: SETTINGS_FORM_NAME, + touchOnBlur: true, + })(TagInputFieldComponent); + + render(, { + initialState: { + form: { + [SETTINGS_FORM_NAME]: { + values: { + [setting.id]: "comma,separated,values", + }, + }, + }, + }, + }); +} + +describe("Tag Input", () => { + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("is rendered", () => { + renderComponent(); + const allTags = document.getElementsByClassName( + "bp3-text-overflow-ellipsis", + ); + const allCrossBtns = document.getElementsByClassName("bp3-tag-remove"); + const numberOfTags = allTags.length; + const numberOfCrossBtns = allCrossBtns.length; + expect(numberOfTags).toEqual(numberOfCrossBtns); + expect(screen.getByText(/comma/)).toBeDefined(); + expect(screen.getByText(/separated/)).toBeDefined(); + expect(screen.getByText(/values/)).toBeDefined(); + }); +}); diff --git a/app/client/src/pages/Settings/FormGroup/TextInput.test.tsx b/app/client/src/pages/Settings/FormGroup/TextInput.test.tsx new file mode 100644 index 0000000000..26d74c1b21 --- /dev/null +++ b/app/client/src/pages/Settings/FormGroup/TextInput.test.tsx @@ -0,0 +1,58 @@ +import { render } from "test/testUtils"; +import React from "react"; +import { + SettingTypes, + SettingSubtype, +} from "@appsmith/pages/AdminSettings/config/types"; +import TextInput from "./TextInput"; +import { SETTINGS_FORM_NAME } from "constants/forms"; +import { reduxForm } from "redux-form"; + +let container: any = null; +const setting = { + id: "SETTING_TEXT_INPUT_ID", + name: "SETTING_TEXT_INPUT_ID", + category: "test category", + controlType: SettingTypes.TEXTINPUT, + controlSubType: SettingSubtype.TEXT, + label: "test label", +}; + +function renderComponent() { + function TextInputFieldComponent() { + return ; + } + const Parent = reduxForm({ + validate: () => { + return {}; + }, + form: SETTINGS_FORM_NAME, + touchOnBlur: true, + })(TextInputFieldComponent); + + render(, { + initialState: { + form: { + [SETTINGS_FORM_NAME]: { + values: { + [setting.id]: "test value", + }, + }, + }, + }, + }); +} + +describe("Text Input", () => { + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("is rendered", () => { + renderComponent(); + const inputEl = document.querySelector("input"); + expect(inputEl?.value).toBeDefined(); + expect(inputEl?.value).toEqual("test value"); + }); +}); diff --git a/app/client/src/pages/Settings/FormGroup/Toggle.test.tsx b/app/client/src/pages/Settings/FormGroup/Toggle.test.tsx new file mode 100644 index 0000000000..5740665809 --- /dev/null +++ b/app/client/src/pages/Settings/FormGroup/Toggle.test.tsx @@ -0,0 +1,62 @@ +import { render } from "test/testUtils"; +import React from "react"; +import { SettingTypes } from "@appsmith/pages/AdminSettings/config/types"; +import Toggle from "./Toggle"; +import { SETTINGS_FORM_NAME } from "constants/forms"; +import { reduxForm } from "redux-form"; + +let container: any = null; +const setting = { + id: "SETTING_TOGGLE_ID", + name: "SETTING_TOGGLE_ID", + category: "test category", + controlType: SettingTypes.TOGGLE, + label: "test label", +}; + +function renderComponent() { + function ToggleComponent() { + return ; + } + const Parent = reduxForm({ + validate: () => { + return {}; + }, + form: SETTINGS_FORM_NAME, + touchOnBlur: true, + })(ToggleComponent); + + render(, { + initialState: { + form: { + [SETTINGS_FORM_NAME]: { + values: { + [setting.id]: false, + }, + }, + }, + }, + }); +} + +describe("Toggle", () => { + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + it("is rendered", () => { + renderComponent(); + const inputEl = document.querySelector("input"); + expect(inputEl?.value).toBeDefined(); + expect(inputEl?.value).toEqual("true"); // value = ![setting.id] + expect(inputEl?.hasAttribute("checked")); + }); + + it("when clicked flips the flag", () => { + renderComponent(); + const inputEl = document.querySelector("input"); + inputEl?.click(); + expect(inputEl?.value).toEqual("false"); + }); +}); diff --git a/app/client/src/sagas/InitSagas.ts b/app/client/src/sagas/InitSagas.ts index 33bd29736a..7c4ea5d025 100644 --- a/app/client/src/sagas/InitSagas.ts +++ b/app/client/src/sagas/InitSagas.ts @@ -357,6 +357,14 @@ export function* initializeAppViewerSaga( let { applicationId } = action.payload; + PerformanceTracker.startAsyncTracking( + PerformanceTransactionName.INIT_VIEW_APP, + ); + + if (branch) yield put(updateBranchLocally(branch)); + + yield put(setAppMode(APP_MODE.PUBLISHED)); + const applicationCall: boolean = yield failFastApiCalls( [fetchApplication({ applicationId, pageId, mode: APP_MODE.PUBLISHED })], [ @@ -371,14 +379,6 @@ export function* initializeAppViewerSaga( if (!applicationCall) return; - if (branch) yield put(updateBranchLocally(branch)); - - PerformanceTracker.startAsyncTracking( - PerformanceTransactionName.INIT_VIEW_APP, - ); - - yield put(setAppMode(APP_MODE.PUBLISHED)); - applicationId = applicationId || (yield select(getCurrentApplicationId)); yield put( updateAppPersistentStore(getPersistentAppStore(applicationId, branch)), diff --git a/app/client/src/selectors/editorSelectors.tsx b/app/client/src/selectors/editorSelectors.tsx index 53e1638454..543187f39e 100644 --- a/app/client/src/selectors/editorSelectors.tsx +++ b/app/client/src/selectors/editorSelectors.tsx @@ -36,7 +36,8 @@ import { PLACEHOLDER_APP_SLUG, PLACEHOLDER_PAGE_SLUG } from "constants/routes"; import { builderURL } from "RouteBuilder"; import { ApplicationVersion } from "actions/applicationActions"; -const getWidgetConfigs = (state: AppState) => state.entities.widgetConfig; +export const getWidgetConfigs = (state: AppState) => + state.entities.widgetConfig; const getPageListState = (state: AppState) => state.entities.pageList; export const getProviderCategories = (state: AppState) => diff --git a/app/client/src/utils/WidgetFactory.tsx b/app/client/src/utils/WidgetFactory.tsx index 52bf48649d..3c02049e09 100644 --- a/app/client/src/utils/WidgetFactory.tsx +++ b/app/client/src/utils/WidgetFactory.tsx @@ -121,6 +121,7 @@ class WidgetFactory { WidgetType, readonly PropertyPaneConfig[] > = new Map(); + static loadingProperties: Map> = new Map(); static widgetConfigMap: Map< WidgetType, @@ -134,6 +135,7 @@ class WidgetFactory { defaultPropertiesMap: Record, metaPropertiesMap: Record, propertyPaneConfig?: PropertyPaneConfig[], + loadingProperties?: Array, ) { if (!this.widgetTypes[widgetType]) { this.widgetTypes[widgetType] = widgetType; @@ -141,6 +143,8 @@ class WidgetFactory { this.derivedPropertiesMap.set(widgetType, derivedPropertiesMap); this.defaultPropertiesMap.set(widgetType, defaultPropertiesMap); this.metaPropertiesMap.set(widgetType, metaPropertiesMap); + loadingProperties && + this.loadingProperties.set(widgetType, loadingProperties); if (propertyPaneConfig) { const validatedPropertyPaneConfig = validatePropertyPaneConfig( @@ -235,6 +239,10 @@ class WidgetFactory { return map; } + static getLoadingProperties(type: WidgetType): Array | undefined { + return this.loadingProperties.get(type); + } + static getWidgetTypeConfigMap(): WidgetTypeConfigMap { const typeConfigMap: WidgetTypeConfigMap = {}; WidgetFactory.getWidgetTypes().forEach((type) => { diff --git a/app/client/src/utils/WidgetLoadingStateUtils.test.ts b/app/client/src/utils/WidgetLoadingStateUtils.test.ts index 52995d3b5a..8830caa806 100644 --- a/app/client/src/utils/WidgetLoadingStateUtils.test.ts +++ b/app/client/src/utils/WidgetLoadingStateUtils.test.ts @@ -7,9 +7,10 @@ import { } from "entities/DataTree/dataTreeFactory"; import { findLoadingEntities, - getEntityDependants, + getEntityDependantPaths, groupAndFilterDependantsMap, } from "utils/WidgetLoadingStateUtils"; +import WidgetFactory from "./WidgetFactory"; const JS_object_tree: DataTreeJSAction = { pluginType: PluginType.JS, @@ -68,14 +69,61 @@ const Query_tree: DataTreeAction = { isLoading: false, }; +const Api_tree: DataTreeAction = { + data: {}, + actionId: "", + config: {}, + pluginType: PluginType.API, + pluginId: "", + name: "", + run: {}, + clear: {}, + dynamicBindingPathList: [], + bindingPaths: {}, + ENTITY_TYPE: ENTITY_TYPE.ACTION, + dependencyMap: {}, + logBlackList: {}, + datasourceUrl: "", + responseMeta: { + isExecutionSuccess: true, + }, + isLoading: false, +}; + +const Table_tree: DataTreeWidget = { + ENTITY_TYPE: ENTITY_TYPE.WIDGET, + bindingPaths: {}, + triggerPaths: {}, + validationPaths: {}, + logBlackList: {}, + propertyOverrideDependency: {}, + overridingPropertyPaths: {}, + privateWidgets: {}, + widgetId: "", + type: "TABLE_WIDGET", + widgetName: "", + renderMode: "CANVAS", + version: 0, + parentColumnSpace: 0, + parentRowSpace: 0, + leftColumn: 0, + rightColumn: 0, + topRow: 0, + bottomRow: 0, + isLoading: false, + animateLoading: true, +}; + const baseDataTree = { JS_file: { ...JS_object_tree, name: "JS_file" }, Select1: { ...Select_tree, name: "Select1" }, Select2: { ...Select_tree, name: "Select2" }, Select3: { ...Select_tree, name: "Select3" }, + Table1: { ...Table_tree, name: "Table1" }, Query1: { ...Query_tree, name: "Query1" }, Query2: { ...Query_tree, name: "Query2" }, Query3: { ...Query_tree, name: "Query3" }, + Api1: { ...Api_tree, name: "Api1" }, }; describe("Widget loading state utils", () => { @@ -116,6 +164,22 @@ describe("Widget loading state utils", () => { ], }; + beforeAll(() => { + // mock WidgetFactory.getLoadingProperties + const loadingPropertiesMap = new Map(); + loadingPropertiesMap.set("TABLE_WIDGET", [/.tableData$/]); + + jest + .spyOn(WidgetFactory, "getLoadingProperties") + .mockImplementation((widgetType) => + loadingPropertiesMap.get(widgetType), + ); + }); + + afterAll(() => { + jest.restoreAllMocks(); + }); + // Select1.options -> JS_file.func1 -> Query1.data it("handles linear dependencies", () => { const loadingEntites = findLoadingEntities( @@ -247,6 +311,20 @@ describe("Widget loading state utils", () => { }); expect(loadingEntites).toStrictEqual(new Set(["Select2"])); }); + + it("includes loading properties", () => { + const loadingEntites = findLoadingEntities(["Api1"], baseDataTree, { + "Api1.data": ["Table1.tableData"], + }); + expect(loadingEntites).toStrictEqual(new Set(["Table1"])); + }); + + it("ignores non-loading properties", () => { + const loadingEntites = findLoadingEntities(["Api1"], baseDataTree, { + "Api1.run": ["Table1.primaryColumns.action.onClick"], + }); + expect(loadingEntites).toStrictEqual(new Set()); + }); }); describe("groupAndFilterDependantsMap", () => { @@ -327,10 +405,10 @@ describe("Widget loading state utils", () => { }); }); - describe("getEntityDependants", () => { + describe("getEntityDependantPaths", () => { // Select1.options -> JS_file.func1 -> Query1.data it("handles simple dependency", () => { - const dependants = getEntityDependants( + const dependants = getEntityDependantPaths( ["Query1"], { Query1: { @@ -342,16 +420,15 @@ describe("Widget loading state utils", () => { }, new Set(), ); - expect(dependants).toStrictEqual({ - names: new Set(["JS_file", "Select1"]), - fullPaths: new Set(["JS_file.func1", "Select1.options"]), - }); + expect(dependants).toStrictEqual( + new Set(["JS_file.func1", "Select1.options"]), + ); }); // Select1.options -> JS_file.func1 -> Query1.data // Select2.options -> JS_file.func2 -> Query1.data it("handles multiple dependencies", () => { - const dependants = getEntityDependants( + const dependants = getEntityDependantPaths( ["Query1"], { Query1: { @@ -364,19 +441,18 @@ describe("Widget loading state utils", () => { }, new Set(), ); - expect(dependants).toStrictEqual({ - names: new Set(["JS_file", "Select1", "Select2"]), - fullPaths: new Set([ + expect(dependants).toStrictEqual( + new Set([ "JS_file.func1", "Select1.options", "JS_file.func2", "Select2.options", ]), - }); + ); }); it("handles specific entity paths", () => { - const dependants = getEntityDependants( + const dependants = getEntityDependantPaths( ["JS_file.func2"], // specific path { Query1: { @@ -392,15 +468,12 @@ describe("Widget loading state utils", () => { }, new Set(), ); - expect(dependants).toStrictEqual({ - names: new Set(["Select2"]), - fullPaths: new Set(["Select2.options"]), - }); + expect(dependants).toStrictEqual(new Set(["Select2.options"])); }); // Select1.options -> JS_file.func1 -> JS_file.internalFunc -> Query1.data it("handles JS self-dependencies", () => { - const dependants = getEntityDependants( + const dependants = getEntityDependantPaths( ["Query1"], { Query1: { @@ -413,19 +486,14 @@ describe("Widget loading state utils", () => { }, new Set(), ); - expect(dependants).toStrictEqual({ - names: new Set(["JS_file", "Select1"]), - fullPaths: new Set([ - "JS_file.internalFunc", - "JS_file.func1", - "Select1.options", - ]), - }); + expect(dependants).toStrictEqual( + new Set(["JS_file.internalFunc", "JS_file.func1", "Select1.options"]), + ); }); // Select1.options -> JS_file.func -> JS_file.internalFunc1 -> JS_file.internalFunc2 -> Query1.data it("handles nested JS self-dependencies", () => { - const dependants = getEntityDependants( + const dependants = getEntityDependantPaths( ["Query1"], { Query1: { @@ -439,15 +507,14 @@ describe("Widget loading state utils", () => { }, new Set(), ); - expect(dependants).toStrictEqual({ - names: new Set(["JS_file", "Select1"]), - fullPaths: new Set([ + expect(dependants).toStrictEqual( + new Set([ "JS_file.internalFunc1", "JS_file.internalFunc2", "JS_file.func", "Select1.options", ]), - }); + ); }); /* Select1.options -> JS.func1 -> Query1.data, @@ -458,7 +525,7 @@ describe("Widget loading state utils", () => { Only Select2 should be listed, not Select1. */ it("handles selective dependencies in same JS file", () => { - const dependants = getEntityDependants( + const dependants = getEntityDependantPaths( ["Query2"], { Query1: { @@ -474,10 +541,9 @@ describe("Widget loading state utils", () => { }, new Set(), ); - expect(dependants).toStrictEqual({ - names: new Set(["JS_file", "Select2"]), - fullPaths: new Set(["JS_file.func2", "Select2.options"]), - }); + expect(dependants).toStrictEqual( + new Set(["JS_file.func2", "Select2.options"]), + ); }); }); }); diff --git a/app/client/src/utils/WidgetLoadingStateUtils.ts b/app/client/src/utils/WidgetLoadingStateUtils.ts index 1e314421d9..d93bda3f92 100644 --- a/app/client/src/utils/WidgetLoadingStateUtils.ts +++ b/app/client/src/utils/WidgetLoadingStateUtils.ts @@ -2,6 +2,7 @@ import { DataTree } from "entities/DataTree/dataTreeFactory"; import { get, set } from "lodash"; import { isJSObject } from "workers/evaluationUtils"; import { DependencyMap } from "./DynamicBindingUtils"; +import WidgetFactory from "./WidgetFactory"; type GroupedDependencyMap = Record; @@ -57,14 +58,13 @@ export const groupAndFilterDependantsMap = ( return entitiesDepMap; }; -// get entities that depend on a given list of entites -// e.g. widgets that depend on a list of actions -export const getEntityDependants = ( +// get entity paths that depend on a given list of entites +// e.g. widget paths that depend on a list of actions +export const getEntityDependantPaths = ( fullEntityPaths: string[], allEntitiesDependantsmap: GroupedDependencyMap, visitedPaths: Set, -): { names: Set; fullPaths: Set } => { - const dependantEntityNames = new Set(); +): Set => { const dependantEntityFullPaths = new Set(); fullEntityPaths.forEach((fullEntityPath) => { @@ -87,25 +87,20 @@ export const getEntityDependants = ( // goes through dependants of a property dependants.forEach((dependantPath) => { - const dependantEntityName = dependantPath.split(".")[0]; // Marking visited paths to avoid infinite recursion. if (visitedPaths.has(dependantPath)) { return; } visitedPaths.add(dependantPath); - dependantEntityNames.add(dependantEntityName); dependantEntityFullPaths.add(dependantPath); - const childDependants = getEntityDependants( + const childDependants = getEntityDependantPaths( [dependantPath], allEntitiesDependantsmap, visitedPaths, ); - childDependants.names.forEach((childDependantName) => { - dependantEntityNames.add(childDependantName); - }); - childDependants.fullPaths.forEach((childDependantPath) => { + childDependants.forEach((childDependantPath) => { dependantEntityFullPaths.add(childDependantPath); }); }); @@ -113,7 +108,7 @@ export const getEntityDependants = ( ); }); - return { names: dependantEntityNames, fullPaths: dependantEntityFullPaths }; + return dependantEntityFullPaths; }; export const findLoadingEntities = ( @@ -125,15 +120,29 @@ export const findLoadingEntities = ( inverseMap, dataTree, ); - const loadingEntitiesDetails = getEntityDependants( + const loadingEntityPaths = getEntityDependantPaths( isLoadingActions, entitiesDependantsMap, new Set(), ); - - // check animateLoading is active on current widgets and set const filteredLoadingEntityNames = new Set(); - loadingEntitiesDetails.names.forEach((entityName) => { + + loadingEntityPaths.forEach((entityPath) => { + const entityPathArray = entityPath.split("."); + const entityName = entityPathArray[0]; + const widgetType = get(dataTree, [entityName, "type"]); + const loadingProperties = WidgetFactory.getLoadingProperties(widgetType); + + // check if propertyPath is listed in widgetConfig + if ( + entityPathArray.length > 1 && + loadingProperties && + !loadingProperties.find((propRegExp) => propRegExp.test(entityPath)) + ) { + return; + } + + // check animateLoading is active on current widgets and set get(dataTree, [entityName, "animateLoading"]) === true && filteredLoadingEntityNames.add(entityName); }); diff --git a/app/client/src/utils/WidgetRegisterHelpers.tsx b/app/client/src/utils/WidgetRegisterHelpers.tsx index 68f8b69985..6fddc07089 100644 --- a/app/client/src/utils/WidgetRegisterHelpers.tsx +++ b/app/client/src/utils/WidgetRegisterHelpers.tsx @@ -26,6 +26,7 @@ export interface WidgetConfiguration { default: Record; meta: Record; derived: DerivedPropertiesMap; + loadingProperties?: Array; }; } @@ -55,6 +56,7 @@ export const registerWidget = (Widget: any, config: WidgetConfiguration) => { config.properties.default, config.properties.meta, config.properties.config, + config.properties.loadingProperties, ); configureWidget(config); }; diff --git a/app/client/src/widgets/BaseWidget.tsx b/app/client/src/widgets/BaseWidget.tsx index fa133715ea..7b30aca4ca 100644 --- a/app/client/src/widgets/BaseWidget.tsx +++ b/app/client/src/widgets/BaseWidget.tsx @@ -75,6 +75,20 @@ abstract class BaseWidget< return {}; } + /** + * getLoadingProperties returns a list of regexp's used to specify bindingPaths, + * which can set the isLoading prop of the widget. + * When: + * 1. the path is bound to an action (API/Query) + * 2. the action is currently in-progress + * + * if undefined, all paths can set the isLoading state + * if empty array, no paths can set the isLoading state + */ + static getLoadingProperties(): Array | undefined { + return; + } + /** * Widget abstraction to register the widget type * ```javascript diff --git a/app/client/src/widgets/FormButtonWidget/icon.svg b/app/client/src/widgets/FormButtonWidget/icon.svg index 8acae73d9a..6246b31269 100644 --- a/app/client/src/widgets/FormButtonWidget/icon.svg +++ b/app/client/src/widgets/FormButtonWidget/icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/client/src/widgets/ListWidget/widget/derived.js b/app/client/src/widgets/ListWidget/widget/derived.js index 3299a57a12..e0e9d9b802 100644 --- a/app/client/src/widgets/ListWidget/widget/derived.js +++ b/app/client/src/widgets/ListWidget/widget/derived.js @@ -113,7 +113,7 @@ export default { return updatedItems; }, - // + // Patch #12438 - hard-coded DEFAULT_GRID_ROW_HEIGHT(parentRowSpace) for calculating template/component height. Ideally it should be dynamic based on props. getPageSize: (props, moment, _) => { const LIST_WIDGET_PAGINATION_HEIGHT = 36; const DEFAULT_GRID_ROW_HEIGHT = 10; @@ -140,7 +140,7 @@ export default { const templateBottomRow = props.templateBottomRow; const templateHeight = templateBottomRow * DEFAULT_GRID_ROW_HEIGHT; const componentHeight = - (props.bottomRow - props.topRow) * props.parentRowSpace; + (props.bottomRow - props.topRow) * DEFAULT_GRID_ROW_HEIGHT; const spaceAvailableWithoutPaginationControls = componentHeight - WIDGET_PADDING * 2; diff --git a/app/client/src/widgets/TableWidget/index.ts b/app/client/src/widgets/TableWidget/index.ts index a13859de81..fc41a41ffe 100644 --- a/app/client/src/widgets/TableWidget/index.ts +++ b/app/client/src/widgets/TableWidget/index.ts @@ -180,6 +180,7 @@ export const CONFIG = { default: Widget.getDefaultPropertiesMap(), meta: Widget.getMetaPropertiesMap(), config: Widget.getPropertyPaneConfig(), + loadingProperties: Widget.getLoadingProperties(), }, }; diff --git a/app/client/src/widgets/TableWidget/widget/index.tsx b/app/client/src/widgets/TableWidget/widget/index.tsx index b7d10ed642..03e769fb92 100644 --- a/app/client/src/widgets/TableWidget/widget/index.tsx +++ b/app/client/src/widgets/TableWidget/widget/index.tsx @@ -109,6 +109,10 @@ class TableWidget extends BaseWidget { }; } + static getLoadingProperties(): Array | undefined { + return [/.tableData$/]; + } + getTableColumns = () => { let columns: ReactTableColumnProps[] = []; const hiddenColumns: ReactTableColumnProps[] = []; diff --git a/app/client/src/workers/DataTreeEvaluator.ts b/app/client/src/workers/DataTreeEvaluator.ts index 041c42e212..1362f34d01 100644 --- a/app/client/src/workers/DataTreeEvaluator.ts +++ b/app/client/src/workers/DataTreeEvaluator.ts @@ -519,12 +519,22 @@ export default class DataTreeEvaluator { if (isWidget(entity)) { // Adding the dynamic triggers in the dependency list as they need linting whenever updated - // we don't make it dependent on anything else - if (entity.dynamicTriggerPathList) { - Object.values(entity.dynamicTriggerPathList).forEach(({ key }) => { - dependencies[`${entityName}.${key}`] = []; + // To keep linting in trigger fields in sync, nodes they depend on need to be added to their dependencies + const dynamicTriggerPathlist = entity.dynamicTriggerPathList; + + if (dynamicTriggerPathlist && dynamicTriggerPathlist.length) { + dynamicTriggerPathlist.forEach((dynamicPath) => { + const propertyPath = dynamicPath.key; + const unevalPropValue = _.get(entity, propertyPath); + const { jsSnippets } = getDynamicBindings(unevalPropValue); + const existingDeps = + dependencies[`${entityName}.${propertyPath}`] || []; + dependencies[`${entityName}.${propertyPath}`] = existingDeps.concat( + jsSnippets.filter((jsSnippet) => !!jsSnippet), + ); }); } + const widgetDependencies = addWidgetPropertyDependencies({ entity, entityName, @@ -1333,7 +1343,10 @@ export default class DataTreeEvaluator { entity, entityPropertyPath, ); - if (isABindingPath) { + const isATriggerPath = + isWidget(entity) && + isPathADynamicTrigger(entity, entityPropertyPath); + if (isABindingPath || isATriggerPath) { didUpdateDependencyMap = true; const { jsSnippets } = getDynamicBindings( diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/converters/GsonUnorderedToOrderedSetConverter.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/converters/GsonUnorderedToOrderedConverter.java similarity index 67% rename from app/server/appsmith-git/src/main/java/com/appsmith/git/converters/GsonUnorderedToOrderedSetConverter.java rename to app/server/appsmith-git/src/main/java/com/appsmith/git/converters/GsonUnorderedToOrderedConverter.java index 580accdd75..506682a9ae 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/converters/GsonUnorderedToOrderedSetConverter.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/converters/GsonUnorderedToOrderedConverter.java @@ -1,7 +1,7 @@ package com.appsmith.git.converters; import com.google.gson.Gson; -import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import org.springframework.util.CollectionUtils; @@ -9,14 +9,23 @@ import org.springframework.util.CollectionUtils; import javax.lang.model.type.PrimitiveType; import java.lang.reflect.Type; import java.util.Collection; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; import java.util.stream.Collectors; -public class GsonUnorderedToOrderedSetConverter implements JsonSerializer { +public class GsonUnorderedToOrderedConverter implements JsonSerializer { @Override - public JsonArray serialize(Set src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { // Sort the set so that same elements will not end up in merge conflicts - return (JsonArray) new Gson().toJsonTree(getOrderedResource(src)); + Gson gson = new Gson(); + if (src instanceof Set) { + return gson.toJsonTree(getOrderedResource((Set) src)); + } + else if (src instanceof Map) { + return gson.toJsonTree(new TreeMap<>((Map) src)); + } + return (JsonElement) src; } /** @@ -28,7 +37,7 @@ public class GsonUnorderedToOrderedSetConverter implements JsonSerializer { * @param * @return sorted collection */ - private Collection getOrderedResource(Set objects) { + private Collection getOrderedResource(Collection objects) { if (!CollectionUtils.isEmpty(objects)) { T element = objects.iterator().next(); if (element instanceof String || element instanceof PrimitiveType) { diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java index 4dd4c1957e..4099eee085 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java @@ -7,7 +7,7 @@ import com.appsmith.external.models.ApplicationGitReference; import com.appsmith.external.models.DatasourceStructure; import com.appsmith.git.configurations.GitServiceConfig; import com.appsmith.git.converters.GsonDoubleToLongConverter; -import com.appsmith.git.converters.GsonUnorderedToOrderedSetConverter; +import com.appsmith.git.converters.GsonUnorderedToOrderedConverter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.stream.JsonReader; @@ -93,7 +93,8 @@ public class FileUtilsImpl implements FileInterface { // Convert unordered set to ordered one Gson gson = new GsonBuilder() .registerTypeAdapter(Double.class, new GsonDoubleToLongConverter()) - .registerTypeAdapter(Set.class, new GsonUnorderedToOrderedSetConverter()) + .registerTypeAdapter(Set.class, new GsonUnorderedToOrderedConverter()) + .registerTypeAdapter(Map.class, new GsonUnorderedToOrderedConverter()) .disableHtmlEscaping() .setPrettyPrinting() .create(); diff --git a/app/server/appsmith-git/src/test/java/GsonUnorderedToOrderedSetTest.java b/app/server/appsmith-git/src/test/java/GsonUnorderedToOrderedSerializationTest.java similarity index 52% rename from app/server/appsmith-git/src/test/java/GsonUnorderedToOrderedSetTest.java rename to app/server/appsmith-git/src/test/java/GsonUnorderedToOrderedSerializationTest.java index 2698b1c5c6..702937ae58 100644 --- a/app/server/appsmith-git/src/test/java/GsonUnorderedToOrderedSetTest.java +++ b/app/server/appsmith-git/src/test/java/GsonUnorderedToOrderedSerializationTest.java @@ -1,21 +1,23 @@ -import com.appsmith.git.converters.GsonUnorderedToOrderedSetConverter; +import com.appsmith.git.converters.GsonUnorderedToOrderedConverter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.junit.Before; import org.junit.Test; import java.util.HashSet; +import java.util.Map; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; -public class GsonUnorderedToOrderedSetTest { +public class GsonUnorderedToOrderedSerializationTest { private Gson gson; @Before public void setUp() { gson = new GsonBuilder() - .registerTypeAdapter(Set.class, new GsonUnorderedToOrderedSetConverter()) + .registerTypeAdapter(Set.class, new GsonUnorderedToOrderedConverter()) + .registerTypeAdapter(Map.class, new GsonUnorderedToOrderedConverter()) .create(); } @@ -38,4 +40,24 @@ public class GsonUnorderedToOrderedSetTest { String orderedData = gson.toJson(data, Set.class); assertThat(orderedData).isEqualTo("[\"0xyz\",\"1abcd\",\"1xyz\",\"abc\",\"abcd\",\"abcd1\",\"xyz\"]"); } + + @Test + public void convert_withNullMap_returnsOrderedMapString() { + String orderedData = gson.toJson(null, Map.class); + assertThat(orderedData).isEqualTo("null"); + } + + @Test + public void convert_withEmptyMap_returnsOrderedMapString() { + Map data = Map.of(); + String orderedData = gson.toJson(data, Map.class); + assertThat(orderedData).isEqualTo("{}"); + } + + @Test + public void convert_withNonEmptyMap_returnsOrderedMapString() { + Map data = Map.of("key2", "value2", "key1", "value1","0key", "value0"); + String orderedData = gson.toJson(data, Map.class); + assertThat(orderedData).isEqualTo("{\"0key\":\"value0\",\"key1\":\"value1\",\"key2\":\"value2\"}"); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java index c664bf68be..87e72843c2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Application.java @@ -140,6 +140,9 @@ public class Application extends BaseDomain { @JsonIgnore String editModeThemeId; + // TODO Temporary provision for exporting the application with datasource configuration for the sample/template apps + Boolean exportWithConfiguration; + // This constructor is used during clone application. It only deeply copies selected fields. The rest are either // initialized newly or is left up to the calling function to set. public Application(Application application) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/TextUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/TextUtils.java index 2eb36663b8..21074bd959 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/TextUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/TextUtils.java @@ -3,7 +3,10 @@ package com.appsmith.server.helpers; import lombok.extern.slf4j.Slf4j; import java.text.Normalizer; +import java.util.Arrays; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; import java.util.regex.Pattern; @Slf4j @@ -42,4 +45,19 @@ public class TextUtils { // if we've only `-` left and nothing else, replace it with empty string return slug.toLowerCase(Locale.ENGLISH).replaceAll("-{2,}","-").replaceAll("^-|-$",""); } + + /** + * Splits a csv string and returns the parts as a set. + * If comma has one or more spaces before and after, it'll ignore the spaces. + * @param inputStringCsv csv string + * @return Set of string containing the parts of the csv + */ + public static Set csvToSet(String inputStringCsv) { + if(inputStringCsv == null) { + return Set.of(); + } + Set parts = new HashSet<>(Arrays.asList(inputStringCsv.trim().split("(\\s*,\\s*)+"))); + parts.remove(""); + return parts; + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ValidationUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ValidationUtils.java index 1aece55258..d4896ed52f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ValidationUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ValidationUtils.java @@ -1,10 +1,19 @@ package com.appsmith.server.helpers; import org.apache.commons.validator.routines.EmailValidator; +import org.springframework.util.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; public final class ValidationUtils { public static final int LOGIN_PASSWORD_MIN_LENGTH = 6; public static final int LOGIN_PASSWORD_MAX_LENGTH = 48; + private static final String EMAIL_PATTERN = "[\\w+\\-.%]+@[\\w\\-.]+\\.[A-Za-z]+"; + + private static final Pattern EMAIL_CSV_PATTERN = Pattern.compile( + "^\\s*(" + EMAIL_PATTERN + "\\s*,\\s*)*(" + EMAIL_PATTERN + ")\\s*$" + ); public static boolean validateEmail(String emailStr) { return EmailValidator.getInstance().isValid(emailStr); @@ -14,4 +23,21 @@ public final class ValidationUtils { int passwordLength = password.length(); return passwordLength >= LOGIN_PASSWORD_MIN_LENGTH && passwordLength <= LOGIN_PASSWORD_MAX_LENGTH; } + + /** + * Validates whether the provided string is a valid csv of emails. + * It considers the following cases:
    + *
  • At least one email must be present. Empty string is not allowed.
  • + *
  • Space is allowed before and after comma
  • + *
+ * @param inputString input source + * @return true if input is valid, false otherwise + */ + public static boolean validateEmailCsv(String inputString) { + if(!StringUtils.hasLength(inputString)) { // check for null and empty string + return false; + } + final Matcher matcher = EMAIL_CSV_PATTERN.matcher(inputString); + return matcher.matches(); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/HelperMethods.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/HelperMethods.java index d21d5ebacf..56026ced33 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/HelperMethods.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/HelperMethods.java @@ -3,6 +3,7 @@ package com.appsmith.server.migrations; import com.appsmith.server.domains.ApplicationJson; import com.appsmith.server.domains.NewAction; import com.appsmith.server.dtos.ActionDTO; +import com.appsmith.server.helpers.CollectionUtils; import java.time.Instant; import java.util.List; @@ -23,17 +24,19 @@ public class HelperMethods { public static void migrateActionFormDataToObject(ApplicationJson applicationJson) { final List actionList = applicationJson.getActionList(); - actionList.parallelStream() - .forEach(newAction -> { - // determine plugin - final String pluginName = newAction.getPluginId(); - if ("mongo-plugin".equals(pluginName)) { - DatabaseChangelog2.migrateMongoActionsFormData(newAction); - } else if ("amazons3-plugin".equals(pluginName)) { - DatabaseChangelog2.migrateAmazonS3ActionsFormData(newAction); - } else if ("firestore-plugin".equals(pluginName)) { - DatabaseChangelog2.migrateFirestoreActionsFormData(newAction); - } - }); + if (!CollectionUtils.isNullOrEmpty(actionList)) { + actionList.parallelStream() + .forEach(newAction -> { + // determine plugin + final String pluginName = newAction.getPluginId(); + if ("mongo-plugin".equals(pluginName)) { + DatabaseChangelog2.migrateMongoActionsFormData(newAction); + } else if ("amazons3-plugin".equals(pluginName)) { + DatabaseChangelog2.migrateAmazonS3ActionsFormData(newAction); + } else if ("firestore-plugin".equals(pluginName)) { + DatabaseChangelog2.migrateFirestoreActionsFormData(newAction); + } + }); + } } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCE.java index f2c4e71670..e562b81a60 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCE.java @@ -26,4 +26,5 @@ public interface ConfigServiceCE { Flux getTemplateDatasources(); + Mono delete(String name); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCEImpl.java index 3a01b60029..6ece92cb70 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConfigServiceCEImpl.java @@ -9,10 +9,8 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.repositories.ApplicationRepository; import com.appsmith.server.repositories.ConfigRepository; import com.appsmith.server.repositories.DatasourceRepository; -import com.appsmith.server.services.ConfigService; import lombok.extern.slf4j.Slf4j; import net.minidev.json.JSONObject; -import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -122,4 +120,11 @@ public class ConfigServiceCEImpl implements ConfigServiceCE { .flatMapMany(datasourceRepository::findByIdIn); } + @Override + public Mono delete(String name) { + return repository.findByName(name) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.CONFIG, name))) + .flatMap(repository::delete); + } + } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java index df83e6eef9..9d637913ec 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java @@ -31,7 +31,7 @@ public interface UserServiceCE extends CrudService { Mono createUserAndSendEmail(User user, String originHeader); - Mono userCreate(User user); + Mono userCreate(User user, boolean isAdminUser); Mono> inviteUsers(InviteUsersDTO inviteUsersDTO, String originHeader); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java index 07d3b0569a..a6d2ad0c6c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java @@ -77,6 +77,7 @@ import java.util.Set; import java.util.UUID; import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS; +import static com.appsmith.server.acl.AclPermission.MANAGE_INSTANCE_ENV; import static com.appsmith.server.acl.AclPermission.MANAGE_USERS; import static com.appsmith.server.acl.AclPermission.ORGANIZATION_INVITE_USERS; import static com.appsmith.server.acl.AclPermission.USER_MANAGE_ORGANIZATIONS; @@ -459,8 +460,17 @@ public class UserServiceCEImpl extends BaseService return new HashSet<>(userPolicies.values()); } + private Set adminUserPolicy(User user) { + + Set aclPermissions = Set.of(MANAGE_INSTANCE_ENV); + + Map userPolicies = policyUtils.generatePolicyFromPermission(aclPermissions, user); + + return new HashSet<>(userPolicies.values()); + } + @Override - public Mono userCreate(User user) { + public Mono userCreate(User user, boolean isAdminUser) { // It is assumed here that the user's password has already been encoded. // convert the user email to lowercase @@ -468,6 +478,9 @@ public class UserServiceCEImpl extends BaseService // Set the permissions for the user user.getPolicies().addAll(crudUserPolicy(user)); + if(isAdminUser) { + user.getPolicies().addAll(adminUserPolicy(user)); + } // Save the new user return Mono.just(user) @@ -555,6 +568,8 @@ public class UserServiceCEImpl extends BaseService } private Mono signupIfAllowed(User user) { + boolean isAdminUser = false; + if (!commonConfig.getAdminEmails().contains(user.getEmail())) { // If this is not an admin email address, only then do we check if signup should be allowed or not. Being an // explicitly set admin email address trumps all everything and signup for this email can never be disabled. @@ -575,10 +590,12 @@ public class UserServiceCEImpl extends BaseService // of a different domain, reject. return Mono.error(new AppsmithException(AppsmithError.SIGNUP_DISABLED)); } + } else { + isAdminUser = true; } // No special configurations found, allow signup for the new user. - return userCreate(user); + return userCreate(user, isAdminUser); } public Mono sendWelcomeEmail(User user, String originHeader) { @@ -769,8 +786,10 @@ public class UserServiceCEImpl extends BaseService // role information to classify the user persona. newUser.setInviteToken(role + ":" + UUID.randomUUID()); + boolean isAdminUser = commonConfig.getAdminEmails().contains(email.toLowerCase()); + // Call user service's userCreate function so that the default organization, etc are also created along with assigning basic permissions. - return userCreate(newUser) + return userCreate(newUser, isAdminUser) .flatMap(createdUser -> { log.debug("Going to send email for invite user to {}", createdUser.getEmail()); String inviteUrl = String.format( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java index 5e02a8de62..1076de3b4c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java @@ -6,6 +6,7 @@ import com.appsmith.server.configurations.GoogleRecaptchaConfig; import com.appsmith.server.helpers.FileUtils; import com.appsmith.server.helpers.PolicyUtils; import com.appsmith.server.notifications.EmailSender; +import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.UserService; import com.appsmith.server.solutions.ce.EnvManagerCEImpl; @@ -19,6 +20,7 @@ public class EnvManagerImpl extends EnvManagerCEImpl implements EnvManager { public EnvManagerImpl(SessionUserService sessionUserService, UserService userService, + UserRepository userRepository, PolicyUtils policyUtils, EmailSender emailSender, CommonConfig commonConfig, @@ -27,7 +29,7 @@ public class EnvManagerImpl extends EnvManagerCEImpl implements EnvManager { GoogleRecaptchaConfig googleRecaptchaConfig, FileUtils fileUtils) { - super(sessionUserService, userService, policyUtils, emailSender, commonConfig, emailConfig, javaMailSender, + super(sessionUserService, userService, userRepository, policyUtils, emailSender, commonConfig, emailConfig, javaMailSender, googleRecaptchaConfig, fileUtils); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ImportExportApplicationServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ImportExportApplicationServiceImpl.java index bf25f69945..a3b9495ad8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ImportExportApplicationServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ImportExportApplicationServiceImpl.java @@ -1,5 +1,6 @@ package com.appsmith.server.solutions; +import com.appsmith.server.helpers.PolicyUtils; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.repositories.DatasourceRepository; import com.appsmith.server.repositories.NewActionRepository; @@ -38,11 +39,12 @@ public class ImportExportApplicationServiceImpl extends ImportExportApplicationS ExamplesOrganizationCloner examplesOrganizationCloner, ActionCollectionRepository actionCollectionRepository, ActionCollectionService actionCollectionService, - ThemeService themeService) { + ThemeService themeService, + PolicyUtils policyUtils) { super(datasourceService, sessionUserService, newActionRepository, datasourceRepository, pluginRepository, organizationService, applicationService, newPageService, applicationPageService, newPageRepository, newActionService, sequenceService, examplesOrganizationCloner, actionCollectionRepository, - actionCollectionService, themeService); + actionCollectionService, themeService, policyUtils); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java index 3a6500867e..de3f18d7b8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java @@ -1,5 +1,6 @@ package com.appsmith.server.solutions.ce; +import com.appsmith.external.models.Policy; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.configurations.CommonConfig; import com.appsmith.server.configurations.EmailConfig; @@ -12,13 +13,15 @@ import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.FileUtils; import com.appsmith.server.helpers.PolicyUtils; +import com.appsmith.server.helpers.TextUtils; +import com.appsmith.server.helpers.ValidationUtils; import com.appsmith.server.notifications.EmailSender; +import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.UserService; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.http.HttpHeaders; @@ -28,7 +31,9 @@ import org.springframework.mail.MailException; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.util.StringUtils; import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; @@ -74,6 +79,7 @@ public class EnvManagerCEImpl implements EnvManagerCE { private final SessionUserService sessionUserService; private final UserService userService; + private final UserRepository userRepository; private final PolicyUtils policyUtils; private final EmailSender emailSender; @@ -152,8 +158,28 @@ public class EnvManagerCEImpl implements EnvManagerCE { return outLines; } + private Mono validateChanges(User user, Map changes) { + if(changes.containsKey(APPSMITH_ADMIN_EMAILS.name())) { + String emailCsv = StringUtils.trimAllWhitespace(changes.get(APPSMITH_ADMIN_EMAILS.name())); + + // validate input is in the format email,email,email and is not empty + if(!ValidationUtils.validateEmailCsv(emailCsv)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "Admin Email")); + } else { // make sure user is not removing own email + Set adminEmails = TextUtils.csvToSet(emailCsv); + if(!adminEmails.contains(user.getEmail())) { // user can not remove own email address + return Mono.error(new AppsmithException( + AppsmithError.GENERIC_BAD_REQUEST, "Removing own email from Admin Email is not allowed" + )); + } + } + } + return Mono.empty(); + } + public Mono applyChanges(Map changes) { return verifyCurrentUserIsSuper() + .flatMap(user -> validateChanges(user, changes).thenReturn(user)) .flatMap(user -> { // Write the changes to the env file. final String originalContent; @@ -165,7 +191,7 @@ public class EnvManagerCEImpl implements EnvManagerCE { log.error("Unable to read env file " + envFilePath, e); return Mono.error(e); } - + Map originalVariables = parseToMap(originalContent); final List changedContent = transformEnvContent(originalContent, changes); try { @@ -175,9 +201,11 @@ public class EnvManagerCEImpl implements EnvManagerCE { return Mono.error(e); } - return Mono.just(user); + return Mono.just(originalVariables); }) - .flatMap(user -> { + .flatMap(originalValues -> { + Mono dependentTasks = Mono.empty(); + // Try and update any at runtime, that can be. final Map changesCopy = new HashMap<>(changes); @@ -195,6 +223,8 @@ public class EnvManagerCEImpl implements EnvManagerCE { if (changesCopy.containsKey(APPSMITH_ADMIN_EMAILS.name())) { commonConfig.setAdminEmails(changesCopy.remove(APPSMITH_ADMIN_EMAILS.name())); + String oldAdminEmailsCsv = originalValues.get(APPSMITH_ADMIN_EMAILS.name()); + dependentTasks = dependentTasks.then(updateAdminUserPolicies(oldAdminEmailsCsv)); } if (changesCopy.containsKey(APPSMITH_MAIL_FROM.name())) { @@ -244,9 +274,9 @@ public class EnvManagerCEImpl implements EnvManagerCE { // Ideally, we should only need a restart here if `changesCopy` is not empty. However, some of these // env variables are also used in client code, which means restart might be necessary there. So, to // provide a more uniform and predictable experience, we always restart. - Mono.delay(Duration.ofSeconds(1)) - .flatMap(ignored -> restart()) + .then(dependentTasks) + .then(restart()) .subscribeOn(Schedulers.boundedElastic()) .subscribe(); @@ -254,6 +284,50 @@ public class EnvManagerCEImpl implements EnvManagerCE { }); } + /** + * Adds or removes admin user policy from users. + * If an email is removed from admin emails, it'll remove the policy from that user. + * If a new email is added as admin email, it'll add the policy to that user + * @param oldAdminEmailsCsv comma separated email addresses that was set as admin email earlier + */ + private Mono updateAdminUserPolicies(String oldAdminEmailsCsv) { + Set oldAdminEmails = TextUtils.csvToSet(oldAdminEmailsCsv); + Set newAdminEmails = commonConfig.getAdminEmails(); + + // we need to find out the removed emails and new emails + Set removedUsers = new HashSet<>(oldAdminEmails); + removedUsers.removeAll(newAdminEmails); + Set newUsers = new HashSet<>(newAdminEmails); + newUsers.removeAll(oldAdminEmails); + + Flux removedUserFlux = Flux.fromIterable(removedUsers).flatMap(userService::findByEmail) + .flatMap(user -> { + Map policyMap = policyUtils.generatePolicyFromPermission( + Set.of(AclPermission.MANAGE_INSTANCE_ENV), user.getUsername() + ); + policyUtils.removePoliciesFromExistingObject(policyMap, user); + return userRepository.save(user); + }); + + Flux newUsersFlux = Flux.fromIterable(newUsers).flatMap(userService::findByEmail) + .flatMap(user -> { + Map policyMap = policyUtils.generatePolicyFromPermission( + Set.of(AclPermission.MANAGE_INSTANCE_ENV), user.getUsername() + ); + policyUtils.addPoliciesToExistingObject(policyMap, user); + return userRepository.save(user); + }); + + /* + * we need to run these two flux immediately because server will be restarted and these changes + * should be persisted to DB before that + */ + return Mono.whenDelayError( + removedUserFlux.then(), + newUsersFlux.then() + ); + } + public Map parseToMap(String content) { final Map data = new HashMap<>(); @@ -336,7 +410,7 @@ public class EnvManagerCEImpl implements EnvManagerCE { props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.timeout", 7000); // 7 seconds - if(!StringUtils.isEmpty(requestDTO.getUsername())) { + if(StringUtils.hasLength(requestDTO.getUsername())) { props.put("mail.smtp.auth", "true"); mailSender.setUsername(requestDTO.getUsername()); mailSender.setPassword(requestDTO.getPassword()); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java index 5b377d47a6..da9412dc4a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java @@ -2,6 +2,7 @@ package com.appsmith.server.solutions.ce; import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.helpers.Stopwatch; +import com.appsmith.external.models.AuthenticationDTO; import com.appsmith.external.models.AuthenticationResponse; import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.BasicAuth; @@ -31,6 +32,7 @@ import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.DefaultResourcesUtils; +import com.appsmith.server.helpers.PolicyUtils; import com.appsmith.server.migrations.ApplicationVersion; import com.appsmith.server.migrations.JsonSchemaMigration; import com.appsmith.server.migrations.JsonSchemaVersions; @@ -81,6 +83,9 @@ import static com.appsmith.server.acl.AclPermission.MANAGE_ACTIONS; import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS; import static com.appsmith.server.acl.AclPermission.MANAGE_DATASOURCES; import static com.appsmith.server.acl.AclPermission.MANAGE_PAGES; +import static com.appsmith.server.acl.AclPermission.READ_ACTIONS; +import static com.appsmith.server.acl.AclPermission.READ_APPLICATIONS; +import static com.appsmith.server.acl.AclPermission.READ_PAGES; import static com.appsmith.server.acl.AclPermission.READ_THEMES; @Slf4j @@ -103,6 +108,7 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica private final ActionCollectionRepository actionCollectionRepository; private final ActionCollectionService actionCollectionService; private final ThemeService themeService; + private final PolicyUtils policyUtils; private static final Set ALLOWED_CONTENT_TYPES = Set.of(MediaType.APPLICATION_JSON); private static final String INVALID_JSON_FILE = "invalid json file"; @@ -111,10 +117,6 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica UNPUBLISHED, PUBLISHED } - private enum IdType { - RESOURCE_ID, DEFAULT_RESOURCE_ID - } - /** * This function will give the application resource to rebuild the application in import application flow * @@ -144,12 +146,38 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID)); } + // Check permissions depending upon the serialization objective: + // Git-sync => Manage permission + // Share application + // : Normal apps => Export permission + // : Sample apps where datasource config needs to be shared => Read permission + Mono applicationMono = SerialiseApplicationObjective.VERSION_CONTROL.equals(serialiseFor) ? applicationService.findById(applicationId, MANAGE_APPLICATIONS) - : applicationService.findById(applicationId, EXPORT_APPLICATIONS) + : applicationService.findById(applicationId, READ_APPLICATIONS) .switchIfEmpty(Mono.error( new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION_ID, applicationId)) - ); + ) + .zipWith(sessionUserService.getCurrentUser()) + .map(objects -> { + Application application = objects.getT1(); + User currentUser = objects.getT2(); + + if (Boolean.TRUE.equals(application.getExportWithConfiguration())) { + // Export the application with datasource configuration + return application; + } + // Explicitly setting the boolean to avoid NPE for future checks + application.setExportWithConfiguration(false); + // Check if the user have export_application permission + Boolean isExportPermissionGranted = policyUtils.isPermissionPresentForUser( + application.getPolicies(), EXPORT_APPLICATIONS.getValue(), currentUser.getUsername() + ); + if (Boolean.TRUE.equals(isExportPermissionGranted)) { + return application; + } + throw new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION_ID, applicationId); + }); // Set json schema version which will be used to check the compatibility while importing the JSON applicationJson.setServerSchemaVersion(JsonSchemaVersions.serverVersion); @@ -201,10 +229,13 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica removeUnwantedFieldsFromApplicationDuringExport(application); examplesOrganizationCloner.makePristine(application); applicationJson.setExportedApplication(application); - Set dbNamesUsedInActions = new HashSet<>(); - return newPageRepository.findByApplicationId(applicationId, MANAGE_PAGES) + Flux pageFlux = Boolean.TRUE.equals(application.getExportWithConfiguration()) + ? newPageRepository.findByApplicationId(applicationId, READ_PAGES) + : newPageRepository.findByApplicationId(applicationId, MANAGE_PAGES); + + return pageFlux .collectList() .flatMap(newPageList -> { // Extract mongoEscapedWidgets from pages and save it to applicationJson object as this @@ -260,16 +291,22 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica applicationJson.setPageList(newPageList); applicationJson.setPublishedLayoutmongoEscapedWidgets(publishedMongoEscapedWidgetsNames); applicationJson.setUnpublishedLayoutmongoEscapedWidgets(unpublishedMongoEscapedWidgetsNames); - return datasourceRepository - .findAllByOrganizationId(organizationId, AclPermission.MANAGE_DATASOURCES) - .collectList(); + + Flux datasourceFlux = Boolean.TRUE.equals(application.getExportWithConfiguration()) + ? datasourceRepository.findAllByOrganizationId(organizationId, AclPermission.READ_DATASOURCES) + : datasourceRepository.findAllByOrganizationId(organizationId, AclPermission.MANAGE_DATASOURCES); + + return datasourceFlux.collectList(); }) .flatMapMany(datasourceList -> { datasourceList.forEach(datasource -> datasourceIdToNameMap.put(datasource.getId(), datasource.getName())); applicationJson.setDatasourceList(datasourceList); - return actionCollectionRepository - .findByApplicationId(applicationId, MANAGE_ACTIONS, null); + + Flux actionCollectionFlux = Boolean.TRUE.equals(application.getExportWithConfiguration()) + ? actionCollectionRepository.findByApplicationId(applicationId, READ_ACTIONS, null) + : actionCollectionRepository.findByApplicationId(applicationId, MANAGE_ACTIONS, null); + return actionCollectionFlux; }) .map(actionCollection -> { // Remove references to ids since the serialized version does not have this information @@ -308,8 +345,12 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica // This object won't have the list of actions but we don't care about that today // Because the actions will have a reference to the collection applicationJson.setActionCollectionList(actionCollections); - return newActionRepository - .findByApplicationId(applicationId, MANAGE_ACTIONS, null); + + Flux actionFlux = Boolean.TRUE.equals(application.getExportWithConfiguration()) + ? newActionRepository.findByApplicationId(applicationId, READ_ACTIONS, null) + : newActionRepository.findByApplicationId(applicationId, MANAGE_ACTIONS, null); + + return actionFlux; }) .map(newAction -> { newAction.setPluginId(pluginMap.get(newAction.getPluginId())); @@ -381,15 +422,28 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica .getDatasourceList() .removeIf(datasource -> !dbNamesUsedInActions.contains(datasource.getName())); - // Save decrypted fields for datasources - applicationJson.getDatasourceList().forEach(datasource -> { - datasource.setId(null); - datasource.setOrganizationId(null); - datasource.setPluginId(pluginMap.get(datasource.getPluginId())); - datasource.setStructure(null); - // Remove the datasourceConfiguration object as user will configure it once imported to other instance - datasource.setDatasourceConfiguration(null); - }); + // Save decrypted fields for datasources for internally used sample apps and templates only + if(Boolean.TRUE.equals(application.getExportWithConfiguration())) { + // Save decrypted fields for datasources + Map decryptedFields = new HashMap<>(); + applicationJson.getDatasourceList().forEach(datasource -> { + decryptedFields.put(datasource.getName(), getDecryptedFields(datasource)); + datasource.setId(null); + datasource.setOrganizationId(null); + datasource.setPluginId(pluginMap.get(datasource.getPluginId())); + datasource.setStructure(null); + }); + applicationJson.setDecryptedFields(decryptedFields); + } else { + applicationJson.getDatasourceList().forEach(datasource -> { + datasource.setId(null); + datasource.setOrganizationId(null); + datasource.setPluginId(pluginMap.get(datasource.getPluginId())); + datasource.setStructure(null); + // Remove the datasourceConfiguration object as user will configure it once imported to other instance + datasource.setDatasourceConfiguration(null); + }); + } // Update ids for layoutOnLoadAction for (NewPage newPage : applicationJson.getPageList()) { @@ -430,7 +484,8 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica }); } } - + // Disable exporting the application with datasource config once imported in destination instance + application.setExportWithConfiguration(null); processStopwatch.stopAndLogTimeInMillis(); return applicationJson; }); @@ -574,9 +629,6 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica Map> publishedActionIdToCollectionIdMap = new HashMap<>(); Application importedApplication = importedDoc.getExportedApplication(); - if(importedApplication.getApplicationVersion() == null) { - importedApplication.setApplicationVersion(ApplicationVersion.EARLIEST_VERSION); - } List importedDatasourceList = importedDoc.getDatasourceList(); List importedNewPageList = importedDoc.getPageList(); @@ -602,6 +654,10 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica if (!errorField.isEmpty()) { return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, errorField, INVALID_JSON_FILE)); } + assert importedApplication != null; + if(importedApplication.getApplicationVersion() == null) { + importedApplication.setApplicationVersion(ApplicationVersion.EARLIEST_VERSION); + } Mono importedApplicationMono = pluginRepository.findAll() .map(plugin -> { @@ -1687,19 +1743,23 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica } return existingDatasourceFlux + .map(ds -> { + final DatasourceConfiguration dsAuthConfig = ds.getDatasourceConfiguration(); + if (dsAuthConfig != null && dsAuthConfig.getAuthentication() != null) { + dsAuthConfig.getAuthentication().setAuthenticationResponse(null); + dsAuthConfig.getAuthentication().setAuthenticationType(null); + } + return ds; + }) // For git import exclude datasource configuration - .filter(ds -> ds.getName().equals(datasource.getName())) + .filter(ds -> applicationId != null ? ds.getName().equals(datasource.getName()) : ds.softEquals(datasource)) .next() // Get the first matching datasource, we don't need more than one here. .switchIfEmpty(Mono.defer(() -> { if (datasourceConfig != null && datasourceConfig.getAuthentication() != null) { datasourceConfig.getAuthentication().setAuthenticationResponse(authResponse); } // No matching existing datasource found, so create a new one. - if (datasourceConfig != null && datasourceConfig.getAuthentication() != null) { - datasource.setIsConfigured(true); - } else { - datasource.setIsConfigured(false); - } + datasource.setIsConfigured(datasourceConfig != null && datasourceConfig.getAuthentication() != null); return datasourceService .findByNameAndOrganizationId(datasource.getName(), organizationId, AclPermission.MANAGE_DATASOURCES) .flatMap(duplicateNameDatasource -> @@ -1790,6 +1850,41 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica }); } + /** + * This will be used to dehydrate sensitive fields from the datasource while exporting the application + * + * @param datasource entity from which sensitive fields need to be dehydrated + * @return sensitive fields which then will be deserialized and exported in JSON file + */ + private DecryptedSensitiveFields getDecryptedFields(Datasource datasource) { + final AuthenticationDTO authentication = datasource.getDatasourceConfiguration() == null + ? null : datasource.getDatasourceConfiguration().getAuthentication(); + + if (authentication != null) { + DecryptedSensitiveFields dsDecryptedFields = + authentication.getAuthenticationResponse() == null + ? new DecryptedSensitiveFields() + : new DecryptedSensitiveFields(authentication.getAuthenticationResponse()); + + if (authentication instanceof DBAuth) { + DBAuth auth = (DBAuth) authentication; + dsDecryptedFields.setPassword(auth.getPassword()); + dsDecryptedFields.setDbAuth(auth); + } else if (authentication instanceof OAuth2) { + OAuth2 auth = (OAuth2) authentication; + dsDecryptedFields.setPassword(auth.getClientSecret()); + dsDecryptedFields.setOpenAuth2(auth); + } else if (authentication instanceof BasicAuth) { + BasicAuth auth = (BasicAuth) authentication; + dsDecryptedFields.setPassword(auth.getPassword()); + dsDecryptedFields.setBasicAuth(auth); + } + dsDecryptedFields.setAuthType(authentication.getClass().getName()); + return dsDecryptedFields; + } + return null; + } + public Mono> findDatasourceByApplicationId(String applicationId, String orgId) { Mono> listMono = datasourceService.findAllByOrganizationId(orgId, MANAGE_DATASOURCES).collectList(); return newActionService.findAllByApplicationIdAndViewMode(applicationId, false, AclPermission.READ_ACTIONS, null) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/TextUtilsTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/TextUtilsTest.java index 1e6a1a4950..4ea621d7c2 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/TextUtilsTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/TextUtilsTest.java @@ -2,6 +2,8 @@ package com.appsmith.server.helpers; import org.junit.Test; +import java.util.Set; + import static org.assertj.core.api.Assertions.assertThat; public class TextUtilsTest { @@ -27,4 +29,24 @@ public class TextUtilsTest { // text in chinese assertThat(TextUtils.makeSlug("测试页")).isEqualTo(""); } + + private void checkFromCsv(String inputString, int expectedSize, String ... parts) { + Set s1 = TextUtils.csvToSet(inputString); + assertThat(s1.size()).isEqualTo(expectedSize); + assertThat(s1).contains(parts); + } + + @Test + public void csvToSet() { + checkFromCsv("a, b", 2, "a", "b"); + checkFromCsv("a, b,", 2, "a", "b"); + checkFromCsv("a, b, ", 2, "a", "b"); + checkFromCsv("a, b, ,c", 3, "a", "b", "c"); + checkFromCsv("a, b,,c", 3, "a", "b", "c"); + checkFromCsv("a, b, ,c ", 3, "a", "b", "c"); + checkFromCsv("a,b,,c ,d", 4, "a", "b", "c", "d"); + checkFromCsv("a,b c,", 2, "a", "b c"); + checkFromCsv("", 0); + checkFromCsv(null, 0); + } } \ No newline at end of file diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ValidationUtilsTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ValidationUtilsTest.java new file mode 100644 index 0000000000..304c72daee --- /dev/null +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ValidationUtilsTest.java @@ -0,0 +1,32 @@ +package com.appsmith.server.helpers; + +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +class ValidationUtilsTest { + + @Test + void validateEmailCsv() { + assertThat(ValidationUtils.validateEmailCsv("")).isFalse(); + assertThat(ValidationUtils.validateEmailCsv(null)).isFalse(); + assertThat(ValidationUtils.validateEmailCsv(" ")).isFalse(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com")).isTrue(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com,a@appsmith.com")).isTrue(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com, b@appsmith.com")).isTrue(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com , a@appsmith.com")).isTrue(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com , a@appsmith.com")).isTrue(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com , b@appsmith.com ,c@appsmith.com")).isTrue(); + assertThat(ValidationUtils.validateEmailCsv(" a@appsmith.com , b@appsmith.com ")).isTrue(); + + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com,a@appsmith.com,xyz")).isFalse(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com,b@appsmith.com,,")).isFalse(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com,b@appsmith.com, ")).isFalse(); + assertThat(ValidationUtils.validateEmailCsv(",,")).isFalse(); + assertThat(ValidationUtils.validateEmailCsv(",")).isFalse(); + assertThat(ValidationUtils.validateEmailCsv("a@appsmith.com,,")).isFalse(); + } +} \ No newline at end of file diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java index 83136f1e91..eb5ab352e3 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java @@ -10,6 +10,7 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.FileUtils; import com.appsmith.server.helpers.PolicyUtils; import com.appsmith.server.notifications.EmailSender; +import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.UserService; import lombok.extern.slf4j.Slf4j; @@ -42,6 +43,8 @@ public class EnvManagerTest { @MockBean private UserService userService; @MockBean + private UserRepository userRepository; + @MockBean private PolicyUtils policyUtils; @MockBean private EmailSender emailSender; @@ -62,6 +65,7 @@ public class EnvManagerTest { public void setup() { envManager = new EnvManagerImpl(sessionUserService, userService, + userRepository, policyUtils, emailSender, commonConfig, diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java index 501bb77aec..3d2068df89 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java @@ -24,6 +24,7 @@ import com.appsmith.server.domains.PluginType; import com.appsmith.server.domains.Theme; import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.ActionDTO; +import com.appsmith.server.dtos.ApplicationAccessDTO; import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; @@ -59,8 +60,10 @@ import net.minidev.json.JSONObject; import org.apache.commons.lang.StringUtils; import org.junit.Assert; import org.junit.Before; +import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -107,6 +110,7 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest @DirtiesContext +@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class ImportExportApplicationServiceTests { @Autowired @@ -171,6 +175,7 @@ public class ImportExportApplicationServiceTests { private static final Map datasourceMap = new HashMap<>(); private static Plugin installedJsPlugin; private static Boolean isSetupDone = false; + private static String exportWithConfigurationAppId; @Before public void setup() { @@ -326,38 +331,6 @@ public class ImportExportApplicationServiceTests { .verifyComplete(); } - @Test - @WithUserDetails(value = "api_user") - public void createExportAppJsonWithoutActionsAndDatasourceTest() { - - final Mono resultMono = importExportApplicationService.exportApplicationById(testAppId, ""); - - StepVerifier.create(resultMono) - .assertNext(applicationJson -> { - Application exportedApp = applicationJson.getExportedApplication(); - List pageList = applicationJson.getPageList(); - List actionList = applicationJson.getActionList(); - List datasourceList = applicationJson.getDatasourceList(); - - NewPage defaultPage = pageList.get(0); - - assertThat(exportedApp.getId()).isNull(); - assertThat(exportedApp.getOrganizationId()).isNull(); - assertThat(exportedApp.getPages()).isNull(); - assertThat(exportedApp.getPolicies()).isNull(); - assertThat(exportedApp.getUserPermissions()).isNull(); - - assertThat(pageList.isEmpty()).isFalse(); - assertThat(defaultPage.getApplicationId()).isNull(); - assertThat(defaultPage.getUnpublishedPage().getLayouts().get(0).getLayoutOnLoadActions()).isNull(); - - assertThat(actionList.isEmpty()).isTrue(); - - assertThat(datasourceList.isEmpty()).isTrue(); - }) - .verifyComplete(); - } - @Test @WithUserDetails(value = "api_user") public void createExportAppJsonWithDatasourceButWithoutActionsTest() { @@ -1966,8 +1939,248 @@ public class ImportExportApplicationServiceTests { assertThat(latestApplicationJson.getClientSchemaVersion()).isEqualTo(JsonSchemaVersions.clientVersion); }) .verifyComplete(); + } + /** + * Testcase to check if the application is exported with the datasource configuration object if this setting is + * enabled from application object + * This can be enabled with exportWithConfiguration: true + */ + @Test + @WithUserDetails(value = "api_user") + public void test1_exportApplication_withDatasourceConfig_exportedWithDecryptedFields() { + Organization newOrganization = new Organization(); + newOrganization.setName("template-org-with-ds"); + Application testApplication = new Application(); + testApplication.setName("exportApplication_withCredentialsForSampleApps_SuccessWithDecryptFields"); + testApplication.setExportWithConfiguration(true); + testApplication = applicationPageService.createApplication(testApplication, orgId).block(); + assert testApplication != null; + exportWithConfigurationAppId = testApplication.getId(); + ApplicationAccessDTO accessDTO = new ApplicationAccessDTO(); + accessDTO.setPublicAccess(true); + applicationService.changeViewAccess(exportWithConfigurationAppId, accessDTO).block(); + final String appName = testApplication.getName(); + final Mono resultMono = Mono.zip( + Mono.just(testApplication), + newPageService.findPageById(testApplication.getPages().get(0).getId(), READ_PAGES, false) + ) + .flatMap(tuple -> { + Application testApp = tuple.getT1(); + PageDTO testPage = tuple.getT2(); + + Layout layout = testPage.getLayouts().get(0); + ObjectMapper objectMapper = new ObjectMapper(); + JSONObject dsl = new JSONObject(); + try { + dsl = new JSONObject(objectMapper.readValue(DEFAULT_PAGE_LAYOUT, new TypeReference>() { + })); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + ArrayList children = (ArrayList) dsl.get("children"); + JSONObject testWidget = new JSONObject(); + testWidget.put("widgetName", "firstWidget"); + JSONArray temp = new JSONArray(); + temp.addAll(List.of(new JSONObject(Map.of("key", "testField")))); + testWidget.put("dynamicBindingPathList", temp); + testWidget.put("testField", "{{ validAction.data }}"); + children.add(testWidget); + + layout.setDsl(dsl); + layout.setPublishedDsl(dsl); + + ActionDTO action = new ActionDTO(); + action.setName("validAction"); + action.setPageId(testPage.getId()); + action.setExecuteOnLoad(true); + ActionConfiguration actionConfiguration = new ActionConfiguration(); + actionConfiguration.setHttpMethod(HttpMethod.GET); + action.setActionConfiguration(actionConfiguration); + action.setDatasource(datasourceMap.get("DS2")); + + ActionDTO action2 = new ActionDTO(); + action2.setName("validAction2"); + action2.setPageId(testPage.getId()); + action2.setExecuteOnLoad(true); + action2.setUserSetOnLoad(true); + ActionConfiguration actionConfiguration2 = new ActionConfiguration(); + actionConfiguration2.setHttpMethod(HttpMethod.GET); + action2.setActionConfiguration(actionConfiguration2); + action2.setDatasource(datasourceMap.get("DS2")); + + ActionCollectionDTO actionCollectionDTO1 = new ActionCollectionDTO(); + actionCollectionDTO1.setName("testCollection1"); + actionCollectionDTO1.setPageId(testPage.getId()); + actionCollectionDTO1.setApplicationId(testApp.getId()); + actionCollectionDTO1.setOrganizationId(testApp.getOrganizationId()); + actionCollectionDTO1.setPluginId(jsDatasource.getPluginId()); + ActionDTO action1 = new ActionDTO(); + action1.setName("testAction1"); + action1.setActionConfiguration(new ActionConfiguration()); + action1.getActionConfiguration().setBody("mockBody"); + actionCollectionDTO1.setActions(List.of(action1)); + actionCollectionDTO1.setPluginType(PluginType.JS); + + return layoutCollectionService.createCollection(actionCollectionDTO1) + .then(layoutActionService.createSingleAction(action)) + .then(layoutActionService.createSingleAction(action2)) + .then(layoutActionService.updateLayout(testPage.getId(), layout.getId(), layout)) + .then(importExportApplicationService.exportApplicationById(testApp.getId(), "")); + }) + .cache(); + + Mono> actionListMono = resultMono + .then(newActionService + .findAllByApplicationIdAndViewMode(testApplication.getId(), false, READ_ACTIONS, null).collectList()); + + Mono> collectionListMono = resultMono.then( + actionCollectionService + .findAllByApplicationIdAndViewMode(testApplication.getId(), false, READ_ACTIONS, null).collectList()); + + Mono> pageListMono = resultMono.then( + newPageService + .findNewPagesByApplicationId(testApplication.getId(), READ_PAGES).collectList()); + + StepVerifier + .create(Mono.zip(resultMono, actionListMono, collectionListMono, pageListMono)) + .assertNext(tuple -> { + + ApplicationJson applicationJson = tuple.getT1(); + List DBActions = tuple.getT2(); + List DBCollections = tuple.getT3(); + List DBPages = tuple.getT4(); + + Application exportedApp = applicationJson.getExportedApplication(); + List pageList = applicationJson.getPageList(); + List actionList = applicationJson.getActionList(); + List actionCollectionList = applicationJson.getActionCollectionList(); + List datasourceList = applicationJson.getDatasourceList(); + + List exportedCollectionIds = actionCollectionList.stream().map(ActionCollection::getId).collect(Collectors.toList()); + List exportedActionIds = actionList.stream().map(NewAction::getId).collect(Collectors.toList()); + List DBCollectionIds = DBCollections.stream().map(ActionCollection::getId).collect(Collectors.toList()); + List DBActionIds = DBActions.stream().map(NewAction::getId).collect(Collectors.toList()); + List DBOnLayoutLoadActionIds = new ArrayList<>(); + List exportedOnLayoutLoadActionIds = new ArrayList<>(); + + DBPages.forEach(newPage -> + newPage.getUnpublishedPage().getLayouts().forEach(layout -> { + if (layout.getLayoutOnLoadActions() != null) { + layout.getLayoutOnLoadActions().forEach(dslActionDTOSet -> { + dslActionDTOSet.forEach(actionDTO -> DBOnLayoutLoadActionIds.add(actionDTO.getId())); + }); + } + }) + ); + + pageList.forEach(newPage -> + newPage.getUnpublishedPage().getLayouts().forEach(layout -> { + if (layout.getLayoutOnLoadActions() != null) { + layout.getLayoutOnLoadActions().forEach(dslActionDTOSet -> { + dslActionDTOSet.forEach(actionDTO -> exportedOnLayoutLoadActionIds.add(actionDTO.getId())); + }); + } + }) + ); + + NewPage defaultPage = pageList.get(0); + + assertThat(exportedApp.getName()).isEqualTo(appName); + assertThat(exportedApp.getOrganizationId()).isNull(); + assertThat(exportedApp.getPages()).isNull(); + + assertThat(exportedApp.getPolicies()).isNull(); + + assertThat(pageList).hasSize(1); + assertThat(defaultPage.getApplicationId()).isNull(); + assertThat(defaultPage.getUnpublishedPage().getLayouts().get(0).getDsl()).isNotNull(); + assertThat(defaultPage.getId()).isNull(); + assertThat(defaultPage.getPolicies()).isEmpty(); + + assertThat(actionList.isEmpty()).isFalse(); + assertThat(actionList).hasSize(3); + NewAction validAction = actionList.stream().filter(action -> action.getId().equals("Page1_validAction")).findFirst().get(); + assertThat(validAction.getApplicationId()).isNull(); + assertThat(validAction.getPluginId()).isEqualTo(installedPlugin.getPackageName()); + assertThat(validAction.getPluginType()).isEqualTo(PluginType.API); + assertThat(validAction.getOrganizationId()).isNull(); + assertThat(validAction.getPolicies()).isNull(); + assertThat(validAction.getId()).isNotNull(); + ActionDTO unpublishedAction = validAction.getUnpublishedAction(); + assertThat(unpublishedAction.getPageId()).isEqualTo(defaultPage.getUnpublishedPage().getName()); + assertThat(unpublishedAction.getDatasource().getPluginId()).isEqualTo(installedPlugin.getPackageName()); + + NewAction testAction1 = actionList.stream().filter(action -> action.getUnpublishedAction().getName().equals("testAction1")).findFirst().get(); + assertThat(testAction1.getId()).isEqualTo("Page1_testCollection1.testAction1"); + + assertThat(actionCollectionList.isEmpty()).isFalse(); + assertThat(actionCollectionList).hasSize(1); + final ActionCollection actionCollection = actionCollectionList.get(0); + assertThat(actionCollection.getApplicationId()).isNull(); + assertThat(actionCollection.getOrganizationId()).isNull(); + assertThat(actionCollection.getPolicies()).isNull(); + assertThat(actionCollection.getId()).isNotNull(); + assertThat(actionCollection.getUnpublishedCollection().getPluginType()).isEqualTo(PluginType.JS); + assertThat(actionCollection.getUnpublishedCollection().getPageId()) + .isEqualTo(defaultPage.getUnpublishedPage().getName()); + assertThat(actionCollection.getUnpublishedCollection().getPluginId()).isEqualTo(installedJsPlugin.getPackageName()); + + assertThat(datasourceList).hasSize(1); + Datasource datasource = datasourceList.get(0); + assertThat(datasource.getOrganizationId()).isNull(); + assertThat(datasource.getId()).isNull(); + assertThat(datasource.getPluginId()).isEqualTo(installedPlugin.getPackageName()); + assertThat(datasource.getDatasourceConfiguration()).isNotNull(); + + final Map invisibleActionFields = applicationJson.getInvisibleActionFields(); + + Assert.assertEquals(3, invisibleActionFields.size()); + NewAction validAction2 = actionList.stream().filter(action -> action.getId().equals("Page1_validAction2")).findFirst().get(); + Assert.assertEquals(true, invisibleActionFields.get(validAction2.getId()).getUnpublishedUserSetOnLoad()); + + assertThat(applicationJson.getUnpublishedLayoutmongoEscapedWidgets()).isNotEmpty(); + assertThat(applicationJson.getPublishedLayoutmongoEscapedWidgets()).isNotEmpty(); + assertThat(applicationJson.getEditModeTheme()).isNotNull(); + assertThat(applicationJson.getEditModeTheme().isSystemTheme()).isTrue(); + assertThat(applicationJson.getEditModeTheme().getName()).isEqualToIgnoringCase(Theme.DEFAULT_THEME_NAME); + + assertThat(applicationJson.getPublishedTheme()).isNotNull(); + assertThat(applicationJson.getPublishedTheme().isSystemTheme()).isTrue(); + assertThat(applicationJson.getPublishedTheme().getName()).isEqualToIgnoringCase(Theme.DEFAULT_THEME_NAME); + + assertThat(exportedCollectionIds).isNotEmpty(); + assertThat(exportedCollectionIds).doesNotContain(String.valueOf(DBCollectionIds)); + + assertThat(exportedActionIds).isNotEmpty(); + assertThat(exportedActionIds).doesNotContain(String.valueOf(DBActionIds)); + + assertThat(exportedOnLayoutLoadActionIds).isNotEmpty(); + assertThat(exportedOnLayoutLoadActionIds).doesNotContain(String.valueOf(DBOnLayoutLoadActionIds)); + + assertThat(applicationJson.getDecryptedFields()).isNotNull(); + }) + .verifyComplete(); + } + + /** + * Test to check if the application can be exported with read only access if this is sample application + */ + @Test + @WithUserDetails(value = "usertest@usertest.com") + public void test2_exportApplication_withReadOnlyAccess_exportedWithDecryptedFields() { + Mono exportApplicationMono = importExportApplicationService + .exportApplicationById(exportWithConfigurationAppId, SerialiseApplicationObjective.SHARE); + + StepVerifier + .create(exportApplicationMono) + .assertNext(applicationJson -> { + assertThat(applicationJson.getExportedApplication()).isNotNull(); + assertThat(applicationJson.getDecryptedFields()).isNotNull(); + }) + .verifyComplete(); } }