Merge pull request #11383 from appsmithorg/feat/4182-form-detect-changes
feat: Internal property to detect changes in a form
This commit is contained in:
commit
e05e75758d
|
|
@ -19,6 +19,22 @@
|
||||||
"dynamicBindingPathList": [],
|
"dynamicBindingPathList": [],
|
||||||
"leftColumn": 0,
|
"leftColumn": 0,
|
||||||
"children": [
|
"children": [
|
||||||
|
{
|
||||||
|
"isVisible": true,
|
||||||
|
"text": "Label",
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetName": "Text1",
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 14.015625,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"leftColumn": 1,
|
||||||
|
"rightColumn": 7,
|
||||||
|
"topRow": 1,
|
||||||
|
"bottomRow": 4,
|
||||||
|
"parentId": "bxekwxgc1i",
|
||||||
|
"widgetId": "9xcfqahpw2"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"isMirrored": true,
|
"isMirrored": true,
|
||||||
"widgetName": "Camera1",
|
"widgetName": "Camera1",
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,22 @@
|
||||||
"renderMode": "CANVAS",
|
"renderMode": "CANVAS",
|
||||||
"isLoading": false,
|
"isLoading": false,
|
||||||
"isInline": true
|
"isInline": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"isVisible": true,
|
||||||
|
"text": "Label",
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetName": "Text1",
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 18.66171875,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"leftColumn": 3,
|
||||||
|
"rightColumn": 10,
|
||||||
|
"topRow": 5,
|
||||||
|
"bottomRow": 9,
|
||||||
|
"parentId": "bxekwxgc1i",
|
||||||
|
"widgetId": "9xcfqahpw2"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,22 @@
|
||||||
"renderMode":"CANVAS",
|
"renderMode":"CANVAS",
|
||||||
"isLoading":false,
|
"isLoading":false,
|
||||||
"allowClear":false
|
"allowClear":false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"isVisible": true,
|
||||||
|
"text": "Label",
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetName": "Text1",
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 15.974999999999998,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"leftColumn": 3,
|
||||||
|
"rightColumn": 15,
|
||||||
|
"topRow": 10,
|
||||||
|
"bottomRow": 12,
|
||||||
|
"parentId": "bxekwxgc1i",
|
||||||
|
"widgetId": "9xcfqahpw2"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
481
app/client/cypress/fixtures/formHasChangesDsl.json
Normal file
481
app/client/cypress/fixtures/formHasChangesDsl.json
Normal file
|
|
@ -0,0 +1,481 @@
|
||||||
|
{
|
||||||
|
"dsl": {
|
||||||
|
"widgetName": "MainContainer",
|
||||||
|
"backgroundColor": "none",
|
||||||
|
"rightColumn": 909,
|
||||||
|
"snapColumns": 64,
|
||||||
|
"detachFromLayout": true,
|
||||||
|
"widgetId": "0",
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 1290,
|
||||||
|
"containerStyle": "none",
|
||||||
|
"snapRows": 125,
|
||||||
|
"parentRowSpace": 1,
|
||||||
|
"type": "CANVAS_WIDGET",
|
||||||
|
"canExtend": true,
|
||||||
|
"version": 52,
|
||||||
|
"minHeight": 690,
|
||||||
|
"parentColumnSpace": 1,
|
||||||
|
"dynamicBindingPathList": [],
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Form1",
|
||||||
|
"backgroundColor": "white",
|
||||||
|
"rightColumn": 62,
|
||||||
|
"isCanvas": true,
|
||||||
|
"displayName": "Form",
|
||||||
|
"iconSVG": "/static/media/icon.ea3e08d1.svg",
|
||||||
|
"widgetId": "ui8kenblnq",
|
||||||
|
"topRow": 5,
|
||||||
|
"bottomRow": 62,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "FORM_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"parentId": "0",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"parentColumnSpace": 14.015625,
|
||||||
|
"leftColumn": 2,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Canvas1",
|
||||||
|
"rightColumn": 336.375,
|
||||||
|
"detachFromLayout": true,
|
||||||
|
"displayName": "Canvas",
|
||||||
|
"widgetId": "rgnqy2hpcb",
|
||||||
|
"containerStyle": "none",
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 570,
|
||||||
|
"parentRowSpace": 1,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "CANVAS_WIDGET",
|
||||||
|
"canExtend": false,
|
||||||
|
"version": 1,
|
||||||
|
"hideCard": true,
|
||||||
|
"parentId": "ui8kenblnq",
|
||||||
|
"minHeight": 400,
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 1,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Text1",
|
||||||
|
"displayName": "Text",
|
||||||
|
"iconSVG": "/static/media/icon.97c59b52.svg",
|
||||||
|
"topRow": 1,
|
||||||
|
"bottomRow": 5,
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"dynamicTriggerPathList": [],
|
||||||
|
"leftColumn": 1.5,
|
||||||
|
"dynamicBindingPathList": [],
|
||||||
|
"shouldTruncate": false,
|
||||||
|
"truncateButtonColor": "#FFC13D",
|
||||||
|
"text": "TopLevelForm",
|
||||||
|
"key": "r71qxtucag",
|
||||||
|
"rightColumn": 25.5,
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetId": "az2x2gnx8i",
|
||||||
|
"isVisible": true,
|
||||||
|
"fontStyle": "BOLD",
|
||||||
|
"textColor": "#231F20",
|
||||||
|
"shouldScroll": false,
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "rgnqy2hpcb",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"fontSize": "HEADING1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"boxShadow": "NONE",
|
||||||
|
"widgetName": "Container1",
|
||||||
|
"borderColor": "transparent",
|
||||||
|
"isCanvas": true,
|
||||||
|
"displayName": "Container",
|
||||||
|
"iconSVG": "/static/media/icon.1977dca3.svg",
|
||||||
|
"topRow": 7,
|
||||||
|
"bottomRow": 55,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"type": "CONTAINER_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"parentColumnSpace": 12.8271484375,
|
||||||
|
"leftColumn": 1,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Canvas2",
|
||||||
|
"rightColumn": 307.8515625,
|
||||||
|
"detachFromLayout": true,
|
||||||
|
"displayName": "Canvas",
|
||||||
|
"widgetId": "o16xur9huq",
|
||||||
|
"containerStyle": "none",
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 490,
|
||||||
|
"parentRowSpace": 1,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "CANVAS_WIDGET",
|
||||||
|
"canExtend": false,
|
||||||
|
"version": 1,
|
||||||
|
"hideCard": true,
|
||||||
|
"parentId": "c3ib5l2wce",
|
||||||
|
"minHeight": 400,
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 1,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Form2",
|
||||||
|
"backgroundColor": "white",
|
||||||
|
"rightColumn": 64,
|
||||||
|
"isCanvas": true,
|
||||||
|
"displayName": "Form",
|
||||||
|
"iconSVG": "/static/media/icon.ea3e08d1.svg",
|
||||||
|
"widgetId": "r0vj63apg4",
|
||||||
|
"topRow": 1,
|
||||||
|
"bottomRow": 47,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "FORM_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"parentId": "o16xur9huq",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"parentColumnSpace": 12.314224243164062,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Canvas3",
|
||||||
|
"rightColumn": 295.5413818359375,
|
||||||
|
"detachFromLayout": true,
|
||||||
|
"displayName": "Canvas",
|
||||||
|
"widgetId": "hyxstzafwr",
|
||||||
|
"containerStyle": "none",
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 460,
|
||||||
|
"parentRowSpace": 1,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "CANVAS_WIDGET",
|
||||||
|
"canExtend": false,
|
||||||
|
"version": 1,
|
||||||
|
"hideCard": true,
|
||||||
|
"parentId": "r0vj63apg4",
|
||||||
|
"minHeight": 400,
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 1,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Text2",
|
||||||
|
"displayName": "Text",
|
||||||
|
"iconSVG": "/static/media/icon.97c59b52.svg",
|
||||||
|
"topRow": 1,
|
||||||
|
"bottomRow": 5,
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"dynamicTriggerPathList": [],
|
||||||
|
"leftColumn": 1.5,
|
||||||
|
"dynamicBindingPathList": [],
|
||||||
|
"shouldTruncate": false,
|
||||||
|
"truncateButtonColor": "#FFC13D",
|
||||||
|
"text": "NestedForm1",
|
||||||
|
"key": "r71qxtucag",
|
||||||
|
"rightColumn": 25.5,
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetId": "9x1tljetyn",
|
||||||
|
"isVisible": true,
|
||||||
|
"fontStyle": "BOLD",
|
||||||
|
"textColor": "#231F20",
|
||||||
|
"shouldScroll": false,
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "hyxstzafwr",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"fontSize": "HEADING1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"boxShadow": "NONE",
|
||||||
|
"widgetName": "Container2",
|
||||||
|
"borderColor": "transparent",
|
||||||
|
"isCanvas": true,
|
||||||
|
"displayName": "Container",
|
||||||
|
"iconSVG": "/static/media/icon.1977dca3.svg",
|
||||||
|
"topRow": 6,
|
||||||
|
"bottomRow": 44,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"type": "CONTAINER_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"parentColumnSpace": 12.001724243164062,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Canvas4",
|
||||||
|
"rightColumn": 288.0413818359375,
|
||||||
|
"detachFromLayout": true,
|
||||||
|
"displayName": "Canvas",
|
||||||
|
"widgetId": "bezg0vuivd",
|
||||||
|
"containerStyle": "none",
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 390,
|
||||||
|
"parentRowSpace": 1,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "CANVAS_WIDGET",
|
||||||
|
"canExtend": false,
|
||||||
|
"version": 1,
|
||||||
|
"hideCard": true,
|
||||||
|
"parentId": "d3bbrwipbo",
|
||||||
|
"minHeight": 400,
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 1,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Form3",
|
||||||
|
"backgroundColor": "white",
|
||||||
|
"rightColumn": 62,
|
||||||
|
"isCanvas": true,
|
||||||
|
"displayName": "Form",
|
||||||
|
"iconSVG": "/static/media/icon.ea3e08d1.svg",
|
||||||
|
"widgetId": "e9qj527b6g",
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 36,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "FORM_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"parentId": "bezg0vuivd",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"parentColumnSpace": 12.001724243164062,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Canvas5",
|
||||||
|
"rightColumn": 288.0413818359375,
|
||||||
|
"detachFromLayout": true,
|
||||||
|
"displayName": "Canvas",
|
||||||
|
"widgetId": "ju0erkgavw",
|
||||||
|
"containerStyle": "none",
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 390,
|
||||||
|
"parentRowSpace": 1,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "CANVAS_WIDGET",
|
||||||
|
"canExtend": false,
|
||||||
|
"version": 1,
|
||||||
|
"hideCard": true,
|
||||||
|
"parentId": "e9qj527b6g",
|
||||||
|
"minHeight": 400,
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 1,
|
||||||
|
"leftColumn": 0,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Text3",
|
||||||
|
"displayName": "Text",
|
||||||
|
"iconSVG": "/static/media/icon.97c59b52.svg",
|
||||||
|
"topRow": 1,
|
||||||
|
"bottomRow": 5,
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"dynamicTriggerPathList": [],
|
||||||
|
"leftColumn": 1.5,
|
||||||
|
"dynamicBindingPathList": [],
|
||||||
|
"shouldTruncate": false,
|
||||||
|
"truncateButtonColor": "#FFC13D",
|
||||||
|
"text": "NestedForm2",
|
||||||
|
"key": "r71qxtucag",
|
||||||
|
"rightColumn": 25.5,
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetId": "kx3kje0esv",
|
||||||
|
"isVisible": true,
|
||||||
|
"fontStyle": "BOLD",
|
||||||
|
"textColor": "#231F20",
|
||||||
|
"shouldScroll": false,
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "ju0erkgavw",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"fontSize": "HEADING1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resetFormOnClick": true,
|
||||||
|
"widgetName": "FormButton1",
|
||||||
|
"buttonColor": "#03B365",
|
||||||
|
"displayName": "FormButton",
|
||||||
|
"iconSVG": "/static/media/icon.c8f649ed.svg",
|
||||||
|
"topRow": 29,
|
||||||
|
"bottomRow": 33,
|
||||||
|
"type": "FORM_BUTTON_WIDGET",
|
||||||
|
"hideCard": true,
|
||||||
|
"animateLoading": true,
|
||||||
|
"leftColumn": 47,
|
||||||
|
"text": "Submit",
|
||||||
|
"key": "6rckarmxa8",
|
||||||
|
"rightColumn": 63,
|
||||||
|
"isDefaultClickDisabled": true,
|
||||||
|
"widgetId": "71jwl9rqyl",
|
||||||
|
"isVisible": true,
|
||||||
|
"recaptchaType": "V3",
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "ju0erkgavw",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"disabledWhenInvalid": true,
|
||||||
|
"buttonVariant": "PRIMARY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resetFormOnClick": true,
|
||||||
|
"widgetName": "FormButton2",
|
||||||
|
"buttonColor": "#03B365",
|
||||||
|
"displayName": "FormButton",
|
||||||
|
"iconSVG": "/static/media/icon.c8f649ed.svg",
|
||||||
|
"topRow": 29,
|
||||||
|
"bottomRow": 33,
|
||||||
|
"type": "FORM_BUTTON_WIDGET",
|
||||||
|
"hideCard": true,
|
||||||
|
"animateLoading": true,
|
||||||
|
"leftColumn": 30,
|
||||||
|
"text": "Reset",
|
||||||
|
"key": "6rckarmxa8",
|
||||||
|
"rightColumn": 46,
|
||||||
|
"isDefaultClickDisabled": true,
|
||||||
|
"widgetId": "385vwj1sak",
|
||||||
|
"isVisible": true,
|
||||||
|
"recaptchaType": "V3",
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "ju0erkgavw",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"disabledWhenInvalid": false,
|
||||||
|
"buttonVariant": "SECONDARY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgetName": "Checkbox1",
|
||||||
|
"displayName": "Checkbox",
|
||||||
|
"iconSVG": "/static/media/icon.aaab032b.svg",
|
||||||
|
"topRow": 7,
|
||||||
|
"bottomRow": 11,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"type": "CHECKBOX_WIDGET",
|
||||||
|
"alignWidget": "LEFT",
|
||||||
|
"hideCard": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"parentColumnSpace": 11.011435985565186,
|
||||||
|
"leftColumn": 1,
|
||||||
|
"isDisabled": false,
|
||||||
|
"key": "kn37pa6063",
|
||||||
|
"isRequired": false,
|
||||||
|
"rightColumn": 21,
|
||||||
|
"widgetId": "xcs2djteir",
|
||||||
|
"isVisible": true,
|
||||||
|
"label": "Label",
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "ju0erkgavw",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"defaultCheckedState": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "invgby4psp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "1yxjunjfwb"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "invgby4psp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"borderWidth": "0",
|
||||||
|
"key": "tpj0tcwdhg",
|
||||||
|
"backgroundColor": "#FFFFFF",
|
||||||
|
"rightColumn": 64,
|
||||||
|
"widgetId": "d3bbrwipbo",
|
||||||
|
"containerStyle": "card",
|
||||||
|
"isVisible": true,
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "hyxstzafwr",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"borderRadius": "0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "invgby4psp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "1yxjunjfwb"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "invgby4psp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"borderWidth": "0",
|
||||||
|
"key": "tpj0tcwdhg",
|
||||||
|
"backgroundColor": "#FFFFFF",
|
||||||
|
"rightColumn": 64,
|
||||||
|
"widgetId": "c3ib5l2wce",
|
||||||
|
"containerStyle": "card",
|
||||||
|
"isVisible": true,
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "rgnqy2hpcb",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"borderRadius": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgetName": "Text4",
|
||||||
|
"displayName": "Text",
|
||||||
|
"iconSVG": "/static/media/icon.97c59b52.svg",
|
||||||
|
"topRow": 1,
|
||||||
|
"bottomRow": 5,
|
||||||
|
"parentRowSpace": 10,
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"hideCard": false,
|
||||||
|
"animateLoading": true,
|
||||||
|
"parentColumnSpace": 12.8271484375,
|
||||||
|
"dynamicTriggerPathList": [],
|
||||||
|
"leftColumn": 47,
|
||||||
|
"dynamicBindingPathList": [
|
||||||
|
{
|
||||||
|
"key": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shouldTruncate": false,
|
||||||
|
"truncateButtonColor": "#FFC13D",
|
||||||
|
"text": "{{Form1.hasChanges}}",
|
||||||
|
"key": "r71qxtucag",
|
||||||
|
"rightColumn": 63,
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetId": "6lwl9odtd7",
|
||||||
|
"isVisible": true,
|
||||||
|
"fontStyle": "BOLD",
|
||||||
|
"textColor": "#231F20",
|
||||||
|
"shouldScroll": false,
|
||||||
|
"version": 1,
|
||||||
|
"parentId": "rgnqy2hpcb",
|
||||||
|
"renderMode": "CANVAS",
|
||||||
|
"isLoading": false,
|
||||||
|
"fontSize": "PARAGRAPH"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "invgby4psp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": "1yxjunjfwb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,6 +105,22 @@
|
||||||
"bottomRow": 7,
|
"bottomRow": 7,
|
||||||
"parentId": "7tkpo9s22m",
|
"parentId": "7tkpo9s22m",
|
||||||
"widgetId": "6h8j08u7ea"
|
"widgetId": "6h8j08u7ea"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"isVisible": true,
|
||||||
|
"text": "Label",
|
||||||
|
"textAlign": "LEFT",
|
||||||
|
"widgetName": "Text1",
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 71.75,
|
||||||
|
"parentRowSpace": 38,
|
||||||
|
"leftColumn": 3,
|
||||||
|
"rightColumn": 5,
|
||||||
|
"topRow": 10,
|
||||||
|
"bottomRow": 12,
|
||||||
|
"parentId": "bxekwxgc1i",
|
||||||
|
"widgetId": "9xcfqahpw2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"widgetId": "7tkpo9s22m",
|
"widgetId": "7tkpo9s22m",
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,25 @@
|
||||||
"leftColumn": 0,
|
"leftColumn": 0,
|
||||||
"dynamicBindingPathList": [],
|
"dynamicBindingPathList": [],
|
||||||
"children": [
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Text1",
|
||||||
|
"rightColumn": 10,
|
||||||
|
"widgetId": "4d8d2eh4xg",
|
||||||
|
"dynamicPropertyPathList": [],
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 3,
|
||||||
|
"parentRowSpace": 38,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"dynamicBindingPathList": [],
|
||||||
|
"shouldScroll": true,
|
||||||
|
"parentId": "hjiybwqair",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 71.75,
|
||||||
|
"leftColumn": 1,
|
||||||
|
"text": "Test text",
|
||||||
|
"textStyle": "HEADING"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"isRequired": false,
|
"isRequired": false,
|
||||||
"widgetName": "Input1",
|
"widgetName": "Input1",
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,25 @@
|
||||||
"snapColumns": 16,
|
"snapColumns": 16,
|
||||||
"orientation": "VERTICAL",
|
"orientation": "VERTICAL",
|
||||||
"children": [
|
"children": [
|
||||||
|
{
|
||||||
|
"widgetName": "Text1",
|
||||||
|
"rightColumn": 3,
|
||||||
|
"widgetId": "4d8d2eh4xg",
|
||||||
|
"dynamicPropertyPathList": [],
|
||||||
|
"topRow": 0,
|
||||||
|
"bottomRow": 1,
|
||||||
|
"parentRowSpace": 38,
|
||||||
|
"isVisible": true,
|
||||||
|
"type": "TEXT_WIDGET",
|
||||||
|
"dynamicBindingPathList": [],
|
||||||
|
"shouldScroll": true,
|
||||||
|
"parentId": "hjiybwqair",
|
||||||
|
"isLoading": false,
|
||||||
|
"parentColumnSpace": 71.75,
|
||||||
|
"leftColumn": 1,
|
||||||
|
"text": "Test text",
|
||||||
|
"textStyle": "HEADING"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"isVisible": true,
|
"isVisible": true,
|
||||||
"inputType": "TEXT",
|
"inputType": "TEXT",
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,10 @@ describe("Entity explorer Drag and Drop widgets testcases", function() {
|
||||||
cy.hoverAndClickParticularIndex(1);
|
cy.hoverAndClickParticularIndex(1);
|
||||||
cy.selectAction("Show Bindings");
|
cy.selectAction("Show Bindings");
|
||||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||||
expect($lis).to.have.length(2);
|
expect($lis).to.have.length(3);
|
||||||
expect($lis.eq(0)).to.contain("{{FormTest.isVisible}}");
|
expect($lis.eq(0)).to.contain("{{FormTest.isVisible}}");
|
||||||
expect($lis.eq(1)).to.contain("{{FormTest.data}}");
|
expect($lis.eq(1)).to.contain("{{FormTest.data}}");
|
||||||
|
expect($lis.eq(2)).to.contain("{{FormTest.hasChanges}}");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,10 @@ describe("Test Suite to validate copy/delete/undo functionalites", function() {
|
||||||
cy.hoverAndClickParticularIndex(1);
|
cy.hoverAndClickParticularIndex(1);
|
||||||
cy.selectAction("Show Bindings");
|
cy.selectAction("Show Bindings");
|
||||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||||
expect($lis).to.have.length(2);
|
expect($lis).to.have.length(3);
|
||||||
expect($lis.eq(0)).to.contain("{{FormTest.isVisible}}");
|
expect($lis.eq(0)).to.contain("{{FormTest.isVisible}}");
|
||||||
expect($lis.eq(1)).to.contain("{{FormTest.data}}");
|
expect($lis.eq(1)).to.contain("{{FormTest.data}}");
|
||||||
|
expect($lis.eq(2)).to.contain("{{FormTest.hasChanges}}");
|
||||||
});
|
});
|
||||||
cy.get(".t--entity-name")
|
cy.get(".t--entity-name")
|
||||||
.contains("FormTest")
|
.contains("FormTest")
|
||||||
|
|
@ -68,9 +69,10 @@ describe("Test Suite to validate copy/delete/undo functionalites", function() {
|
||||||
cy.hoverAndClickParticularIndex(1);
|
cy.hoverAndClickParticularIndex(1);
|
||||||
cy.selectAction("Show Bindings");
|
cy.selectAction("Show Bindings");
|
||||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||||
expect($lis).to.have.length(2);
|
expect($lis).to.have.length(3);
|
||||||
expect($lis.eq(0)).to.contain("{{FormTest.isVisible}}");
|
expect($lis.eq(0)).to.contain("{{FormTest.isVisible}}");
|
||||||
expect($lis.eq(1)).to.contain("{{FormTest.data}}");
|
expect($lis.eq(1)).to.contain("{{FormTest.data}}");
|
||||||
|
expect($lis.eq(2)).to.contain("{{FormTest.hasChanges}}");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,10 @@ describe("Test Suite to validate copy/delete/undo functionalites", function() {
|
||||||
ee.expandCollapseEntity("FormTest");
|
ee.expandCollapseEntity("FormTest");
|
||||||
ee.ActionContextMenuByEntityName("FormTestCopy", "Show Bindings");
|
ee.ActionContextMenuByEntityName("FormTestCopy", "Show Bindings");
|
||||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||||
expect($lis).to.have.length(2);
|
expect($lis).to.have.length(3);
|
||||||
expect($lis.eq(0)).to.contain("{{FormTestCopy.isVisible}}");
|
expect($lis.eq(0)).to.contain("{{FormTestCopy.isVisible}}");
|
||||||
expect($lis.eq(1)).to.contain("{{FormTestCopy.data}}");
|
expect($lis.eq(1)).to.contain("{{FormTestCopy.data}}");
|
||||||
|
expect($lis.eq(2)).to.contain("{{FormTestCopy.hasChanges}}");
|
||||||
cy.contains("FormTestCopy");
|
cy.contains("FormTestCopy");
|
||||||
cy.get($lis.eq(1))
|
cy.get($lis.eq(1))
|
||||||
.contains("{{FormTestCopy.data}}")
|
.contains("{{FormTestCopy.data}}")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
|
|
||||||
|
const widgetName = "audiorecorderwidget";
|
||||||
|
|
||||||
|
describe("AudioRecorder Widget", () => {
|
||||||
|
it("Drag & drop AudioRecorder and Text widgets", () => {
|
||||||
|
cy.get(explorer.addWidget).click();
|
||||||
|
cy.dragAndDropToCanvas(widgetName, { x: 300, y: 300 });
|
||||||
|
cy.get(`.t--widget-${widgetName}`).should("exist");
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 300, y: 500 });
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{AudioRecorder1.isDirty}}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", () => {
|
||||||
|
// Check if isDirty is false for the first time
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(`.t--widget-${widgetName} button`)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
cy.get(`.t--widget-${widgetName} .status`)
|
||||||
|
.should("have.text", "Press to start recording")
|
||||||
|
.should("exist");
|
||||||
|
// Start recording and recorder for 3 seconds
|
||||||
|
cy.get(`.t--widget-${widgetName} button`)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
cy.wait(3000);
|
||||||
|
// Stop recording
|
||||||
|
cy.get(`.t--widget-${widgetName} button span.bp3-icon-symbol-square`)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -14,12 +14,16 @@ describe("Camera Widget", () => {
|
||||||
cy.goToEditFromPublish();
|
cy.goToEditFromPublish();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Property: onImageSave, show modal", () => {
|
it("Check isDirty, onImageSave", () => {
|
||||||
const modalName = `modal`;
|
const modalName = `modal`;
|
||||||
const mainControlSelector =
|
const mainControlSelector =
|
||||||
"//div[contains(@class, 't--widget-camerawidget')]//button";
|
"//div[contains(@class, 't--widget-camerawidget')]//button";
|
||||||
|
|
||||||
cy.createModal(modalName);
|
cy.createModal(modalName);
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", "{{Camera1.isDirty}}");
|
||||||
|
// Initial value of isDirty should be false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
// Take photo
|
// Take photo
|
||||||
cy.xpath(mainControlSelector)
|
cy.xpath(mainControlSelector)
|
||||||
.eq(2)
|
.eq(2)
|
||||||
|
|
@ -32,5 +36,7 @@ describe("Camera Widget", () => {
|
||||||
|
|
||||||
// Assert: should trigger onImageSave action - modal popup
|
// Assert: should trigger onImageSave action - modal popup
|
||||||
cy.get(modalWidgetPage.modelTextField).should("have.text", modalName);
|
cy.get(modalWidgetPage.modelTextField).should("have.text", modalName);
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ const publish = require("../../../../locators/publishWidgetspage.json");
|
||||||
const dsl = require("../../../../fixtures/newFormDsl.json");
|
const dsl = require("../../../../fixtures/newFormDsl.json");
|
||||||
const formWidgetDsl = require("../../../../fixtures/formWidgetdsl.json");
|
const formWidgetDsl = require("../../../../fixtures/formWidgetdsl.json");
|
||||||
const pages = require("../../../../locators/Pages.json");
|
const pages = require("../../../../locators/Pages.json");
|
||||||
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
|
|
||||||
describe("Checkbox Widget Functionality", function() {
|
describe("Checkbox Widget Functionality", function() {
|
||||||
before(() => {
|
before(() => {
|
||||||
|
|
@ -72,6 +73,26 @@ describe("Checkbox Widget Functionality", function() {
|
||||||
cy.get(publish.checkboxWidget + " " + "input").should("be.checked");
|
cy.get(publish.checkboxWidget + " " + "input").should("be.checked");
|
||||||
cy.get(publish.backToEditor).click();
|
cy.get(publish.backToEditor).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{checker.isDirty}}`);
|
||||||
|
// Check if initial value of isDirty is false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(`${formWidgetsPage.checkboxWidget} label`)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultCheckedState property
|
||||||
|
cy.openPropertyPane("checkboxwidget");
|
||||||
|
cy.get(".t--property-control-defaultselected label")
|
||||||
|
.last()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const commonlocators = require("../../../../locators/commonlocators.json");
|
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||||
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
|
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
|
||||||
const publish = require("../../../../locators/publishWidgetspage.json");
|
const publish = require("../../../../locators/publishWidgetspage.json");
|
||||||
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
const dsl = require("../../../../fixtures/checkboxgroupDsl.json");
|
const dsl = require("../../../../fixtures/checkboxgroupDsl.json");
|
||||||
|
|
||||||
describe("Checkbox Group Widget Functionality", function() {
|
describe("Checkbox Group Widget Functionality", function() {
|
||||||
|
|
@ -129,6 +130,27 @@ describe("Checkbox Group Widget Functionality", function() {
|
||||||
".t--draggable-checkboxgroupwidget div[data-cy^='checkbox-group-container']",
|
".t--draggable-checkboxgroupwidget div[data-cy^='checkbox-group-container']",
|
||||||
).should("have.css", "justify-content", "flex-start");
|
).should("have.css", "justify-content", "flex-start");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.get(explorer.addWidget).click();
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 300, y: 500 });
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{checkboxgrouptest.isDirty}}`,
|
||||||
|
);
|
||||||
|
// Change defaultSelectedValues
|
||||||
|
cy.openPropertyPane("checkboxgroupwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-defaultselectedvalues", "GREEN");
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(formWidgetsPage.labelCheckboxGroup)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
// put your clean up code if any
|
// put your clean up code if any
|
||||||
|
|
|
||||||
|
|
@ -248,4 +248,28 @@ describe("Currency widget - ", () => {
|
||||||
enterAndTest(d[0], d[1]);
|
enterAndTest(d[0], d[1]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{CurrencyInput1.isDirty}}`,
|
||||||
|
);
|
||||||
|
// Init isDirty
|
||||||
|
cy.openPropertyPane(widgetName);
|
||||||
|
cy.updateCodeInput(".t--property-control-defaulttext", "1");
|
||||||
|
cy.closePropertyPane();
|
||||||
|
// Check if initial value of isDirty is false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(widgetInput).clear();
|
||||||
|
cy.wait(300);
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultText
|
||||||
|
cy.openPropertyPane(widgetName);
|
||||||
|
cy.updateCodeInput(".t--property-control-defaulttext", "5");
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,49 @@ describe("DatePicker Widget Property pane tests with js bindings", function() {
|
||||||
.should("have.text", "May 4, 2021 6:25 AM");
|
.should("have.text", "May 4, 2021 6:25 AM");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{DatePicker1.isDirty}}`);
|
||||||
|
// Init isDirty
|
||||||
|
cy.openPropertyPane("datepickerwidget2");
|
||||||
|
cy.get(formWidgetsPage.toggleJsDefaultDate).click();
|
||||||
|
cy.get(".t--property-control-defaultdate .bp3-input").clear();
|
||||||
|
cy.get(formWidgetsPage.toggleJsDefaultDate).click();
|
||||||
|
cy.testJsontext(
|
||||||
|
"defaultdate",
|
||||||
|
'{{moment("04/05/2021 05:25", "DD/MM/YYYY HH:mm").toISOString()}}',
|
||||||
|
);
|
||||||
|
cy.closePropertyPane();
|
||||||
|
// Check if initial value of isDirty is false
|
||||||
|
cy.get(".t--widget-textwidget")
|
||||||
|
.first()
|
||||||
|
.should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(".t--draggable-datepickerwidget2 .bp3-input")
|
||||||
|
.clear({
|
||||||
|
force: true,
|
||||||
|
})
|
||||||
|
.type("04/05/2021 06:25");
|
||||||
|
cy.wait("@updateLayout");
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget")
|
||||||
|
.first()
|
||||||
|
.should("contain", "true");
|
||||||
|
// Change defaultDate
|
||||||
|
cy.openPropertyPane("datepickerwidget2");
|
||||||
|
cy.get(formWidgetsPage.toggleJsDefaultDate).click();
|
||||||
|
cy.get(".t--property-control-defaultdate .bp3-input").clear();
|
||||||
|
cy.get(formWidgetsPage.toggleJsDefaultDate).click();
|
||||||
|
cy.testJsontext(
|
||||||
|
"defaultdate",
|
||||||
|
'{{moment("07/05/2021 05:25", "DD/MM/YYYY HH:mm").toISOString()}}',
|
||||||
|
);
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget")
|
||||||
|
.first()
|
||||||
|
.should("contain", "false");
|
||||||
|
});
|
||||||
|
|
||||||
it("Datepicker default date validation with js binding", function() {
|
it("Datepicker default date validation with js binding", function() {
|
||||||
cy.PublishtheApp();
|
cy.PublishtheApp();
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
|
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||||
|
|
||||||
|
const widgetName = "filepickerwidgetv2";
|
||||||
|
|
||||||
|
describe("File picker widget v2", () => {
|
||||||
|
it("1. Drag & drop FilePicker/Text widgets", () => {
|
||||||
|
cy.get(explorer.addWidget).click();
|
||||||
|
cy.dragAndDropToCanvas(widgetName, { x: 300, y: 300 });
|
||||||
|
cy.get(`.t--widget-${widgetName}`).should("exist");
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 300, y: 500 });
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{FilePicker1.isDirty}}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
// Check if initial value of isDirty is false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Upload a new file
|
||||||
|
cy.get(`.t--widget-${widgetName}`).click();
|
||||||
|
cy.get(commonlocators.filePickerInput)
|
||||||
|
.first()
|
||||||
|
.attachFile("testFile.mov");
|
||||||
|
cy.get(commonlocators.filePickerUploadButton).click();
|
||||||
|
//eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
|
cy.wait(500);
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
const dsl = require("../../../../fixtures/formHasChangesDsl.json");
|
||||||
|
|
||||||
|
describe("Form Widget", () => {
|
||||||
|
before(() => {
|
||||||
|
cy.addDsl(dsl);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Check hasChanges meta property", () => {
|
||||||
|
// Check if isDirty is false for the first time
|
||||||
|
cy.contains(".t--widget-textwidget", "false").should("exist");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(`.t--widget-checkboxwidget label`)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.contains(".t--widget-textwidget", "false").should("not.exist");
|
||||||
|
cy.contains(".t--widget-textwidget", "true").should("exist");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -422,6 +422,29 @@ describe("Input widget V2 - ", () => {
|
||||||
cy.get(".t--widget-textwidget").should("contain", "1.0001:1.0001:true");
|
cy.get(".t--widget-textwidget").should("contain", "1.0001:1.0001:true");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{Input1.isDirty}}`);
|
||||||
|
// Init isDirty
|
||||||
|
cy.openPropertyPane(widgetName);
|
||||||
|
cy.selectDropdownValue(".t--property-control-datatype", "Text");
|
||||||
|
cy.updateCodeInput(".t--property-control-defaulttext", "a");
|
||||||
|
// Check if initial value of isDirty is false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(widgetInput).clear();
|
||||||
|
cy.wait(300);
|
||||||
|
cy.get(widgetInput).type("b");
|
||||||
|
cy.wait(300);
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultText
|
||||||
|
cy.openPropertyPane(widgetName);
|
||||||
|
cy.updateCodeInput(".t--property-control-defaulttext", "c");
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
|
|
||||||
function enterAndTest(text, expected) {
|
function enterAndTest(text, expected) {
|
||||||
cy.get(`.t--widget-${widgetName} input`).clear();
|
cy.get(`.t--widget-${widgetName} input`).clear();
|
||||||
cy.wait(300);
|
cy.wait(300);
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,30 @@ describe("MultiSelect Widget Functionality", function() {
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.should("have.text", "Option 2");
|
.should("have.text", "Option 2");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{MultiSelect2.isDirty}}`);
|
||||||
|
// Init isDirty by changing defaultOptionValue
|
||||||
|
cy.openPropertyPane("multiselectwidgetv2");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-defaultvalue",
|
||||||
|
'[\n {\n "label": "Option 1",\n "value": "1"\n }\n]',
|
||||||
|
);
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(".rc-select-selector").click({ force: true });
|
||||||
|
cy.dropdownMultiSelectDynamic("Option 2");
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Reset isDirty by changing defaultOptionValue
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-defaultvalue",
|
||||||
|
'[\n {\n "label": "Option 2",\n "value": "2"\n }\n]',
|
||||||
|
);
|
||||||
|
// Check if isDirty is set to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
// put your clean up code if any
|
// put your clean up code if any
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const dsl = require("../../../../fixtures/TreeSelectDsl.json");
|
||||||
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
|
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
|
||||||
const publish = require("../../../../locators/publishWidgetspage.json");
|
const publish = require("../../../../locators/publishWidgetspage.json");
|
||||||
const commonlocators = require("../../../../locators/commonlocators.json");
|
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||||
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
|
|
||||||
describe("MultiSelectTree Widget Functionality", function() {
|
describe("MultiSelectTree Widget Functionality", function() {
|
||||||
before(() => {
|
before(() => {
|
||||||
|
|
@ -41,6 +42,32 @@ describe("MultiSelectTree Widget Functionality", function() {
|
||||||
).should("be.visible");
|
).should("be.visible");
|
||||||
cy.get(publish.backToEditor).click();
|
cy.get(publish.backToEditor).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.get(explorer.addWidget).click();
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 300, y: 500 });
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{MultiSelectTree1.isDirty}}`,
|
||||||
|
);
|
||||||
|
// Change defaultValue
|
||||||
|
cy.openPropertyPane("multiselecttreewidget");
|
||||||
|
cy.testJsontext("defaultvalue", "GREEN\n");
|
||||||
|
// Check if isDirty is set to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(formWidgetsPage.treeSelectInput)
|
||||||
|
.first()
|
||||||
|
.click({ force: true });
|
||||||
|
cy.treeMultiSelectDropdown("Red");
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Reset isDirty by changing defaultValue
|
||||||
|
cy.testJsontext("defaultvalue", "BLUE\n");
|
||||||
|
// Check if isDirty is set to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
// put your clean up code if any
|
// put your clean up code if any
|
||||||
|
|
|
||||||
|
|
@ -105,4 +105,27 @@ describe("Phone input widget - ", () => {
|
||||||
cy.get(widgetInput).should("contain.value", "");
|
cy.get(widgetInput).should("contain.value", "");
|
||||||
cy.get(".t--widget-textwidget").should("contain", ":undefined");
|
cy.get(".t--widget-textwidget").should("contain", ":undefined");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{PhoneInput1.isDirty}}`);
|
||||||
|
// Change defaultText
|
||||||
|
cy.openPropertyPane(widgetName);
|
||||||
|
cy.updateCodeInput(".t--property-control-defaulttext", "1");
|
||||||
|
cy.closePropertyPane();
|
||||||
|
// Check if isDirty is set to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(widgetInput).clear();
|
||||||
|
cy.wait(300);
|
||||||
|
cy.get(widgetInput).type("2");
|
||||||
|
cy.wait(300);
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Reset isDirty by changing defaultText
|
||||||
|
cy.openPropertyPane(widgetName);
|
||||||
|
cy.updateCodeInput(".t--property-control-defaulttext", "3");
|
||||||
|
// Check if isDirty is set to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
|
|
||||||
|
const widgetName = "radiogroupwidget";
|
||||||
|
|
||||||
|
describe("Radio Group Widget", () => {
|
||||||
|
it("Drag & drop Radio group & Text widgets", () => {
|
||||||
|
cy.get(explorer.addWidget).click();
|
||||||
|
cy.dragAndDropToCanvas(widgetName, { x: 300, y: 300 });
|
||||||
|
cy.get(`.t--widget-${widgetName}`).should("exist");
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 300, y: 500 });
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{RadioGroup1.isDirty}}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
// Check if initial value of isDirty is false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(".t--widget-radiogroupwidget .bp3-radio")
|
||||||
|
.last()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultOptionValue
|
||||||
|
cy.openPropertyPane(widgetName);
|
||||||
|
cy.updateCodeInput(".t--property-control-defaultselectedvalue", "N");
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -128,6 +128,28 @@ describe("RichTextEditor Widget Functionality", function() {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{RichtextEditor.isDirty}}`,
|
||||||
|
);
|
||||||
|
// Change defaultText
|
||||||
|
cy.openPropertyPane("richtexteditorwidget");
|
||||||
|
cy.testJsontext("defaulttext", "a");
|
||||||
|
// Check if isDirty has been changed into false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.setTinyMceContent("rte-6h8j08u7ea", "abc");
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultText
|
||||||
|
cy.openPropertyPane("richtexteditorwidget");
|
||||||
|
cy.testJsontext("defaulttext", "b");
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
cy.goToEditFromPublish();
|
cy.goToEditFromPublish();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
|
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||||
|
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
|
||||||
|
const widgetLocators = require("../../../../locators/Widgets.json");
|
||||||
|
|
||||||
|
const widgetName = "selectwidget";
|
||||||
|
|
||||||
|
describe("Select widget", () => {
|
||||||
|
it("1. Drag and drop Select/Text widgets", () => {
|
||||||
|
cy.get(explorer.addWidget).click();
|
||||||
|
cy.dragAndDropToCanvas(widgetName, { x: 300, y: 300 });
|
||||||
|
cy.get(`.t--widget-${widgetName}`).should("exist");
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 300, y: 500 });
|
||||||
|
});
|
||||||
|
it("2. Check isDirty meta property", () => {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{Select1.isDirty}}`);
|
||||||
|
// Check if initial value of isDirty is false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(formWidgetsPage.selectWidget)
|
||||||
|
.find(widgetLocators.dropdownSingleSelect)
|
||||||
|
.click({ force: true });
|
||||||
|
cy.get(commonlocators.singleSelectWidgetMenuItem)
|
||||||
|
.contains("Blue")
|
||||||
|
.click({ force: true });
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultOptionValue property
|
||||||
|
cy.updateCodeInput(".t--property-control-defaultvalue", "RED");
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -41,6 +41,35 @@ describe("Single Select Widget Functionality", function() {
|
||||||
).should("be.visible");
|
).should("be.visible");
|
||||||
cy.get(publish.backToEditor).click();
|
cy.get(publish.backToEditor).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{SingleSelectTree1.isDirty}}`,
|
||||||
|
);
|
||||||
|
// Change defaultText
|
||||||
|
cy.openPropertyPane("singleselecttreewidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-defaultvalue", "GREEN");
|
||||||
|
cy.closePropertyPane();
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(formWidgetsPage.treeSelectInput)
|
||||||
|
.last()
|
||||||
|
.click({ force: true });
|
||||||
|
cy.get(formWidgetsPage.treeSelectFilterInput)
|
||||||
|
.click()
|
||||||
|
.type("light");
|
||||||
|
cy.treeSelectDropdown("Light Blue");
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultText
|
||||||
|
cy.openPropertyPane("singleselecttreewidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-defaultvalue", "RED");
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
// put your clean up code if any
|
// put your clean up code if any
|
||||||
|
|
|
||||||
|
|
@ -100,4 +100,34 @@ describe("Switch Group Widget Functionality", function() {
|
||||||
this.data.ModalName,
|
this.data.ModalName,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{switchgrouptest.isDirty}}`,
|
||||||
|
);
|
||||||
|
// Change defaultSelectedValues
|
||||||
|
cy.openPropertyPane("switchgroupwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-defaultselectedvalues",
|
||||||
|
`[\n"BLUE"\n]`,
|
||||||
|
);
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(formWidgetsPage.labelSwitchGroup)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultSelectedValues
|
||||||
|
cy.openPropertyPane("switchgroupwidget");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-defaultselectedvalues",
|
||||||
|
`[\n"GREEN"\n]`,
|
||||||
|
);
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,31 @@ describe("Switch Widget Functionality", function() {
|
||||||
cy.get(publish.switchwidget + " " + ".bp3-align-left").should("not.exist");
|
cy.get(publish.switchwidget + " " + ".bp3-align-left").should("not.exist");
|
||||||
cy.get(publish.backToEditor).click();
|
cy.get(publish.backToEditor).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Check isDirty meta property", function() {
|
||||||
|
cy.openPropertyPane("textwidget");
|
||||||
|
cy.updateCodeInput(".t--property-control-text", `{{Toggler.isDirty}}`);
|
||||||
|
// Change defaultSwitchState property
|
||||||
|
cy.openPropertyPane("switchwidget");
|
||||||
|
cy.get(".t--property-control-defaultselected label")
|
||||||
|
.last()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
// Interact with UI
|
||||||
|
cy.get(`${formWidgetsPage.switchWidget} label`)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is set to true
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "true");
|
||||||
|
// Change defaultSwitchState property
|
||||||
|
cy.openPropertyPane("switchwidget");
|
||||||
|
cy.get(".t--property-control-defaultselected label")
|
||||||
|
.last()
|
||||||
|
.click();
|
||||||
|
// Check if isDirty is reset to false
|
||||||
|
cy.get(".t--widget-textwidget").should("contain", "false");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
// put your clean up code if any
|
// put your clean up code if any
|
||||||
|
|
|
||||||
|
|
@ -311,6 +311,7 @@ export const entityDefinitions: Record<string, unknown> = {
|
||||||
"!url": "https://docs.appsmith.com/widget-reference/form",
|
"!url": "https://docs.appsmith.com/widget-reference/form",
|
||||||
isVisible: isVisible,
|
isVisible: isVisible,
|
||||||
data: generateTypeDef(widget.data),
|
data: generateTypeDef(widget.data),
|
||||||
|
hasChanges: "bool",
|
||||||
}),
|
}),
|
||||||
FORM_BUTTON_WIDGET: {
|
FORM_BUTTON_WIDGET: {
|
||||||
"!doc":
|
"!doc":
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ export interface AudioRecorderWidgetProps extends WidgetProps {
|
||||||
onRecordingStart?: string;
|
onRecordingStart?: string;
|
||||||
onRecordingComplete?: string;
|
onRecordingComplete?: string;
|
||||||
blobURL?: string;
|
blobURL?: string;
|
||||||
|
isDirty: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AudioRecorderWidget extends BaseWidget<
|
class AudioRecorderWidget extends BaseWidget<
|
||||||
|
|
@ -117,6 +118,7 @@ class AudioRecorderWidget extends BaseWidget<
|
||||||
blobURL: undefined,
|
blobURL: undefined,
|
||||||
dataURL: undefined,
|
dataURL: undefined,
|
||||||
rawBinary: undefined,
|
rawBinary: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,6 +127,10 @@ class AudioRecorderWidget extends BaseWidget<
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRecordingStart = () => {
|
handleRecordingStart = () => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.props.blobURL) {
|
if (this.props.blobURL) {
|
||||||
URL.revokeObjectURL(this.props.blobURL);
|
URL.revokeObjectURL(this.props.blobURL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -906,7 +906,9 @@ function CameraComponent(props: CameraComponentProps) {
|
||||||
}, [isAudioMuted, isVideoMuted]);
|
}, [isAudioMuted, isVideoMuted]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsReadyPlayerTimer(false);
|
// Clean up
|
||||||
|
resetMedia();
|
||||||
|
|
||||||
if (mode === CameraModeTypes.CAMERA) {
|
if (mode === CameraModeTypes.CAMERA) {
|
||||||
setMediaCaptureStatus(MediaCaptureStatusTypes.IMAGE_DEFAULT);
|
setMediaCaptureStatus(MediaCaptureStatusTypes.IMAGE_DEFAULT);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -160,10 +160,10 @@ class CameraWidget extends BaseWidget<CameraWidgetProps, WidgetState> {
|
||||||
imageDataURL: undefined,
|
imageDataURL: undefined,
|
||||||
imageRawBinary: undefined,
|
imageRawBinary: undefined,
|
||||||
mediaCaptureStatus: MediaCaptureStatusTypes.IMAGE_DEFAULT,
|
mediaCaptureStatus: MediaCaptureStatusTypes.IMAGE_DEFAULT,
|
||||||
timer: undefined,
|
|
||||||
videoBlobURL: undefined,
|
videoBlobURL: undefined,
|
||||||
videoDataURL: undefined,
|
videoDataURL: undefined,
|
||||||
videoRawBinary: undefined,
|
videoRawBinary: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,6 +215,11 @@ class CameraWidget extends BaseWidget<CameraWidgetProps, WidgetState> {
|
||||||
this.props.updateWidgetMetaProperty("imageRawBinary", undefined);
|
this.props.updateWidgetMetaProperty("imageRawBinary", undefined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Set isDirty to true when an image is caputured
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
const base64Data = image.split(",")[1];
|
const base64Data = image.split(",")[1];
|
||||||
const imageBlob = base64ToBlob(base64Data, "image/webp");
|
const imageBlob = base64ToBlob(base64Data, "image/webp");
|
||||||
const blobURL = URL.createObjectURL(imageBlob);
|
const blobURL = URL.createObjectURL(imageBlob);
|
||||||
|
|
@ -251,6 +256,10 @@ class CameraWidget extends BaseWidget<CameraWidgetProps, WidgetState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleRecordingStart = () => {
|
handleRecordingStart = () => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.props.onRecordingStart) {
|
if (this.props.onRecordingStart) {
|
||||||
super.executeAction({
|
super.executeAction({
|
||||||
triggerPropertyName: "onRecordingStart",
|
triggerPropertyName: "onRecordingStart",
|
||||||
|
|
@ -319,6 +328,7 @@ export interface CameraWidgetProps extends WidgetProps {
|
||||||
onRecordingStop?: string;
|
onRecordingStop?: string;
|
||||||
onVideoSave?: string;
|
onVideoSave?: string;
|
||||||
videoBlobURL?: string;
|
videoBlobURL?: string;
|
||||||
|
isDirty: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CameraWidget;
|
export default CameraWidget;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { compact } from "lodash";
|
import { compact, xor } from "lodash";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ValidationResponse,
|
ValidationResponse,
|
||||||
|
|
@ -267,6 +267,7 @@ class CheckboxGroupWidget extends BaseWidget<
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
selectedValues: undefined,
|
selectedValues: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,6 +309,14 @@ class CheckboxGroupWidget extends BaseWidget<
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Reset isDirty to false whenever defaultSelectedValues changes
|
||||||
|
if (
|
||||||
|
xor(this.props.defaultSelectedValues, prevProps.defaultSelectedValues)
|
||||||
|
.length > 0 &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
|
|
@ -346,6 +355,11 @@ class CheckboxGroupWidget extends BaseWidget<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update isDirty to true whenever value changes
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("selectedValues", selectedValues, {
|
this.props.updateWidgetMetaProperty("selectedValues", selectedValues, {
|
||||||
triggerPropertyName: "onSelectionChange",
|
triggerPropertyName: "onSelectionChange",
|
||||||
dynamicString: this.props.onSelectionChange,
|
dynamicString: this.props.onSelectionChange,
|
||||||
|
|
@ -370,6 +384,10 @@ class CheckboxGroupWidget extends BaseWidget<
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("selectedValues", selectedValues, {
|
this.props.updateWidgetMetaProperty("selectedValues", selectedValues, {
|
||||||
triggerPropertyName: "onSelectionChange",
|
triggerPropertyName: "onSelectionChange",
|
||||||
dynamicString: this.props.onSelectionChange,
|
dynamicString: this.props.onSelectionChange,
|
||||||
|
|
|
||||||
|
|
@ -127,9 +127,19 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
isChecked: undefined,
|
isChecked: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: CheckboxWidgetProps) {
|
||||||
|
if (
|
||||||
|
this.props.defaultCheckedState !== prevProps.defaultCheckedState &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<CheckboxComponent
|
<CheckboxComponent
|
||||||
|
|
@ -148,6 +158,10 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onCheckChange = (isChecked: boolean) => {
|
onCheckChange = (isChecked: boolean) => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("isChecked", isChecked, {
|
this.props.updateWidgetMetaProperty("isChecked", isChecked, {
|
||||||
triggerPropertyName: "onCheckChange",
|
triggerPropertyName: "onCheckChange",
|
||||||
dynamicString: this.props.onCheckChange,
|
dynamicString: this.props.onCheckChange,
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,13 @@ class CurrencyInputWidget extends BaseInputWidget<
|
||||||
) {
|
) {
|
||||||
this.formatText();
|
this.formatText();
|
||||||
}
|
}
|
||||||
|
// If defaultText property has changed, reset isDirty to false
|
||||||
|
if (
|
||||||
|
this.props.defaultText !== prevProps.defaultText &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formatText() {
|
formatText() {
|
||||||
|
|
@ -303,6 +310,10 @@ class CurrencyInputWidget extends BaseInputWidget<
|
||||||
this.props.decimals,
|
this.props.decimals,
|
||||||
String(value),
|
String(value),
|
||||||
);
|
);
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("text", String(formattedValue), {
|
this.props.updateWidgetMetaProperty("text", String(formattedValue), {
|
||||||
triggerPropertyName: "onTextChanged",
|
triggerPropertyName: "onTextChanged",
|
||||||
dynamicString: this.props.onTextChanged,
|
dynamicString: this.props.onTextChanged,
|
||||||
|
|
|
||||||
|
|
@ -230,9 +230,19 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
value: undefined,
|
value: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: DatePickerWidget2Props): void {
|
||||||
|
if (
|
||||||
|
this.props.defaultDate !== prevProps.defaultDate &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<DatePickerComponent
|
<DatePickerComponent
|
||||||
|
|
@ -255,6 +265,10 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onDateSelected = (selectedDate: string) => {
|
onDateSelected = (selectedDate: string) => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("value", selectedDate, {
|
this.props.updateWidgetMetaProperty("value", selectedDate, {
|
||||||
triggerPropertyName: "onDateSelected",
|
triggerPropertyName: "onDateSelected",
|
||||||
dynamicString: this.props.onDateSelected,
|
dynamicString: this.props.onDateSelected,
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,7 @@ class FilePickerWidget extends BaseWidget<
|
||||||
return {
|
return {
|
||||||
selectedFiles: [],
|
selectedFiles: [],
|
||||||
uploadedFileData: {},
|
uploadedFileData: {},
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -383,6 +384,10 @@ class FilePickerWidget extends BaseWidget<
|
||||||
});
|
});
|
||||||
|
|
||||||
Promise.all(fileReaderPromises).then((files) => {
|
Promise.all(fileReaderPromises).then((files) => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty(
|
this.props.updateWidgetMetaProperty(
|
||||||
"selectedFiles",
|
"selectedFiles",
|
||||||
dslFiles.concat(files),
|
dslFiles.concat(files),
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,45 @@ class FormWidget extends ContainerWidget {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
super.componentDidMount();
|
super.componentDidMount();
|
||||||
this.updateFormData();
|
this.updateFormData();
|
||||||
|
|
||||||
|
// Check if the form is dirty
|
||||||
|
const hasChanges = this.checkFormValueChanges(
|
||||||
|
get(this.props, "children[0]"),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasChanges !== this.props.hasChanges) {
|
||||||
|
this.props.updateWidgetMetaProperty("hasChanges", hasChanges);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps: ContainerWidgetProps<any>) {
|
componentDidUpdate(prevProps: ContainerWidgetProps<any>) {
|
||||||
super.componentDidUpdate(prevProps);
|
super.componentDidUpdate(prevProps);
|
||||||
this.updateFormData();
|
this.updateFormData();
|
||||||
|
// Check if the form is dirty
|
||||||
|
const hasChanges = this.checkFormValueChanges(
|
||||||
|
get(this.props, "children[0]"),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasChanges !== this.props.hasChanges) {
|
||||||
|
this.props.updateWidgetMetaProperty("hasChanges", hasChanges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFormValueChanges(
|
||||||
|
containerWidget: ContainerWidgetProps<WidgetProps>,
|
||||||
|
): boolean {
|
||||||
|
const childWidgets = containerWidget.children || [];
|
||||||
|
|
||||||
|
const hasChanges = childWidgets.some((child) => child.isDirty);
|
||||||
|
if (!hasChanges) {
|
||||||
|
return childWidgets.some(
|
||||||
|
(child) =>
|
||||||
|
child.children &&
|
||||||
|
this.checkFormValueChanges(get(child, "children[0]")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFormData() {
|
updateFormData() {
|
||||||
|
|
@ -75,6 +109,7 @@ class FormWidget extends ContainerWidget {
|
||||||
export interface FormWidgetProps extends ContainerComponentProps {
|
export interface FormWidgetProps extends ContainerComponentProps {
|
||||||
name: string;
|
name: string;
|
||||||
data: Record<string, unknown>;
|
data: Record<string, unknown>;
|
||||||
|
hasChanges: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FormWidget;
|
export default FormWidget;
|
||||||
|
|
|
||||||
|
|
@ -379,6 +379,13 @@ class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||||
getParsedText(this.props.inputText, this.props.inputType),
|
getParsedText(this.props.inputText, this.props.inputType),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// If defaultText property has changed, reset isDirty to false
|
||||||
|
if (
|
||||||
|
this.props.defaultText !== prevProps.defaultText &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onValueChange = (value: string) => {
|
onValueChange = (value: string) => {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { ReactNode } from "react";
|
||||||
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||||
import { TextSize, WidgetType } from "constants/WidgetConstants";
|
import { TextSize, WidgetType } from "constants/WidgetConstants";
|
||||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||||
import { isArray, findIndex } from "lodash";
|
import { isArray, findIndex, xor } from "lodash";
|
||||||
import {
|
import {
|
||||||
ValidationResponse,
|
ValidationResponse,
|
||||||
ValidationTypes,
|
ValidationTypes,
|
||||||
|
|
@ -354,8 +354,20 @@ class MultiSelectTreeWidget extends BaseWidget<
|
||||||
return {
|
return {
|
||||||
selectedOptionValueArr: undefined,
|
selectedOptionValueArr: undefined,
|
||||||
selectedLabel: [],
|
selectedLabel: [],
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: MultiSelectTreeWidgetProps): void {
|
||||||
|
if (
|
||||||
|
xor(this.props.defaultOptionValue, prevProps.defaultOptionValue).length >
|
||||||
|
0 &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
const options =
|
const options =
|
||||||
isArray(this.props.options) &&
|
isArray(this.props.options) &&
|
||||||
|
|
@ -407,6 +419,9 @@ class MultiSelectTreeWidget extends BaseWidget<
|
||||||
}
|
}
|
||||||
|
|
||||||
onOptionChange = (value?: DefaultValueType, labelList?: ReactNode[]) => {
|
onOptionChange = (value?: DefaultValueType, labelList?: ReactNode[]) => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
this.props.updateWidgetMetaProperty("selectedOptionValueArr", value);
|
this.props.updateWidgetMetaProperty("selectedOptionValueArr", value);
|
||||||
this.props.updateWidgetMetaProperty("selectedLabel", labelList, {
|
this.props.updateWidgetMetaProperty("selectedLabel", labelList, {
|
||||||
triggerPropertyName: "onOptionChange",
|
triggerPropertyName: "onOptionChange",
|
||||||
|
|
@ -472,7 +487,7 @@ export interface MultiSelectTreeWidgetProps extends WidgetProps {
|
||||||
labelTextColor?: string;
|
labelTextColor?: string;
|
||||||
labelTextSize?: TextSize;
|
labelTextSize?: TextSize;
|
||||||
labelStyle?: string;
|
labelStyle?: string;
|
||||||
isDirty?: boolean;
|
isDirty: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MultiSelectTreeWidget;
|
export default MultiSelectTreeWidget;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,15 @@ import React from "react";
|
||||||
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||||
import { WidgetType } from "constants/WidgetConstants";
|
import { WidgetType } from "constants/WidgetConstants";
|
||||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||||
import { isArray, isString, isNumber, LoDashStatic } from "lodash";
|
import {
|
||||||
|
isArray,
|
||||||
|
isEqual,
|
||||||
|
isFinite,
|
||||||
|
isString,
|
||||||
|
isNumber,
|
||||||
|
LoDashStatic,
|
||||||
|
xorWith,
|
||||||
|
} from "lodash";
|
||||||
import {
|
import {
|
||||||
ValidationResponse,
|
ValidationResponse,
|
||||||
ValidationTypes,
|
ValidationTypes,
|
||||||
|
|
@ -208,7 +216,7 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
fn: defaultOptionValueValidation,
|
fn: defaultOptionValueValidation,
|
||||||
expected: {
|
expected: {
|
||||||
type: "Array of values",
|
type: "Array of values",
|
||||||
example: `['option1', 'option2'] | [{ "label": "label1", "value": "value1" }]`,
|
example: ` "option1, option2" | ['option1', 'option2'] | [{ "label": "label1", "value": "value1" }]`,
|
||||||
autocompleteDataType: AutocompleteDataType.ARRAY,
|
autocompleteDataType: AutocompleteDataType.ARRAY,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -431,9 +439,38 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
return {
|
return {
|
||||||
selectedOptions: undefined,
|
selectedOptions: undefined,
|
||||||
filterText: "",
|
filterText: "",
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: MultiSelectWidgetProps): void {
|
||||||
|
// Check if defaultOptionValue is string
|
||||||
|
let isStringArray = false;
|
||||||
|
if (
|
||||||
|
this.props.defaultOptionValue.some(
|
||||||
|
(value: any) => isString(value) || isFinite(value),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
isStringArray = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasChanges = isStringArray
|
||||||
|
? xorWith(
|
||||||
|
this.props.defaultOptionValue as string[],
|
||||||
|
prevProps.defaultOptionValue as string[],
|
||||||
|
isEqual,
|
||||||
|
).length > 0
|
||||||
|
: xorWith(
|
||||||
|
this.props.defaultOptionValue as OptionValue[],
|
||||||
|
prevProps.defaultOptionValue as OptionValue[],
|
||||||
|
isEqual,
|
||||||
|
).length > 0;
|
||||||
|
|
||||||
|
if (hasChanges && this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
const options = isArray(this.props.options) ? this.props.options : [];
|
const options = isArray(this.props.options) ? this.props.options : [];
|
||||||
const dropDownWidth = MinimumPopupRows * this.props.parentColumnSpace;
|
const dropDownWidth = MinimumPopupRows * this.props.parentColumnSpace;
|
||||||
|
|
@ -527,7 +564,7 @@ export interface MultiSelectWidgetProps extends WidgetProps {
|
||||||
options?: DropdownOption[];
|
options?: DropdownOption[];
|
||||||
onOptionChange: string;
|
onOptionChange: string;
|
||||||
onFilterChange: string;
|
onFilterChange: string;
|
||||||
defaultOptionValue: string | string[] | OptionValue[];
|
defaultOptionValue: string[] | OptionValue[];
|
||||||
isRequired: boolean;
|
isRequired: boolean;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
selectedOptions: LabelValueType[];
|
selectedOptions: LabelValueType[];
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,13 @@ class PhoneInputWidget extends BaseInputWidget<
|
||||||
);
|
);
|
||||||
this.props.updateWidgetMetaProperty("text", formattedValue);
|
this.props.updateWidgetMetaProperty("text", formattedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If defaultText property has changed, reset isDirty to false
|
||||||
|
if (this.props.defaultText !== prevProps.defaultText) {
|
||||||
|
if (this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onISDCodeChange = (dialCode?: string) => {
|
onISDCodeChange = (dialCode?: string) => {
|
||||||
|
|
|
||||||
|
|
@ -272,9 +272,19 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
selectedOptionValue: undefined,
|
selectedOptionValue: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: RadioGroupWidgetProps): void {
|
||||||
|
if (
|
||||||
|
this.props.defaultOptionValue !== prevProps.defaultOptionValue &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<RadioGroupComponent
|
<RadioGroupComponent
|
||||||
|
|
@ -297,6 +307,11 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
|
||||||
} else {
|
} else {
|
||||||
newVal = updatedValue;
|
newVal = updatedValue;
|
||||||
}
|
}
|
||||||
|
// Set isDirty to true when the selection changes
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("selectedOptionValue", newVal, {
|
this.props.updateWidgetMetaProperty("selectedOptionValue", newVal, {
|
||||||
triggerPropertyName: "onSelectionChange",
|
triggerPropertyName: "onSelectionChange",
|
||||||
dynamicString: this.props.onSelectionChange,
|
dynamicString: this.props.onSelectionChange,
|
||||||
|
|
@ -318,6 +333,7 @@ export interface RadioGroupWidgetProps extends WidgetProps {
|
||||||
onSelectionChange: string;
|
onSelectionChange: string;
|
||||||
defaultOptionValue: string;
|
defaultOptionValue: string;
|
||||||
isRequired?: boolean;
|
isRequired?: boolean;
|
||||||
|
isDirty: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RadioGroupWidget;
|
export default RadioGroupWidget;
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,8 @@ class RichTextEditorWidget extends BaseWidget<
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
text: undefined,
|
text: undefined,
|
||||||
|
shouldReset: false,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,7 +148,30 @@ class RichTextEditorWidget extends BaseWidget<
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount(): void {
|
||||||
|
if (this.props.defaultText) {
|
||||||
|
this.props.updateWidgetMetaProperty("shouldReset", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: RichTextEditorWidgetProps): void {
|
||||||
|
if (this.props.defaultText !== prevProps.defaultText) {
|
||||||
|
if (this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
if (this.props.defaultText) {
|
||||||
|
this.props.updateWidgetMetaProperty("shouldReset", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onValueChange = (text: string) => {
|
onValueChange = (text: string) => {
|
||||||
|
if (this.props.shouldReset) {
|
||||||
|
this.props.updateWidgetMetaProperty("shouldReset", false);
|
||||||
|
} else if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("text", text, {
|
this.props.updateWidgetMetaProperty("text", text, {
|
||||||
triggerPropertyName: "onTextChange",
|
triggerPropertyName: "onTextChange",
|
||||||
dynamicString: this.props.onTextChange,
|
dynamicString: this.props.onTextChange,
|
||||||
|
|
@ -196,6 +221,7 @@ export interface RichTextEditorWidgetProps extends WidgetProps {
|
||||||
isVisible?: boolean;
|
isVisible?: boolean;
|
||||||
isRequired?: boolean;
|
isRequired?: boolean;
|
||||||
isToolbarHidden?: boolean;
|
isToolbarHidden?: boolean;
|
||||||
|
isDirty: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RichTextEditorWidget;
|
export default RichTextEditorWidget;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,14 @@ import {
|
||||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||||
import { MinimumPopupRows, GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
|
import { MinimumPopupRows, GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
|
||||||
import { AutocompleteDataType } from "utils/autocomplete/TernServer";
|
import { AutocompleteDataType } from "utils/autocomplete/TernServer";
|
||||||
import { findIndex, isArray, isNumber, isString, LoDashStatic } from "lodash";
|
import {
|
||||||
|
findIndex,
|
||||||
|
isArray,
|
||||||
|
isEqual,
|
||||||
|
isNumber,
|
||||||
|
isString,
|
||||||
|
LoDashStatic,
|
||||||
|
} from "lodash";
|
||||||
|
|
||||||
export function defaultOptionValueValidation(
|
export function defaultOptionValueValidation(
|
||||||
value: unknown,
|
value: unknown,
|
||||||
|
|
@ -335,6 +342,7 @@ class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
||||||
value: undefined,
|
value: undefined,
|
||||||
label: undefined,
|
label: undefined,
|
||||||
filterText: "",
|
filterText: "",
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,6 +359,16 @@ class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
||||||
this.changeSelectedOption();
|
this.changeSelectedOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: SelectWidgetProps): void {
|
||||||
|
// Reset isDirty to false if defaultOptionValue changes
|
||||||
|
if (
|
||||||
|
!isEqual(this.props.defaultOptionValue, prevProps.defaultOptionValue) &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isStringOrNumber = (value: any): value is string | number =>
|
isStringOrNumber = (value: any): value is string | number =>
|
||||||
isString(value) || isNumber(value);
|
isString(value) || isNumber(value);
|
||||||
|
|
||||||
|
|
@ -408,6 +426,10 @@ class SelectWidget extends BaseWidget<SelectWidgetProps, WidgetState> {
|
||||||
isChanged = !(this.props.selectedOptionValue === selectedOption.value);
|
isChanged = !(this.props.selectedOptionValue === selectedOption.value);
|
||||||
}
|
}
|
||||||
if (isChanged) {
|
if (isChanged) {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("label", selectedOption.label ?? "");
|
this.props.updateWidgetMetaProperty("label", selectedOption.label ?? "");
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("value", selectedOption.value ?? "", {
|
this.props.updateWidgetMetaProperty("value", selectedOption.value ?? "", {
|
||||||
|
|
|
||||||
|
|
@ -319,9 +319,19 @@ class SingleSelectTreeWidget extends BaseWidget<
|
||||||
selectedOption: undefined,
|
selectedOption: undefined,
|
||||||
selectedOptionValueArr: undefined,
|
selectedOptionValueArr: undefined,
|
||||||
selectedLabel: [],
|
selectedLabel: [],
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: SingleSelectTreeWidgetProps): void {
|
||||||
|
if (
|
||||||
|
this.props.defaultOptionValue !== prevProps.defaultOptionValue &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
const options =
|
const options =
|
||||||
isArray(this.props.options) &&
|
isArray(this.props.options) &&
|
||||||
|
|
@ -372,6 +382,10 @@ class SingleSelectTreeWidget extends BaseWidget<
|
||||||
}
|
}
|
||||||
|
|
||||||
onOptionChange = (value?: DefaultValueType, labelList?: ReactNode[]) => {
|
onOptionChange = (value?: DefaultValueType, labelList?: ReactNode[]) => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("selectedOption", value);
|
this.props.updateWidgetMetaProperty("selectedOption", value);
|
||||||
this.props.updateWidgetMetaProperty("selectedLabel", labelList, {
|
this.props.updateWidgetMetaProperty("selectedLabel", labelList, {
|
||||||
triggerPropertyName: "onOptionChange",
|
triggerPropertyName: "onOptionChange",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Alignment } from "@blueprintjs/core";
|
import { Alignment } from "@blueprintjs/core";
|
||||||
|
import { xor } from "lodash";
|
||||||
|
|
||||||
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||||
import { DerivedPropertiesMap } from "utils/WidgetFactory";
|
import { DerivedPropertiesMap } from "utils/WidgetFactory";
|
||||||
|
|
@ -178,6 +179,7 @@ class SwitchGroupWidget extends BaseWidget<
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
selectedValuesArray: undefined,
|
selectedValuesArray: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,6 +198,22 @@ class SwitchGroupWidget extends BaseWidget<
|
||||||
return "SWITCH_GROUP_WIDGET";
|
return "SWITCH_GROUP_WIDGET";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: SwitchGroupWidgetProps): void {
|
||||||
|
if (
|
||||||
|
xor(this.props.defaultSelectedValues, prevProps.defaultSelectedValues)
|
||||||
|
.length > 0
|
||||||
|
) {
|
||||||
|
if (this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.updateWidgetMetaProperty(
|
||||||
|
"selectedValuesArray",
|
||||||
|
this.props.defaultSelectedValues,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
const {
|
const {
|
||||||
alignment,
|
alignment,
|
||||||
|
|
@ -205,7 +223,7 @@ class SwitchGroupWidget extends BaseWidget<
|
||||||
isValid,
|
isValid,
|
||||||
options,
|
options,
|
||||||
parentRowSpace,
|
parentRowSpace,
|
||||||
selectedValues,
|
selectedValuesArray,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -217,7 +235,7 @@ class SwitchGroupWidget extends BaseWidget<
|
||||||
options={options}
|
options={options}
|
||||||
required={isRequired}
|
required={isRequired}
|
||||||
rowSpace={parentRowSpace}
|
rowSpace={parentRowSpace}
|
||||||
selected={selectedValues}
|
selected={selectedValuesArray}
|
||||||
valid={isValid}
|
valid={isValid}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
@ -235,6 +253,10 @@ class SwitchGroupWidget extends BaseWidget<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty(
|
this.props.updateWidgetMetaProperty(
|
||||||
"selectedValuesArray",
|
"selectedValuesArray",
|
||||||
selectedValuesArray,
|
selectedValuesArray,
|
||||||
|
|
@ -253,6 +275,7 @@ class SwitchGroupWidget extends BaseWidget<
|
||||||
export interface SwitchGroupWidgetProps extends WidgetProps {
|
export interface SwitchGroupWidgetProps extends WidgetProps {
|
||||||
options: OptionProps[];
|
options: OptionProps[];
|
||||||
defaultSelectedValues: string[];
|
defaultSelectedValues: string[];
|
||||||
|
selectedValuesArray: string[];
|
||||||
isInline: boolean;
|
isInline: boolean;
|
||||||
isRequired?: boolean;
|
isRequired?: boolean;
|
||||||
isValid?: boolean;
|
isValid?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ class SwitchWidget extends BaseWidget<SwitchWidgetProps, WidgetState> {
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
isSwitchedOn: undefined,
|
isSwitchedOn: undefined,
|
||||||
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,7 +141,20 @@ class SwitchWidget extends BaseWidget<SwitchWidgetProps, WidgetState> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: SwitchWidgetProps): void {
|
||||||
|
if (
|
||||||
|
this.props.defaultSwitchState !== prevProps.defaultSwitchState &&
|
||||||
|
this.props.isDirty
|
||||||
|
) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onChange = (isSwitchedOn: boolean) => {
|
onChange = (isSwitchedOn: boolean) => {
|
||||||
|
if (!this.props.isDirty) {
|
||||||
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
||||||
|
}
|
||||||
|
|
||||||
this.props.updateWidgetMetaProperty("isSwitchedOn", isSwitchedOn, {
|
this.props.updateWidgetMetaProperty("isSwitchedOn", isSwitchedOn, {
|
||||||
triggerPropertyName: "onChange",
|
triggerPropertyName: "onChange",
|
||||||
dynamicString: this.props.onChange,
|
dynamicString: this.props.onChange,
|
||||||
|
|
@ -156,6 +170,7 @@ export interface SwitchWidgetProps extends WidgetProps {
|
||||||
defaultSwitchState: boolean;
|
defaultSwitchState: boolean;
|
||||||
alignWidget: AlignWidget;
|
alignWidget: AlignWidget;
|
||||||
label: string;
|
label: string;
|
||||||
|
isDirty: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SwitchWidget;
|
export default SwitchWidget;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user