diff --git a/.github/config.json b/.github/config.json index 28c550304b10..d5e17dc2d4ef 100644 --- a/.github/config.json +++ b/.github/config.json @@ -1 +1 @@ -{"runners":[{"versioning":{"source":"milestones","type":"SemVer"},"prereleaseName":"alpha","issue":{"labels":{"Widgets Product":{"conditions":[{"label":"Button Widget","type":"hasLabel","value":true},{"label":"Chart Widget","type":"hasLabel","value":true},{"label":"Container Widget","type":"hasLabel","value":true},{"label":"Date Picker Widget","type":"hasLabel","value":true},{"label":"Select Widget","type":"hasLabel","value":true},{"label":"File Picker Widget","type":"hasLabel","value":true},{"label":"Form Widget","type":"hasLabel","value":true},{"label":"Image Widget","type":"hasLabel","value":true},{"label":"Input Widget","type":"hasLabel","value":true},{"label":"List Widget","type":"hasLabel","value":true},{"label":"MultiSelect Widget","type":"hasLabel","value":true},{"label":"Map Widget","type":"hasLabel","value":true},{"label":"Modal Widget","type":"hasLabel","value":true},{"label":"Radio Widget","type":"hasLabel","value":true},{"label":"Rich Text Editor Widget","type":"hasLabel","value":true},{"label":"Tab Widget","type":"hasLabel","value":true},{"label":"Table Widget","type":"hasLabel","value":true},{"label":"Text Widget","type":"hasLabel","value":true},{"label":"Video Widget","type":"hasLabel","value":true},{"label":"iFrame","type":"hasLabel","value":true},{"label":"Menu Button","type":"hasLabel","value":true},{"label":"Rating","type":"hasLabel","value":true},{"label":"Widget Validation","type":"hasLabel","value":true},{"label":"New Widget","type":"hasLabel","value":true},{"label":"Switch widget","type":"hasLabel","value":true},{"label":"Audio Widget","type":"hasLabel","value":true},{"label":"Icon Button Widget","type":"hasLabel","value":true},{"label":"Stat Box Widget","type":"hasLabel","value":true},{"label":"Voice Recorder Widget","type":"hasLabel","value":true},{"label":"Calendar Widget","type":"hasLabel","value":true},{"label":"Menu Button Widget","type":"hasLabel","value":true},{"label":"Divider Widget","type":"hasLabel","value":true},{"label":"Rating Widget","type":"hasLabel","value":true},{"label":"View Mode","type":"hasLabel","value":true},{"label":"Widget Property","type":"hasLabel","value":true},{"label":"Document Viewer Widget","type":"hasLabel","value":true},{"label":"Radio Group Widget","type":"hasLabel","value":true},{"label":"Currency Input Widget","type":"hasLabel","value":true},{"label":"TreeSelect","type":"hasLabel","value":true},{"label":"MultiTree Select Widget","type":"hasLabel","value":true},{"label":"Phone Input Widget","type":"hasLabel","value":true},{"label":"JSON Form","type":"hasLabel","value":true},{"label":"All Widgets","type":"hasLabel","value":true},{"label":"Button Group widget","type":"hasLabel","value":true},{"label":"Progress bar widget","type":"hasLabel","value":true},{"label":"Audio Recorder Widget","type":"hasLabel","value":true},{"label":"Camera Widget","type":"hasLabel","value":true},{"label":"Table Widget V2","type":"hasLabel","value":true},{"label":"Map Chart Widget","type":"hasLabel","value":true},{"label":"Code Scanner Widget","type":"hasLabel","value":true},{"label":"Widget keyboard accessibility","type":"hasLabel","value":true},{"label":"List Widget V2","type":"hasLabel","value":true},{"label":"Slider Widget","type":"hasLabel","value":true},{"label":"One-click Binding","type":"hasLabel","value":true},{"label":"Old widget version","type":"hasLabel","value":true},{"label":"Widget Discoverability","type":"hasLabel","value":true},{"label":"Switch Group Widget","type":"hasLabel","value":true},{"label":"Checkbox Group widget","type":"hasLabel","value":true},{"label":"Checkbox Widget","type":"hasLabel","value":true},{"label":"Table Inline Edit","type":"hasLabel","value":true},{"label":"Custom Widgets","type":"hasLabel","value":true}],"requires":1},"Javascript Product":{"conditions":[{"label":"JS Linting & Errors","type":"hasLabel","value":true},{"label":"Autocomplete","type":"hasLabel","value":true},{"label":"Evaluated Value","type":"hasLabel","value":true},{"label":"Slash Command","type":"hasLabel","value":true},{"label":"New JS Function","type":"hasLabel","value":true},{"label":"JS Usability","type":"hasLabel","value":true},{"label":"Framework Functions","type":"hasLabel","value":true},{"label":"JS Objects","type":"hasLabel","value":true},{"label":"JS Evaluation","type":"hasLabel","value":true},{"label":"Custom JS Libraries","type":"hasLabel","value":true},{"label":"Action Selector","type":"hasLabel","value":true},{"label":"Widget setter method","type":"hasLabel","value":true},{"label":"Entity Refactor","type":"hasLabel","value":true},{"label":"AST-frontend","type":"hasLabel","value":true},{"label":"Sniping Mode","type":"hasLabel","value":true},{"label":"AST-backend","type":"hasLabel","value":true}],"requires":1},"IDE Product":{"conditions":[{"label":"IDE Product","type":"hasLabel","value":true},{"label":"IDE Infra","type":"hasLabel","value":true},{"label":"IDE Navigation","type":"hasLabel","value":true},{"label":"IDE tabs","type":"hasLabel","value":true},{"label":"Omnibar","type":"hasLabel","value":true},{"label":"Entity Explorer","type":"hasLabel","value":true},{"label":"Page Management","type":"hasLabel","value":true},{"label":"Preview mode","type":"hasLabel","value":true}],"requires":1},"Accelerators Product":{"conditions":[{"label":"Generate Page","type":"hasLabel","value":true},{"label":"Building blocks","type":"hasLabel","value":true}],"requires":1},"Templates Product":{"conditions":[{"label":"Partial-import-export","type":"hasLabel","value":true},{"label":"Templates Product","type":"hasLabel","value":true}],"requires":1},"Design System Product":{"conditions":[{"label":"Design System Product","type":"hasLabel","value":true},{"label":"ADS Component Issue","type":"hasLabel","value":true},{"label":"Keyboard accessibility ","type":"hasLabel","value":true},{"label":"Toggle button","type":"hasLabel","value":true},{"label":"ADS Category Token","type":"hasLabel","value":true},{"label":"ADS Component Documentation","type":"hasLabel","value":true},{"label":"ADS Migration","type":"hasLabel","value":true},{"label":"ADS Deduplication ","type":"hasLabel","value":true},{"label":"ADS Revamp","type":"hasLabel","value":true},{"label":"ADS Deduplication","type":"hasLabel","value":true},{"label":"ADS Unit Test","type":"hasLabel","value":true},{"label":"ADS Components","type":"hasLabel","value":true},{"label":"ADS Grayscale","type":"hasLabel","value":true},{"label":"Design System","type":"hasLabel","value":true},{"label":"ADS Typography","type":"hasLabel","value":true},{"label":"ADS Visual Styles","type":"hasLabel","value":true},{"label":"ADS Component Design","type":"hasLabel","value":true},{"label":"Modal Component","type":"hasLabel","value":true},{"label":"ADS Spacing","type":"hasLabel","value":true},{"label":"ads unit test","type":"hasLabel","value":true},{"label":"ads revamp","type":"hasLabel","value":true},{"label":"ads deduplication","type":"hasLabel","value":true}],"requires":1},"RBAC Product":{"conditions":[{"label":"Invite users","type":"hasLabel","value":true},{"label":"RBAC Product","type":"hasLabel","value":true}],"requires":1},"Workspace Product":{"conditions":[{"label":"Home Page","type":"hasLabel","value":true},{"label":"Workspace Product","type":"hasLabel","value":true}],"requires":1},"Billing & Licensing Product":{"conditions":[{"label":"Customer Portal","type":"hasLabel","value":true},{"label":"Cloud Services","type":"hasLabel","value":true},{"label":"Billing","type":"hasLabel","value":true},{"label":"Self Serve","type":"hasLabel","value":true},{"label":"Enterprise Billing","type":"hasLabel","value":true},{"label":"Analytics Improvements","type":"hasLabel","value":true},{"label":"Self Serve 1.0","type":"hasLabel","value":true},{"label":"License","type":"hasLabel","value":true},{"label":"BE instance","type":"hasLabel","value":true},{"label":"Invite flow","type":"hasLabel","value":true},{"label":"CE Instance Usage","type":"hasLabel","value":true},{"label":"Feature Flagging","type":"hasLabel","value":true}],"requires":1},"Packages Product":{"conditions":[{"label":"Packages Product","type":"hasLabel","value":true}],"requires":1},"Environments Product":{"conditions":[{"label":"Environments Product","type":"hasLabel","value":true}],"requires":1},"UI Building Product":{"conditions":[{"label":"Property Pane","type":"hasLabel","value":true},{"label":"Copy Paste","type":"hasLabel","value":true},{"label":"Drag & Drop","type":"hasLabel","value":true},{"label":"Undo/Redo","type":"hasLabel","value":true},{"label":"Widgets Pane","type":"hasLabel","value":true},{"label":"UI Performance","type":"hasLabel","value":true},{"label":"Widget Grouping","type":"hasLabel","value":true},{"label":"Reflow & Resize","type":"hasLabel","value":true},{"label":"Canvas / Grid","type":"hasLabel","value":true},{"label":"Auto Height","type":"hasLabel","value":true},{"label":"Browser specific","type":"hasLabel","value":true},{"label":"Auto Layout","type":"hasLabel","value":true},{"label":"Fixed layout","type":"hasLabel","value":true},{"label":"App Navigation","type":"hasLabel","value":true}],"requires":1},"Onboarding Product":{"conditions":[{"label":"Welcome Screen","type":"hasLabel","value":true}],"requires":1},"Git Product":{"conditions":[{"label":"Git Product","type":"hasLabel","value":true},{"label":"Git Auto-commit","type":"hasLabel","value":true},{"label":"Auto-commit","type":"hasLabel","value":true},{"label":"Continuous Deployment","type":"hasLabel","value":true},{"label":"Branch protection","type":"hasLabel","value":true},{"label":"Default branch","type":"hasLabel","value":true},{"label":"Git status","type":"hasLabel","value":true},{"label":"Git performance","type":"hasLabel","value":true},{"label":"SDLC","type":"hasLabel","value":true},{"label":"Git IA","type":"hasLabel","value":true}],"requires":1},"Embedding Apps Product":{"conditions":[{"label":"Embedding Apps Product","type":"hasLabel","value":true}],"requires":1},"Integrations Product":{"conditions":[{"label":"New Datasource","type":"hasLabel","value":true},{"label":"Firestore","type":"hasLabel","value":true},{"label":"Google Sheets","type":"hasLabel","value":true},{"label":"Mongo","type":"hasLabel","value":true},{"label":"Redshift","type":"hasLabel","value":true},{"label":"snowflake","type":"hasLabel","value":true},{"label":"S3","type":"hasLabel","value":true},{"label":"Redis","type":"hasLabel","value":true},{"label":"Postgres","type":"hasLabel","value":true},{"label":"GraphQL Plugin","type":"hasLabel","value":true},{"label":"ArangoDB","type":"hasLabel","value":true},{"label":"MsSQL","type":"hasLabel","value":true},{"label":"Elastic Search","type":"hasLabel","value":true},{"label":"OAuth","type":"hasLabel","value":true},{"label":"Airtable","type":"hasLabel","value":true},{"label":"CURL","type":"hasLabel","value":true},{"label":"DynamoDB","type":"hasLabel","value":true},{"label":"Zendesk","type":"hasLabel","value":true},{"label":"Hubspot","type":"hasLabel","value":true},{"label":"Query Forms","type":"hasLabel","value":true},{"label":"Twilio","type":"hasLabel","value":true},{"label":"MySQL","type":"hasLabel","value":true},{"label":"Connection pool","type":"hasLabel","value":true},{"label":"MariaDB","type":"hasLabel","value":true},{"label":"Integrations Pod General","type":"hasLabel","value":true},{"label":"SMTP plugin","type":"hasLabel","value":true},{"label":"Oracle SQL DB","type":"hasLabel","value":true},{"label":"Query filter","type":"hasLabel","value":true},{"label":"Activation - datasources","type":"hasLabel","value":true},{"label":"REST API","type":"hasLabel","value":true},{"label":"REST API","type":"hasLabel","value":true},{"label":"Datasources","type":"hasLabel","value":true},{"label":"REST API plugin","type":"hasLabel","value":true},{"label":"Prepared statements","type":"hasLabel","value":true},{"label":"Query Generation","type":"hasLabel","value":true},{"label":"Core Query Execution","type":"hasLabel","value":true},{"label":"Query Management","type":"hasLabel","value":true},{"label":"Query Settings","type":"hasLabel","value":true},{"label":"Query performance","type":"hasLabel","value":true},{"label":"Datatype issue","type":"hasLabel","value":true},{"label":"SmartSubstitution","type":"hasLabel","value":true},{"label":"Suggested Widgets","type":"hasLabel","value":true},{"label":"SAAS Plugins","type":"hasLabel","value":true},{"label":"Reconnect DS modal","type":"hasLabel","value":true},{"label":"OnPageLoad","type":"hasLabel","value":true},{"label":"File upload issues","type":"hasLabel","value":true},{"label":"AI","type":"hasLabel","value":true},{"label":"Appsmith AI","type":"hasLabel","value":true},{"label":"Database Schema","type":"hasLabel","value":true}],"requires":1},"Identity & Authentication Product":{"conditions":[{"label":"Login / Signup","type":"hasLabel","value":true},{"label":"SSO","type":"hasLabel","value":true},{"label":"SCIM","type":"hasLabel","value":true},{"label":"Email verification","type":"hasLabel","value":true}],"requires":1},"Artifact Platform Product":{"conditions":[{"label":"Fork App","type":"hasLabel","value":true},{"label":"Publish App","type":"hasLabel","value":true},{"label":"Secret Management","type":"hasLabel","value":true},{"label":"Import-Export-App","type":"hasLabel","value":true}],"requires":1},"DevOps Pod":{"conditions":[{"label":"Docker","type":"hasLabel","value":true},{"label":"Super Admin","type":"hasLabel","value":true},{"label":"Deployment","type":"hasLabel","value":true},{"label":"K8s","type":"hasLabel","value":true},{"label":"Email Config","type":"hasLabel","value":true},{"label":"Backup & Restore","type":"hasLabel","value":true},{"label":"AWS AMI","type":"hasLabel","value":true},{"label":"Observability","type":"hasLabel","value":true},{"label":"Heroku","type":"hasLabel","value":true},{"label":"New Deployment Mode","type":"hasLabel","value":true},{"label":"Supervisor","type":"hasLabel","value":true},{"label":"Deployment Certificates","type":"hasLabel","value":true},{"label":"Mock Data","type":"hasLabel","value":true},{"label":"AWS ECS","type":"hasLabel","value":true},{"label":"Ingress","type":"hasLabel","value":true},{"label":"Nginx","type":"hasLabel","value":true}],"requires":1},"Performance Pod":{"conditions":[{"label":"Performance","type":"hasLabel","value":true},{"label":"Performance infra","type":"hasLabel","value":true}],"requires":1},"Git Platform Pod":{"conditions":[{"label":"Environments Product","type":"hasLabel","value":true},{"label":"Git Product","type":"hasLabel","value":true},{"label":"Artifact Platform Product","type":"hasLabel","value":true}],"requires":1},"IDE Pod":{"conditions":[{"label":"Telemetry","type":"hasLabel","value":true},{"label":"i18n","type":"hasLabel","value":true},{"label":"IDE Product","type":"hasLabel","value":true},{"label":"App setting","type":"hasLabel","value":true},{"label":"Debugger Product","type":"hasLabel","value":true},{"label":"Embedding Apps Product","type":"hasLabel","value":true}],"requires":1},"Platform Administration Pod":{"conditions":[{"label":"Airgap","type":"hasLabel","value":true},{"label":"Enterprise Edition","type":"hasLabel","value":true},{"label":"Invite flow","type":"hasLabel","value":true},{"label":"User Profile","type":"hasLabel","value":true},{"label":"User Session ","type":"hasLabel","value":true},{"label":"User Session","type":"hasLabel","value":true},{"label":"Admin Settings Product","type":"hasLabel","value":true},{"label":"RBAC Product","type":"hasLabel","value":true},{"label":"Workspace Product","type":"hasLabel","value":true},{"label":"Branding Product","type":"hasLabel","value":true},{"label":"Audit Logs Product","type":"hasLabel","value":true},{"label":"Identity & Authentication Product","type":"hasLabel","value":true}],"requires":1},"DB Infrastructure Pod":{"conditions":[{"label":"Move to Postgres","type":"hasLabel","value":true}],"requires":1},"Widgets & Accelerators Pod":{"conditions":[{"label":"Accelerators Product","type":"hasLabel","value":true},{"label":"Templates Product","type":"hasLabel","value":true},{"label":"Widgets Product","type":"hasLabel","value":true},{"label":"App Theming Product","type":"hasLabel","value":true}],"requires":1},"Packages Pod":{"conditions":[{"label":"Module creator","type":"hasLabel","value":true},{"label":"Module consumer","type":"hasLabel","value":true},{"label":"Package versioning","type":"hasLabel","value":true},{"label":"Convert to module","type":"hasLabel","value":true},{"label":"Query module","type":"hasLabel","value":true},{"label":"JS module","type":"hasLabel","value":true},{"label":"UI module","type":"hasLabel","value":true},{"label":"Packages Pod","type":"hasLabel","value":true},{"label":"Packages Product","type":"hasLabel","value":true}],"requires":1},"Workflows Pod":{"conditions":[{"label":"Workflows Product","type":"hasLabel","value":true}],"requires":1},"Query & JS Pod":{"conditions":[{"label":"Javascript Product","type":"hasLabel","value":true},{"label":"Onboarding Product","type":"hasLabel","value":true},{"label":"Integrations Product","type":"hasLabel","value":true}],"requires":1},"QA Pod":{"conditions":[{"label":"QA","type":"hasLabel","value":true},{"label":"Automation Test","type":"hasLabel","value":true},{"label":"TestGap","type":"hasLabel","value":true},{"label":"Automation failures","type":"hasLabel","value":true},{"label":"Needs automation","type":"hasLabel","value":true}],"requires":1},"Anvil POD":{"conditions":[{"label":"Checkbox Component","type":"hasLabel","value":true},{"label":"WDS team","type":"hasLabel","value":true},{"label":"Anvil POD","type":"hasLabel","value":true},{"label":"WDS - all widgets","type":"hasLabel","value":true},{"label":"WDS - input widget","type":"hasLabel","value":true},{"label":"WDS - paragraph widget","type":"hasLabel","value":true},{"label":"WDS - statbox widget","type":"hasLabel","value":true},{"label":"WDS - modal widget","type":"hasLabel","value":true},{"label":"WDS - icon widget","type":"hasLabel","value":true},{"label":"WDS - checkbox widget","type":"hasLabel","value":true},{"label":"WDS - table widget","type":"hasLabel","value":true},{"label":"WDS - keyValue widget","type":"hasLabel","value":true},{"label":"WDS - switch group widget","type":"hasLabel","value":true},{"label":"WDS - theming","type":"hasLabel","value":true},{"label":"Anvil layout","type":"hasLabel","value":true},{"label":"Anvil - theming","type":"hasLabel","value":true},{"label":"Anvil - vertical alignment","type":"hasLabel","value":true},{"label":"Anvil - layout component","type":"hasLabel","value":true},{"label":"Anvil - drag & drop","type":"hasLabel","value":true},{"label":"Anvil - zones & sections","type":"hasLabel","value":true},{"label":"Anvil - copy paste experience","type":"hasLabel","value":true},{"label":"WDS - phone widget","type":"hasLabel","value":true},{"label":"WDS - responsive widget","type":"hasLabel","value":true},{"label":"Anvil - responsive viewport","type":"hasLabel","value":true},{"label":"WDS - widget styling","type":"hasLabel","value":true},{"label":"Anvil - spacing","type":"hasLabel","value":true},{"label":"Anvil - responsive canvas","type":"hasLabel","value":true},{"label":"WDS - inline button widget","type":"hasLabel","value":true},{"label":"Anvil team","type":"hasLabel","value":true}],"requires":1},"Activation Pod":{"conditions":[{"label":"Activation","type":"hasLabel","value":true}],"requires":1},"Stability Pod":{"conditions":[{"label":"Stability Issue","type":"hasLabel","value":true},{"label":"cypress-flaky-fix","type":"hasLabel","value":true},{"label":"Cypress flaky tests","type":"hasLabel","value":true}],"requires":1},"Documentation Pod":{"conditions":[{"label":"Documentation","type":"hasLabel","value":true}],"requires":1}}},"root":"."}],"labels":{"Tab Widget":{"color":"e2c76c","name":"Tab Widget","description":""},"Dont merge":{"color":"ADB39C","name":"Dont merge","description":""},"Epic":{"color":"3E4B9E","name":"Epic","description":"A zenhub epic that describes a project"},"Menu Button Widget":{"color":"235708","name":"Menu Button Widget","description":"Issues related to Menu Button widget"},"Checkbox Group widget":{"color":"bbeecd","name":"Checkbox Group widget","description":"Issues related to Checkbox Group Widget"},"Input Widget":{"color":"ae65d8","name":"Input Widget","description":""},"Security":{"color":"99139C","name":"Security","description":""},"QA":{"color":"","name":"QA","description":"Needs QA attention"},"Verified":{"color":"9bf416","name":"Verified","description":""},"Wont Fix":{"color":"ffffff","name":"Wont Fix","description":"This will not be worked on"},"MySQL":{"color":"c9ddc6","name":"MySQL","description":"Issues related to MySQL plugin"},"Development":{"color":"9F8A02","name":"Development","description":""},"Help Wanted":{"color":"008672","name":"Help Wanted","description":"Extra attention is needed"},"Home Page":{"color":"","name":"Home Page","description":"Issues related to the application home page"},"Rating Widget":{"color":"235708","name":"Rating Widget","description":"Issues related to the rating widget"},"Stat Box Widget":{"color":"f1c9ce","name":"Stat Box Widget","description":"Issues related to stat box"},"Enhancement":{"color":"a2eeef","name":"Enhancement","description":"New feature or request"},"Fork App":{"color":"af87c7","name":"Fork App","description":"Issues related to forking apps"},"Container Widget":{"color":"19AD0D","name":"Container Widget","description":"Container widget"},"Papercut":{"color":"B562F6","name":"Papercut","description":""},"Needs Design":{"color":"bfd4f2","name":"Needs Design","description":"needs design or changes to design"},"i18n":{"color":"1799b0","name":"i18n","description":"Represents issues that need to be tackled to handle internationalization"},"Rich Text Editor Widget":{"color":"f72cac","name":"Rich Text Editor Widget","description":""},"skip-changelog":{"color":"06086F","name":"skip-changelog","description":"Adding this label to a PR prevents it from being listed in the changelog"},"Low":{"color":"79e53b","name":"Low","description":"An issue that is neither critical nor breaks a user flow"},"potential-duplicate":{"color":"d3cb2e","name":"potential-duplicate","description":"This label marks issues that are potential duplicates of already open issues"},"Audio Widget":{"color":"447B9A","name":"Audio Widget","description":"Issues related to Audio Widget"},"Firestore":{"color":"8078b0","name":"Firestore","description":"Issues related to the firestore Integration"},"New Widget":{"color":"be4cf2","name":"New Widget","description":"A request for a new widget"},"Modal Widget":{"color":"03846f","name":"Modal Widget","description":""},"UX Improvement":{"color":"f4a089","name":"UX Improvement","description":""},"S3":{"color":"8078b0","name":"S3","description":"Issues related to the S3 plugin"},"Release Blocker":{"color":"5756bf","name":"Release Blocker","description":"This issue must be resolved before the release"},"safari":{"color":"51C6AA","name":"safari","description":"Bugs seen on safari browser"},"Example Apps":{"color":"1799b0","name":"Example Apps","description":"Example apps created for new signups"},"MultiSelect Widget":{"color":"AB62D4","name":"MultiSelect Widget","description":"Issues related to MultiSelect Widget"},"Calendar Widget":{"color":"8c6644","name":"Calendar Widget","description":""},"Website":{"color":"151720","name":"Website","description":"Related to www.appsmith.com website"},"Low effort":{"color":"8B59F0","name":"Low effort","description":"Something that'll take a few days to build"},"Checkbox Widget":{"color":"bbeecd","name":"Checkbox Widget","description":""},"Spam":{"color":"620faf","name":"Spam","description":""},"Voice Recorder Widget":{"color":"85bc87","name":"Voice Recorder Widget","description":""},"Select Widget":{"color":"0c669e","name":"Select Widget","description":"Select or dropdown widget"},"Bug":{"color":"8ba6fd","name":"Bug","description":"Something isn't right"},"Widget Validation":{"color":"6990BC","name":"Widget Validation","description":"Issues related to widget property validation"},"Generate Page":{"color":"2b4664","name":"Generate Page","description":"Issures related to page generation"},"File Picker Widget":{"color":"6ae4f2","name":"File Picker Widget","description":""},"snowflake":{"color":"8078b0","name":"snowflake","description":"Issues related to the snowflake Integration"},"Automation":{"color":"CCAF60","name":"Automation","description":""},"hotfix":{"color":"BA3F1D","name":"hotfix","description":""},"Import-Export-App":{"color":"48883f","name":"Import-Export-App","description":"Issues related to importing and exporting apps"},"High effort":{"color":"A7E87B","name":"High effort","description":"Something that'll take more than a month to build"},"Telemetry":{"color":"bc70f9","name":"Telemetry","description":"Issues related to instrumenting appsmith"},"Radio Widget":{"color":"91ef15","name":"Radio Widget","description":""},"Omnibar":{"color":"1bb96a","name":"Omnibar","description":"Issues related to the omnibar for navigation"},"Button Widget":{"color":"34efae","name":"Button Widget","description":""},"Switch widget":{"color":"33A8CE","name":"Switch widget","description":"The switch widget"},"Map Widget":{"color":"7eef7a","name":"Map Widget","description":""},"Task":{"color":"085630","name":"Task","description":"A simple Todo"},"Design System":{"color":"2958a4","name":"Design System","description":"Design system"},"opera":{"color":"C63F5B","name":"opera","description":"Any issues identified on the opera browser"},"Login / Signup":{"color":"","name":"Login / Signup","description":"Authentication flows"},"Image Widget":{"color":"8de8ad","name":"Image Widget","description":""},"firefox":{"color":"6d56e2","name":"firefox","description":""},"Property Pane":{"color":"b356ff","name":"Property Pane","description":"Issues related to the behaviour of the property pane"},"Deployment":{"color":"93491f","name":"Deployment","description":"Installation process of appsmith"},"Production":{"color":"b60205","name":"Production","description":""},"Dependencies":{"color":"0366d6","name":"Dependencies","description":"Pull requests that update a dependency file"},"Google Sheets":{"color":"8078b0","name":"Google Sheets","description":"Issues related to Google Sheets"},"Icon Button Widget":{"color":"D319CE","name":"Icon Button Widget","description":"Issues related to the icon button widget"},"Mongo":{"color":"8078b0","name":"Mongo","description":"Issues related to Mongo DB plugin"},"Documentation":{"color":"a8dff7","name":"Documentation","description":"Improvements or additions to documentation"},"TestGap":{"color":"","name":"TestGap","description":"Issues identified for test plan improvement"},"keyboard shortcut":{"color":"0688B6","name":"keyboard shortcut","description":""},"Reopen":{"color":"897548","name":"Reopen","description":""},"Redshift":{"color":"8078b0","name":"Redshift","description":"Issues related to the redshift integration"},"Date Picker Widget":{"color":"ef1ce1","name":"Date Picker Widget","description":""},"Entity Explorer":{"color":"1bb96a","name":"Entity Explorer","description":"Issues related to navigation using the entity explorer"},"JS Linting & Errors":{"color":"E56AA5","name":"JS Linting & Errors","description":"Issues related to JS Linting and errors"},"iFrame":{"color":"3CD1DB","name":"iFrame","description":"Issues related to iFrame"},"Stale":{"color":"ededed","name":"Stale","description":null},"Text Widget":{"color":"d130d1","name":"Text Widget","description":""},"Video Widget":{"color":"23dd4b","name":"Video Widget","description":""},"Datasources":{"color":"3d590f","name":"Datasources","description":"Issues related to configuring datasource on appsmith"},"error":{"color":"B66773","name":"error","description":"All issues connected to error messages"},"Form Widget":{"color":"09ed77","name":"Form Widget","description":""},"Needs Triaging":{"color":"e8b851","name":"Needs Triaging","description":"Needs attention from maintainers to triage"},"Autocomplete":{"color":"235708","name":"Autocomplete","description":"Issues related to the autocomplete"},"hacktoberfest":{"color":"0052cc","name":"hacktoberfest","description":"All issues that can be solved by the community during Hacktoberfest"},"Medium effort":{"color":"D31156","name":"Medium effort","description":"Something that'll take more than a week but less than a month to build"},"Release":{"color":"57e5e0","name":"Release","description":""},"High":{"color":"c94d14","name":"High","description":"This issue blocks a user from building or impacts a lot of users"},"UI Performance":{"color":"1799b0","name":"UI Performance","description":"Issues related to UI performance"},"Deploy Preview":{"color":"bfdadc","name":"Deploy Preview","description":"Issues found in Deploy Preview"},"Needs Tests":{"color":"8ee263","name":"Needs Tests","description":"Needs automated tests to assert a feature/bug fix"},"Refactor":{"color":"B96662","name":"Refactor","description":"needs refactoring of code"},"Divider Widget":{"color":"235708","name":"Divider Widget","description":"Issues related to the divider widget"},"Table Widget":{"color":"2eead1","name":"Table Widget","description":""},"Needs More Info":{"color":"e54c10","name":"Needs More Info","description":"Needs additional information"},"Good First Issue":{"color":"7057ff","name":"Good First Issue","description":"Good for newcomers"},"UI Improvement":{"color":"9aeef4","name":"UI Improvement","description":""},"Backend":{"color":"d4c5f9","name":"Backend","description":"This marks the issue or pull request to reference server code"},"Frontend":{"color":"87c7f2","name":"Frontend","description":"This label marks the issue or pull request to reference client code"},"Chart Widget":{"color":"616ecc","name":"Chart Widget","description":""},"List Widget":{"color":"8508A0","name":"List Widget","description":"Issues related to the list widget"},"Duplicate":{"color":"cfd3d7","name":"Duplicate","description":"This issue or pull request already exists"},"JS Snippets":{"color":"8d62d2","name":"JS Snippets","description":"issues related to JS Snippets"},"Copy Paste":{"name":"Copy Paste","description":"Issues related to copy paste","color":"b4f0a9"},"Drag & Drop":{"name":"Drag & Drop","description":"Issues related to the drag & drop experience","color":"92115a"},"Sniping Mode":{"name":"Sniping Mode","description":"Issues related to sniping mode","color":"48883f"},"Redis":{"name":"Redis","description":"Issues related to Redis","color":"8078b0"},"New Datasource":{"color":"60b14c","name":"New Datasource","description":"Requests for new datasources"},"Evaluated Value":{"name":"Evaluated Value","description":"Issues related to evaluated values","color":"39f6e7"},"Undo/Redo":{"name":"Undo/Redo","description":"Issues related to undo/redo","color":"f25880"},"App Navigation":{"name":"App Navigation","description":"Issues related to the topbar navigation and configuring it","color":"4773ab"},"Widgets Pane":{"name":"Widgets Pane","description":"Issues related to the discovery and organisation of widgets","color":"ad5d78"},"View Mode":{"color":"1799b0","name":"View Mode","description":"Issues related to the view mode"},"Content":{"name":"Content","description":"For content related topics i.e blogs, templates, videos","color":"a8dff7"},"Slash Command":{"name":"Slash Command","description":"Issues related to the slash command","color":"a0608e"},"Widget Property":{"name":"Widget Property","description":"Issues related to adding / modifying widget properties across widgets","color":"5e92cb"},"Windows":{"name":"Windows","description":"Issues related exclusively to Windows systems","color":"b4cb8a"},"Old App Issues":{"name":"Old App Issues","description":"Issues related to apps old apps a few weeks old and app issues in stale browser session","color":"87ab18"},"Document Viewer Widget":{"name":"Document Viewer Widget","description":"Issues related to Document Viewer Widget","color":"899d4b"},"Radio Group Widget":{"name":"Radio Group Widget","description":"Issues related to radio group widget","color":"b68495"},"Super Admin":{"name":"Super Admin","description":"Issues related to the super admin page","color":"aa95cf"},"Postgres":{"name":"Postgres","description":"Postgres related issues","color":"8078b0"},"New JS Function":{"name":"New JS Function","description":"Issues related to adding a JS Function","color":"8e8aa4"},"Cannot Reproduce Issue":{"color":"93c9cc","name":"Cannot Reproduce Issue","description":"Issues that cannot be reproduced"},"Widget Grouping":{"name":"Widget Grouping","description":"Issues related to Widget Grouping","color":"a49951"},"K8s":{"name":"K8s","description":"Kubernetes related issues","color":"5f318a"},"Docker":{"name":"Docker","description":"Issues related to docker","color":"89b808"},"Camera Widget":{"name":"Camera Widget","description":"Issues and enhancements related to camera widget","color":"e6038e"},"SAAS Plugins":{"name":"SAAS Plugins","description":"Issues related to SAAS Plugins","color":"80e18f"},"JS Promises":{"name":"JS Promises","description":"Issues related to promises","color":"d7771f"},"OnPageLoad":{"name":"OnPageLoad","description":"OnPageLoad issues on functions and queries","color":"2b4664"},"JS Usability":{"name":"JS Usability","description":"usability issues with JS editor and JS elsewhere","color":"a302b0"},"Currency Input Widget":{"name":"Currency Input Widget","description":"Issues related to currency input widget","color":"b2164f"},"TreeSelect":{"name":"TreeSelect","description":"Issues related to TreeSelect Widget","color":"a1633e"},"MultiTree Select Widget":{"name":"MultiTree Select Widget","description":"Issues related to MultiTree Select Widget","color":"a1633e"},"Welcome Screen":{"name":"Welcome Screen","description":"Issues related to the welcome screen","color":"48883f"},"Realtime Commenting":{"color":"a70b86","name":"Realtime Commenting","description":"In-app communication between teams"},"Phone Input Widget":{"name":"Phone Input Widget","description":"Issues related to the Phone Input widget","color":"a70b86"},"JSON Form":{"name":"JSON Form","description":"Issue / features related to the JSON form wiget","color":"46b209"},"All Widgets":{"name":"All Widgets","description":"Issues related to all widgets","color":"972b36"},"V1":{"name":"V1","description":"V1","color":"67ab2e"},"Reflow & Resize":{"name":"Reflow & Resize","description":"All issues related to reflow and resize experience","color":"748a13"},"SSO":{"name":"SSO","description":"Issues, requests and enhancements around Single sign-on.","color":""},"Multi User Realtime":{"name":"Multi User Realtime","description":"Issues related to multiple users using or editing an application","color":"e7b6ce"},"Ready for design":{"name":"Ready for design","description":"this issue is ready for design: it contains clear problem statements and other required information","color":"ebf442"},"Support":{"name":"Support","description":"Issues created by the A-force team to address user queries","color":"1740f3"},"Button Group widget":{"name":"Button Group widget","description":"Issue and enhancements related to the button group widget","color":"f17025"},"GraphQL Plugin":{"name":"GraphQL Plugin","description":"Issues related to GraphQL plugin","color":"8078b0"},"DevOps Pod":{"name":"DevOps Pod","description":"Issues related to devops","color":"d956c7"},"medium":{"name":"medium","description":"Issues that frustrate users due to poor UX","color":"23dfd9"},"ArangoDB":{"name":"ArangoDB","description":"Issues related to arangoDB","color":"8078b0"},"Code Refactoring":{"name":"Code Refactoring","description":"Issues related to code refactoring","color":"76310e"},"Progress bar widget":{"name":"Progress bar widget","description":"To track issues related to progress bar","color":"2d7abf"},"Audio Recorder Widget":{"name":"Audio Recorder Widget","description":"Issues related to Audio Recorder Widget","color":"9accef"},"Airtable":{"name":"Airtable","description":"Issues for Airtable","color":"60885f"},"Canvas / Grid":{"name":"Canvas / Grid","description":"Issues related to the canvas","color":"16b092"},"Email Config":{"name":"Email Config","description":"Issues related to configuring the email service","color":"2a21d1"},"CURL":{"name":"CURL","description":"Issues related to CURL impor","color":"60885f"},"Canvas Zooms":{"name":"Canvas Zooms","description":"Issues related to zooming the canvas","color":"e6038e"},"business":{"name":"business","description":"Features that will be a part of our business edition","color":"cd59eb"},"Action Pod":{"name":"Action Pod","description":"","color":"ee2e36"},"AutomationGap1":{"color":"a5e07c","name":"AutomationGap1","description":"Issues that needs automated tests"},"A-Force11":{"name":"A-Force11","description":"Issues raised by A-Force team","color":"d667b6"},"Business Edition":{"name":"Business Edition","description":"Features that will be a part of our business edition","color":"89bb6c"},"storeValue":{"name":"storeValue","description":"Issues related to the store value function","color":"5d3e66"},"DynamoDB":{"name":"DynamoDB","description":"Issues that are related to DynamoDB should have this label","color":"60885f"},"Backup & Restore":{"name":"Backup & Restore","description":"Issues related to backup and restore","color":"86874d"},"Billing":{"name":"Billing","description":"Billing infrastructure and flows for Business Edition and Trial users","color":"d2bc40"},"Datatype issue":{"name":"Datatype issue","description":"Issues that have risen because data types weren't handled","color":"cef66b"},"OAuth":{"name":"OAuth","description":"OAuth related bugs or features","color":"60885f"},"Table Widget V2":{"name":"Table Widget V2","description":"Issues related to Table Widget V2","color":"3a7192"},"IDE Navigation":{"name":"IDE Navigation","description":"Issues/feature requests related to IDE navigation, and context switching","color":"1bb96a"},"Query performance":{"name":"Query performance","description":"Issues that have to do with lack in performance of query execution","color":"cef66b"},"SAAS Manager App":{"name":"SAAS Manager App","description":"Issues with the SAAS manager app","color":"d427db"},"Twilio":{"name":"Twilio","description":"Issues related to Twilio integration","color":"23ba8d"},"Hubspot":{"name":"Hubspot","description":"Issues related to Hubspot integration","color":"60885f"},"Zendesk":{"name":"Zendesk","description":"Issues related to Zendesk integration","color":"60885f"},"Entity Refactor":{"name":"Entity Refactor","description":"Issues related to refactor logic","color":"705a2c"},"Map Chart Widget":{"name":"Map Chart Widget","description":"Issues related to Map Chart Widgets","color":"c8397f"},"Product Catchup":{"name":"Product Catchup","description":"Issues created in the product catchup","color":"29cd2c"},"Framework Functions":{"name":"Framework Functions","description":"Issues related to internal functions like showAlert(), navigateTo() etc...","color":"c25a09"},"Frontend Libraries Upgrade":{"name":"Frontend Libraries Upgrade","description":"Issues related to frontend libraries upgrade","color":"ede1fc"},"MsSQL":{"name":"MsSQL","description":"Issues related to MsSQL plugin","color":"8078b0"},"Elastic Search":{"name":"Elastic Search","description":"Issues related to the elastic search datasource","color":"8078b0"},"Core Query Execution":{"color":"cef66b","name":"Core Query Execution","description":"Issues related to the execution of all queries"},"Query Management":{"name":"Query Management","description":"Issues related to the CRUD of actions or queries","color":"cef66b"},"Query Settings":{"name":"Query Settings","description":"Issues related to the settings of all queries","color":"cef66b"},"Code Editor":{"name":"Code Editor","description":"Issues related to the code editor","color":"4ca16e"},"Query Forms":{"color":"12b253","name":"Query Forms","description":"Isuses related to the query forms"},"JS Objects":{"color":"22962c","name":"JS Objects","description":"Issues related to JS Objects"},"JS Evaluation":{"color":"22962c","name":"JS Evaluation","description":"Issues related to JS evaluation on the platform"},"SmartSubstitution":{"name":"SmartSubstitution","description":"Issues related to Smart substitution of mustache bindings in queries","color":"bae511"},"Query Generation":{"name":"Query Generation","description":"Issues related to query generation","color":"cef66b"},"Suggested Widgets":{"name":"Suggested Widgets","description":"Issues related to suggesting widgets based on query response","color":"6ac063"},"Code Scanner Widget":{"name":"Code Scanner Widget","description":"Issues related to code scanner widget","color":"9bc1a0"},"Clean URLs":{"name":"Clean URLs","description":"Issues related to clean URLs epic","color":"112623"},"Widget keyboard accessibility":{"name":"Widget keyboard accessibility","description":"All issues related to keyboard accessibility in widgets","color":"b626fd"},"Connection pool":{"name":"Connection pool","description":"issues to do with connection pooling of various plugins","color":"94fe36"},"List Widget V2":{"name":"List Widget V2","description":"Issues related to the list widget v2","color":"adaaf7"},"Auto Height":{"name":"Auto Height","description":"Issues related to dynamic height of widgets","color":"5149cf"},"cypress_failed_test":{"name":"cypress_failed_test","description":"Cypress failed tests","color":"4745d5"},"Needs validation":{"name":"Needs validation","description":"Needs problem validation before being picked up","color":"66673d"},"Slider Widget":{"name":"Slider Widget","description":"Issues raised for slider widgets.","color":"2eef5f"},"Multitenancy":{"name":"Multitenancy","description":"Support multitenancy within single appsmith instance","color":"8c49a9"},"Conversion Algorithm":{"name":"Conversion Algorithm","description":"All issue related to converting app from fixed to flex mode & vice versa","color":"d12d2e"},"Browser specific":{"name":"Browser specific","description":"All issue related to browser","color":"d12d2e"},"Performance infra":{"name":"Performance infra","description":"all issue related to the performance infra","color":"8a60f6"},"DSL Update":{"name":"DSL Update","description":"Issues related to storing and updating the DSL","color":"e16cf3"},"AST-frontend":{"name":"AST-frontend","description":"Issues related to maintaining AST logic","color":"2b4664"},"AST-backend":{"name":"AST-backend","description":"Backend issues related to AST parsing","color":"48883f"},"MariaDB":{"name":"MariaDB","description":"MariaDB datasource","color":"8428c3"},"ADS Component Issue":{"name":"ADS Component Issue","description":"Issues which are caused due to ADS components","color":"d89119"},"Regressed":{"color":"723fd0","name":"Regressed","description":"Scenarios that were working before but have now regressed"},"Needs RCA":{"name":"Needs RCA","description":"a critical or high priority issue that needs an RCA","color":"2cc68f"},"Custom JS Libraries":{"name":"Custom JS Libraries","description":"Issues related to adding custom JS library","color":"bacb6d"},"Integrations Pod General":{"name":"Integrations Pod General","description":"Issues related to the Integrations Pod that don't fit into other tags.","color":"287823"},"Performance Pod":{"name":"Performance Pod","description":"All things related to Appsmith performance","color":"b5a25d"},"Performance":{"name":"Performance","description":"Issues related to performance","color":"9a18d7"},"File upload issues":{"name":"File upload issues","description":"Issues related to uploading any type of files from within Appsmith","color":"2b4664"},"Action Selector":{"name":"Action Selector","description":"Issues related to action selector on the property pane","color":"2f9e20"},"Community Reported":{"name":"Community Reported","description":"issues reported by community members","color":"1402e5"},"JS Function execution":{"name":"JS Function execution","description":"JS function execution","color":"7c2de1"},"Self Serve":{"name":"Self Serve","description":"For all issues related to self-serve flow for business edition","color":"4dacfc"},"Self Serve 1.0":{"name":"Self Serve 1.0","description":"For all issues related to v1 of the self serve project","color":"ae839e"},"Customer Portal":{"name":"Customer Portal","description":"For all tasks/issues pertaining to customer.appsmith.com","color":"d2bc40"},"Cloud Services":{"name":"Cloud Services","description":"For all tasks/issues on Appsmith cloud-services relating to licensing, usage and billing","color":"d2bc40"},"One-click Binding":{"name":"One-click Binding","description":"Issues related to the One click binding epic","color":"f1661c"},"Airgap":{"name":"Airgap","description":"Tickets related to supporting air-gapped Appsmith instances","color":"1cb294"},"SMTP plugin":{"name":"SMTP plugin","description":"Issues related to SMTP plugin","color":"541457"},"AWS AMI":{"name":"AWS AMI","description":"Issues Related to AWS AMI","color":"b44680"},"Old widget version":{"name":"Old widget version","description":"Use this label to raise issue specific only to an older version of a widget","color":"ff3814"},"Enterprise Billing":{"name":"Enterprise Billing","description":"To track all tasks/issues related to licensing & billing for enterprise customers","color":"14c156"},"Oracle SQL DB":{"name":"Oracle SQL DB","description":"Issues related to the Oracle plugin","color":"cbabcb"},"Community Contributor":{"name":"Community Contributor","description":"Meant to track issues that are assigned to external contributors","color":"149ab6"},"widget vertical alignment":{"name":"widget vertical alignment","description":"All issue related widget vertical alignment on the auto layout canvas","color":"d12d2e"},"Observability":{"name":"Observability","description":"Issues related to observability on the Appsmith instance","color":"dff913"},"Checkbox Component":{"name":"Checkbox Component","description":"This labels deals with checkbox component in wds package","color":"75a401"},"Analytics Improvements":{"name":"Analytics Improvements","description":"For all tasks focused on improving our overall analytics and fixing any issues ","color":"29b8ed"},"WDS team":{"name":"WDS team","description":"","color":"8d675a"},"Enterprise Edition":{"name":"Enterprise Edition","description":"Features that will be supported in Enterprise Edition only","color":"984f5e"},"Query filter":{"name":"Query filter","description":"Issues related to query filtering, e.g., WHERE clause","color":"a15134"},"Keyboard accessibility ":{"name":"Keyboard accessibility ","description":"All issue related to ADS component keyboard accessibility","color":"2ba696"},"Toggle button":{"name":"Toggle button","description":"All issue related to ADS toggle button","color":"edc47f"},"SCIM":{"name":"SCIM","description":"Label to collate our SCIM issues","color":"48883f"},"ADS Category Token":{"name":"ADS Category Token","description":"All issues related appsmith design system category tokens","color":"920961"},"ADS Component Documentation":{"name":"ADS Component Documentation","description":"All issues Appsmith design system component documentation","color":"64c46a"},"ADS Migration":{"name":"ADS Migration","description":"All issues related to Appsmith design system migration","color":"b082d6"},"ADS Deduplication ":{"name":"ADS Deduplication ","description":"Replacing component with ADS components","color":"b082d6"},"ADS Revamp":{"name":"ADS Revamp","description":"All issues related to ads revamp. ","color":"b082d6"},"ADS Deduplication":{"name":"ADS Deduplication","description":"Replacing component with ADS components","color":"b082d6"},"ADS Grayscale":{"name":"ADS Grayscale","description":"Support grayscale color changes","color":"b03577"},"ADS Unit Test":{"name":"ADS Unit Test","description":"All issue related ads unit cases ","color":"b082d6"},"ADS Components":{"name":"ADS Components","description":"All issues related ADS components","color":"b082d6"},"Widget Discoverability":{"name":"Widget Discoverability","description":"Issues related to Widget Discoverability","color":"7b55ce"},"Widget setter method":{"name":"Widget setter method","description":"Issues with widget property setters","color":"8dce87"},"License":{"name":"License","description":"For all issues/tasks related to licensing of appsmith-ee edition","color":"90ee98"},"Platformization":{"name":"Platformization","description":"Issues or tasks related to platformization of Appsmith codebase","color":"4e972b"},"Activation - datasources":{"name":"Activation - datasources","description":"issues related to activation projects","color":"7c7ace"},"Partial-import-export":{"name":"Partial-import-export","description":"Label for granular reusability.","color":"717732"},"AI":{"name":"AI","description":"All tasks related to AI","color":"2b4664"},"ADS Typography":{"name":"ADS Typography","description":"All issue related typographical changes","color":"2dbe8d"},"Auto Layout":{"name":"Auto Layout","description":"Issues relates to auto layout","color":"92cf8c"},"Heroku":{"name":"Heroku","description":"Issues related to Heroku","color":"a81b69"},"ADS Visual Styles":{"name":"ADS Visual Styles","description":"All issues related to ADS visual styles","color":"d3da89"},"ADS Component Design":{"name":"ADS Component Design","description":"All issue related to component design","color":"5cc91e"},"Modal Component":{"name":"Modal Component","description":"All issue related to ads modal component","color":"ee63f3"},"App setting":{"name":"App setting","description":"Related to app settings panel within the app","color":"174f98"},"BE instance":{"name":"BE instance","description":"For all issues related to license, billing on BE instance","color":"ae8f98"},"Fixed layout":{"name":"Fixed layout","description":"issues related to fixed layout","color":"b66681"},"Anvil layout":{"name":"Anvil layout","description":"issues related to the new layout system anvil","color":"5e0904"},"New Deployment Mode":{"name":"New Deployment Mode","description":"Support a new mode of deployment","color":"108033"},"Custom widgets":{"name":"Custom widgets","description":"For all issues related to the custom widget project","color":"c9db9c"},"Homepage Experience V2":{"name":"Homepage Experience V2","description":"Label for reporting new tasks and bug fixes related to revamped homepage experience","color":"c55d54"},"Customer Success":{"name":"Customer Success","description":"Issues that the success team cares about","color":"6ccabd"},"Invite flow":{"name":"Invite flow","description":"Invite users flow and any associated actions","color":"881b35"},"Invite users":{"name":"Invite users","description":"Invite users flow and any associated actions","color":""},"Workflows Pod":{"name":"Workflows Pod","description":"Issues that the workflows team owns","color":"446925"},"DailyPromotionBlocker":{"name":"DailyPromotionBlocker","description":"DailyPromotion Blocker","color":"9b2280"},"JS Binding":{"name":"JS Binding","description":"All issues related to the JS Binding experience","color":"422fed"},"REST API":{"name":"REST API","description":"REST API plugin related issues","color":"e3ede5"},"Critical":{"color":"a1e3db","name":"Critical","description":"This issue breaks existing apps. Drop everything else to resolve"},"Module creator":{"name":"Module creator","description":"Issues related to the module creator side","color":"bb2c05"},"Module consumer":{"name":"Module consumer","description":"Issues related to the module consumer side","color":"83d3c5"},"Package versioning":{"name":"Package versioning","description":"ISsues related to how we manage versions for packages","color":"4c5218"},"Convert to module":{"name":"Convert to module","description":"Issues related to the module creation flow using conversion","color":"4c5218"},"Query module":{"name":"Query module","description":"Issues affecting query modules or its instances","color":"b11a7e"},"JS module":{"name":"JS module","description":"Issues affecting JS modules or its instances","color":"bf76f6"},"Secret Management":{"name":"Secret Management","description":"Issues related to secret management","color":"2b4664"},"REST API plugin":{"name":"REST API plugin","description":"REST API plugin related issues","color":"b5948a"},"UI module":{"name":"UI module","description":"Issues affecting UI modules or its instances","color":"d2acee"},"Preview mode":{"name":"Preview mode","description":"Issues related to app previews","color":"48883f"},"Git Auto-commit":{"name":"Git Auto-commit","description":"Issues related to autocommit","color":"717732"},"QA Pod":{"name":"QA Pod","description":"Issues under the QA Pod","color":"717732"},"Automation Test":{"name":"Automation Test","description":"","color":""},"Automation failures":{"name":"Automation failures","description":"","color":""},"Needs automation":{"name":"Needs automation","description":"Issues that needs automated tests","color":""},"Prepared statements":{"name":"Prepared statements","description":"Issues related to prepared statement flow","color":""},"Switch Group Widget":{"name":"Switch Group Widget","description":"Issues related to Switch group Widget","color":""},"Supervisor":{"name":"Supervisor","description":"Issues related to supervisor","color":"2c5813"},"Deployment Certificates":{"name":"Deployment Certificates","description":"Issues related to lets encrypt","color":"e148aa"},"Mock Data":{"name":"Mock Data","description":"Issues related to mock databases","color":"ebf251"},"AWS ECS":{"name":"AWS ECS","description":"Issues related to ECS Fargate","color":"e506ff"},"Publish App":{"name":"Publish App","description":"Issues related to app deployment","color":"2b4664"},"IDE Infra":{"name":"IDE Infra","description":"Issues related to the IDE infrastructure like saving changes","color":"1bb96a"},"User Profile":{"name":"User Profile","description":"Issues related to a user profile","color":"a60d34"},"Page Management":{"color":"1bb96a","name":"Page Management","description":"Issues related to configuring pages"},"Ingress":{"name":"Ingress","description":"Ingress Controller","color":"a86802"},"Nginx":{"name":"Nginx","description":"Issues related to Nginx","color":"e54195"},"Building blocks":{"name":"Building blocks","description":"Building blocks on cavas, on templates listing or drag and drop of building blocks.","color":"48883f"},"Table Inline Edit":{"name":"Table Inline Edit","description":"Issues related to inline editing","color":"60895a"},"User Session ":{"name":"User Session ","description":"For all issues/tasks related to user sessions","color":"65a3f5"},"WDS - all widgets":{"name":"WDS - all widgets","description":"all widget present in WDS","color":"2670ae"},"WDS - input widget":{"name":"WDS - input widget","description":"Issues related to input widget on WDS","color":"2670ae"},"WDS - paragraph widget":{"name":"WDS - paragraph widget","description":"issues related to paragraph widget on WDS","color":"2670ae"},"WDS - statbox widget":{"name":"WDS - statbox widget","description":"issues related to statbox widget on WDS","color":"2670ae"},"WDS - modal widget":{"name":"WDS - modal widget","description":"Issues related to modal widget on WDS","color":"2670ae"},"WDS - icon widget":{"name":"WDS - icon widget","description":"Issues related to icon widget on WDS","color":"2670ae"},"WDS - checkbox widget":{"name":"WDS - checkbox widget","description":"Issues related to checkbox widget on WDS","color":"2670ae"},"WDS - table widget":{"name":"WDS - table widget","description":"Issues related to table widget on WDS","color":"2670ae"},"WDS - keyValue widget":{"name":"WDS - keyValue widget","description":"Issues related to key-value widget on WDS","color":"2670ae"},"WDS - switch group widget":{"name":"WDS - switch group widget","description":"Issues related to switch group widget on WDS","color":"2670ae"},"WDS - theming":{"name":"WDS - theming","description":"Issues related to theming on the Anvil instance","color":"2670ae"},"Anvil POD":{"name":"Anvil POD","description":"Issue related to Anvil project","color":"5e0904"},"Anvil - theming":{"name":"Anvil - theming","description":"Issues related to theming on the Anvil instance","color":"c28de5"},"Anvil - vertical alignment":{"name":"Anvil - vertical alignment","description":"Issues related to vertical alignment on the Anvil layout","color":"c28de5"},"Anvil - layout component":{"name":"Anvil - layout component","description":"Issues related to layout component on the Anvil layout","color":"c28de5"},"Anvil - drag & drop":{"name":"Anvil - drag & drop","description":"Issues related to drag & drop experience on Anvil","color":"c28de5"},"Anvil - zones & sections":{"name":"Anvil - zones & sections","description":"Issues related to zones and sections on the Anvil layout","color":"c28de5"},"Anvil - copy paste experience":{"name":"Anvil - copy paste experience","description":"Issues related to copy paste experience on the Anvil layout","color":"c28de5"},"WDS - phone widget":{"name":"WDS - phone widget","description":"Issues related to phone widget on WDS","color":"c28de5"},"WDS - responsive widget":{"name":"WDS - responsive widget","description":"All issues related to widget responsiveness","color":"11ee05"},"Anvil - responsive viewport":{"color":"11ee05","name":"Anvil - responsive viewport","description":"Issues seen on different viewports like mobile"},"WDS - widget styling":{"color":"11ee05","name":"WDS - widget styling","description":"all about widget styling"},"Anvil - spacing":{"name":"Anvil - spacing","description":"Related to spacing between widgets in auto layout","color":"11ee05"},"Anvil - responsive canvas":{"name":"Anvil - responsive canvas","description":"All issues related to canvas responsiveness","color":"11ee05"},"WDS - inline button widget":{"name":"WDS - inline button widget","description":"Issues related to inline button widget on WDS","color":"7cef83"},"Activation Pod":{"name":"Activation Pod","description":"for Activation group","color":"d67d00"},"Activation":{"name":"Activation","description":"for Activation group","color":"d67d00"},"Tests":{"name":"Tests","description":"Test issues","color":"4fc7b6"},"Ballpark: XXS":{"name":"Ballpark: XXS","description":"~1xDev in 1/2xSprint","color":""},"Ballpark: XS":{"name":"Ballpark: XS","description":"~1xDev in 1xSprint","color":"53bf71"},"Ballpark: S":{"name":"Ballpark: S","description":"~2xDev in 1xSprint","color":"6e9e65"},"Ballpark: M":{"name":"Ballpark: M","description":"~1xPOD in 1xSprint","color":"2229e6"},"Ballpark: L":{"name":"Ballpark: L","description":"~1xPOD in 3xSprint or 2xPODs in 1xSprint","color":"49962f"},"Ballpark: XL":{"name":"Ballpark: XL","description":"~1xPOD in 1xQuarter or 2xPODs in 2xSprint","color":"b524c9"},"Ballpark: XXL":{"name":"Ballpark: XXL","description":"~2xPODs in 1xQuarter","color":"22092c"},"Auto-commit":{"name":"Auto-commit","description":"Issues related to auto-generated commits showing up on git ","color":"e25b89"},"Continuous Deployment":{"name":"Continuous Deployment","description":"Issues related to CD pipeline on git","color":"aea47c"},"Branch protection":{"name":"Branch protection","description":"Issues related to using a protected branch on git","color":"ab511a"},"Default branch":{"name":"Default branch","description":"Issues related to using a default branch on git","color":"195737"},"Git status":{"name":"Git status","description":"Issues related to information shown on git status modal or number of changes appearing in a branch","color":"c851b8"},"Git performance":{"name":"Git performance","description":"Issues related to perceived performance on any git operation","color":"189af6"},"Anvil team":{"name":"Anvil team","description":"issues related to the new layout system anvil","color":"798200"},"SDLC":{"name":"SDLC","description":"Issues related to software development lifecycle experiences","color":"bae511"},"Reconnect DS modal":{"name":"Reconnect DS modal","description":"Issues related to reconnect datasource modal post app import","color":"2e398b"},"Stability Pod":{"name":"Stability Pod","description":"For all issues/tasks to be prioritized under Stability pod","color":"86ddf6"},"Stability Issue":{"name":"Stability Issue","description":"Every issue handle by Stability Pod","color":"4d024a"},"Move to Postgres":{"name":"Move to Postgres","description":"Issues required to be solved for the move to Postgres as repository layer","color":"4e13ac"},"User Session":{"name":"User Session","description":"Issues related to user sessions","color":"8255e5"},"IDE tabs":{"name":"IDE tabs","description":"query and js tabs","color":"1bb96a"},"Inviting Contribution":{"name":"Inviting Contribution","description":"Issues that we would like contributions to","color":""},"cypress-flaky-fix":{"name":"cypress-flaky-fix","description":"This label is auto-added when a PR which only has Cypress fixes are merged to release","color":"722cbc"},"Cypress flaky tests":{"name":"Cypress flaky tests","description":"Test scripts that need to be fixed on Cypress by dev or SDET","color":"722cbc"},"Help enterprise":{"name":"Help enterprise","description":"Requested by Appsmith customers or prospects","color":"FF8C00"},"Learnability":{"name":"Learnability","description":"Issues affecting the product learnability, making the product harder for new users.","color":"800c2f"},"ADS Spacing":{"name":"ADS Spacing","description":"","color":"686ebb"},"ads unit test":{"name":"ads unit test","description":"All issue related ads unit cases","color":"686ebb"},"ads revamp":{"name":"ads revamp","description":"All issues related to ads revamp.","color":"686ebb"},"Javascript Product":{"color":"709a21","name":"Javascript Product","description":"Issues related to users writing javascript in appsmith"},"IDE Product":{"color":"1bb96a","name":"IDE Product","description":"Issues related to the IDE Product"},"IDE Pod":{"color":"1bb96a","name":"IDE Pod","description":"Issues that new developers face while exploring the IDE"},"Accelerators Product":{"name":"Accelerators Product","description":"Issues related to app building accelerators","color":"f3fce6"},"Templates Product":{"name":"Templates Product","description":"Issues related to Templates","color":"f3fce6"},"Design System Product":{"name":"Design System Product","description":"Appsmith design system related issues","color":"2b4664"},"ads deduplication":{"name":"ads deduplication","description":"Replacing component with ADS components","color":"708943"},"Admin Settings Product":{"color":"708943","name":"Admin Settings Product","description":"Issues in admin settings pages"},"Appsmith AI":{"name":"Appsmith AI","description":"All issues related to the Appsmith AI datasource","color":"708943"},"Query & JS Pod":{"color":"709a21","name":"Query & JS Pod","description":"Issues related to the query & JS Pod"},"RBAC Product":{"name":"RBAC Product","description":"Issues, requests and enhancements around RBAC.","color":""},"Workspace Product":{"name":"Workspace Product","description":"Issues related to workspaces","color":""},"CE Instance Usage":{"name":"CE Instance Usage","description":"For all issues relating to usage, licensing or billing on the CE instance","color":""},"Billing & Licensing Product":{"name":"Billing & Licensing Product","description":"Issues pertaining to licensing, billing and usage across self serve and enterprise customers","color":"446925"},"Platform Administration Pod":{"color":"446925","name":"Platform Administration Pod","description":"Issues related to platform administration & management"},"DB Infrastructure Pod":{"name":"DB Infrastructure Pod","description":"Pod to handle database infrastructure","color":"446925"},"Packages Product":{"name":"Packages Product","description":"Issues related to packages","color":"446925"},"Workflows Product":{"name":"Workflows Product","description":"Issues related to the workflows product","color":"446925"},"Debugger Product":{"color":"857f58","name":"Debugger Product","description":"Issues related to the debugger"},"Packages Pod":{"name":"Packages Pod","description":"issues that belong to the packages pod","color":"857f58"},"Environments Product":{"name":"Environments Product","description":"Issues related to datasource environments","color":"857f58"},"Custom Widgets":{"name":"Custom Widgets","description":"For all issues related to the custom widget project","color":"857f58"},"Branding Product":{"name":"Branding Product","description":"All issues under branding and whitelabelling appsmith ecosystem","color":"857f58"},"Widgets & Accelerators Pod":{"name":"Widgets & Accelerators Pod","description":"Issues related to widgets & Accelerators","color":"27496a"},"Widgets Product":{"name":"Widgets Product","description":"This label groups issues related to widgets","color":"f3fce6"},"App Theming Product":{"name":"App Theming Product","description":"Items that are related to the App level theming controls epic","color":"48883f"},"UI Building Product":{"color":"48883f","name":"UI Building Product","description":"Issues related to the UI Building experience"},"Onboarding Product":{"color":"48883f","name":"Onboarding Product","description":"Issues related to onboarding new developers"},"Database Schema":{"name":"Database Schema","description":"Issues related to database schema","color":"48883f"},"Git Product":{"color":"48883f","name":"Git Product","description":"Issues related to version control product"},"Git Platform Pod":{"name":"Git Platform Pod","description":"Issues related to the git & the app platform ","color":"48883f"},"Embedding Apps Product":{"name":"Embedding Apps Product","description":"Issues related to embedding","color":"48883f"},"Integrations Product":{"name":"Integrations Product","description":"Issues related to a specific integration","color":"b9f21c"},"Feature Flagging":{"name":"Feature Flagging","description":"Anything related feature flagging","color":"4574ae"},"Audit Logs Product":{"name":"Audit Logs Product","description":"Audit trails to ensure data security","color":"4574ae"},"Identity & Authentication Product":{"name":"Identity & Authentication Product","description":"Issues related to user identity & authentication","color":"4574ae"},"Email verification":{"name":"Email verification","description":"Email verification issues","color":"4574ae"},"Artifact Platform Product":{"name":"Artifact Platform Product","description":"Issues related to the application platform","color":"4574ae"},"Git IA":{"name":"Git IA","description":"Issues related to Git IA changes","color":"df8bd6"},"Documentation Pod":{"name":"Documentation Pod","description":"Issues related to user education","color":"8c8c02"}},"success":true} \ No newline at end of file +{"runners":[{"versioning":{"source":"milestones","type":"SemVer"},"prereleaseName":"alpha","issue":{"labels":{"Widgets Product":{"conditions":[{"label":"Button Widget","type":"hasLabel","value":true},{"label":"Chart Widget","type":"hasLabel","value":true},{"label":"Container Widget","type":"hasLabel","value":true},{"label":"Date Picker Widget","type":"hasLabel","value":true},{"label":"Select Widget","type":"hasLabel","value":true},{"label":"File Picker Widget","type":"hasLabel","value":true},{"label":"Form Widget","type":"hasLabel","value":true},{"label":"Image Widget","type":"hasLabel","value":true},{"label":"Input Widget","type":"hasLabel","value":true},{"label":"List Widget","type":"hasLabel","value":true},{"label":"MultiSelect Widget","type":"hasLabel","value":true},{"label":"Map Widget","type":"hasLabel","value":true},{"label":"Modal Widget","type":"hasLabel","value":true},{"label":"Radio Widget","type":"hasLabel","value":true},{"label":"Rich Text Editor Widget","type":"hasLabel","value":true},{"label":"Tab Widget","type":"hasLabel","value":true},{"label":"Table Widget","type":"hasLabel","value":true},{"label":"Text Widget","type":"hasLabel","value":true},{"label":"Video Widget","type":"hasLabel","value":true},{"label":"iFrame","type":"hasLabel","value":true},{"label":"Menu Button","type":"hasLabel","value":true},{"label":"Rating","type":"hasLabel","value":true},{"label":"Widget Validation","type":"hasLabel","value":true},{"label":"New Widget","type":"hasLabel","value":true},{"label":"Switch widget","type":"hasLabel","value":true},{"label":"Audio Widget","type":"hasLabel","value":true},{"label":"Icon Button Widget","type":"hasLabel","value":true},{"label":"Stat Box Widget","type":"hasLabel","value":true},{"label":"Voice Recorder Widget","type":"hasLabel","value":true},{"label":"Calendar Widget","type":"hasLabel","value":true},{"label":"Menu Button Widget","type":"hasLabel","value":true},{"label":"Divider Widget","type":"hasLabel","value":true},{"label":"Rating Widget","type":"hasLabel","value":true},{"label":"View Mode","type":"hasLabel","value":true},{"label":"Widget Property","type":"hasLabel","value":true},{"label":"Document Viewer Widget","type":"hasLabel","value":true},{"label":"Radio Group Widget","type":"hasLabel","value":true},{"label":"Currency Input Widget","type":"hasLabel","value":true},{"label":"TreeSelect","type":"hasLabel","value":true},{"label":"MultiTree Select Widget","type":"hasLabel","value":true},{"label":"Phone Input Widget","type":"hasLabel","value":true},{"label":"JSON Form","type":"hasLabel","value":true},{"label":"All Widgets","type":"hasLabel","value":true},{"label":"Button Group widget","type":"hasLabel","value":true},{"label":"Progress bar widget","type":"hasLabel","value":true},{"label":"Audio Recorder Widget","type":"hasLabel","value":true},{"label":"Camera Widget","type":"hasLabel","value":true},{"label":"Table Widget V2","type":"hasLabel","value":true},{"label":"Map Chart Widget","type":"hasLabel","value":true},{"label":"Code Scanner Widget","type":"hasLabel","value":true},{"label":"Widget keyboard accessibility","type":"hasLabel","value":true},{"label":"List Widget V2","type":"hasLabel","value":true},{"label":"Slider Widget","type":"hasLabel","value":true},{"label":"One-click Binding","type":"hasLabel","value":true},{"label":"Old widget version","type":"hasLabel","value":true},{"label":"Widget Discoverability","type":"hasLabel","value":true},{"label":"Switch Group Widget","type":"hasLabel","value":true},{"label":"Checkbox Group widget","type":"hasLabel","value":true},{"label":"Checkbox Widget","type":"hasLabel","value":true},{"label":"Table Inline Edit","type":"hasLabel","value":true},{"label":"Custom Widgets","type":"hasLabel","value":true}],"requires":1},"Javascript Product":{"conditions":[{"label":"JS Linting & Errors","type":"hasLabel","value":true},{"label":"Autocomplete","type":"hasLabel","value":true},{"label":"Evaluated Value","type":"hasLabel","value":true},{"label":"Slash Command","type":"hasLabel","value":true},{"label":"New JS Function","type":"hasLabel","value":true},{"label":"JS Usability","type":"hasLabel","value":true},{"label":"Framework Functions","type":"hasLabel","value":true},{"label":"JS Objects","type":"hasLabel","value":true},{"label":"JS Evaluation","type":"hasLabel","value":true},{"label":"Custom JS Libraries","type":"hasLabel","value":true},{"label":"Action Selector","type":"hasLabel","value":true},{"label":"Widget setter method","type":"hasLabel","value":true},{"label":"Entity Refactor","type":"hasLabel","value":true},{"label":"AST-frontend","type":"hasLabel","value":true},{"label":"Sniping Mode","type":"hasLabel","value":true},{"label":"AST-backend","type":"hasLabel","value":true}],"requires":1},"IDE Product":{"conditions":[{"label":"IDE Product","type":"hasLabel","value":true},{"label":"IDE Infra","type":"hasLabel","value":true},{"label":"IDE Navigation","type":"hasLabel","value":true},{"label":"IDE tabs","type":"hasLabel","value":true},{"label":"Omnibar","type":"hasLabel","value":true},{"label":"Entity Explorer","type":"hasLabel","value":true},{"label":"Page Management","type":"hasLabel","value":true},{"label":"Preview mode","type":"hasLabel","value":true}],"requires":1},"Accelerators Product":{"conditions":[{"label":"Generate Page","type":"hasLabel","value":true},{"label":"Building blocks","type":"hasLabel","value":true}],"requires":1},"Templates Product":{"conditions":[{"label":"Partial-import-export","type":"hasLabel","value":true},{"label":"Templates Product","type":"hasLabel","value":true}],"requires":1},"Design System Product":{"conditions":[{"label":"Design System Product","type":"hasLabel","value":true},{"label":"ADS Component Issue","type":"hasLabel","value":true},{"label":"Keyboard accessibility ","type":"hasLabel","value":true},{"label":"Toggle button","type":"hasLabel","value":true},{"label":"ADS Category Token","type":"hasLabel","value":true},{"label":"ADS Component Documentation","type":"hasLabel","value":true},{"label":"ADS Migration","type":"hasLabel","value":true},{"label":"ADS Deduplication ","type":"hasLabel","value":true},{"label":"ADS Revamp","type":"hasLabel","value":true},{"label":"ADS Deduplication","type":"hasLabel","value":true},{"label":"ADS Unit Test","type":"hasLabel","value":true},{"label":"ADS Components","type":"hasLabel","value":true},{"label":"ADS Grayscale","type":"hasLabel","value":true},{"label":"Design System","type":"hasLabel","value":true},{"label":"ADS Typography","type":"hasLabel","value":true},{"label":"ADS Visual Styles","type":"hasLabel","value":true},{"label":"ADS Component Design","type":"hasLabel","value":true},{"label":"Modal Component","type":"hasLabel","value":true},{"label":"ADS Spacing","type":"hasLabel","value":true},{"label":"ads unit test","type":"hasLabel","value":true},{"label":"ads revamp","type":"hasLabel","value":true},{"label":"ads deduplication","type":"hasLabel","value":true}],"requires":1},"RBAC Product":{"conditions":[{"label":"Invite users","type":"hasLabel","value":true},{"label":"RBAC Product","type":"hasLabel","value":true}],"requires":1},"Workspace Product":{"conditions":[{"label":"Home Page","type":"hasLabel","value":true},{"label":"Workspace Product","type":"hasLabel","value":true}],"requires":1},"Billing & Licensing Product":{"conditions":[{"label":"Customer Portal","type":"hasLabel","value":true},{"label":"Cloud Services","type":"hasLabel","value":true},{"label":"Billing","type":"hasLabel","value":true},{"label":"Self Serve","type":"hasLabel","value":true},{"label":"Enterprise Billing","type":"hasLabel","value":true},{"label":"Analytics Improvements","type":"hasLabel","value":true},{"label":"Self Serve 1.0","type":"hasLabel","value":true},{"label":"License","type":"hasLabel","value":true},{"label":"BE instance","type":"hasLabel","value":true},{"label":"Invite flow","type":"hasLabel","value":true},{"label":"CE Instance Usage","type":"hasLabel","value":true},{"label":"Feature Flagging","type":"hasLabel","value":true}],"requires":1},"Packages Product":{"conditions":[{"label":"Packages Product","type":"hasLabel","value":true}],"requires":1},"Environments Product":{"conditions":[{"label":"Environments Product","type":"hasLabel","value":true}],"requires":1},"UI Building Product":{"conditions":[{"label":"Property Pane","type":"hasLabel","value":true},{"label":"Copy Paste","type":"hasLabel","value":true},{"label":"Drag & Drop","type":"hasLabel","value":true},{"label":"Undo/Redo","type":"hasLabel","value":true},{"label":"Widgets Pane","type":"hasLabel","value":true},{"label":"UI Performance","type":"hasLabel","value":true},{"label":"Widget Grouping","type":"hasLabel","value":true},{"label":"Reflow & Resize","type":"hasLabel","value":true},{"label":"Canvas / Grid","type":"hasLabel","value":true},{"label":"Auto Height","type":"hasLabel","value":true},{"label":"Browser specific","type":"hasLabel","value":true},{"label":"Auto Layout","type":"hasLabel","value":true},{"label":"Fixed layout","type":"hasLabel","value":true},{"label":"App Navigation","type":"hasLabel","value":true}],"requires":1},"Onboarding Product":{"conditions":[{"label":"Welcome Screen","type":"hasLabel","value":true}],"requires":1},"Git Product":{"conditions":[{"label":"Git Product","type":"hasLabel","value":true},{"label":"Git Auto-commit","type":"hasLabel","value":true},{"label":"Auto-commit","type":"hasLabel","value":true},{"label":"Continuous Deployment","type":"hasLabel","value":true},{"label":"Default branch","type":"hasLabel","value":true},{"label":"Git status","type":"hasLabel","value":true},{"label":"Git performance","type":"hasLabel","value":true},{"label":"SDLC","type":"hasLabel","value":true},{"label":"Git IA","type":"hasLabel","value":true},{"label":"Branch management","type":"hasLabel","value":true}],"requires":1},"Embedding Apps Product":{"conditions":[{"label":"Embedding Apps Product","type":"hasLabel","value":true}],"requires":1},"Integrations Product":{"conditions":[{"label":"New Datasource","type":"hasLabel","value":true},{"label":"Firestore","type":"hasLabel","value":true},{"label":"Google Sheets","type":"hasLabel","value":true},{"label":"Mongo","type":"hasLabel","value":true},{"label":"Redshift","type":"hasLabel","value":true},{"label":"snowflake","type":"hasLabel","value":true},{"label":"S3","type":"hasLabel","value":true},{"label":"Redis","type":"hasLabel","value":true},{"label":"Postgres","type":"hasLabel","value":true},{"label":"GraphQL Plugin","type":"hasLabel","value":true},{"label":"ArangoDB","type":"hasLabel","value":true},{"label":"MsSQL","type":"hasLabel","value":true},{"label":"Elastic Search","type":"hasLabel","value":true},{"label":"OAuth","type":"hasLabel","value":true},{"label":"Airtable","type":"hasLabel","value":true},{"label":"CURL","type":"hasLabel","value":true},{"label":"DynamoDB","type":"hasLabel","value":true},{"label":"Zendesk","type":"hasLabel","value":true},{"label":"Hubspot","type":"hasLabel","value":true},{"label":"Query Forms","type":"hasLabel","value":true},{"label":"Twilio","type":"hasLabel","value":true},{"label":"MySQL","type":"hasLabel","value":true},{"label":"Connection pool","type":"hasLabel","value":true},{"label":"MariaDB","type":"hasLabel","value":true},{"label":"Integrations Pod General","type":"hasLabel","value":true},{"label":"SMTP plugin","type":"hasLabel","value":true},{"label":"Oracle SQL DB","type":"hasLabel","value":true},{"label":"Query filter","type":"hasLabel","value":true},{"label":"Activation - datasources","type":"hasLabel","value":true},{"label":"REST API","type":"hasLabel","value":true},{"label":"REST API","type":"hasLabel","value":true},{"label":"Datasources","type":"hasLabel","value":true},{"label":"REST API plugin","type":"hasLabel","value":true},{"label":"Prepared statements","type":"hasLabel","value":true},{"label":"Query Generation","type":"hasLabel","value":true},{"label":"Core Query Execution","type":"hasLabel","value":true},{"label":"Query Management","type":"hasLabel","value":true},{"label":"Query Settings","type":"hasLabel","value":true},{"label":"Query performance","type":"hasLabel","value":true},{"label":"Datatype issue","type":"hasLabel","value":true},{"label":"SmartSubstitution","type":"hasLabel","value":true},{"label":"Suggested Widgets","type":"hasLabel","value":true},{"label":"SAAS Plugins","type":"hasLabel","value":true},{"label":"Reconnect DS modal","type":"hasLabel","value":true},{"label":"OnPageLoad","type":"hasLabel","value":true},{"label":"File upload issues","type":"hasLabel","value":true},{"label":"AI","type":"hasLabel","value":true},{"label":"Appsmith AI","type":"hasLabel","value":true},{"label":"Database Schema","type":"hasLabel","value":true}],"requires":1},"Identity & Authentication Product":{"conditions":[{"label":"Login / Signup","type":"hasLabel","value":true},{"label":"SSO","type":"hasLabel","value":true},{"label":"SCIM","type":"hasLabel","value":true},{"label":"Email verification","type":"hasLabel","value":true}],"requires":1},"Artifact Platform Product":{"conditions":[{"label":"Fork App","type":"hasLabel","value":true},{"label":"Publish App","type":"hasLabel","value":true},{"label":"Secret Management","type":"hasLabel","value":true},{"label":"Import-Export-App","type":"hasLabel","value":true}],"requires":1},"DevOps Pod":{"conditions":[{"label":"Docker","type":"hasLabel","value":true},{"label":"Super Admin","type":"hasLabel","value":true},{"label":"Deployment","type":"hasLabel","value":true},{"label":"K8s","type":"hasLabel","value":true},{"label":"Email Config","type":"hasLabel","value":true},{"label":"Backup & Restore","type":"hasLabel","value":true},{"label":"AWS AMI","type":"hasLabel","value":true},{"label":"Observability","type":"hasLabel","value":true},{"label":"Heroku","type":"hasLabel","value":true},{"label":"New Deployment Mode","type":"hasLabel","value":true},{"label":"Supervisor","type":"hasLabel","value":true},{"label":"Deployment Certificates","type":"hasLabel","value":true},{"label":"Mock Data","type":"hasLabel","value":true},{"label":"AWS ECS","type":"hasLabel","value":true},{"label":"Ingress","type":"hasLabel","value":true},{"label":"Nginx","type":"hasLabel","value":true}],"requires":1},"Performance Pod":{"conditions":[{"label":"Performance","type":"hasLabel","value":true},{"label":"Performance infra","type":"hasLabel","value":true}],"requires":1},"Git Platform Pod":{"conditions":[{"label":"Environments Product","type":"hasLabel","value":true},{"label":"Git Product","type":"hasLabel","value":true},{"label":"Artifact Platform Product","type":"hasLabel","value":true}],"requires":1},"IDE Pod":{"conditions":[{"label":"Telemetry","type":"hasLabel","value":true},{"label":"i18n","type":"hasLabel","value":true},{"label":"IDE Product","type":"hasLabel","value":true},{"label":"App setting","type":"hasLabel","value":true},{"label":"Debugger Product","type":"hasLabel","value":true},{"label":"Embedding Apps Product","type":"hasLabel","value":true}],"requires":1},"Platform Administration Pod":{"conditions":[{"label":"Airgap","type":"hasLabel","value":true},{"label":"Enterprise Edition","type":"hasLabel","value":true},{"label":"Invite flow","type":"hasLabel","value":true},{"label":"User Profile","type":"hasLabel","value":true},{"label":"User Session ","type":"hasLabel","value":true},{"label":"User Session","type":"hasLabel","value":true},{"label":"Admin Settings Product","type":"hasLabel","value":true},{"label":"RBAC Product","type":"hasLabel","value":true},{"label":"Workspace Product","type":"hasLabel","value":true},{"label":"Branding Product","type":"hasLabel","value":true},{"label":"Audit Logs Product","type":"hasLabel","value":true},{"label":"Identity & Authentication Product","type":"hasLabel","value":true}],"requires":1},"DB Infrastructure Pod":{"conditions":[{"label":"Move to Postgres","type":"hasLabel","value":true}],"requires":1},"Widgets & Accelerators Pod":{"conditions":[{"label":"Accelerators Product","type":"hasLabel","value":true},{"label":"Templates Product","type":"hasLabel","value":true},{"label":"Widgets Product","type":"hasLabel","value":true},{"label":"App Theming Product","type":"hasLabel","value":true}],"requires":1},"Packages Pod":{"conditions":[{"label":"Module creator","type":"hasLabel","value":true},{"label":"Module consumer","type":"hasLabel","value":true},{"label":"Package versioning","type":"hasLabel","value":true},{"label":"Convert to module","type":"hasLabel","value":true},{"label":"Query module","type":"hasLabel","value":true},{"label":"JS module","type":"hasLabel","value":true},{"label":"UI module","type":"hasLabel","value":true},{"label":"Packages Pod","type":"hasLabel","value":true},{"label":"Packages Product","type":"hasLabel","value":true}],"requires":1},"Workflows Pod":{"conditions":[{"label":"Workflows Product","type":"hasLabel","value":true}],"requires":1},"Query & JS Pod":{"conditions":[{"label":"Javascript Product","type":"hasLabel","value":true},{"label":"Onboarding Product","type":"hasLabel","value":true},{"label":"Integrations Product","type":"hasLabel","value":true}],"requires":1},"QA Pod":{"conditions":[{"label":"QA","type":"hasLabel","value":true},{"label":"Automation Test","type":"hasLabel","value":true},{"label":"TestGap","type":"hasLabel","value":true},{"label":"Automation failures","type":"hasLabel","value":true},{"label":"Needs automation","type":"hasLabel","value":true}],"requires":1},"Anvil POD":{"conditions":[{"label":"Checkbox Component","type":"hasLabel","value":true},{"label":"WDS team","type":"hasLabel","value":true},{"label":"Anvil POD","type":"hasLabel","value":true},{"label":"WDS - all widgets","type":"hasLabel","value":true},{"label":"WDS - input widget","type":"hasLabel","value":true},{"label":"WDS - paragraph widget","type":"hasLabel","value":true},{"label":"WDS - statbox widget","type":"hasLabel","value":true},{"label":"WDS - modal widget","type":"hasLabel","value":true},{"label":"WDS - icon widget","type":"hasLabel","value":true},{"label":"WDS - checkbox widget","type":"hasLabel","value":true},{"label":"WDS - table widget","type":"hasLabel","value":true},{"label":"WDS - keyValue widget","type":"hasLabel","value":true},{"label":"WDS - switch group widget","type":"hasLabel","value":true},{"label":"WDS - theming","type":"hasLabel","value":true},{"label":"Anvil layout","type":"hasLabel","value":true},{"label":"Anvil - theming","type":"hasLabel","value":true},{"label":"Anvil - vertical alignment","type":"hasLabel","value":true},{"label":"Anvil - layout component","type":"hasLabel","value":true},{"label":"Anvil - drag & drop","type":"hasLabel","value":true},{"label":"Anvil - zones & sections","type":"hasLabel","value":true},{"label":"Anvil - copy paste experience","type":"hasLabel","value":true},{"label":"WDS - phone widget","type":"hasLabel","value":true},{"label":"WDS - responsive widget","type":"hasLabel","value":true},{"label":"Anvil - responsive viewport","type":"hasLabel","value":true},{"label":"WDS - widget styling","type":"hasLabel","value":true},{"label":"Anvil - spacing","type":"hasLabel","value":true},{"label":"Anvil - responsive canvas","type":"hasLabel","value":true},{"label":"WDS - inline button widget","type":"hasLabel","value":true},{"label":"Anvil team","type":"hasLabel","value":true}],"requires":1},"Activation Pod":{"conditions":[{"label":"Activation","type":"hasLabel","value":true}],"requires":1},"Stability Pod":{"conditions":[{"label":"Stability Issue","type":"hasLabel","value":true},{"label":"cypress-flaky-fix","type":"hasLabel","value":true},{"label":"Cypress flaky tests","type":"hasLabel","value":true}],"requires":1},"Documentation Pod":{"conditions":[{"label":"Documentation","type":"hasLabel","value":true}],"requires":1}}},"root":"."}],"labels":{"Tab Widget":{"color":"e2c76c","name":"Tab Widget","description":""},"Dont merge":{"color":"ADB39C","name":"Dont merge","description":""},"Epic":{"color":"3E4B9E","name":"Epic","description":"A zenhub epic that describes a project"},"Menu Button Widget":{"color":"235708","name":"Menu Button Widget","description":"Issues related to Menu Button widget"},"Checkbox Group widget":{"color":"bbeecd","name":"Checkbox Group widget","description":"Issues related to Checkbox Group Widget"},"Input Widget":{"color":"ae65d8","name":"Input Widget","description":""},"Security":{"color":"99139C","name":"Security","description":""},"QA":{"color":"","name":"QA","description":"Needs QA attention"},"Verified":{"color":"9bf416","name":"Verified","description":""},"Wont Fix":{"color":"ffffff","name":"Wont Fix","description":"This will not be worked on"},"MySQL":{"color":"c9ddc6","name":"MySQL","description":"Issues related to MySQL plugin"},"Development":{"color":"9F8A02","name":"Development","description":""},"Help Wanted":{"color":"008672","name":"Help Wanted","description":"Extra attention is needed"},"Home Page":{"color":"","name":"Home Page","description":"Issues related to the application home page"},"Rating Widget":{"color":"235708","name":"Rating Widget","description":"Issues related to the rating widget"},"Stat Box Widget":{"color":"f1c9ce","name":"Stat Box Widget","description":"Issues related to stat box"},"Enhancement":{"color":"a2eeef","name":"Enhancement","description":"New feature or request"},"Fork App":{"color":"af87c7","name":"Fork App","description":"Issues related to forking apps"},"Container Widget":{"color":"19AD0D","name":"Container Widget","description":"Container widget"},"Papercut":{"color":"B562F6","name":"Papercut","description":""},"Needs Design":{"color":"bfd4f2","name":"Needs Design","description":"needs design or changes to design"},"i18n":{"color":"1799b0","name":"i18n","description":"Represents issues that need to be tackled to handle internationalization"},"Rich Text Editor Widget":{"color":"f72cac","name":"Rich Text Editor Widget","description":""},"skip-changelog":{"color":"06086F","name":"skip-changelog","description":"Adding this label to a PR prevents it from being listed in the changelog"},"Low":{"color":"79e53b","name":"Low","description":"An issue that is neither critical nor breaks a user flow"},"potential-duplicate":{"color":"d3cb2e","name":"potential-duplicate","description":"This label marks issues that are potential duplicates of already open issues"},"Audio Widget":{"color":"447B9A","name":"Audio Widget","description":"Issues related to Audio Widget"},"Firestore":{"color":"8078b0","name":"Firestore","description":"Issues related to the firestore Integration"},"New Widget":{"color":"be4cf2","name":"New Widget","description":"A request for a new widget"},"Modal Widget":{"color":"03846f","name":"Modal Widget","description":""},"UX Improvement":{"color":"f4a089","name":"UX Improvement","description":""},"S3":{"color":"8078b0","name":"S3","description":"Issues related to the S3 plugin"},"Release Blocker":{"color":"5756bf","name":"Release Blocker","description":"This issue must be resolved before the release"},"safari":{"color":"51C6AA","name":"safari","description":"Bugs seen on safari browser"},"Example Apps":{"color":"1799b0","name":"Example Apps","description":"Example apps created for new signups"},"MultiSelect Widget":{"color":"AB62D4","name":"MultiSelect Widget","description":"Issues related to MultiSelect Widget"},"Calendar Widget":{"color":"8c6644","name":"Calendar Widget","description":""},"Website":{"color":"151720","name":"Website","description":"Related to www.appsmith.com website"},"Low effort":{"color":"8B59F0","name":"Low effort","description":"Something that'll take a few days to build"},"Checkbox Widget":{"color":"bbeecd","name":"Checkbox Widget","description":""},"Spam":{"color":"620faf","name":"Spam","description":""},"Voice Recorder Widget":{"color":"85bc87","name":"Voice Recorder Widget","description":""},"Select Widget":{"color":"0c669e","name":"Select Widget","description":"Select or dropdown widget"},"Bug":{"color":"8ba6fd","name":"Bug","description":"Something isn't right"},"Widget Validation":{"color":"6990BC","name":"Widget Validation","description":"Issues related to widget property validation"},"Generate Page":{"color":"2b4664","name":"Generate Page","description":"Issures related to page generation"},"File Picker Widget":{"color":"6ae4f2","name":"File Picker Widget","description":""},"snowflake":{"color":"8078b0","name":"snowflake","description":"Issues related to the snowflake Integration"},"Automation":{"color":"CCAF60","name":"Automation","description":""},"hotfix":{"color":"BA3F1D","name":"hotfix","description":""},"Import-Export-App":{"color":"48883f","name":"Import-Export-App","description":"Issues related to importing and exporting apps"},"High effort":{"color":"A7E87B","name":"High effort","description":"Something that'll take more than a month to build"},"Telemetry":{"color":"bc70f9","name":"Telemetry","description":"Issues related to instrumenting appsmith"},"Radio Widget":{"color":"91ef15","name":"Radio Widget","description":""},"Omnibar":{"color":"1bb96a","name":"Omnibar","description":"Issues related to the omnibar for navigation"},"Button Widget":{"color":"34efae","name":"Button Widget","description":""},"Switch widget":{"color":"33A8CE","name":"Switch widget","description":"The switch widget"},"Map Widget":{"color":"7eef7a","name":"Map Widget","description":""},"Task":{"color":"085630","name":"Task","description":"A simple Todo"},"Design System":{"color":"2958a4","name":"Design System","description":"Design system"},"opera":{"color":"C63F5B","name":"opera","description":"Any issues identified on the opera browser"},"Login / Signup":{"color":"","name":"Login / Signup","description":"Authentication flows"},"Image Widget":{"color":"8de8ad","name":"Image Widget","description":""},"firefox":{"color":"6d56e2","name":"firefox","description":""},"Property Pane":{"color":"b356ff","name":"Property Pane","description":"Issues related to the behaviour of the property pane"},"Deployment":{"color":"93491f","name":"Deployment","description":"Installation process of appsmith"},"Production":{"color":"b60205","name":"Production","description":""},"Dependencies":{"color":"0366d6","name":"Dependencies","description":"Pull requests that update a dependency file"},"Google Sheets":{"color":"8078b0","name":"Google Sheets","description":"Issues related to Google Sheets"},"Icon Button Widget":{"color":"D319CE","name":"Icon Button Widget","description":"Issues related to the icon button widget"},"Mongo":{"color":"8078b0","name":"Mongo","description":"Issues related to Mongo DB plugin"},"Documentation":{"color":"a8dff7","name":"Documentation","description":"Improvements or additions to documentation"},"TestGap":{"color":"","name":"TestGap","description":"Issues identified for test plan improvement"},"keyboard shortcut":{"color":"0688B6","name":"keyboard shortcut","description":""},"Reopen":{"color":"897548","name":"Reopen","description":""},"Redshift":{"color":"8078b0","name":"Redshift","description":"Issues related to the redshift integration"},"Date Picker Widget":{"color":"ef1ce1","name":"Date Picker Widget","description":""},"Entity Explorer":{"color":"1bb96a","name":"Entity Explorer","description":"Issues related to navigation using the entity explorer"},"JS Linting & Errors":{"color":"E56AA5","name":"JS Linting & Errors","description":"Issues related to JS Linting and errors"},"iFrame":{"color":"3CD1DB","name":"iFrame","description":"Issues related to iFrame"},"Stale":{"color":"ededed","name":"Stale","description":null},"Text Widget":{"color":"d130d1","name":"Text Widget","description":""},"Video Widget":{"color":"23dd4b","name":"Video Widget","description":""},"Datasources":{"color":"3d590f","name":"Datasources","description":"Issues related to configuring datasource on appsmith"},"error":{"color":"B66773","name":"error","description":"All issues connected to error messages"},"Form Widget":{"color":"09ed77","name":"Form Widget","description":""},"Needs Triaging":{"color":"e8b851","name":"Needs Triaging","description":"Needs attention from maintainers to triage"},"Autocomplete":{"color":"235708","name":"Autocomplete","description":"Issues related to the autocomplete"},"hacktoberfest":{"color":"0052cc","name":"hacktoberfest","description":"All issues that can be solved by the community during Hacktoberfest"},"Medium effort":{"color":"D31156","name":"Medium effort","description":"Something that'll take more than a week but less than a month to build"},"Release":{"color":"57e5e0","name":"Release","description":""},"High":{"color":"c94d14","name":"High","description":"This issue blocks a user from building or impacts a lot of users"},"UI Performance":{"color":"1799b0","name":"UI Performance","description":"Issues related to UI performance"},"Deploy Preview":{"color":"bfdadc","name":"Deploy Preview","description":"Issues found in Deploy Preview"},"Needs Tests":{"color":"8ee263","name":"Needs Tests","description":"Needs automated tests to assert a feature/bug fix"},"Refactor":{"color":"B96662","name":"Refactor","description":"needs refactoring of code"},"Divider Widget":{"color":"235708","name":"Divider Widget","description":"Issues related to the divider widget"},"Table Widget":{"color":"2eead1","name":"Table Widget","description":""},"Needs More Info":{"color":"e54c10","name":"Needs More Info","description":"Needs additional information"},"Good First Issue":{"color":"7057ff","name":"Good First Issue","description":"Good for newcomers"},"UI Improvement":{"color":"9aeef4","name":"UI Improvement","description":""},"Backend":{"color":"d4c5f9","name":"Backend","description":"This marks the issue or pull request to reference server code"},"Frontend":{"color":"87c7f2","name":"Frontend","description":"This label marks the issue or pull request to reference client code"},"Chart Widget":{"color":"616ecc","name":"Chart Widget","description":""},"List Widget":{"color":"8508A0","name":"List Widget","description":"Issues related to the list widget"},"Duplicate":{"color":"cfd3d7","name":"Duplicate","description":"This issue or pull request already exists"},"JS Snippets":{"color":"8d62d2","name":"JS Snippets","description":"issues related to JS Snippets"},"Copy Paste":{"name":"Copy Paste","description":"Issues related to copy paste","color":"b4f0a9"},"Drag & Drop":{"name":"Drag & Drop","description":"Issues related to the drag & drop experience","color":"92115a"},"Sniping Mode":{"name":"Sniping Mode","description":"Issues related to sniping mode","color":"48883f"},"Redis":{"name":"Redis","description":"Issues related to Redis","color":"8078b0"},"New Datasource":{"color":"60b14c","name":"New Datasource","description":"Requests for new datasources"},"Evaluated Value":{"name":"Evaluated Value","description":"Issues related to evaluated values","color":"39f6e7"},"Undo/Redo":{"name":"Undo/Redo","description":"Issues related to undo/redo","color":"f25880"},"App Navigation":{"name":"App Navigation","description":"Issues related to the topbar navigation and configuring it","color":"4773ab"},"Widgets Pane":{"name":"Widgets Pane","description":"Issues related to the discovery and organisation of widgets","color":"ad5d78"},"View Mode":{"color":"1799b0","name":"View Mode","description":"Issues related to the view mode"},"Content":{"name":"Content","description":"For content related topics i.e blogs, templates, videos","color":"a8dff7"},"Slash Command":{"name":"Slash Command","description":"Issues related to the slash command","color":"a0608e"},"Widget Property":{"name":"Widget Property","description":"Issues related to adding / modifying widget properties across widgets","color":"5e92cb"},"Windows":{"name":"Windows","description":"Issues related exclusively to Windows systems","color":"b4cb8a"},"Old App Issues":{"name":"Old App Issues","description":"Issues related to apps old apps a few weeks old and app issues in stale browser session","color":"87ab18"},"Document Viewer Widget":{"name":"Document Viewer Widget","description":"Issues related to Document Viewer Widget","color":"899d4b"},"Radio Group Widget":{"name":"Radio Group Widget","description":"Issues related to radio group widget","color":"b68495"},"Super Admin":{"name":"Super Admin","description":"Issues related to the super admin page","color":"aa95cf"},"Postgres":{"name":"Postgres","description":"Postgres related issues","color":"8078b0"},"New JS Function":{"name":"New JS Function","description":"Issues related to adding a JS Function","color":"8e8aa4"},"Cannot Reproduce Issue":{"color":"93c9cc","name":"Cannot Reproduce Issue","description":"Issues that cannot be reproduced"},"Widget Grouping":{"name":"Widget Grouping","description":"Issues related to Widget Grouping","color":"a49951"},"K8s":{"name":"K8s","description":"Kubernetes related issues","color":"5f318a"},"Docker":{"name":"Docker","description":"Issues related to docker","color":"89b808"},"Camera Widget":{"name":"Camera Widget","description":"Issues and enhancements related to camera widget","color":"e6038e"},"SAAS Plugins":{"name":"SAAS Plugins","description":"Issues related to SAAS Plugins","color":"80e18f"},"JS Promises":{"name":"JS Promises","description":"Issues related to promises","color":"d7771f"},"OnPageLoad":{"name":"OnPageLoad","description":"OnPageLoad issues on functions and queries","color":"2b4664"},"JS Usability":{"name":"JS Usability","description":"usability issues with JS editor and JS elsewhere","color":"a302b0"},"Currency Input Widget":{"name":"Currency Input Widget","description":"Issues related to currency input widget","color":"b2164f"},"TreeSelect":{"name":"TreeSelect","description":"Issues related to TreeSelect Widget","color":"a1633e"},"MultiTree Select Widget":{"name":"MultiTree Select Widget","description":"Issues related to MultiTree Select Widget","color":"a1633e"},"Welcome Screen":{"name":"Welcome Screen","description":"Issues related to the welcome screen","color":"48883f"},"Realtime Commenting":{"color":"a70b86","name":"Realtime Commenting","description":"In-app communication between teams"},"Phone Input Widget":{"name":"Phone Input Widget","description":"Issues related to the Phone Input widget","color":"a70b86"},"JSON Form":{"name":"JSON Form","description":"Issue / features related to the JSON form wiget","color":"46b209"},"All Widgets":{"name":"All Widgets","description":"Issues related to all widgets","color":"972b36"},"V1":{"name":"V1","description":"V1","color":"67ab2e"},"Reflow & Resize":{"name":"Reflow & Resize","description":"All issues related to reflow and resize experience","color":"748a13"},"SSO":{"name":"SSO","description":"Issues, requests and enhancements around Single sign-on.","color":""},"Multi User Realtime":{"name":"Multi User Realtime","description":"Issues related to multiple users using or editing an application","color":"e7b6ce"},"Ready for design":{"name":"Ready for design","description":"this issue is ready for design: it contains clear problem statements and other required information","color":"ebf442"},"Support":{"name":"Support","description":"Issues created by the A-force team to address user queries","color":"1740f3"},"Button Group widget":{"name":"Button Group widget","description":"Issue and enhancements related to the button group widget","color":"f17025"},"GraphQL Plugin":{"name":"GraphQL Plugin","description":"Issues related to GraphQL plugin","color":"8078b0"},"DevOps Pod":{"name":"DevOps Pod","description":"Issues related to devops","color":"d956c7"},"medium":{"name":"medium","description":"Issues that frustrate users due to poor UX","color":"23dfd9"},"ArangoDB":{"name":"ArangoDB","description":"Issues related to arangoDB","color":"8078b0"},"Code Refactoring":{"name":"Code Refactoring","description":"Issues related to code refactoring","color":"76310e"},"Progress bar widget":{"name":"Progress bar widget","description":"To track issues related to progress bar","color":"2d7abf"},"Audio Recorder Widget":{"name":"Audio Recorder Widget","description":"Issues related to Audio Recorder Widget","color":"9accef"},"Airtable":{"name":"Airtable","description":"Issues for Airtable","color":"60885f"},"Canvas / Grid":{"name":"Canvas / Grid","description":"Issues related to the canvas","color":"16b092"},"Email Config":{"name":"Email Config","description":"Issues related to configuring the email service","color":"2a21d1"},"CURL":{"name":"CURL","description":"Issues related to CURL impor","color":"60885f"},"Canvas Zooms":{"name":"Canvas Zooms","description":"Issues related to zooming the canvas","color":"e6038e"},"business":{"name":"business","description":"Features that will be a part of our business edition","color":"cd59eb"},"Action Pod":{"name":"Action Pod","description":"","color":"ee2e36"},"AutomationGap1":{"color":"a5e07c","name":"AutomationGap1","description":"Issues that needs automated tests"},"A-Force11":{"name":"A-Force11","description":"Issues raised by A-Force team","color":"d667b6"},"Business Edition":{"name":"Business Edition","description":"Features that will be a part of our business edition","color":"89bb6c"},"storeValue":{"name":"storeValue","description":"Issues related to the store value function","color":"5d3e66"},"DynamoDB":{"name":"DynamoDB","description":"Issues that are related to DynamoDB should have this label","color":"60885f"},"Backup & Restore":{"name":"Backup & Restore","description":"Issues related to backup and restore","color":"86874d"},"Billing":{"name":"Billing","description":"Billing infrastructure and flows for Business Edition and Trial users","color":"d2bc40"},"Datatype issue":{"name":"Datatype issue","description":"Issues that have risen because data types weren't handled","color":"cef66b"},"OAuth":{"name":"OAuth","description":"OAuth related bugs or features","color":"60885f"},"Table Widget V2":{"name":"Table Widget V2","description":"Issues related to Table Widget V2","color":"3a7192"},"IDE Navigation":{"name":"IDE Navigation","description":"Issues/feature requests related to IDE navigation, and context switching","color":"1bb96a"},"Query performance":{"name":"Query performance","description":"Issues that have to do with lack in performance of query execution","color":"cef66b"},"SAAS Manager App":{"name":"SAAS Manager App","description":"Issues with the SAAS manager app","color":"d427db"},"Twilio":{"name":"Twilio","description":"Issues related to Twilio integration","color":"23ba8d"},"Hubspot":{"name":"Hubspot","description":"Issues related to Hubspot integration","color":"60885f"},"Zendesk":{"name":"Zendesk","description":"Issues related to Zendesk integration","color":"60885f"},"Entity Refactor":{"name":"Entity Refactor","description":"Issues related to refactor logic","color":"705a2c"},"Map Chart Widget":{"name":"Map Chart Widget","description":"Issues related to Map Chart Widgets","color":"c8397f"},"Product Catchup":{"name":"Product Catchup","description":"Issues created in the product catchup","color":"29cd2c"},"Framework Functions":{"name":"Framework Functions","description":"Issues related to internal functions like showAlert(), navigateTo() etc...","color":"c25a09"},"Frontend Libraries Upgrade":{"name":"Frontend Libraries Upgrade","description":"Issues related to frontend libraries upgrade","color":"ede1fc"},"MsSQL":{"name":"MsSQL","description":"Issues related to MsSQL plugin","color":"8078b0"},"Elastic Search":{"name":"Elastic Search","description":"Issues related to the elastic search datasource","color":"8078b0"},"Core Query Execution":{"color":"cef66b","name":"Core Query Execution","description":"Issues related to the execution of all queries"},"Query Management":{"name":"Query Management","description":"Issues related to the CRUD of actions or queries","color":"cef66b"},"Query Settings":{"name":"Query Settings","description":"Issues related to the settings of all queries","color":"cef66b"},"Code Editor":{"name":"Code Editor","description":"Issues related to the code editor","color":"4ca16e"},"Query Forms":{"color":"12b253","name":"Query Forms","description":"Isuses related to the query forms"},"JS Objects":{"color":"22962c","name":"JS Objects","description":"Issues related to JS Objects"},"JS Evaluation":{"color":"22962c","name":"JS Evaluation","description":"Issues related to JS evaluation on the platform"},"SmartSubstitution":{"name":"SmartSubstitution","description":"Issues related to Smart substitution of mustache bindings in queries","color":"bae511"},"Query Generation":{"name":"Query Generation","description":"Issues related to query generation","color":"cef66b"},"Suggested Widgets":{"name":"Suggested Widgets","description":"Issues related to suggesting widgets based on query response","color":"6ac063"},"Code Scanner Widget":{"name":"Code Scanner Widget","description":"Issues related to code scanner widget","color":"9bc1a0"},"Clean URLs":{"name":"Clean URLs","description":"Issues related to clean URLs epic","color":"112623"},"Widget keyboard accessibility":{"name":"Widget keyboard accessibility","description":"All issues related to keyboard accessibility in widgets","color":"b626fd"},"Connection pool":{"name":"Connection pool","description":"issues to do with connection pooling of various plugins","color":"94fe36"},"List Widget V2":{"name":"List Widget V2","description":"Issues related to the list widget v2","color":"adaaf7"},"Auto Height":{"name":"Auto Height","description":"Issues related to dynamic height of widgets","color":"5149cf"},"cypress_failed_test":{"name":"cypress_failed_test","description":"Cypress failed tests","color":"4745d5"},"Needs validation":{"name":"Needs validation","description":"Needs problem validation before being picked up","color":"66673d"},"Slider Widget":{"name":"Slider Widget","description":"Issues raised for slider widgets.","color":"2eef5f"},"Multitenancy":{"name":"Multitenancy","description":"Support multitenancy within single appsmith instance","color":"8c49a9"},"Conversion Algorithm":{"name":"Conversion Algorithm","description":"All issue related to converting app from fixed to flex mode & vice versa","color":"d12d2e"},"Browser specific":{"name":"Browser specific","description":"All issue related to browser","color":"d12d2e"},"Performance infra":{"name":"Performance infra","description":"all issue related to the performance infra","color":"8a60f6"},"DSL Update":{"name":"DSL Update","description":"Issues related to storing and updating the DSL","color":"e16cf3"},"AST-frontend":{"name":"AST-frontend","description":"Issues related to maintaining AST logic","color":"2b4664"},"AST-backend":{"name":"AST-backend","description":"Backend issues related to AST parsing","color":"48883f"},"MariaDB":{"name":"MariaDB","description":"MariaDB datasource","color":"8428c3"},"ADS Component Issue":{"name":"ADS Component Issue","description":"Issues which are caused due to ADS components","color":"d89119"},"Regressed":{"color":"723fd0","name":"Regressed","description":"Scenarios that were working before but have now regressed"},"Needs RCA":{"name":"Needs RCA","description":"a critical or high priority issue that needs an RCA","color":"2cc68f"},"Custom JS Libraries":{"name":"Custom JS Libraries","description":"Issues related to adding custom JS library","color":"bacb6d"},"Integrations Pod General":{"name":"Integrations Pod General","description":"Issues related to the Integrations Pod that don't fit into other tags.","color":"287823"},"Performance Pod":{"name":"Performance Pod","description":"All things related to Appsmith performance","color":"b5a25d"},"Performance":{"name":"Performance","description":"Issues related to performance","color":"9a18d7"},"File upload issues":{"name":"File upload issues","description":"Issues related to uploading any type of files from within Appsmith","color":"2b4664"},"Action Selector":{"name":"Action Selector","description":"Issues related to action selector on the property pane","color":"2f9e20"},"Community Reported":{"name":"Community Reported","description":"issues reported by community members","color":"1402e5"},"JS Function execution":{"name":"JS Function execution","description":"JS function execution","color":"7c2de1"},"Self Serve":{"name":"Self Serve","description":"For all issues related to self-serve flow for business edition","color":"4dacfc"},"Self Serve 1.0":{"name":"Self Serve 1.0","description":"For all issues related to v1 of the self serve project","color":"ae839e"},"Customer Portal":{"name":"Customer Portal","description":"For all tasks/issues pertaining to customer.appsmith.com","color":"d2bc40"},"Cloud Services":{"name":"Cloud Services","description":"For all tasks/issues on Appsmith cloud-services relating to licensing, usage and billing","color":"d2bc40"},"One-click Binding":{"name":"One-click Binding","description":"Issues related to the One click binding epic","color":"f1661c"},"Airgap":{"name":"Airgap","description":"Tickets related to supporting air-gapped Appsmith instances","color":"1cb294"},"SMTP plugin":{"name":"SMTP plugin","description":"Issues related to SMTP plugin","color":"541457"},"AWS AMI":{"name":"AWS AMI","description":"Issues Related to AWS AMI","color":"b44680"},"Old widget version":{"name":"Old widget version","description":"Use this label to raise issue specific only to an older version of a widget","color":"ff3814"},"Enterprise Billing":{"name":"Enterprise Billing","description":"To track all tasks/issues related to licensing & billing for enterprise customers","color":"14c156"},"Oracle SQL DB":{"name":"Oracle SQL DB","description":"Issues related to the Oracle plugin","color":"cbabcb"},"Community Contributor":{"name":"Community Contributor","description":"Meant to track issues that are assigned to external contributors","color":"149ab6"},"widget vertical alignment":{"name":"widget vertical alignment","description":"All issue related widget vertical alignment on the auto layout canvas","color":"d12d2e"},"Observability":{"name":"Observability","description":"Issues related to observability on the Appsmith instance","color":"dff913"},"Checkbox Component":{"name":"Checkbox Component","description":"This labels deals with checkbox component in wds package","color":"75a401"},"Analytics Improvements":{"name":"Analytics Improvements","description":"For all tasks focused on improving our overall analytics and fixing any issues ","color":"29b8ed"},"WDS team":{"name":"WDS team","description":"","color":"8d675a"},"Enterprise Edition":{"name":"Enterprise Edition","description":"Features that will be supported in Enterprise Edition only","color":"984f5e"},"Query filter":{"name":"Query filter","description":"Issues related to query filtering, e.g., WHERE clause","color":"a15134"},"Keyboard accessibility ":{"name":"Keyboard accessibility ","description":"All issue related to ADS component keyboard accessibility","color":"2ba696"},"Toggle button":{"name":"Toggle button","description":"All issue related to ADS toggle button","color":"edc47f"},"SCIM":{"name":"SCIM","description":"Label to collate our SCIM issues","color":"48883f"},"ADS Category Token":{"name":"ADS Category Token","description":"All issues related appsmith design system category tokens","color":"920961"},"ADS Component Documentation":{"name":"ADS Component Documentation","description":"All issues Appsmith design system component documentation","color":"64c46a"},"ADS Migration":{"name":"ADS Migration","description":"All issues related to Appsmith design system migration","color":"b082d6"},"ADS Deduplication ":{"name":"ADS Deduplication ","description":"Replacing component with ADS components","color":"b082d6"},"ADS Revamp":{"name":"ADS Revamp","description":"All issues related to ads revamp. ","color":"b082d6"},"ADS Deduplication":{"name":"ADS Deduplication","description":"Replacing component with ADS components","color":"b082d6"},"ADS Grayscale":{"name":"ADS Grayscale","description":"Support grayscale color changes","color":"b03577"},"ADS Unit Test":{"name":"ADS Unit Test","description":"All issue related ads unit cases ","color":"b082d6"},"ADS Components":{"name":"ADS Components","description":"All issues related ADS components","color":"b082d6"},"Widget Discoverability":{"name":"Widget Discoverability","description":"Issues related to Widget Discoverability","color":"7b55ce"},"Widget setter method":{"name":"Widget setter method","description":"Issues with widget property setters","color":"8dce87"},"License":{"name":"License","description":"For all issues/tasks related to licensing of appsmith-ee edition","color":"90ee98"},"Platformization":{"name":"Platformization","description":"Issues or tasks related to platformization of Appsmith codebase","color":"4e972b"},"Activation - datasources":{"name":"Activation - datasources","description":"issues related to activation projects","color":"7c7ace"},"Partial-import-export":{"name":"Partial-import-export","description":"Label for granular reusability.","color":"717732"},"AI":{"name":"AI","description":"All tasks related to AI","color":"2b4664"},"ADS Typography":{"name":"ADS Typography","description":"All issue related typographical changes","color":"2dbe8d"},"Auto Layout":{"name":"Auto Layout","description":"Issues relates to auto layout","color":"92cf8c"},"Heroku":{"name":"Heroku","description":"Issues related to Heroku","color":"a81b69"},"ADS Visual Styles":{"name":"ADS Visual Styles","description":"All issues related to ADS visual styles","color":"d3da89"},"ADS Component Design":{"name":"ADS Component Design","description":"All issue related to component design","color":"5cc91e"},"Modal Component":{"name":"Modal Component","description":"All issue related to ads modal component","color":"ee63f3"},"App setting":{"name":"App setting","description":"Related to app settings panel within the app","color":"174f98"},"BE instance":{"name":"BE instance","description":"For all issues related to license, billing on BE instance","color":"ae8f98"},"Fixed layout":{"name":"Fixed layout","description":"issues related to fixed layout","color":"b66681"},"Anvil layout":{"name":"Anvil layout","description":"issues related to the new layout system anvil","color":"5e0904"},"New Deployment Mode":{"name":"New Deployment Mode","description":"Support a new mode of deployment","color":"108033"},"Custom widgets":{"name":"Custom widgets","description":"For all issues related to the custom widget project","color":"c9db9c"},"Homepage Experience V2":{"name":"Homepage Experience V2","description":"Label for reporting new tasks and bug fixes related to revamped homepage experience","color":"c55d54"},"Customer Success":{"name":"Customer Success","description":"Issues that the success team cares about","color":"6ccabd"},"Invite flow":{"name":"Invite flow","description":"Invite users flow and any associated actions","color":"881b35"},"Invite users":{"name":"Invite users","description":"Invite users flow and any associated actions","color":""},"Workflows Pod":{"name":"Workflows Pod","description":"Issues that the workflows team owns","color":"446925"},"DailyPromotionBlocker":{"name":"DailyPromotionBlocker","description":"DailyPromotion Blocker","color":"9b2280"},"JS Binding":{"name":"JS Binding","description":"All issues related to the JS Binding experience","color":"422fed"},"REST API":{"name":"REST API","description":"REST API plugin related issues","color":"e3ede5"},"Critical":{"color":"a1e3db","name":"Critical","description":"This issue breaks existing apps. Drop everything else to resolve"},"Module creator":{"name":"Module creator","description":"Issues related to the module creator side","color":"bb2c05"},"Module consumer":{"name":"Module consumer","description":"Issues related to the module consumer side","color":"83d3c5"},"Package versioning":{"name":"Package versioning","description":"ISsues related to how we manage versions for packages","color":"4c5218"},"Convert to module":{"name":"Convert to module","description":"Issues related to the module creation flow using conversion","color":"4c5218"},"Query module":{"name":"Query module","description":"Issues affecting query modules or its instances","color":"b11a7e"},"JS module":{"name":"JS module","description":"Issues affecting JS modules or its instances","color":"bf76f6"},"Secret Management":{"name":"Secret Management","description":"Issues related to secret management","color":"2b4664"},"REST API plugin":{"name":"REST API plugin","description":"REST API plugin related issues","color":"b5948a"},"UI module":{"name":"UI module","description":"Issues affecting UI modules or its instances","color":"d2acee"},"Preview mode":{"name":"Preview mode","description":"Issues related to app previews","color":"48883f"},"Git Auto-commit":{"name":"Git Auto-commit","description":"Issues related to autocommit","color":"717732"},"QA Pod":{"name":"QA Pod","description":"Issues under the QA Pod","color":"717732"},"Automation Test":{"name":"Automation Test","description":"","color":""},"Automation failures":{"name":"Automation failures","description":"","color":""},"Needs automation":{"name":"Needs automation","description":"Issues that needs automated tests","color":""},"Prepared statements":{"name":"Prepared statements","description":"Issues related to prepared statement flow","color":""},"Switch Group Widget":{"name":"Switch Group Widget","description":"Issues related to Switch group Widget","color":""},"Supervisor":{"name":"Supervisor","description":"Issues related to supervisor","color":"2c5813"},"Deployment Certificates":{"name":"Deployment Certificates","description":"Issues related to lets encrypt","color":"e148aa"},"Mock Data":{"name":"Mock Data","description":"Issues related to mock databases","color":"ebf251"},"AWS ECS":{"name":"AWS ECS","description":"Issues related to ECS Fargate","color":"e506ff"},"Publish App":{"name":"Publish App","description":"Issues related to app deployment","color":"2b4664"},"IDE Infra":{"name":"IDE Infra","description":"Issues related to the IDE infrastructure like saving changes","color":"1bb96a"},"User Profile":{"name":"User Profile","description":"Issues related to a user profile","color":"a60d34"},"Page Management":{"color":"1bb96a","name":"Page Management","description":"Issues related to configuring pages"},"Ingress":{"name":"Ingress","description":"Ingress Controller","color":"a86802"},"Nginx":{"name":"Nginx","description":"Issues related to Nginx","color":"e54195"},"Building blocks":{"name":"Building blocks","description":"Building blocks on cavas, on templates listing or drag and drop of building blocks.","color":"48883f"},"Table Inline Edit":{"name":"Table Inline Edit","description":"Issues related to inline editing","color":"60895a"},"User Session ":{"name":"User Session ","description":"For all issues/tasks related to user sessions","color":"65a3f5"},"WDS - all widgets":{"name":"WDS - all widgets","description":"all widget present in WDS","color":"2670ae"},"WDS - input widget":{"name":"WDS - input widget","description":"Issues related to input widget on WDS","color":"2670ae"},"WDS - paragraph widget":{"name":"WDS - paragraph widget","description":"issues related to paragraph widget on WDS","color":"2670ae"},"WDS - statbox widget":{"name":"WDS - statbox widget","description":"issues related to statbox widget on WDS","color":"2670ae"},"WDS - modal widget":{"name":"WDS - modal widget","description":"Issues related to modal widget on WDS","color":"2670ae"},"WDS - icon widget":{"name":"WDS - icon widget","description":"Issues related to icon widget on WDS","color":"2670ae"},"WDS - checkbox widget":{"name":"WDS - checkbox widget","description":"Issues related to checkbox widget on WDS","color":"2670ae"},"WDS - table widget":{"name":"WDS - table widget","description":"Issues related to table widget on WDS","color":"2670ae"},"WDS - keyValue widget":{"name":"WDS - keyValue widget","description":"Issues related to key-value widget on WDS","color":"2670ae"},"WDS - switch group widget":{"name":"WDS - switch group widget","description":"Issues related to switch group widget on WDS","color":"2670ae"},"WDS - theming":{"name":"WDS - theming","description":"Issues related to theming on the Anvil instance","color":"2670ae"},"Anvil POD":{"name":"Anvil POD","description":"Issue related to Anvil project","color":"5e0904"},"Anvil - theming":{"name":"Anvil - theming","description":"Issues related to theming on the Anvil instance","color":"c28de5"},"Anvil - vertical alignment":{"name":"Anvil - vertical alignment","description":"Issues related to vertical alignment on the Anvil layout","color":"c28de5"},"Anvil - layout component":{"name":"Anvil - layout component","description":"Issues related to layout component on the Anvil layout","color":"c28de5"},"Anvil - drag & drop":{"name":"Anvil - drag & drop","description":"Issues related to drag & drop experience on Anvil","color":"c28de5"},"Anvil - zones & sections":{"name":"Anvil - zones & sections","description":"Issues related to zones and sections on the Anvil layout","color":"c28de5"},"Anvil - copy paste experience":{"name":"Anvil - copy paste experience","description":"Issues related to copy paste experience on the Anvil layout","color":"c28de5"},"WDS - phone widget":{"name":"WDS - phone widget","description":"Issues related to phone widget on WDS","color":"c28de5"},"WDS - responsive widget":{"name":"WDS - responsive widget","description":"All issues related to widget responsiveness","color":"11ee05"},"Anvil - responsive viewport":{"color":"11ee05","name":"Anvil - responsive viewport","description":"Issues seen on different viewports like mobile"},"WDS - widget styling":{"color":"11ee05","name":"WDS - widget styling","description":"all about widget styling"},"Anvil - spacing":{"name":"Anvil - spacing","description":"Related to spacing between widgets in auto layout","color":"11ee05"},"Anvil - responsive canvas":{"name":"Anvil - responsive canvas","description":"All issues related to canvas responsiveness","color":"11ee05"},"WDS - inline button widget":{"name":"WDS - inline button widget","description":"Issues related to inline button widget on WDS","color":"7cef83"},"Activation Pod":{"name":"Activation Pod","description":"for Activation group","color":"d67d00"},"Activation":{"name":"Activation","description":"for Activation group","color":"d67d00"},"Tests":{"name":"Tests","description":"Test issues","color":"4fc7b6"},"Ballpark: XXS":{"name":"Ballpark: XXS","description":"~1xDev in 1/2xSprint","color":""},"Ballpark: XS":{"name":"Ballpark: XS","description":"~1xDev in 1xSprint","color":"53bf71"},"Ballpark: S":{"name":"Ballpark: S","description":"~2xDev in 1xSprint","color":"6e9e65"},"Ballpark: M":{"name":"Ballpark: M","description":"~1xPOD in 1xSprint","color":"2229e6"},"Ballpark: L":{"name":"Ballpark: L","description":"~1xPOD in 3xSprint or 2xPODs in 1xSprint","color":"49962f"},"Ballpark: XL":{"name":"Ballpark: XL","description":"~1xPOD in 1xQuarter or 2xPODs in 2xSprint","color":"b524c9"},"Ballpark: XXL":{"name":"Ballpark: XXL","description":"~2xPODs in 1xQuarter","color":"22092c"},"Auto-commit":{"name":"Auto-commit","description":"Issues related to auto-generated commits showing up on git ","color":"e25b89"},"Continuous Deployment":{"name":"Continuous Deployment","description":"Issues related to CD pipeline on git","color":"aea47c"},"Default branch":{"name":"Default branch","description":"Issues related to using a default branch on git","color":"195737"},"Git status":{"name":"Git status","description":"Issues related to information shown on git status modal or number of changes appearing in a branch","color":"c851b8"},"Git performance":{"name":"Git performance","description":"Issues related to perceived performance on any git operation","color":"189af6"},"Anvil team":{"name":"Anvil team","description":"issues related to the new layout system anvil","color":"798200"},"SDLC":{"name":"SDLC","description":"Issues related to software development lifecycle experiences","color":"bae511"},"Reconnect DS modal":{"name":"Reconnect DS modal","description":"Issues related to reconnect datasource modal post app import","color":"2e398b"},"Stability Pod":{"name":"Stability Pod","description":"For all issues/tasks to be prioritized under Stability pod","color":"86ddf6"},"Stability Issue":{"name":"Stability Issue","description":"Every issue handle by Stability Pod","color":"4d024a"},"Move to Postgres":{"name":"Move to Postgres","description":"Issues required to be solved for the move to Postgres as repository layer","color":"4e13ac"},"User Session":{"name":"User Session","description":"Issues related to user sessions","color":"8255e5"},"IDE tabs":{"name":"IDE tabs","description":"query and js tabs","color":"1bb96a"},"Inviting Contribution":{"name":"Inviting Contribution","description":"Issues that we would like contributions to","color":""},"cypress-flaky-fix":{"name":"cypress-flaky-fix","description":"This label is auto-added when a PR which only has Cypress fixes are merged to release","color":"722cbc"},"Cypress flaky tests":{"name":"Cypress flaky tests","description":"Test scripts that need to be fixed on Cypress by dev or SDET","color":"722cbc"},"Help enterprise":{"name":"Help enterprise","description":"Requested by Appsmith customers or prospects","color":"FF8C00"},"Learnability":{"name":"Learnability","description":"Issues affecting the product learnability, making the product harder for new users.","color":"800c2f"},"ADS Spacing":{"name":"ADS Spacing","description":"","color":"686ebb"},"ads unit test":{"name":"ads unit test","description":"All issue related ads unit cases","color":"686ebb"},"ads revamp":{"name":"ads revamp","description":"All issues related to ads revamp.","color":"686ebb"},"Javascript Product":{"color":"709a21","name":"Javascript Product","description":"Issues related to users writing javascript in appsmith"},"IDE Product":{"color":"1bb96a","name":"IDE Product","description":"Issues related to the IDE Product"},"IDE Pod":{"color":"1bb96a","name":"IDE Pod","description":"Issues that new developers face while exploring the IDE"},"Accelerators Product":{"name":"Accelerators Product","description":"Issues related to app building accelerators","color":"f3fce6"},"Templates Product":{"name":"Templates Product","description":"Issues related to Templates","color":"f3fce6"},"Design System Product":{"name":"Design System Product","description":"Appsmith design system related issues","color":"2b4664"},"ads deduplication":{"name":"ads deduplication","description":"Replacing component with ADS components","color":"708943"},"Admin Settings Product":{"color":"708943","name":"Admin Settings Product","description":"Issues in admin settings pages"},"Appsmith AI":{"name":"Appsmith AI","description":"All issues related to the Appsmith AI datasource","color":"708943"},"Query & JS Pod":{"color":"709a21","name":"Query & JS Pod","description":"Issues related to the query & JS Pod"},"RBAC Product":{"name":"RBAC Product","description":"Issues, requests and enhancements around RBAC.","color":""},"Workspace Product":{"name":"Workspace Product","description":"Issues related to workspaces","color":""},"CE Instance Usage":{"name":"CE Instance Usage","description":"For all issues relating to usage, licensing or billing on the CE instance","color":""},"Billing & Licensing Product":{"name":"Billing & Licensing Product","description":"Issues pertaining to licensing, billing and usage across self serve and enterprise customers","color":"446925"},"Platform Administration Pod":{"color":"446925","name":"Platform Administration Pod","description":"Issues related to platform administration & management"},"DB Infrastructure Pod":{"name":"DB Infrastructure Pod","description":"Pod to handle database infrastructure","color":"446925"},"Packages Product":{"name":"Packages Product","description":"Issues related to packages","color":"446925"},"Workflows Product":{"name":"Workflows Product","description":"Issues related to the workflows product","color":"446925"},"Debugger Product":{"color":"857f58","name":"Debugger Product","description":"Issues related to the debugger"},"Packages Pod":{"name":"Packages Pod","description":"issues that belong to the packages pod","color":"857f58"},"Environments Product":{"name":"Environments Product","description":"Issues related to datasource environments","color":"857f58"},"Custom Widgets":{"name":"Custom Widgets","description":"For all issues related to the custom widget project","color":"857f58"},"Branding Product":{"name":"Branding Product","description":"All issues under branding and whitelabelling appsmith ecosystem","color":"857f58"},"Widgets & Accelerators Pod":{"name":"Widgets & Accelerators Pod","description":"Issues related to widgets & Accelerators","color":"27496a"},"Widgets Product":{"name":"Widgets Product","description":"This label groups issues related to widgets","color":"f3fce6"},"App Theming Product":{"name":"App Theming Product","description":"Items that are related to the App level theming controls epic","color":"48883f"},"UI Building Product":{"color":"48883f","name":"UI Building Product","description":"Issues related to the UI Building experience"},"Onboarding Product":{"color":"48883f","name":"Onboarding Product","description":"Issues related to onboarding new developers"},"Database Schema":{"name":"Database Schema","description":"Issues related to database schema","color":"48883f"},"Git Product":{"color":"48883f","name":"Git Product","description":"Issues related to version control product"},"Git Platform Pod":{"name":"Git Platform Pod","description":"Issues related to the git & the app platform ","color":"48883f"},"Embedding Apps Product":{"name":"Embedding Apps Product","description":"Issues related to embedding","color":"48883f"},"Integrations Product":{"name":"Integrations Product","description":"Issues related to a specific integration","color":"b9f21c"},"Feature Flagging":{"name":"Feature Flagging","description":"Anything related feature flagging","color":"4574ae"},"Audit Logs Product":{"name":"Audit Logs Product","description":"Audit trails to ensure data security","color":"4574ae"},"Identity & Authentication Product":{"name":"Identity & Authentication Product","description":"Issues related to user identity & authentication","color":"4574ae"},"Email verification":{"name":"Email verification","description":"Email verification issues","color":"4574ae"},"Artifact Platform Product":{"name":"Artifact Platform Product","description":"Issues related to the application platform","color":"4574ae"},"Git IA":{"name":"Git IA","description":"Issues related to Git IA changes","color":"df8bd6"},"Documentation Pod":{"name":"Documentation Pod","description":"Issues related to user education","color":"8c8c02"},"Branch management":{"name":"Branch management","description":"Issues related to using a branch management on git","color":"ebe6af"}},"success":true} \ No newline at end of file diff --git a/.github/workflows/build-client-server-count.yml b/.github/workflows/build-client-server-count.yml index 7f2210f32063..c15a92947b0c 100644 --- a/.github/workflows/build-client-server-count.yml +++ b/.github/workflows/build-client-server-count.yml @@ -149,6 +149,7 @@ jobs: with: pr: ${{fromJson(needs.file-check.outputs.pr)}} run_count: ${{fromJson(needs.file-check.outputs.run_count)}} + ci-test-limited-existing-docker-image: needs: [file-check] @@ -260,39 +261,62 @@ jobs: with: name: cypress-repeat-logs path: app/client + + - name: Download the ci_test_status + uses: actions/download-artifact@v4 + with: + name: ci_test_status + path: app/client - name: Read and Set File Content as ENV Variable id: set-summary-content run: | summary_content=$(cat app/client/cy-repeat-summary.txt | tr '\n' ' ') - echo "summary_content=$summary_content" >> $GITHUB_ENV + echo "summary_content=$summary_content" >> $GITHUB_ENV + + - name: Check CI Test Result + id: check-ci-test + run: | + # Check if the ci_test_failed flag is set + if [ -f app/client/ci_test_status.txt ]; then + if grep -q "ci_test_failed=true" app/client/ci_test_status.txt; then + echo "Tests failed. Please review the test results." + echo "ci_test_failed=true" >> $GITHUB_ENV + else + echo "Tests passed." + echo "ci_test_failed=false" >> $GITHUB_ENV + fi + else + echo "ci_test_status.txt file not found." + echo "ci_test_failed=unknown" >> $GITHUB_ENV + fi - name: Add a comment on the PR with new CI failures - if: needs.ci-test-limited.result != 'success' && needs.file-check.outputs.pr != '0' + if: env.ci_test_failed != 'true' && needs.file-check.outputs.pr != '0' uses: peter-evans/create-or-update-comment@v3 with: issue-number: ${{fromJson(needs.file-check.outputs.pr)}} body: | - Workflow run: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>. - Cypress dashboard: Click here! - The following are new failures, please fix them before merging the PR: ${{env.new_failed_spec_env}} - To know the list of identified flaky tests - Refer here - ``` - ${{ env.summary_content }} - ``` - - - name: Add a comment on the PR when ci-test-limited is success - if: needs.ci-test-limited.result == 'success' && needs.file-check.outputs.pr != '0' + Workflow run: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>. + Cypress dashboard: Click here! + The following are new failures, please fix them before merging the PR: ${{env.new_failed_spec_env}} + To know the list of identified flaky tests - Refer here + ``` + ${{ env.summary_content }} + ``` + + - name: Add a comment on the PR when ci-test-limited is successful + if: env.ci_test_failed == 'true' && needs.file-check.outputs.pr != '0' uses: peter-evans/create-or-update-comment@v3 with: issue-number: ${{fromJson(needs.file-check.outputs.pr)}} body: | - Workflow run: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>. - Cypress dashboard url: Click here! - All cypress tests have passed 🎉🎉🎉 - ``` - ${{ env.summary_content }} - ``` + Workflow run: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>. + Cypress dashboard url: Click here! + All Cypress tests have passed 🎉🎉🎉 + ``` + ${{ env.summary_content }} + ``` - name: Check ci-test-limited set status if: needs.ci-test-limited.result != 'success' @@ -396,6 +420,12 @@ jobs: with: name: cypress-repeat-logs path: app/client + + - name: Download the ci_test_status + uses: actions/download-artifact@v4 + with: + name: ci_test_status + path: app/client - name: Read and Set File Content as ENV Variable id: set-summary-content @@ -403,9 +433,25 @@ jobs: summary_content=$(cat app/client/cy-repeat-summary.txt | tr '\n' ' ') echo "summary_content=$summary_content" >> $GITHUB_ENV + - name: Check CI Test Result + id: check-ci-test + run: | + # Check if the ci_test_failed flag is set + if [ -f app/client/ci_test_status.txt ]; then + if grep -q "ci_test_failed=true" app/client/ci_test_status.txt; then + echo "Tests failed. Please review the test results." + echo "ci_test_failed=true" >> $GITHUB_ENV + else + echo "Tests passed." + echo "ci_test_failed=false" >> $GITHUB_ENV + fi + else + echo "ci_test_status.txt file not found." + echo "ci_test_failed=unknown" >> $GITHUB_ENV + fi - name: Add a comment on the PR with new CI failures - if: needs.ci-test-limited-existing-docker-image.result != 'success' && needs.file-check.outputs.pr != '0' + if: env.ci_test_failed != 'true' && needs.file-check.outputs.pr != '0' uses: peter-evans/create-or-update-comment@v3 with: issue-number: ${{fromJson(needs.file-check.outputs.pr)}} @@ -419,7 +465,7 @@ jobs: ``` - name: Add a comment on the PR when ci-test-limited-existing-docker-image is success - if: needs.ci-test-limited-existing-docker-image.result == 'success' && needs.file-check.outputs.pr != '0' + if: env.ci_test_failed == 'true' && needs.file-check.outputs.pr != '0' uses: peter-evans/create-or-update-comment@v3 with: issue-number: ${{fromJson(needs.file-check.outputs.pr)}} diff --git a/.github/workflows/ci-test-limited-with-count.yml b/.github/workflows/ci-test-limited-with-count.yml index d6553309d0f2..65af0adfb198 100644 --- a/.github/workflows/ci-test-limited-with-count.yml +++ b/.github/workflows/ci-test-limited-with-count.yml @@ -349,8 +349,18 @@ jobs: npx cypress-repeat-pro run -n ${{ inputs.run_count }} --force \ --spec ${{ env.specs_to_run }} \ --config-file "cypress_ci_custom.config.ts" - cat cy-repeat-summary.txt - + cat cy-repeat-summary.txt + # Define the path for the failure flag file + FAILURE_FLAG_FILE="ci_test_status.txt" + + # Check for test results and store the status in the file + if ! grep -q "Total Failed: 0" cy-repeat-summary.txt; then + echo "ci_test_failed=true" > "$FAILURE_FLAG_FILE" + else + echo "ci_test_failed=false" > "$FAILURE_FLAG_FILE" + fi + cat "$FAILURE_FLAG_FILE" + - name: Trim number of cypress log files if: failure() run: | @@ -363,9 +373,17 @@ jobs: name: cypress-repeat-logs path: ${{ github.workspace }}/app/client/cy-repeat-summary.txt overwrite: true + + - name: Upload ci_test_status.txt artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: ci_test_status + path: ${{ github.workspace }}/app/client/ci_test_status.txt + overwrite: true - name: Upload failed test cypress logs artifact - if: failure() + if: always() uses: actions/upload-artifact@v4 with: name: cypress-console-logs @@ -381,7 +399,7 @@ jobs: overwrite: true - name: Collect CI container logs - if: failure() + if: always() working-directory: "." run: | mkdir -p ~/dockerlogs @@ -389,7 +407,7 @@ jobs: # Upload docker logs - name: Upload failed test list artifact - if: failure() + if: always() uses: actions/upload-artifact@v4 with: name: dockerlogs @@ -397,13 +415,13 @@ jobs: overwrite: true - name: Rename reports - if: failure() + if: always() run: | mkdir -p ~/results mv ${{ github.workspace }}/app/client/results ~/results - name: Upload cypress report - if: failure() + if: always() uses: actions/upload-artifact@v4 with: name: results-${{github.run_attempt}} @@ -412,13 +430,13 @@ jobs: # Set status = failedtest - name: Set fail if there are test failures - if: failure() + if: always() run: | echo "failedtest" > ~/run_result # Force store previous run result to cache - name: Store the previous run result - if: failure() + if: always() uses: actions/cache/save@v4 with: path: | @@ -428,7 +446,7 @@ jobs: # Upload the log artifact so that it can be used by the test & deploy job in the workflow - name: Upload server logs bundle on failure uses: actions/upload-artifact@v4 - if: failure() + if: always() with: name: server-logs path: app/server/server-logs.log diff --git a/.github/workflows/on-demand-build-docker-image-deploy-preview.yml b/.github/workflows/on-demand-build-docker-image-deploy-preview.yml index 69c3e6a0b911..44cce790ba30 100644 --- a/.github/workflows/on-demand-build-docker-image-deploy-preview.yml +++ b/.github/workflows/on-demand-build-docker-image-deploy-preview.yml @@ -118,6 +118,10 @@ jobs: push-image: needs: [client-build, rts-build, server-build] runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + if: success() steps: # Check out merge commit @@ -176,6 +180,9 @@ jobs: scripts/prepare_server_artifacts.sh fi + - name: Set up Depot CLI + uses: depot/setup-action@v1 + - name: Login to DockerHub uses: docker/login-action@v1 with: @@ -193,11 +200,12 @@ jobs: echo "base_tag=$base_tag" >> $GITHUB_OUTPUT - name: Push to Docker Hub - uses: docker/build-push-action@v4 + uses: depot/build-push-action@v1 with: context: . pull: true push: true + platforms: linux/arm64,linux/amd64 cache-from: ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-${{ vars.EDITION }}:release tags: | ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-dp:${{ vars.EDITION }}-${{ github.event.client_payload.pull_request.number }} diff --git a/CODEOWNERS b/CODEOWNERS index 03d957a9d9f7..f1ae93a1aae9 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -53,13 +53,11 @@ app/server/appsmith-server/src/test/java/com/appsmith/server/services/FeatureFla # UI Builders Pod app/client/generators/* @appsmithorg/anvil-team -app/client/src/actions/autoHeightActions.ts @appsmithorg/anvil-team -app/client/src/actions/autoLayoutActions.ts @appsmithorg/anvil-team app/client/src/actions/canvasSelectionActions.ts @appsmithorg/anvil-team app/client/src/actions/reflowActions.ts @appsmithorg/anvil-team app/client/src/actions/widgetSelectionActions.ts @appsmithorg/anvil-team app/client/src/components/propertyControls/* @appsmithorg/anvil-team -app/client/src/layoutSystems/* @appsmithorg/anvil-team +app/client/src/layoutSystems/anvil/* @appsmithorg/anvil-team app/client/src/pages/Editor/Canvas.tsx @appsmithorg/anvil-team app/client/src/pages/Editor/CanvasLayoutConversion/* @appsmithorg/anvil-team app/client/src/pages/Editor/PropertyPane/* @appsmithorg/anvil-team @@ -67,7 +65,6 @@ app/client/src/pages/Editor/WidgetsEditor/* @appsmithorg/anvil-team app/client/src/reducers/entityReducers/autoHeightReducers/* @appsmithorg/anvil-team app/client/src/reducers/entityReducers/canvasWidgetsReducer.ts @appsmithorg/anvil-team app/client/src/reflow/* @appsmithorg/anvil-team -app/client/src/sagas/AutoLayoutUpdateSagas.tsx @appsmithorg/anvil-team app/client/src/sagas/CanvasSagas/* @appsmithorg/anvil-team app/client/src/sagas/ReplaySaga.ts @appsmithorg/anvil-team app/client/src/sagas/SnapshotSagas.ts @appsmithorg/anvil-team @@ -78,14 +75,9 @@ app/client/src/sagas/WidgetOperationSagas.tsx @appsmithorg/anvil-team app/client/src/sagas/WidgetOperationUtils.ts @appsmithorg/anvil-team app/client/src/sagas/WidgetSelectUtils.ts @appsmithorg/anvil-team app/client/src/sagas/WidgetSelectionSagas.ts @appsmithorg/anvil-team -app/client/src/sagas/autoHeightSagas/* @appsmithorg/anvil-team app/client/src/sagas/layoutConversionSagas.ts @appsmithorg/anvil-team -app/client/src/selectors/autoHeightSelectors.ts @appsmithorg/anvil-team -app/client/src/selectors/autoLayoutSelectors.tsx @appsmithorg/anvil-team app/client/src/selectors/canvasSelectors.ts @appsmithorg/anvil-team app/client/src/selectors/widgetSelectors.ts @appsmithorg/anvil-team -app/client/src/utils/autoHeight/* @appsmithorg/anvil-team -app/client/src/utils/hooks/autoHeightUIHooks.ts @appsmithorg/anvil-team app/client/src/utils/hooks/useAllowEditorDragToSelect.ts @appsmithorg/anvil-team app/client/src/utils/hooks/useClickToSelectWidget.tsx @appsmithorg/anvil-team app/client/src/utils/hooks/useDynamicAppLayout.tsx @appsmithorg/anvil-team diff --git a/app/client/cypress.config.ts b/app/client/cypress.config.ts index 12603c6ad370..abe2c52c9fb1 100644 --- a/app/client/cypress.config.ts +++ b/app/client/cypress.config.ts @@ -1,4 +1,5 @@ import { defineConfig } from "cypress"; +import { addMatchImageSnapshotPlugin } from "@simonsmith/cypress-image-snapshot/plugin"; export default defineConfig({ watchForFileChanges: false, @@ -32,6 +33,7 @@ export default defineConfig({ grepOmitFiltered: true, }, setupNodeEvents(on, config) { + addMatchImageSnapshotPlugin(on); require("@cypress/grep/src/plugin")(config); require("./cypress/plugins/index.js")(on, config); return config; diff --git a/app/client/cypress/Dockerfile b/app/client/cypress/Dockerfile index 46183e9e9cf8..bfcc443f79f9 100644 --- a/app/client/cypress/Dockerfile +++ b/app/client/cypress/Dockerfile @@ -1,6 +1,6 @@ #ARG CHROME_VERSION="126.0.6478.114-1" ARG YARN_VERSION='1.22.22' -ARG NODE_VERSION='20.11.1' +ARG NODE_VERSION='20.13.1' ARG CYPRESS_VERSION='13.13.0' FROM cypress/factory:4.0.2 diff --git a/app/client/cypress/e2e/GSheet/AllAccess_Spec.ts b/app/client/cypress/e2e/GSheet/AllAccess_Spec.ts index 0f4ac2f2d2a1..aca3a5ab40df 100644 --- a/app/client/cypress/e2e/GSheet/AllAccess_Spec.ts +++ b/app/client/cypress/e2e/GSheet/AllAccess_Spec.ts @@ -15,7 +15,7 @@ const workspaceName = "gsheet apps"; const dataSourceName = "gsheet-all"; let appName = "gsheet-app"; let spreadSheetName = "test-sheet"; -describe( +describe.skip( "GSheet-Functional Tests With All Access", { tags: ["@tag.Datasource", "@tag.GSheet"] }, function () { diff --git a/app/client/cypress/e2e/GSheet/GsheetMisc_Spec.ts b/app/client/cypress/e2e/GSheet/GsheetMisc_Spec.ts index 479c3b65b52e..b54a27b257c2 100644 --- a/app/client/cypress/e2e/GSheet/GsheetMisc_Spec.ts +++ b/app/client/cypress/e2e/GSheet/GsheetMisc_Spec.ts @@ -21,7 +21,7 @@ const workspaceName = "gsheet apps"; const dataSourceName = "gsheet-all"; let appName = "gsheet-app"; let spreadSheetName = "test-sheet"; -describe( +describe.skip( "GSheet Miscellaneous Tests", { tags: ["@tag.Datasource", "@tag.GSheet"] }, function () { diff --git a/app/client/cypress/e2e/GSheet/ReadNWrite_Access_Spec.ts b/app/client/cypress/e2e/GSheet/ReadNWrite_Access_Spec.ts index 38bfcc82f85e..8d5a72c78b33 100644 --- a/app/client/cypress/e2e/GSheet/ReadNWrite_Access_Spec.ts +++ b/app/client/cypress/e2e/GSheet/ReadNWrite_Access_Spec.ts @@ -11,7 +11,7 @@ import { appSettings, } from "../../support/Objects/ObjectsCore"; -describe( +describe.skip( "GSheet-Functional Tests With Read/Write Access", { tags: ["@tag.Datasource", "@tag.GSheet"] }, function () { diff --git a/app/client/cypress/e2e/GSheet/ReadOnly_Access_Spec.ts b/app/client/cypress/e2e/GSheet/ReadOnly_Access_Spec.ts index 95ad0629d440..e90840f7d3ca 100644 --- a/app/client/cypress/e2e/GSheet/ReadOnly_Access_Spec.ts +++ b/app/client/cypress/e2e/GSheet/ReadOnly_Access_Spec.ts @@ -11,7 +11,7 @@ import { appSettings, } from "../../support/Objects/ObjectsCore"; -describe( +describe.skip( "GSheet-Functional Tests With Read Access", { tags: ["@tag.Datasource", "@tag.GSheet"] }, function () { diff --git a/app/client/cypress/e2e/GSheet/WidgetBinding_AllAccess_Spec.ts b/app/client/cypress/e2e/GSheet/WidgetBinding_AllAccess_Spec.ts index 1bf593992248..a3afbd77610c 100644 --- a/app/client/cypress/e2e/GSheet/WidgetBinding_AllAccess_Spec.ts +++ b/app/client/cypress/e2e/GSheet/WidgetBinding_AllAccess_Spec.ts @@ -21,7 +21,7 @@ const workspaceName = "gsheet apps"; const dataSourceName = "gsheet-all"; let appName = "gsheet-app"; let spreadSheetName = "test-sheet"; -describe( +describe.skip( "GSheet-widget binding", { tags: ["@tag.Datasource", "@tag.GSheet"] }, function () { diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts index f9c14d70c4ea..c253987eb48c 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts @@ -12,7 +12,7 @@ import EditorNavigation, { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Modals`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { // Cleanup the canvas before each test diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/AppTheming/AnvilAppThemingSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/AppTheming/AnvilAppThemingSnapshot_spec.ts index 7000e5d226dc..6f2bb3ff6e60 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/AppTheming/AnvilAppThemingSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/AppTheming/AnvilAppThemingSnapshot_spec.ts @@ -36,17 +36,7 @@ describe( anvilSnapshot.setAccentColor("#0080ff"); }); - it("3. Typography", () => { - anvilSnapshot.setTypography("Inter"); - - anvilSnapshot.matchSnapshotForCanvasMode("AppThemingTypography"); - anvilSnapshot.matchSnapshotForPreviewMode("AppThemingTypography"); - anvilSnapshot.matchSnapshotForDeployMode("AppThemingTypography"); - - anvilSnapshot.setTypography("System Default"); - }); - - it("4. Density", () => { + it("3. Density", () => { ["Tight", "Regular", "Loose"].forEach((density) => { anvilSnapshot.setDensity(density); @@ -58,7 +48,7 @@ describe( }); }); - it("5. Sizing", () => { + it("4. Sizing", () => { ["Small", "Regular", "Big"].forEach((size) => { anvilSnapshot.setSizing(size); @@ -68,7 +58,7 @@ describe( }); }); - it("6. Corners", () => { + it("5. Corners", () => { ["0px", "6px", "20px"].forEach((corner) => { anvilSnapshot.setCorners(corner); @@ -77,15 +67,5 @@ describe( anvilSnapshot.matchSnapshotForDeployMode(`AppThemingCorner${corner}`); }); }); - - it("7. Icon Style", () => { - ["Filled", "Outlined"].forEach((iconStyle) => { - anvilSnapshot.setIconStyle(iconStyle); - - anvilSnapshot.matchSnapshotForCanvasMode(`AppThemingIcon${iconStyle}`); - anvilSnapshot.matchSnapshotForPreviewMode(`AppThemingIcon${iconStyle}`); - anvilSnapshot.matchSnapshotForDeployMode(`AppThemingIcon${iconStyle}`); - }); - }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts index 32e2a215c4dd..210fdf47b579 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Button Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilButtonWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts index 77367eb7706e..98e24b1e0b20 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Checkbox Group Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilCheckboxGroupWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts index 4bec7f5d9536..3cd3bd49848f 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Checkbox Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilCheckboxWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts index fe65f5d4a0b7..3e41473ebfec 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Currency Input Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilCurrencyInputWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts index 005190388998..89991dabaf35 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Heading Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilHeadingWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts index 1431f1a632a3..b73f2486036c 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Icon Button Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilIconButtonWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts index 9744fb27290c..a75a3048216a 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Inline Button Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilInlineButtonWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts index ca8110184a2e..0ed3244be5cb 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Input Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilInputWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts index 2fc78c9a212d..009f63dad631 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Paragraph Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilParagraphWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts index 4dac924d2331..653df4d7871e 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Phone Input Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilPhoneInputWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts index 1cc2e0134123..dfa3d7963739 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Radio Group Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilRadioGroupWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts index acf667d9d6a9..87af914cbdee 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Stats Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilStatsWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts index a6c0cfdf620c..8e183efadc0e 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Switch Group Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilSwitchGroupWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts index c14d8b1022df..c8bdf6124968 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Switch Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilSwitchWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts index 71a9dee23835..e5edcb37d91d 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Table Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilTableWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts index bc2dccda99d2..ecf7a60d0511 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Toolbar Button Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilToolbarButtonWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts index 88ff44c651bc..336d17180eba 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts @@ -6,7 +6,7 @@ import { describe( `${ANVIL_EDITOR_TEST}: Anvil tests for Zone and Section Widget`, - { tags: ["@tag.Anvil"] }, + { tags: ["@tag.Anvil", "@tag.Visual"] }, () => { before(() => { agHelper.AddDsl("anvilZoneSectionWidget"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/BugTests/Bug29566_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/BugTests/Bug29566_Spec.ts deleted file mode 100644 index e4e8d6d378cf..000000000000 --- a/app/client/cypress/e2e/Regression/ClientSide/BugTests/Bug29566_Spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import largeJSONData from "../../../../fixtures/largeJSONData.json"; -import { - agHelper, - deployMode, - jsEditor, -} from "../../../../support/Objects/ObjectsCore"; - -describe("JS Function execution data mutation", function () { - before(() => { - agHelper.AddDsl("listwidgetData"); - }); - - it("1. List widget gets populated on page load", function () { - const APIJS = `export default { - - async runFetch(dataRequest) { - return fetch(dataRequest.url, dataRequest.config) - .then(response => { - return response.json(); - }).catch(error => { - showAlert('API error') - }); - }, - - async getConditionGroups() { - const dataRequest = { - url: "https://api.jsonbin.io/v3/b/656ed15d54105e766fd9ca52", - config: { - method: 'GET', - }, - name: 'getConditionGroups' - }; - return await this.runFetch(dataRequest); - }, - - async getConditionListData() { - const dataRequest = { - url: "https://api.jsonbin.io/v3/b/656ed18454105e766fd9ca6c", - config: { - method: 'GET', - }, - name: 'getConditionGroups' - }; - return await this.runFetch(dataRequest); - }, - - }`; - const PAGE1JS = `export default { - - conditionGroups: [], - allConditionGroups: [], - maxItemsOnPageMachineConditionGroups: 6, - startIndex_MCG: 0, - conditionGroupsToShow: [], - splittingDataOf_MCG_ToShowIntoThreeColumns: [[],[],[]], - selectedMachineConditionGroups: [], - - async getAllConditionGroupsData() { - const conditionGroups = await ApiJS.getConditionGroups()|| []; - this.conditionGroups = conditionGroups.record - console.log("conditionGroups ====> ",conditionGroups); - this.conditionGroups.filter((item) => { - this.allConditionGroups.push(item.conditionGroup); - }); - this.allConditionGroupsSplitedIntoThreeColumns() - }, - - allConditionGroupsSplitedIntoThreeColumns() { - let tmpCounter_MCG = 0; - for(let i = 0; i < this.maxItemsOnPageMachineConditionGroups; i++) { - this.conditionGroupsToShow.push([this.allConditionGroups[this.startIndex_MCG]]); - this.splittingDataOf_MCG_ToShowIntoThreeColumns[tmpCounter_MCG].push(this.allConditionGroups[this.startIndex_MCG]); - this.startIndex_MCG++; - tmpCounter_MCG === 2 ? tmpCounter_MCG = 0 : tmpCounter_MCG++; - } - }, - - setBgSelected_MCG(id) { - return this.selectedMachineConditionGroups.includes(id) ? '#0d9be2' : '#383838'; - }, - test(){ - this.splittingDataOf_MCG_ToShowIntoThreeColumns = [[],[],[]] - return this.splittingDataOf_MCG_ToShowIntoThreeColumns - } - - }`; - jsEditor.CreateJSObject(APIJS, { - paste: true, - completeReplace: true, - toRun: false, - shouldCreateNewJSObj: true, - prettify: false, - }); - jsEditor.RenameJSObjFromPane("ApiJS"); - cy.wait(5000); - - jsEditor.CreateJSObject(PAGE1JS, { - paste: true, - completeReplace: true, - toRun: false, - shouldCreateNewJSObj: true, - prettify: false, - }); - jsEditor.RenameJSObjFromPane("Page1JS"); - cy.wait(5000); - jsEditor.EnableDisableAsyncFuncSettings( - "getAllConditionGroupsData", - true, - false, - ); - deployMode.DeployApp(); - agHelper.AssertContains("MK Condition"); - }); -}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts index 717b0edbe2ed..d0a02c28e0bb 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts @@ -3,6 +3,7 @@ import { dataSources, entityItems, homePage, + locators, } from "../../../../support/Objects/ObjectsCore"; import EditorNavigation, { EntityType, @@ -46,7 +47,8 @@ describe( }); }); - it("2. Verify if schema was fetched once #18448", () => { + //This test is failing because of this bug #36348 + it.skip("2. Verify if schema was fetched once #36348", () => { agHelper.RefreshPage(); EditorNavigation.SelectEntityByName( dataSourceName, @@ -70,13 +72,14 @@ describe( agHelper.RefreshPage(); dataSources.CreateMockDB("Users"); dataSources.CreateQueryAfterDSSaved(); - dataSources.VerifyTableSchemaOnQueryEditor("public.users"); - dataSources.SelectTableFromPreviewSchemaList("public.users"); - dataSources.VerifyColumnSchemaOnQueryEditor("id", 1); + agHelper.GetNClick(dataSources._dsTabSchema); + agHelper.AssertElementAbsence(locators._btnSpinner); dataSources.FilterAndVerifyDatasourceSchemaBySearch( "public.us", "public.users", ); + dataSources.SelectTableFromPreviewSchemaList("public.users"); + dataSources.VerifyColumnSchemaOnQueryEditor("id", 1); }, ); @@ -87,10 +90,13 @@ describe( agHelper.RefreshPage(); dataSources.CreateMockDB("Users"); dataSources.CreateQueryAfterDSSaved(); + agHelper.GetNClick(dataSources._dsTabSchema); + dataSources.FilterAndVerifyDatasourceSchemaBySearch("public.users"); dataSources.VerifyTableSchemaOnQueryEditor("public.users"); // then refresh dataSources.RefreshDatasourceSchema(); // assert the schema is still shown. + dataSources.FilterAndVerifyDatasourceSchemaBySearch("public.users"); dataSources.VerifyTableSchemaOnQueryEditor("public.users"); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/BugTests/ListWidgetOnPageLoad_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/BugTests/ListWidgetOnPageLoad_Spec.ts new file mode 100644 index 000000000000..4826088ab6d7 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/BugTests/ListWidgetOnPageLoad_Spec.ts @@ -0,0 +1,59 @@ +import { + agHelper, + dataSources, + deployMode, + locators, + propPane, +} from "../../../../support/Objects/ObjectsCore"; +import EditorNavigation, { + AppSidebar, + AppSidebarButton, + EntityType, + PageLeftPane, + PagePaneSegment, +} from "../../../../support/Pages/EditorNavigation"; + +describe( + "JS Function execution data mutation", + { tags: ["@tag.Widget", "@tag.List"] }, + function () { + before(() => { + agHelper.AddDsl("Listv2/simpleList"); + }); + + it("1. List widget gets populated on page load. Bug: 29566", function () { + dataSources.CreateDataSource("Postgres"); + cy.get("@dsName").then(() => { + dataSources.CreateQueryAfterDSSaved( + "SELECT id,name FROM public.users LIMIT 10;", + ); + dataSources.ToggleUsePreparedStatement(false); + dataSources.RunQuery(); + }); + AppSidebar.navigate(AppSidebarButton.Editor); + PageLeftPane.switchSegment(PagePaneSegment.UI); + EditorNavigation.SelectEntityByName("List1", EntityType.Widget); + propPane.UpdatePropertyFieldValue("Items", "{{Query1.data}}"); + propPane.TogglePropertyState("Server side pagination", "Off"); + propPane.SelectPropertiesDropDown("Data Identifier", "id"); + agHelper + .GetText(locators._widgetInCanvas("textwidget") + " span") + .then((initialTexts: string[]) => { + deployMode.DeployApp(); + agHelper.AssertElementLength(locators._textWidgetInDeployed, 6); + agHelper + .GetText(locators._textWidgetInDeployed) + .then((deployedTexts: string[]) => { + expect(deployedTexts).to.deep.equal(initialTexts); + }); + agHelper.CypressReload(); + agHelper.AssertElementLength(locators._textWidgetInDeployed, 6); + agHelper + .GetText(locators._textWidgetInDeployed) + .then((deployedTexts: string[]) => { + expect(deployedTexts).to.deep.equal(initialTexts); + }); + }); + }); + }, +); diff --git a/app/client/cypress/e2e/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts index e7a90a863194..2a7907dd7495 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts @@ -1,7 +1,7 @@ import adminsSettings from "../../../../locators/AdminsSettings"; import { adminSettings as adminSettingsHelper } from "../../../../support/Objects/ObjectsCore"; -describe("Email verification", () => { +describe("Email verification", { tags: ["@tag.Visual"] }, () => { it("1. Shows the email verification pending page correctly", () => { cy.LogOut(); cy.visit("/user/verificationPending?email=test@appsmith.com"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Git/GitAutocommit_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Git/GitAutocommit_spec.ts index fbc7b921c5a3..724e9c72a043 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Git/GitAutocommit_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Git/GitAutocommit_spec.ts @@ -11,7 +11,7 @@ let repoName: string = "TED-testrepo1"; describe( "Git Autocommit", - { tags: ["@tag.Git", "@tag.GitAutocommit"] }, + { tags: ["@tag.Git", "@tag.GitAutocommit", "@tag.excludeForAirgap"] }, function () { it("Check if autocommit progress bar is visible and network requests are properly called", function () { featureFlagIntercept({ diff --git a/app/client/cypress/e2e/Regression/ClientSide/Templates/Fork_Template_To_App_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Templates/Fork_Template_To_App_spec.ts index 2838e49a8674..46bd1a99a335 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Templates/Fork_Template_To_App_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Templates/Fork_Template_To_App_spec.ts @@ -15,17 +15,14 @@ describe( it("1. Fork a template to the current app + Bug 17477", () => { PageList.AddNewPage("Add page from template"); agHelper.AssertElementVisibility(template.templateDialogBox); - agHelper.GetNClick("//h1[text()='Applicant Tracker-test']"); + agHelper.GetNClick(template.templateCard, 0, true); agHelper.FailIfErrorToast("INTERNAL_SERVER_ERROR"); agHelper.GetNClick(template.templateViewForkButton); agHelper.WaitUntilToastDisappear("template added successfully"); assertHelper.AssertNetworkStatus("updateLayout"); - // [Bug]: Getting 'Resource not found' error on deploying template #17477 + PageList.AddNewPage("Generate page with data"); deployMode.DeployApp(); - agHelper.GetNClickByContains( - ".t--page-switch-tab", - "1 Track Applications", - ); + agHelper.GetNClick(locators._deployedPage, 0, true); deployMode.NavigateBacktoEditor(); homePage.NavigateToHome(); agHelper.WaitUntilAllToastsDisappear(); @@ -35,14 +32,13 @@ describe( homePage.CreateNewApplication(); PageList.AddNewPage("Add page from template"); agHelper.AssertElementVisibility(template.templateDialogBox); - agHelper.GetNClick("//h1[text()='Applicant Tracker-test']"); + agHelper.GetNClick(template.templateCard, 0, true); agHelper.FailIfErrorToast( "Internal server error while processing request", ); assertHelper.AssertNetworkStatus("getTemplatePages"); agHelper.CheckUncheck(template.selectAllPages, false); agHelper.GetNClick(template.selectCheckbox, 1); - // [Bug]: On forking selected pages from a template, resource not found error is shown #17270 agHelper.GetNClick(template.templateViewForkButton); agHelper.AssertElementAbsence( locators._visibleTextSpan("Setting up the template"), diff --git a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js index b65976ec99b5..cf0fadbb7afa 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js @@ -20,90 +20,4 @@ describe("Visual tests for datasources", { tags: ["@tag.Visual"] }, () => { AppSidebar.navigate(AppSidebarButton.Data); cy.get(".t--data-blank-state").matchImageSnapshot("emptydatasourcepage"); }); - /* cy.NavigateToDatasourceEditor(); - cy.wait(2000); - cy.get("#new-api").matchImageSnapshot("apiSection"); - cy.get("span:contains('Database')") - .first() - .click(); - cy.get("#new-datasources").matchImageSnapshot("databaseSection"); - cy.get("#mock-database") - .scrollIntoView() - .matchImageSnapshot("sampleDatabasesSection"); - }); - it("Layout validation for postgres page", () => { - cy.get(datasource.PostgreSQL).click(); - cy.get(".t--edit-datasource-name").click(); - cy.get(".t--edit-datasource-name input") - .clear() - .type(postgres, { force: true }) - .should("have.value", postgres) - .blur(); - cy.get('[data-testid="section-Connection"]') - .next() - .matchImageSnapshot("postgresConnectionSection2"); - cy.get('[data-testid="section-Connection"]').click(); - cy.get('[data-testid="section-Authentication"]') - .scrollIntoView() - .click(); - cy.wait(1000); - cy.get('[data-testid="section-Authentication"]') - .next() - .matchImageSnapshot("postgresAuthenticationSection2"); - cy.get('[data-testid="section-Authentication"]').click(); - cy.get('[data-testid="section-SSL (optional)"]') - .scrollIntoView() - .click(); - cy.wait(1000); - cy.get('[data-testid="section-SSL (optional)"]') - .next() - .matchImageSnapshot("postgresSSLSection2"); - cy.get('[data-testid="section-SSL (optional)"]').click(); - cy.get('[data-testid="section-SSL (optional)"]') - .next() - .next() - .matchImageSnapshot("ctaButtons"); - cy.get(".t--close-editor").click(); - cy.contains(".t--datasource-name", postgres).matchImageSnapshot( - "PostgresActivetab", - ); - }); - it("Layout validation for mongodb page", () => { - cy.NavigateToDatasourceEditor(); - cy.get(datasource.MongoDB).click({ force: true }); - cy.get(".t--edit-datasource-name").click(); - cy.get(".t--edit-datasource-name input") - .clear() - .type(mongo, { force: true }) - .should("have.value", mongo) - .blur(); - cy.get('[data-testid="section-Connection"]') - .next() - .matchImageSnapshot("mongoConnectionSection2"); - cy.get('[data-testid="section-Connection"]').click(); - cy.get('[data-testid="section-Authentication"]') - .scrollIntoView() - .click(); - cy.wait(1000); - cy.get('[data-testid="section-Authentication"]') - .next() - .matchImageSnapshot("mongoAuthenticationSection2"); - cy.get('[data-testid="section-Authentication"]').click(); - cy.get('[data-testid="section-SSL (optional)"]') - .scrollIntoView() - .click(); - cy.wait(1000); - cy.get('[data-testid="section-SSL (optional)"]') - .next() - .matchImageSnapshot("mongoSSLSection2"); - cy.get('[data-testid="section-SSL (optional)"]').click(); - cy.get('[data-testid="section-SSL (optional)"]') - .next() - .next() - .matchImageSnapshot("ctaButtons"); - cy.get(".t--close-editor").click(); - cy.contains(".t--datasource-name", mongo).matchImageSnapshot( - "MongoDBActivetab", - ); - }); */ }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js index 5dff94ada5cf..7f8692969748 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js @@ -61,18 +61,15 @@ myFun2: async () => { agHelper.ActionContextMenuWithInPane({ action: "Prettify code" }); agHelper.Sleep(2000); //allowing time to prettify! - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify6"); // taking a snap after clicking inside the editor to make sure prettify has not reverted agHelper.Sleep(110); agHelper.GetNClick(jsEditor._lineinJsEditor(26)); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify6"); homePage.NavigateToHome(); homePage.FilterApplication(workspaceName); homePage.ForkApplication(appName); EditorNavigation.SelectEntityByName("JSObject1", EntityType.JSObject); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify6"); }); it("7. TC 1933 - JSEditor prettify verification on cloned page", () => { @@ -119,17 +116,14 @@ myFun2: async () => { agHelper.ActionContextMenuWithInPane({ action: "Prettify code" }); agHelper.Sleep(); //allowing time to prettify! - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify7"); // taking a snap after clicking inside the editor to make sure prettify has not reverted agHelper.Sleep(110); agHelper.GetNClick(jsEditor._lineinJsEditor(26)); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify7"); PageList.ClonePage("Page1"); EditorNavigation.SelectEntityByName("JSObject1", EntityType.JSObject); agHelper.Sleep(3000); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify7"); }); it("1. TC 1864 : JSEditor validation for Prettify code with lint errors, triggered by menu option", () => { @@ -208,27 +202,21 @@ myFun2: async () => { }, ); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjBeforePrettify2"); - agHelper.ActionContextMenuWithInPane({ action: "Prettify code" }); agHelper.Sleep(2000); //allowing time to prettify! - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify2"); // taking a snap after clicking inside the editor to make sure prettify has not reverted agHelper.Sleep(110); agHelper.GetNClick(jsEditor._lineinJsEditor(26)); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify2"); // click run button and take a snap to make sure prettify did not revert agHelper.GetNClick(jsEditor._runButton); agHelper.Sleep(); // allow time to run //Close bottom bar after execution. debuggerHelper.CloseBottomBar(); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify2"); // click dropdown to change function and make sure prettify has not reverted jsEditor.SelectFunctionDropdown("myFun2"); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify2"); agHelper.AssertContains("ran successfully", "not.exist"); }); @@ -323,18 +311,15 @@ myFun2: async () => { // taking a snap after clicking inside the editor to make sure prettify has not reverted agHelper.Sleep(110); agHelper.GetNClick(jsEditor._lineinJsEditor(26)); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify4_1"); // click run button and take a snap to make sure prettify did not revert agHelper.GetNClick(jsEditor._runButton); agHelper.Sleep(); // allow time to run //Close bottom bar after execution. debuggerHelper.CloseBottomBar(); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify4_1"); // click dropdown to change function and make sure prettify has not reverted jsEditor.SelectFunctionDropdown("myFun2"); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterPrettify4_1"); agHelper.AssertContains("ran successfully", "not.exist"); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js index 6c777faea1cc..6d47d02a34ed 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js @@ -48,13 +48,11 @@ myFun2: async () => { cy.get("div.CodeMirror").type("{cmd+s}").wait(2000); _.agHelper.GetNClick(_.jsEditor._lineinJsEditor(5)); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterSaveAndPrettify"); _.agHelper.AssertAutoSave(); // taking a snap after clicking inside the editor to make sure prettify has not reverted _.agHelper.Sleep(110); _.agHelper.GetNClick(_.jsEditor._lineinJsEditor(25)); - cy.get("div.CodeMirror").matchImageSnapshot("jsObjAfterSaveAndPrettify"); }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js index f813a29176a1..cf7fca399ba2 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js @@ -5,44 +5,48 @@ describe("Visual regression tests", { tags: ["@tag.Visual"] }, () => { // command: "npx cypress run --spec cypress/e2e/Regression_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js --browser chrome" // 3. New screenshot will be generated in the snapshot folder - it("Verify SwitchGroup inline enable/disbale", () => { - cy.dragAndDropToCanvas("switchgroupwidget", { x: 300, y: 300 }); - cy.wait(1000); + it( + "Verify SwitchGroup inline enable/disbale", + { tags: ["@tag.Visual"] }, + () => { + cy.dragAndDropToCanvas("switchgroupwidget", { x: 300, y: 300 }); + cy.wait(1000); - //Verify default check - cy.get(".t--property-control-inline input").should("be.checked"); - // taking screenshot of switch container - cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( - "inlineEnabled", - ); + //Verify default check + cy.get(".t--property-control-inline input").should("be.checked"); + // taking screenshot of switch container + cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( + "inlineEnabled", + ); - //Unchecking & verify snap - cy.get(".t--property-control-inline input") - .uncheck({ force: true }) - .wait(2000) - .should("not.be.checked"); - cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( - "inlineDisabled", - ); + //Unchecking & verify snap + cy.get(".t--property-control-inline input") + .uncheck({ force: true }) + .wait(2000) + .should("not.be.checked"); + cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( + "inlineDisabled", + ); - //Checking again & verify snap - cy.get(".t--property-control-inline input") - .check({ force: true }) - .wait(2000) - .should("be.checked"); + //Checking again & verify snap + cy.get(".t--property-control-inline input") + .check({ force: true }) + .wait(2000) + .should("be.checked"); - cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( - "inlineEnabled", - ); + cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( + "inlineEnabled", + ); - //Unchecking again & verify snap - cy.get(".t--property-control-inline input") - .uncheck({ force: true }) - .wait(2000) - .should("not.be.checked"); - // taking screenshot of app home page in edit mode - cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( - "inlineDisabled", - ); - }); + //Unchecking again & verify snap + cy.get(".t--property-control-inline input") + .uncheck({ force: true }) + .wait(2000) + .should("not.be.checked"); + // taking screenshot of app home page in edit mode + cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( + "inlineDisabled", + ); + }, + ); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraImage_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraImage_Spec.ts index ed9e2cfff71c..e0438a393e29 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraImage_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraImage_Spec.ts @@ -15,7 +15,7 @@ import PageList from "../../../../../support/Pages/PageList"; describe( "Camera widget - Image test", - { tags: ["@tag.Widget", "@tag.Camera"] }, + { tags: ["@tag.Widget", "@tag.Camera", "@tag.Visual"] }, () => { before(() => { //Reset video source to default incase it got changed in other specs @@ -86,13 +86,6 @@ describe( agHelper.AssertExistingToggleState("Mirrored", "true"); propPane.EnterJSContext("Mirrored", "{{(55>45)?false:true}}", true, true); deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.CAMERA)); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraImageMirroredScreen", { - failureThreshold: 0.15, - failureThresholdType: "percent", - customDiffConfig: { threshold: 0.15 }, - }); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Camera1", EntityType.Widget); propPane.EnterJSContext("Mirrored", "", false); @@ -125,29 +118,16 @@ describe( //Validate camera screen & icons agHelper.AssertElementVisibility(widgetLocators.cameraImageVideoOnOffBtn); agHelper.AssertElementVisibility(widgetLocators.cameraImageVideoDropdown); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraImageScreen"); //Capture image agHelper.GetNClick(widgetLocators.cameraCaptureBtn); agHelper.AssertElementVisibility(widgetLocators.cameraSaveBtn); agHelper.AssertElementVisibility(widgetLocators.cameraImageDiscardBtn); - //Validate image in preview screen - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraImagePreviewScreen"); - //Save image agHelper.GetNClick(widgetLocators.cameraSaveBtn); agHelper.AssertElementVisibility(widgetLocators.cameraRefreshBtn); - //Validate image in refresh screen - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraImageSavedScreen"); - //Refresh image agHelper.GetNClick(widgetLocators.cameraRefreshBtn); agHelper.AssertElementVisibility(widgetLocators.cameraCaptureBtn); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraVideo_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraVideo_Spec.ts index e269b80bd6d4..9c010aa16c69 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraVideo_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Camera/CameraVideo_Spec.ts @@ -14,7 +14,7 @@ import EditorNavigation, { describe( "Camera widget - Video test", - { tags: ["@tag.Widget", "@tag.Camera"] }, + { tags: ["@tag.Widget", "@tag.Camera", "@tag.Visual"] }, () => { before(() => { //Reset video source to default incase it got changed in other specs @@ -68,9 +68,6 @@ describe( agHelper.AssertExistingToggleState("Mirrored", "true"); propPane.EnterJSContext("Mirrored", "{{(55>45)?false:true}}", true, true); deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.CAMERA)); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraVideoMirroredScreen"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Camera1", EntityType.Widget); propPane.EnterJSContext("Mirrored", "", false); @@ -105,9 +102,6 @@ describe( agHelper.AssertElementVisibility(widgetLocators.cameraMicrophoneDropdown); agHelper.AssertElementVisibility(widgetLocators.cameraVideoOnOffBtn); agHelper.AssertElementVisibility(widgetLocators.cameraVideoDropdown); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraVideoScreen"); //Start video recording agHelper.GetNClick(widgetLocators.cameraCaptureBtn); @@ -119,19 +113,11 @@ describe( agHelper.AssertElementVisibility(widgetLocators.cameraVideodiscardBtn); agHelper.AssertElementVisibility(widgetLocators.cameraVideoPlayBtn); - //Validate video in preview screen - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraVideoPreviewScreen"); - //Save video agHelper.GetNClick(widgetLocators.cameraSaveBtn); //Validate video in refresh screen agHelper.AssertElementVisibility(widgetLocators.cameraRefreshBtn); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CAMERA)) - .matchImageSnapshot("cameraVideoSavedScreen"); //Refresh video agHelper.GetNClick(widgetLocators.cameraRefreshBtn); @@ -163,111 +149,5 @@ describe( table.ValidateDownloadNVerify("video1.mp4"); table.ValidateDownloadNVerify("video.mp4"); }); - - //Tests to Validate camera to video widget binding - //Skipping below tests due to issue - https://github.com/appsmithorg/appsmith/issues/26166 - // it("7. Video Recording test - Disabled Camera but Enabled Microphone", () => { - // deployMode.NavigateBacktoEditor(); - // entityExplorer.SelectEntityByName("Camera1"); - // agHelper.GetNClick(propPane._mode("Video"), 1); - // entityExplorer.DragNDropWidget(draggableWidgets.VIDEO); - // propPane.TypeTextIntoField("URL", "{{Camera1.videoBlobURL}}"); - - // deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.CAMERA)); - // agHelper.GetNClick(widgetLocators.cameraVideoOnOffBtn); - // agHelper.GetNClick(widgetLocators.cameraCaptureBtn); - // agHelper.Sleep(3000); - // agHelper.GetNClick(widgetLocators.cameraStopRecordingBtn); - // agHelper.GetNClick(widgetLocators.cameraSaveBtn); - // agHelper.GetNClick(draggableWidgets.VIDEO); - // agHelper.Sleep(5000); - // agHelper - // .GetElement(widgetLocators.cameraVideo) - // .eq(1) - // .should(($el) => { - // const attrValue = $el[0].webkitAudioDecodedByteCount; - - // //Threshold greater than 30000 shows that the audio is playing - // expect(attrValue).be.greaterThan(30000); - // }); - // agHelper - // .GetElement(widgetLocators.cameraVideo) - // .eq(1) - // .should(($el) => { - // const attrValue = $el[0].webkitVideoDecodedByteCount; - - // //Threshold less than 10000 shows that the video is not playing - // expect(attrValue).be.lessThan(10000); - // }); - // }); - - // it("8. Video Recording test - Enabled Camera but Disabled Microphone", () => { - // entityExplorer.SelectEntityByName("Camera1"); - // agHelper.GetNClick(propPane._mode("Video"), 1); - // entityExplorer.DragNDropWidget(draggableWidgets.VIDEO); - // propPane.TypeTextIntoField("URL", "{{Camera1.videoBlobURL}}"); - - // deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.CAMERA)); - // agHelper.GetNClick(widgetLocators.cameraVideoOnOffBtn); - // agHelper.GetNClick(widgetLocators.cameraMicrophoneBtn); - // agHelper.GetNClick(widgetLocators.cameraCaptureBtn); - // agHelper.Sleep(3000); - // agHelper.GetNClick(widgetLocators.cameraStopRecordingBtn); - // agHelper.GetNClick(widgetLocators.cameraSaveBtn); - // agHelper.GetNClick(draggableWidgets.VIDEO); - // agHelper.Sleep(5000); - // agHelper - // .GetElement(widgetLocators.cameraVideo) - // .eq(1) - // .should(($el) => { - // const attrValue = $el[0].webkitAudioDecodedByteCount; - - // //Threshold less than 1000 shows that the audio is not playing - // expect(attrValue).be.lessThan(1000); - // }); - // agHelper - // .GetElement(widgetLocators.cameraVideo) - // .eq(1) - // .should(($el) => { - // const attrValue = $el[0].webkitVideoDecodedByteCount; - - // //Threshold greater than 30000 shows that the video is playing - // expect(attrValue).be.greaterThan(30000); - // }); - // }); - - // it("9. Video Recording test - Enabled Camera but Enabled Microphone", () => { - // entityExplorer.SelectEntityByName("Camera1"); - // agHelper.GetNClick(propPane._mode("Video"), 1); - // entityExplorer.DragNDropWidget(draggableWidgets.VIDEO); - // propPane.TypeTextIntoField("URL", "{{Camera1.videoBlobURL}}"); - - // deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.CAMERA)); - // agHelper.GetNClick(widgetLocators.cameraMicrophoneBtn); - // agHelper.GetNClick(widgetLocators.cameraCaptureBtn); - // agHelper.Sleep(3000); - // agHelper.GetNClick(widgetLocators.cameraStopRecordingBtn); - // agHelper.GetNClick(widgetLocators.cameraSaveBtn); - // agHelper.GetNClick(draggableWidgets.VIDEO); - // agHelper.Sleep(5000); - // agHelper - // .GetElement(widgetLocators.cameraVideo) - // .eq(1) - // .should(($el) => { - // const attrValue = $el[0].webkitAudioDecodedByteCount; - - // //Threshold greater than 30000 shows that the audio is playing - // expect(attrValue).be.greaterThan(30000); - // }); - // agHelper - // .GetElement(widgetLocators.cameraVideo) - // .eq(1) - // .should(($el) => { - // const attrValue = $el[0].webkitVideoDecodedByteCount; - - // //Threshold greater than 30000 shows that the video is playing - // expect(attrValue).be.greaterThan(30000); - // }); - // }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_1.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_1.ts index b0a61eb35abf..46d0fc2cbb19 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_1.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_1.ts @@ -10,7 +10,7 @@ import EditorNavigation, { EntityType, } from "../../../../../support/Pages/EditorNavigation"; -describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { +describe("", { tags: ["@tag.Widget", "@tag.Chart", "@tag.Visual"] }, () => { before(() => { entityExplorer.DragDropWidgetNVerify(draggableWidgets.CHART); }); @@ -24,16 +24,10 @@ describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { propPane.SelectPropertiesDropDown("Chart Type", "Pie chart"); agHelper.AssertAutoSave(); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/piechartsnapshot"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); propPane.TogglePropertyState("Show Labels", "On"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/piechartsnapshotwithlabels"); }); it("2. Test line chart", () => { @@ -41,32 +35,20 @@ describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { propPane.SelectPropertiesDropDown("Chart Type", "Line chart"); agHelper.AssertAutoSave(); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/linechartsnapshot"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); propPane.TogglePropertyState("Show Labels", "On"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/linechartsnapshotwithlabels"); }); it("3. Test column chart", () => { propPane.TogglePropertyState("Show Labels", "Off"); propPane.SelectPropertiesDropDown("Chart Type", "Column chart"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/columnchartsnapshot"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); propPane.TogglePropertyState("Show Labels", "On"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/columnchartsnapshotwithlabels"); }); it("4. Test area chart", () => { @@ -74,15 +56,9 @@ describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { propPane.SelectPropertiesDropDown("Chart Type", "Area chart"); agHelper.AssertAutoSave(); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/areachartsnapshot"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); propPane.TogglePropertyState("Show Labels", "On"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/areachartsnapshotwithlabels"); }); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_2.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_2.ts index e06da685d29b..e114e5f11493 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_2.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_widget_spec_2.ts @@ -10,7 +10,7 @@ import EditorNavigation, { EntityType, } from "../../../../../support/Pages/EditorNavigation"; -describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { +describe("", { tags: ["@tag.Widget", "@tag.Chart", "@tag.Visual"] }, () => { before(() => { entityExplorer.DragDropWidgetNVerify(draggableWidgets.CHART); }); @@ -23,9 +23,6 @@ describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { ); agHelper.AssertAutoSave(); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/piechartsnapshotwithtitle"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); }); @@ -34,16 +31,10 @@ describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { propPane.SelectPropertiesDropDown("Chart Type", "Column chart"); agHelper.AssertAutoSave(); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/columnchartsnapshotwithoutadaptiveaxis"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); propPane.TogglePropertyState("Adaptive axis", "On"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/columnchartsnapshotwithadaptiveaxis"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); }); @@ -51,27 +42,14 @@ describe("", { tags: ["@tag.Widget", "@tag.Chart"] }, () => { it("3. Test x axis label orientation chart", () => { propPane.SelectPropertiesDropDown("Chart Type", "Line chart"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot("chartwidget/linechartWithAutoXAxisLabelOrientation"); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); propPane.SelectPropertiesDropDown("x-axis label orientation", "Slant"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot( - "chartwidget/linechartWithSlantXAxisLabelOrientation", - ); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); propPane.SelectPropertiesDropDown("x-axis label orientation", "Rotate"); deployMode.DeployApp(); - agHelper - .GetElement(locators._widgetInDeployed(draggableWidgets.CHART)) - .matchImageSnapshot( - "chartwidget/linechartWithRotateXAxisLabelOrientation", - ); deployMode.NavigateBacktoEditor(); EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts index c5841d32ccf5..696303aad3cc 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts @@ -5,9 +5,9 @@ import EditorNavigation, { } from "../../../../../support/Pages/EditorNavigation"; const publicWidgetsPage = require("../../../../../locators/publishWidgetspage.json"); -describe( +describe.skip( "3D Custom EChart feature", - { tags: ["@tag.Widget", "@tag.Chart"] }, + { tags: ["@tag.Widget", "@tag.Chart", "@tag.Visual"] }, function () { it("1. 3D EChart Custom Chart Widget Functionality", function () { _.agHelper.RefreshPage(); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePickerV2_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePickerV2_spec.js index 5a38be07678a..953307c20c63 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePickerV2_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePickerV2_spec.js @@ -83,41 +83,7 @@ describe( cy.closePropertyPane(); }); - it("5. Datepicker should not change the display data unless user selects the date", () => { - _.agHelper.AddDsl("datePickerdsl"); - - cy.openPropertyPane("datepickerwidget2"); - - cy.testJsontext( - "defaultdate", - '{{moment("04/05/2021 05:25", "DD/MM/YYYY HH:mm").toISOString()}}', - ); - cy.get(formWidgetsPage.toggleJsMinDate).click(); - cy.get( - ".t--property-control-mindate .ads-v2-input__input-section-input", - ).clear(); - cy.get( - ".t--property-control-mindate .ads-v2-input__input-section-input", - ).type("2020-02-01"); - cy.selectDateFormat("D MMMM, YYYY"); - cy.get(".t--widget-datepickerwidget2 .bp3-input").should( - "contain.value", - "4 May, 2021", - ); - cy.get(".t--widget-datepickerwidget2 .bp3-input").click({ force: true }); - cy.get(".DayPicker-NavButton--next").click({ force: true }); - cy.get(".t--widget-datepickerwidget2 .bp3-input").should( - "contain.value", - "4 May, 2021", - ); - cy.get(formWidgetsPage.toggleJsMinDate).click(); - cy.testJsontext( - "mindate", - "{{moment().subtract(10, 'days').toISOString()}}", - ); - }); - - it("6. Datepicker input value changes to work with selected date formats", function () { + it("5. Datepicker input value changes to work with selected date formats", function () { _.agHelper.AddDsl("datePickerdsl"); EditorNavigation.SelectEntityByName("DatePicker1", EntityType.Widget); @@ -144,7 +110,7 @@ describe( _.agHelper.AssertPopoverTooltip("Date out of range"); }); - it("7. Check isDirty meta property", function () { + it("6. Check isDirty meta property", function () { _.agHelper.AddDsl("datePickerdsl"); cy.openPropertyPane("textwidget"); cy.updateCodeInput( @@ -191,10 +157,50 @@ describe( cy.get(".t--widget-textwidget").first().should("contain", "false"); }); - it("8. Datepicker default date validation with js binding", function () { + it("7. Datepicker default date validation with js binding", function () { _.deployMode.DeployApp(); // eslint-disable-next-line cypress/no-unnecessary-waiting _.deployMode.NavigateBacktoEditor(); }); + + it("8. Datepicker should not change the display data unless user selects the date", () => { + _.agHelper.AddDsl("datePickerdsl"); + + cy.openPropertyPane("datepickerwidget2"); + + cy.testJsontext( + "defaultdate", + '{{moment("04/05/2021 05:25", "DD/MM/YYYY HH:mm").toISOString()}}', + ); + _.agHelper.PressEscape(); + _.agHelper.GetNClick(formWidgetsPage.minDateTextArea, 0, true); + cy.testJsontextclear("mindate"); + _.agHelper.GetNClick(formWidgetsPage.toggleJsMinDate, 0, true); + _.agHelper.WaitUntilEleAppear(formWidgetsPage.minDateInput); + _.agHelper.AssertAttribute( + formWidgetsPage.minDateInput, + "placeholder", + "YYYY-MM-DD HH:mm", + 0, + ); + _.agHelper.ClickNClear(formWidgetsPage.minDateInput, true, 0); + cy.get(formWidgetsPage.minDateInput).type("2020-02-01"); + cy.selectDateFormat("D MMMM, YYYY"); + cy.get(formWidgetsPage.datePickerInput).should( + "contain.value", + "4 May, 2021", + ); + cy.get(formWidgetsPage.datePickerInput).click({ force: true }); + cy.get(formWidgetsPage.dayPickerNextButton).click({ force: true }); + cy.get(formWidgetsPage.datePickerInput).should( + "contain.value", + "4 May, 2021", + ); + cy.get(formWidgetsPage.toggleJsMinDate).click(); + cy.testJsontext( + "mindate", + "{{moment().subtract(10, 'days').toISOString()}}", + ); + }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapChart_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapChart_Spec.ts index e0610d3324c5..3e4e9fa9649e 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapChart_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapChart_Spec.ts @@ -18,7 +18,7 @@ const _mapChartPlot = (text: string) => describe( "Map Chart Widget Functionality", - { tags: ["@tag.Widget", "@tag.Maps"] }, + { tags: ["@tag.Widget", "@tag.Maps", "@tag.Visual"] }, function () { it("1. Drag and drop a Map Chart widget and verify", function () { entityExplorer.DragDropWidgetNVerify(draggableWidgets.MAPCHART, 200, 200); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapWidget_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapWidget_Spec.ts index 0c93b96d17d1..96a6cb701f9d 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapWidget_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/MapWidget_Spec.ts @@ -29,139 +29,143 @@ const location = [ }, ]; -describe("Map Widget", { tags: ["@tag.Widget", "@tag.Maps"] }, function () { - it("1.Drag Map Widget and Verify the Map Widget with Initial Location", () => { - //Add map and verify - entityExplorer.DragDropWidgetNVerify(draggableWidgets.MAP, 200, 200); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapsimple"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Add Initial location and verify - propPane.TypeTextIntoField("Initial location", "New York, NY, USA"); - agHelper.PressEnter(); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithInitalLocation"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // convert Initial location to JS, update and verify - propPane.EnterJSContext("Initial location", JSON.stringify(location[0])); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithinItalLocationAsJS"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - }); - - it("2.Verify the Map Widget with Default markers", () => { - // With single default marker - propPane.TypeTextIntoField( - "Default Markers", - JSON.stringify(location.slice(0, 1)), - ); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithDefaultMarker1"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // With multiple default marker - propPane.TypeTextIntoField( - "Default Markers", - JSON.stringify(location.slice(0, 2)), - ); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithDefaultMarker2"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - }); - - it("3.Verify the Map Widget with zoom level", () => { - // With multiple default marker - propPane.SetZoomLevel(70); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithDefaultZoomOut"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Zoom in and verify - propPane.SetZoomLevel(30); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithDefaultZoomIn"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - }); - - it("4.1 Verify the Map Widget with different general settings", () => { - // With visibility off - propPane.TogglePropertyState("Visible", "Off"); - deployMode.DeployApp(); - agHelper.VerifySnapshot(locators._root, "mapWithVisibilityOff"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Convert visibility to JS and set the visibility "On" and verify - propPane.EnterJSContext("Visible", "true"); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithVisibilityOnWithJS"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Toggle off Enable pick location and verify - propPane.TogglePropertyState("Enable pick location", "Off"); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithPickLocationOff"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Toggle off Map & marker centering and verify - propPane.TogglePropertyState("Map & marker centering", "Off"); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithMapNMarkerCenteringOff"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - }); - - it("4.2 Verify the Map Widget with different general settings", () => { - // Toggle On Enabling clustering and verify - propPane.TogglePropertyState("Enable clustering", "On"); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithEnablingClusteringON"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Convert Enabling clustering and disable it and verify - propPane.EnterJSContext("Enable clustering", "false"); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithEnablingClusteringOff"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Toggle off Enable search location and verify - propPane.TogglePropertyState("Enable search location", "Off"); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithEnableSearchLocationOff"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - }); - - it("5 Verify the style changes", () => { - // Change border radius and verify - propPane.MoveToTab("Style"); - propPane.EnterJSContext("Border radius", "1.5rem"); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithBorderRadius"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - - // Change box shadow and verify - const boxShadow = - "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"; - propPane.MoveToTab("Style"); - propPane.EnterJSContext("Box shadow", boxShadow); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); - agHelper.VerifySnapshot(locators._root, "mapWithBoxShadow"); - deployMode.NavigateBacktoEditor(); - EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); - }); -}); +describe( + "Map Widget", + { tags: ["@tag.Widget", "@tag.Maps", "@tag.Visual"] }, + function () { + it("1.Drag Map Widget and Verify the Map Widget with Initial Location", () => { + //Add map and verify + entityExplorer.DragDropWidgetNVerify(draggableWidgets.MAP, 200, 200); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapsimple"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Add Initial location and verify + propPane.TypeTextIntoField("Initial location", "New York, NY, USA"); + agHelper.PressEnter(); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithInitalLocation"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // convert Initial location to JS, update and verify + propPane.EnterJSContext("Initial location", JSON.stringify(location[0])); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithinItalLocationAsJS"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + }); + + it("2.Verify the Map Widget with Default markers", () => { + // With single default marker + propPane.TypeTextIntoField( + "Default Markers", + JSON.stringify(location.slice(0, 1)), + ); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithDefaultMarker1"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // With multiple default marker + propPane.TypeTextIntoField( + "Default Markers", + JSON.stringify(location.slice(0, 2)), + ); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithDefaultMarker2"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + }); + + it("3.Verify the Map Widget with zoom level", () => { + // With multiple default marker + propPane.SetZoomLevel(70); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithDefaultZoomOut"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Zoom in and verify + propPane.SetZoomLevel(30); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithDefaultZoomIn"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + }); + + it("4.1 Verify the Map Widget with different general settings", () => { + // With visibility off + propPane.TogglePropertyState("Visible", "Off"); + deployMode.DeployApp(); + agHelper.VerifySnapshot(locators._root, "mapWithVisibilityOff"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Convert visibility to JS and set the visibility "On" and verify + propPane.EnterJSContext("Visible", "true"); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithVisibilityOnWithJS"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Toggle off Enable pick location and verify + propPane.TogglePropertyState("Enable pick location", "Off"); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithPickLocationOff"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Toggle off Map & marker centering and verify + propPane.TogglePropertyState("Map & marker centering", "Off"); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithMapNMarkerCenteringOff"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + }); + + it("4.2 Verify the Map Widget with different general settings", () => { + // Toggle On Enabling clustering and verify + propPane.TogglePropertyState("Enable clustering", "On"); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithEnablingClusteringON"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Convert Enabling clustering and disable it and verify + propPane.EnterJSContext("Enable clustering", "false"); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithEnablingClusteringOff"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Toggle off Enable search location and verify + propPane.TogglePropertyState("Enable search location", "Off"); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithEnableSearchLocationOff"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + }); + + it("5 Verify the style changes", () => { + // Change border radius and verify + propPane.MoveToTab("Style"); + propPane.EnterJSContext("Border radius", "1.5rem"); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithBorderRadius"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + + // Change box shadow and verify + const boxShadow = + "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"; + propPane.MoveToTab("Style"); + propPane.EnterJSContext("Box shadow", boxShadow); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.MAP)); + agHelper.VerifySnapshot(locators._root, "mapWithBoxShadow"); + deployMode.NavigateBacktoEditor(); + EditorNavigation.SelectEntityByName("Map1", EntityType.Widget); + }); + }, +); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2Filter1_1_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2Filter1_1_Spec.ts index d5e0741608be..142401c067c9 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2Filter1_1_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2Filter1_1_Spec.ts @@ -1,3 +1,5 @@ +import { demoTableDataForSelect } from "../../../../../fixtures/Table/DemoTableData"; +import { featureFlagIntercept } from "../../../../../support/Objects/FeatureFlags"; import { entityExplorer, propPane, @@ -8,6 +10,9 @@ import { draggableWidgets, agHelper, } from "../../../../../support/Objects/ObjectsCore"; +import EditorNavigation, { + EntityType, +} from "../../../../../support/Pages/EditorNavigation"; describe( "Verify various Table_Filter combinations", @@ -136,5 +141,46 @@ describe( table.WaitForTableEmpty("v2"); table.RemoveFilterNVerify("2381224", true, true, 0, "v2"); }); + + it("11. Verify table search includes label and value for table with select column type", () => { + deployMode.NavigateBacktoEditor(); + // This flag is turned on to allow the label show in the table select cell content + // when this feature is turned on fully, this flag will be removed + featureFlagIntercept({ release_table_cell_label_value_enabled: true }); + EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); + propPane.EnterJSContext("Table data", demoTableDataForSelect); + + // Edit role column to select type + table.ChangeColumnType("role", "Select", "v2"); + table.EditColumn("role", "v2"); + agHelper.UpdateCodeInput( + locators._controlOption, + ` + {{ + [ + {"label": "Software Engineer", + "value": 10,}, + {"label": "Product Manager", + "value": 20,}, + {"label": "UX Designer", + "value": 30,} + ] + }} + `, + ); + // Search for a label in the table + table.SearchTable("Software Engineer"); + table.ReadTableRowColumnData(0, 2, "v2").then((afterSearch) => { + expect(afterSearch).to.eq("Software Engineer"); + }); + table.RemoveSearchTextNVerify("1", "v2"); + + // Search for a value in the table + table.SearchTable("20"); + table.ReadTableRowColumnData(0, 2, "v2").then((afterSearch) => { + expect(afterSearch).to.eq("Product Manager"); + }); + table.RemoveSearchTextNVerify("1", "v2"); + }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/Select1_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/Select1_spec.ts index fafe2da10f90..dd77c5338ad3 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/Select1_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/Select1_spec.ts @@ -37,10 +37,10 @@ describe( }); }); - it("3. should check that options given in the property pane is appearing on the table", () => { - cy.get(".t--property-control-options").should("exist"); + it("3. should check that JSON options given in the property pane is appearing on the table", () => { + cy.get(_.locators._controlOption).should("exist"); cy.updateCodeInput( - ".t--property-control-options", + _.locators._controlOption, ` [ { @@ -80,9 +80,52 @@ describe( cy.get(".menu-item-active.has-focus").should("contain", "#1"); }); - it("4. should check that placeholder property is working", () => { + it("4. should check that javascript options given in the property pane is appearing on the table", () => { + cy.get(_.locators._controlOption).should("exist"); cy.updateCodeInput( - ".t--property-control-options", + _.locators._controlOption, + ` + {{[ + { + "label": "#1", + "value": "#1" + }, + { + "label": "#2", + "value": "#2" + }, + { + "label": "#3", + "value": "#3" + } + ]}} + `, + ); + cy.editTableSelectCell(0, 0); + + [ + { + label: "#1", + value: "#1", + }, + { + label: "#2", + value: "#2", + }, + { + label: "#3", + value: "#3", + }, + ].forEach((item) => { + cy.get(".menu-item-text").contains(item.value).should("exist"); + }); + + cy.get(".menu-item-active.has-focus").should("contain", "#1"); + }); + + it("5. should check that placeholder property is working", () => { + cy.updateCodeInput( + _.locators._controlOption, ` [ { @@ -116,9 +159,9 @@ describe( ).should("contain", "choose an item"); }); - it("5. should check that filterable property is working", () => { + it("6. should check that filterable property is working", () => { cy.updateCodeInput( - ".t--property-control-options", + _.locators._controlOption, ` {{[ { @@ -161,7 +204,8 @@ describe( cy.get(".t--canvas-artboard").click({ force: true }); }); - it("6. should check that on option select is working", () => { + it("7. should check that on option select is working", () => { + _.agHelper.CheckForPageSaveError(); featureFlagIntercept({ release_table_cell_label_value_enabled: true }); cy.openPropertyPane("tablewidgetv2"); cy.editColumn("step"); @@ -173,7 +217,7 @@ describe( `, ); cy.updateCodeInput( - ".t--property-control-options", + _.locators._controlOption, ` [ { @@ -203,9 +247,9 @@ describe( cy.discardTableRow(4, 0); }); - it("7. should check that currentRow is accessible in the select options", () => { + it("8. should check that currentRow is accessible in the select options", () => { cy.updateCodeInput( - ".t--property-control-options", + _.locators._controlOption, ` {{[ { @@ -228,7 +272,7 @@ describe( cy.get(".menu-item-text").contains("#1").should("not.exist"); }); - it("8. should check that 'same select option in new row' property is working", () => { + it("9. should check that 'same select option in new row' property is working", () => { _.propPane.NavigateBackToPropertyPane(); const checkSameOptionsInNewRowWhileEditing = () => { @@ -245,7 +289,7 @@ describe( cy.get(".t--property-control-newrowoptions").should("not.exist"); cy.updateCodeInput( - ".t--property-control-options", + _.locators._controlOption, ` {{[{ "label": "male", @@ -294,7 +338,7 @@ describe( checkSameOptionsWhileAddingNewRow(); }); - it("9. should check that 'new row select options' is working", () => { + it("10. should check that 'new row select options' is working", () => { const checkNewRowOptions = () => { // New row select options should be visible when "Same options in new row" is turned off _.propPane.TogglePropertyState("Same options in new row", "Off"); @@ -359,7 +403,7 @@ describe( checkNoOptionState(); }); - it("10. should check that server side filering is working", () => { + it("11. should check that server side filering is working", () => { _.dataSources.CreateDataSource("Postgres"); _.dataSources.CreateQueryAfterDSSaved( "SELECT * FROM public.astronauts {{this.params.filterText ? `WHERE name LIKE '%${this.params.filterText}%'` : ''}} LIMIT 10;", diff --git a/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/Mongo_Spec.ts b/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/Mongo_Spec.ts index dfa1c2c48f6e..94cf82fc284e 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/Mongo_Spec.ts +++ b/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/Mongo_Spec.ts @@ -41,6 +41,10 @@ describe( assertHelper.AssertNetworkStatus("@getDatasourceStructure"); //Making sure table dropdown is populated agHelper.GetNClick(dataSources._selectTableDropdown, 0, true); agHelper.GetNClickByContains(dataSources._dropdownOption, "pokemon"); + + agHelper.GetNClick(dataSources._selectTableDropdown, 1, true); + agHelper.GetNClickByContains(dataSources._dropdownOption, "img"); + GenerateCRUDNValidateDeployPage( "http://www.serebii.net/pokemongo/pokemon/150.png", "150", @@ -103,30 +107,68 @@ describe( assertHelper.AssertNetworkStatus("@postExecute", 200); agHelper.ClickButton("Got it"); assertHelper.AssertNetworkStatus("@updateLayout", 200); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE)); //Validating loaded table agHelper.AssertElementExist(dataSources._selectedRow); - table.ReadTableRowColumnData(0, 0, "v2", 2000).then(($cellData) => { - expect($cellData).to.eq(col1Text); - }); - table.ReadTableRowColumnData(0, 3, "v2", 200).then(($cellData) => { - expect($cellData).to.eq(col2Text); - }); - table.ReadTableRowColumnData(0, 6, "v2", 200).then(($cellData) => { - expect($cellData).to.eq(col3Text); - }); - //Validating loaded JSON form - cy.xpath(locators._buttonByText("Update")).then((selector) => { - cy.wrap(selector) - .invoke("attr", "class") - .then((classes) => { - //cy.log("classes are:" + classes); - expect(classes).not.contain("bp3-disabled"); + findTheDataRow(col1Text).then((rowIndex: number) => { + cy.log(`This is the rowIndex of ${col1Text} : ${rowIndex}`); + table + .ReadTableRowColumnData(rowIndex, 0, "v2", 2000) + .then(($cellData) => { + expect($cellData).to.eq(col1Text); }); + table + .ReadTableRowColumnData(rowIndex, 3, "v2", 200) + .then(($cellData) => { + expect($cellData).to.eq(col2Text); + }); + table + .ReadTableRowColumnData(rowIndex, 6, "v2", 200) + .then(($cellData) => { + expect($cellData).to.eq(col3Text); + }); + + //Validating loaded JSON form + cy.xpath(locators._buttonByText("Update")).then((selector) => { + cy.wrap(selector) + .invoke("attr", "class") + .then((classes) => { + //cy.log("classes are:" + classes); + expect(classes).not.contain("bp3-disabled"); + }); + }); + dataSources.AssertJSONFormHeader(0, idIndex, "Id", "", true); }); - dataSources.AssertJSONFormHeader(0, idIndex, "Id", "", true); + } + + function findTheDataRow(col1Text: string) { + if (col1Text.length === 0) { + return cy.wrap(0); + } + + return agHelper + .GetElement(table._tableColumnDataWithText(0, col1Text, "v2")) + .closest(".tr") + .then(($p1) => { + return cy + .wrap($p1) + .parent() + .children() + .then(($children) => { + let index = 0; + $children.each((i, el) => { + // Iterate through the children + if (Cypress.$(el).is($p1)) { + // Check if the current child is p1 + index = i; // Assign the index when found + } + }); + return index; + }); + }); } }, ); diff --git a/app/client/cypress/e2e/Regression/ServerSide/QueryPane/GoogleSheets_spec.ts b/app/client/cypress/e2e/Regression/ServerSide/QueryPane/GoogleSheets_spec.ts index 345f3982e4cf..792f633cd865 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/QueryPane/GoogleSheets_spec.ts +++ b/app/client/cypress/e2e/Regression/ServerSide/QueryPane/GoogleSheets_spec.ts @@ -20,9 +20,10 @@ describe( dataSources.CreatePlugIn("Google Sheets"); VerifyFunctionDropdown([ "Read / Write / Delete | Selected google sheets", - "Read / Write / Delete | All google sheets", - "Read / Write | All google sheets", - "Read | All google sheets", + // Hiding below methods as they are not authorized at this state + // "Read / Write / Delete | All google sheets", + // "Read / Write | All google sheets", + // "Read | All google sheets", ]); dataSources.SaveDSFromDialog(false); }); @@ -31,8 +32,6 @@ describe( agHelper.GetNClick(dataSources._gsScopeDropdown); cy.get(dataSources._gsScopeOptions).then(function ($ele) { expect($ele.eq(0).text()).to.be.oneOf(scopeOptions); - expect($ele.eq(1).text()).to.be.oneOf(scopeOptions); - expect($ele.eq(2).text()).to.be.oneOf(scopeOptions); }); agHelper.GetNClick(dataSources._gsScopeDropdown); } diff --git a/app/client/cypress/e2e/Sanity/Datasources/GraphQL_spec.ts b/app/client/cypress/e2e/Sanity/Datasources/GraphQL_spec.ts index 68b07e359a8e..22f5f17454cd 100644 --- a/app/client/cypress/e2e/Sanity/Datasources/GraphQL_spec.ts +++ b/app/client/cypress/e2e/Sanity/Datasources/GraphQL_spec.ts @@ -279,7 +279,7 @@ describe( }); apiPage.SelectPaneTab("Authentication"); - agHelper.ClickButton("Save as datasource"); + agHelper.GetNClick(locators._saveDatasource); agHelper.AssertText( locators._inputFieldByName("URL") + "//" + locators._inputField, @@ -296,16 +296,14 @@ describe( // }); dataSources.SaveDatasource(); agHelper.ValidateToastMessage("datasource created"); - agHelper.AssertElementVisibility( - locators._buttonByText("Edit datasource"), - ); + agHelper.AssertElementVisibility(locators._saveDatasource); apiPage.SelectPaneTab("Body"); dataSources.UpdateGraphqlQueryAndVariable({ query: GRAPHQL_QUERY, variable: GRAPHQL_VARIABLES, }); apiPage.RunAPI(); - agHelper.ClickButton("Edit datasource"); + agHelper.GetNClick(locators._saveDatasource); dataSources.AssertDataSourceInfo([ dataManager.dsValues[ dataManager.defaultEnviorment diff --git a/app/client/cypress/fixtures/Table/DemoTableData.ts b/app/client/cypress/fixtures/Table/DemoTableData.ts new file mode 100644 index 000000000000..1b0bfdfb49e8 --- /dev/null +++ b/app/client/cypress/fixtures/Table/DemoTableData.ts @@ -0,0 +1,46 @@ +export const demoTableDataForSelect = ` +{{ + [ + { + role: 10, + id: 1, + name: "Alice Johnson", + email: "alice.johnson@example.com", + age: 28, + gender: 2 + }, + { + role: 20, + id: 2, + name: "Bob Smith", + email: "bob.smith@example.com", + age: 34, + gender: 1 + }, + { + role: 30, + id: 3, + name: "Charlie Brown", + email: "charlie.brown@example.com", + age: 25, + gender: 3 + }, + { + role: 20, + id: 4, + name: "Diana Prince", + email: "diana.prince@example.com", + age: 30, + gender: 2 + }, + { + role: 10, + id: 5, + name: "Evan Williams", + email: "evan.williams@example.com", + age: 27, + gender: 1 + } + ] +}} + `; diff --git a/app/client/cypress/locators/FormWidgets.json b/app/client/cypress/locators/FormWidgets.json index 8fc1f5d26921..db603de7b8c0 100644 --- a/app/client/cypress/locators/FormWidgets.json +++ b/app/client/cypress/locators/FormWidgets.json @@ -74,5 +74,9 @@ "NavHomePage": "[data-testid='t--default-home-icon']", "apiCallToast": "div.Toastify__toast-body", "toggleOnOptionChange": ".t--property-control-onoptionchange .t--js-toggle", - "toggleButtonVariant": ".t--property-control-buttonvariant .t--js-toggle" + "toggleButtonVariant": ".t--property-control-buttonvariant .t--js-toggle", + "minDateTextArea" : ".t--property-control-mindate .CodeMirror textarea", + "minDateInput" : ".t--property-control-mindate .ads-v2-input__input-section-input", + "datePickerInput": ".t--widget-datepickerwidget2 .bp3-input", + "dayPickerNextButton": ".DayPicker-NavButton--next" } diff --git a/app/client/cypress/plugins/index.js b/app/client/cypress/plugins/index.js index 705c200c175b..f2172d7ffc3c 100644 --- a/app/client/cypress/plugins/index.js +++ b/app/client/cypress/plugins/index.js @@ -5,9 +5,6 @@ const dotenv = require("dotenv"); const chalk = require("chalk"); const cypressLogToOutput = require("cypress-log-to-output"); const installLogsPrinter = require("cypress-terminal-report/src/installLogsPrinter"); -const { - addMatchImageSnapshotPlugin, -} = require("cypress-image-snapshot/plugin"); const { tagify } = require("cypress-tags"); const { cypressHooks } = require("../scripts/cypress-hooks"); const { dynamicSplit } = require("../scripts/cypress-split-dynamic"); @@ -30,12 +27,6 @@ const { staticSplit } = require("../scripts/cypress-split-static"); */ module.exports = async (on, config) => { - // on("task", { - // isFileExist, - // }); - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config - cypressLogToOutput.install(on, (type, event) => { if (event.level === "error" || event.type === "error") { return true; @@ -54,7 +45,6 @@ module.exports = async (on, config) => { installLogsPrinter(on, logsPrinterOptions); on("file:preprocessor", tagify(config)); - addMatchImageSnapshotPlugin(on, config); on("before:browser:launch", (browser = {}, launchOptions) => { /* @@ -65,7 +55,7 @@ module.exports = async (on, config) => { browser, launchOptions.args, ); - if (browser.name === "chrome") { + if (browser.name === "chrome" || browser.name === "chromium") { const video = path.join( "cypress", "fixtures", @@ -81,11 +71,6 @@ module.exports = async (on, config) => { return launchOptions; } - if (browser.name === "chromium") { - launchOptions.args.push("--window-size=1400,1100"); - return launchOptions; - } - if (browser.name === "electron") { // && browser.isHeadless) { launchOptions.preferences.fullscreen = true; @@ -96,20 +81,6 @@ module.exports = async (on, config) => { return launchOptions; } }); - // module.exports = (on, config) => { - // on("after:spec", (spec, results) => { - // if (results && results.video) { - // // Do we have failures for any retry attempts? - // const failures = _.some(results.tests, (test) => { - // return _.some(test.attempts, { state: "failed" }); - // }); - // if (!failures) { - // // delete the video if the spec passed and no tests retried - // return del(results.video); - // } - // } - // }); - // }; /** * Fallback to APPSMITH_* env variables for Cypress.env if config.env doesn't already have it. diff --git a/app/client/cypress/snapshots/3DCustomECharts.snap.png b/app/client/cypress/snapshots/3DCustomECharts.snap.png deleted file mode 100644 index 4e66133b5ba4..000000000000 Binary files a/app/client/cypress/snapshots/3DCustomECharts.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvas.snap.png deleted file mode 100644 index ef5d81690ca4..000000000000 Binary files a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvasDark.snap.png deleted file mode 100644 index 5eeca50fc2fe..000000000000 Binary files a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeploy.snap.png deleted file mode 100644 index 014c61a806cf..000000000000 Binary files a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIpad2.snap.png deleted file mode 100644 index 40f7ea83e990..000000000000 Binary files a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIphone6.snap.png deleted file mode 100644 index ba31f0587df7..000000000000 Binary files a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployMacbook13.snap.png deleted file mode 100644 index e8cb208a1373..000000000000 Binary files a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetPreview.snap.png deleted file mode 100644 index d42810feaef1..000000000000 Binary files a/app/client/cypress/snapshots/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvas.snap.png deleted file mode 100644 index c00073656464..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvasDark.snap.png deleted file mode 100644 index 99723edea0c3..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeploy.snap.png deleted file mode 100644 index 07af06a39ac8..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIpad2.snap.png deleted file mode 100644 index a48d0521e5c2..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIphone6.snap.png deleted file mode 100644 index 4ab8649a1c4f..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployMacbook13.snap.png deleted file mode 100644 index 667b23d5a9ea..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvas.snap.png deleted file mode 100644 index 638f7512b652..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvasDark.snap.png deleted file mode 100644 index e10556e339c3..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeploy.snap.png deleted file mode 100644 index d056070f672a..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIpad2.snap.png deleted file mode 100644 index cfef083ea76d..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIphone6.snap.png deleted file mode 100644 index 28688affe504..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployMacbook13.snap.png deleted file mode 100644 index e167ae4c4eab..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetPreview.snap.png deleted file mode 100644 index 21192f733d80..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvas.snap.png deleted file mode 100644 index 0300c70eca16..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvasDark.snap.png deleted file mode 100644 index f3bb4c7cbcc1..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeploy.snap.png deleted file mode 100644 index 55dfe0963484..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIpad2.snap.png deleted file mode 100644 index a44d594b89a5..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIphone6.snap.png deleted file mode 100644 index 40beff09e2f2..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployMacbook13.snap.png deleted file mode 100644 index ace1518f413b..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetPreview.snap.png deleted file mode 100644 index 4cc425161260..000000000000 Binary files a/app/client/cypress/snapshots/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvas.snap.png deleted file mode 100644 index 038d014e57cd..000000000000 Binary files a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvasDark.snap.png deleted file mode 100644 index c450cbe6a599..000000000000 Binary files a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeploy.snap.png deleted file mode 100644 index 68a64fe39d55..000000000000 Binary files a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployMacbook13.snap.png deleted file mode 100644 index ff97d7e69f9a..000000000000 Binary files a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetPreview.snap.png deleted file mode 100644 index f25eff6c00fd..000000000000 Binary files a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvas.snap.png deleted file mode 100644 index 88a423ef13fd..000000000000 Binary files a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvasDark.snap.png deleted file mode 100644 index b3f18cd3767e..000000000000 Binary files a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeploy.snap.png deleted file mode 100644 index 16dbfc575203..000000000000 Binary files a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIpad2.snap.png deleted file mode 100644 index cedf5f26409e..000000000000 Binary files a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIphone6.snap.png deleted file mode 100644 index 69c87e22c6ab..000000000000 Binary files a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployMacbook13.snap.png deleted file mode 100644 index 6917fed9138e..000000000000 Binary files a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetPreview.snap.png deleted file mode 100644 index 5e73e20572cf..000000000000 Binary files a/app/client/cypress/snapshots/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvas.snap.png deleted file mode 100644 index 2ea0bd9d1459..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvasDark.snap.png deleted file mode 100644 index a85340f51221..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeploy.snap.png deleted file mode 100644 index 1242df0a23c0..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIpad2.snap.png deleted file mode 100644 index 35e847e4f176..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIphone6.snap.png deleted file mode 100644 index 461f4146d3c6..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployMacbook13.snap.png deleted file mode 100644 index 81b1c10e0676..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetPreview.snap.png deleted file mode 100644 index 2ebe45e1d741..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvas.snap.png deleted file mode 100644 index 0e50a787fb7a..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvasDark.snap.png deleted file mode 100644 index 4d3d81b038a4..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeploy.snap.png deleted file mode 100644 index e837056c60c4..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIpad2.snap.png deleted file mode 100644 index 7187ace9df9a..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIphone6.snap.png deleted file mode 100644 index e738b362115f..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployMacbook13.snap.png deleted file mode 100644 index 71d69088cd52..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetPreview.snap.png deleted file mode 100644 index 2aeb70b4da02..000000000000 Binary files a/app/client/cypress/snapshots/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvas.snap.png deleted file mode 100644 index 8aff5fc0f16d..000000000000 Binary files a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvasDark.snap.png deleted file mode 100644 index 98507e2f17f7..000000000000 Binary files a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeploy.snap.png deleted file mode 100644 index 5125adede622..000000000000 Binary files a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployMacbook13.snap.png deleted file mode 100644 index 133bbde75a69..000000000000 Binary files a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetPreview.snap.png deleted file mode 100644 index bc507cbf212a..000000000000 Binary files a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvas.snap.png deleted file mode 100644 index 838e864772b0..000000000000 Binary files a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvasDark.snap.png deleted file mode 100644 index 12e321bb3467..000000000000 Binary files a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeploy.snap.png deleted file mode 100644 index ca337536f191..000000000000 Binary files a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIpad2.snap.png deleted file mode 100644 index 16d3674230c5..000000000000 Binary files a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIphone6.snap.png deleted file mode 100644 index 16406441c465..000000000000 Binary files a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployMacbook13.snap.png deleted file mode 100644 index ad31a8ef9198..000000000000 Binary files a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetPreview.snap.png deleted file mode 100644 index 78ee48243c58..000000000000 Binary files a/app/client/cypress/snapshots/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvas.snap.png deleted file mode 100644 index 0c21e07e3677..000000000000 Binary files a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvasDark.snap.png deleted file mode 100644 index 4904545566c8..000000000000 Binary files a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeploy.snap.png deleted file mode 100644 index ab2899a61ae4..000000000000 Binary files a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIpad2.snap.png deleted file mode 100644 index 6a0186d5d717..000000000000 Binary files a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIphone6.snap.png deleted file mode 100644 index d7d5c6ba9c85..000000000000 Binary files a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployMacbook13.snap.png deleted file mode 100644 index 688f1ab51c93..000000000000 Binary files a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetPreview.snap.png deleted file mode 100644 index a43461898213..000000000000 Binary files a/app/client/cypress/snapshots/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvas.snap.png deleted file mode 100644 index 06434512ee84..000000000000 Binary files a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvasDark.snap.png deleted file mode 100644 index d6bb8a6bbe51..000000000000 Binary files a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeploy.snap.png deleted file mode 100644 index 2604bb7793d4..000000000000 Binary files a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIpad2.snap.png deleted file mode 100644 index c35cc253f724..000000000000 Binary files a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIphone6.snap.png deleted file mode 100644 index c73ebbc717f8..000000000000 Binary files a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployMacbook13.snap.png deleted file mode 100644 index ae6ba5ce2719..000000000000 Binary files a/app/client/cypress/snapshots/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvas.snap.png deleted file mode 100644 index 25a6e224ec47..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvasDark.snap.png deleted file mode 100644 index 372c306a8926..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeploy.snap.png deleted file mode 100644 index d311d84a2c3b..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIpad2.snap.png deleted file mode 100644 index d76b0fb3ec01..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIphone6.snap.png deleted file mode 100644 index 720adcecad36..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployMacbook13.snap.png deleted file mode 100644 index c41500b2eb8c..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetPreview.snap.png deleted file mode 100644 index 95464079c100..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvas.snap.png deleted file mode 100644 index 05cde1d1851a..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvasDark.snap.png deleted file mode 100644 index a68b7638cff6..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeploy.snap.png deleted file mode 100644 index b58bf199d78f..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIpad2.snap.png deleted file mode 100644 index cca05065c637..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIphone6.snap.png deleted file mode 100644 index d51e119cc1da..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployMacbook13.snap.png deleted file mode 100644 index c91e2c20ec33..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetPreview.snap.png deleted file mode 100644 index f28d5ac8e8a3..000000000000 Binary files a/app/client/cypress/snapshots/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvas.snap.png deleted file mode 100644 index 48f94e8f6635..000000000000 Binary files a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvasDark.snap.png deleted file mode 100644 index 2ebdd516b6bb..000000000000 Binary files a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeploy.snap.png deleted file mode 100644 index 77a560e978ad..000000000000 Binary files a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIpad2.snap.png deleted file mode 100644 index 334bd746c155..000000000000 Binary files a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIphone6.snap.png deleted file mode 100644 index b39cad5b10d9..000000000000 Binary files a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployMacbook13.snap.png deleted file mode 100644 index cb3800ddbf6c..000000000000 Binary files a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetPreview.snap.png deleted file mode 100644 index a546b3aed63d..000000000000 Binary files a/app/client/cypress/snapshots/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvas.snap.png deleted file mode 100644 index 6570399ec676..000000000000 Binary files a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvasDark.snap.png deleted file mode 100644 index fc6cd6dc684f..000000000000 Binary files a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeploy.snap.png deleted file mode 100644 index 2a8b74cb3853..000000000000 Binary files a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIpad2.snap.png deleted file mode 100644 index d77a35808608..000000000000 Binary files a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIpad2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIphone6.snap.png deleted file mode 100644 index 6969910c89cd..000000000000 Binary files a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIphone6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployMacbook13.snap.png deleted file mode 100644 index 5507d155809e..000000000000 Binary files a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetPreview.snap.png deleted file mode 100644 index 8b9610336376..000000000000 Binary files a/app/client/cypress/snapshots/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvas.snap.png b/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvas.snap.png deleted file mode 100644 index beec045b8f04..000000000000 Binary files a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvas.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvasDark.snap.png deleted file mode 100644 index 1f2c0315dee8..000000000000 Binary files a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvasDark.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeploy.snap.png b/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeploy.snap.png deleted file mode 100644 index 22a20536010c..000000000000 Binary files a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeploy.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployMacbook13.snap.png deleted file mode 100644 index 7d6fae1623a7..000000000000 Binary files a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployMacbook13.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetPreview.snap.png b/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetPreview.snap.png deleted file mode 100644 index 417d8133fc9e..000000000000 Binary files a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetPreview.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AppPageLayout_spec.js/EmptyApp.snap.png b/app/client/cypress/snapshots/AppPageLayout_spec.js/EmptyApp.snap.png deleted file mode 100644 index cf3ce916fbaa..000000000000 Binary files a/app/client/cypress/snapshots/AppPageLayout_spec.js/EmptyApp.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AppPageLayout_spec.js/Profile.snap.png b/app/client/cypress/snapshots/AppPageLayout_spec.js/Profile.snap.png deleted file mode 100644 index 76481833a7fc..000000000000 Binary files a/app/client/cypress/snapshots/AppPageLayout_spec.js/Profile.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AppPageLayout_spec.js/apppage.snap.png b/app/client/cypress/snapshots/AppPageLayout_spec.js/apppage.snap.png deleted file mode 100644 index f27c15ad7a49..000000000000 Binary files a/app/client/cypress/snapshots/AppPageLayout_spec.js/apppage.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AppPageLayout_spec.js/emptyAppBuilder.snap.png b/app/client/cypress/snapshots/AppPageLayout_spec.js/emptyAppBuilder.snap.png deleted file mode 100644 index f27c15ad7a49..000000000000 Binary files a/app/client/cypress/snapshots/AppPageLayout_spec.js/emptyAppBuilder.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AppPageLayout_spec.js/loginpage.snap.png b/app/client/cypress/snapshots/AppPageLayout_spec.js/loginpage.snap.png deleted file mode 100644 index ca3f579fc980..000000000000 Binary files a/app/client/cypress/snapshots/AppPageLayout_spec.js/loginpage.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/AppPageLayout_spec.js/quickPageWizard.snap.png b/app/client/cypress/snapshots/AppPageLayout_spec.js/quickPageWizard.snap.png deleted file mode 100644 index 8391571782f2..000000000000 Binary files a/app/client/cypress/snapshots/AppPageLayout_spec.js/quickPageWizard.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageMirroredScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageMirroredScreen.snap.png deleted file mode 100644 index 3a2b81bf4b34..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageMirroredScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImagePreviewScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImagePreviewScreen.snap.png deleted file mode 100644 index 6037d00ee8aa..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImagePreviewScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageSavedScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageSavedScreen.snap.png deleted file mode 100644 index 6b33565d8e3c..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageSavedScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageScreen.snap.png deleted file mode 100644 index ad99b6860250..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraImageScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoMirroredScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoMirroredScreen.snap.png deleted file mode 100644 index fce03d6c38ee..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoMirroredScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoPreviewScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoPreviewScreen.snap.png deleted file mode 100644 index 62a2bc185626..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoPreviewScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoSavedScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoSavedScreen.snap.png deleted file mode 100644 index 4c2081c55d3e..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoSavedScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoScreen.snap.png b/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoScreen.snap.png deleted file mode 100644 index 58a46287c01d..000000000000 Binary files a/app/client/cypress/snapshots/CameraWidgetSpec.ts/cameraVideoScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/Custom3DChartSpec.ts/2DCustomECharts.snap.png b/app/client/cypress/snapshots/Custom3DChartSpec.ts/2DCustomECharts.snap.png deleted file mode 100644 index d70c91094b55..000000000000 Binary files a/app/client/cypress/snapshots/Custom3DChartSpec.ts/2DCustomECharts.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/Custom3DChartSpec.ts/3DCustomECharts-2.snap.png b/app/client/cypress/snapshots/Custom3DChartSpec.ts/3DCustomECharts-2.snap.png deleted file mode 100644 index 3d254136971d..000000000000 Binary files a/app/client/cypress/snapshots/Custom3DChartSpec.ts/3DCustomECharts-2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/Custom3DChartSpec.ts/3DCustomECharts.snap.png b/app/client/cypress/snapshots/Custom3DChartSpec.ts/3DCustomECharts.snap.png deleted file mode 100644 index c0bea562a540..000000000000 Binary files a/app/client/cypress/snapshots/Custom3DChartSpec.ts/3DCustomECharts.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/Custom3DChartSpec.ts/FusionCharts.snap.png b/app/client/cypress/snapshots/Custom3DChartSpec.ts/FusionCharts.snap.png deleted file mode 100644 index 99ca77a8d0f4..000000000000 Binary files a/app/client/cypress/snapshots/Custom3DChartSpec.ts/FusionCharts.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/DatasourcePageLayout_spec.js/emptydatasourcepage.snap.png b/app/client/cypress/snapshots/DatasourcePageLayout_spec.js/emptydatasourcepage.snap.png deleted file mode 100644 index 60b7e941179e..000000000000 Binary files a/app/client/cypress/snapshots/DatasourcePageLayout_spec.js/emptydatasourcepage.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/Expired Token.snap.png b/app/client/cypress/snapshots/Expired Token.snap.png deleted file mode 100644 index 41ad5e09ea7f..000000000000 Binary files a/app/client/cypress/snapshots/Expired Token.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorComment_spec.js/jsObjAfterCommenting1.snap.png b/app/client/cypress/snapshots/JSEditorComment_spec.js/jsObjAfterCommenting1.snap.png deleted file mode 100644 index 7517889c1b8c..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorComment_spec.js/jsObjAfterCommenting1.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorComment_spec.js/jsObjBeforeCommenting1.snap.png b/app/client/cypress/snapshots/JSEditorComment_spec.js/jsObjBeforeCommenting1.snap.png deleted file mode 100644 index e32b87efc997..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorComment_spec.js/jsObjBeforeCommenting1.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/formattedJSONBodyAfterSave.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/formattedJSONBodyAfterSave.snap.png deleted file mode 100644 index 4d5cf7f4924e..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/formattedJSONBodyAfterSave.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterGoLineStartSmart5.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterGoLineStartSmart5.snap.png deleted file mode 100644 index 9d7b49e02925..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterGoLineStartSmart5.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify1.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify1.snap.png deleted file mode 100644 index 15136312993b..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify1.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify2.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify2.snap.png deleted file mode 100644 index d9568bd339b2..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify3.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify3.snap.png deleted file mode 100644 index 7b97b74c5d17..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify3.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify4.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify4.snap.png deleted file mode 100644 index 9555cee5ea81..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify4.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify4_1.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify4_1.snap.png deleted file mode 100644 index b76f64cf6be5..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify4_1.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify6.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify6.snap.png deleted file mode 100644 index d9568bd339b2..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify7.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify7.snap.png deleted file mode 100644 index c6e3c82c4f69..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjAfterPrettify7.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforeGoLineStartSmart5.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforeGoLineStartSmart5.snap.png deleted file mode 100644 index e73b7b1098c3..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforeGoLineStartSmart5.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify1.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify1.snap.png deleted file mode 100644 index 3174be50f8ae..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify1.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify2.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify2.snap.png deleted file mode 100644 index 7042165d69b0..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify3.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify3.snap.png deleted file mode 100644 index c88f695784a8..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify3.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify4.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify4.snap.png deleted file mode 100644 index 0a51ab030951..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify4.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify6.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify6.snap.png deleted file mode 100644 index 8000d375c498..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify6.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify7.snap.png b/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify7.snap.png deleted file mode 100644 index 31975d44bc71..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorIndent_spec.js/jsObjBeforePrettify7.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorSaveAndAutoIndent_spec.js/jsObjAfterSaveAndPrettify.snap.png b/app/client/cypress/snapshots/JSEditorSaveAndAutoIndent_spec.js/jsObjAfterSaveAndPrettify.snap.png deleted file mode 100644 index f2f44d41bd6f..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorSaveAndAutoIndent_spec.js/jsObjAfterSaveAndPrettify.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/JSEditorSaveAndAutoIndent_spec.js/jsObjBeforeSaveAndPrettify.snap.png b/app/client/cypress/snapshots/JSEditorSaveAndAutoIndent_spec.js/jsObjBeforeSaveAndPrettify.snap.png deleted file mode 100644 index 8000d375c498..000000000000 Binary files a/app/client/cypress/snapshots/JSEditorSaveAndAutoIndent_spec.js/jsObjBeforeSaveAndPrettify.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithBorderRadius.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithBorderRadius.snap.png deleted file mode 100644 index f6eca1aa1f4f..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithBorderRadius.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithBoxShadow.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithBoxShadow.snap.png deleted file mode 100644 index bd5f3f6c65a5..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithBoxShadow.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithColorRange.snag.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithColorRange.snag.png deleted file mode 100644 index edd1a8149ff5..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapChartWithColorRange.snag.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapchartsimple.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapchartsimple.snap.png deleted file mode 100644 index 20054343e051..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapchartsimple.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithafrica.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithafrica.snap.png deleted file mode 100644 index 3046d3ade39c..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithafrica.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithantarctica.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithantarctica.snap.png deleted file mode 100644 index 190f3498757d..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithantarctica.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithasia.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithasia.snap.png deleted file mode 100644 index 3d352c9175a0..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithasia.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithcustomdata.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithcustomdata.snap.png deleted file mode 100644 index 453746bfabf4..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithcustomdata.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithcustomtitle.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithcustomtitle.snap.png deleted file mode 100644 index ee87464bb06b..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithcustomtitle.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwitheurope.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwitheurope.snap.png deleted file mode 100644 index c8a54f9b1331..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwitheurope.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithnorthamerica.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithnorthamerica.snap.png deleted file mode 100644 index 8974d2ff3eee..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithnorthamerica.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithoceania.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithoceania.snap.png deleted file mode 100644 index b5277daf2cdd..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithoceania.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithshowlabelsoff.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithshowlabelsoff.snap.png deleted file mode 100644 index 291698119e08..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithshowlabelsoff.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithshowlableson.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithshowlableson.snap.png deleted file mode 100644 index 64cc95dd1770..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithshowlableson.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithsouthamerica.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithsouthamerica.snap.png deleted file mode 100644 index 954afd2aca08..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithsouthamerica.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithusa.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithusa.snap.png deleted file mode 100644 index 6b5d92df19db..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithusa.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithvisibilityoff.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithvisibilityoff.snap.png deleted file mode 100644 index 1bc8cd17ab3f..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithvisibilityoff.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithvisibilityon.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithvisibilityon.snap.png deleted file mode 100644 index b89737c5eaf7..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithvisibilityon.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithworld.snap.png b/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithworld.snap.png deleted file mode 100644 index 20054343e051..000000000000 Binary files a/app/client/cypress/snapshots/MapChart_Spec.ts/mapwithworld.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithBorderRadius.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithBorderRadius.snap.png deleted file mode 100644 index 073ed59d2823..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithBorderRadius.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithBoxShadow.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithBoxShadow.snap.png deleted file mode 100644 index 9d0241382280..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithBoxShadow.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultMarker1.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultMarker1.snap.png deleted file mode 100644 index 79b48d28579f..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultMarker1.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultMarker2.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultMarker2.snap.png deleted file mode 100644 index a27c00a79972..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultMarker2.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultZoomIn.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultZoomIn.snap.png deleted file mode 100644 index af196e948dcf..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultZoomIn.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultZoomOut.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultZoomOut.snap.png deleted file mode 100644 index c30e60de620f..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithDefaultZoomOut.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnableSearchLocationOff.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnableSearchLocationOff.snap.png deleted file mode 100644 index 912836e8463b..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnableSearchLocationOff.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnablingClusteringON.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnablingClusteringON.snap.png deleted file mode 100644 index df9aa889964a..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnablingClusteringON.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnablingClusteringOff.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnablingClusteringOff.snap.png deleted file mode 100644 index a61315a9e06e..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithEnablingClusteringOff.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithInitalLocation.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithInitalLocation.snap.png deleted file mode 100644 index 9734ba0ba376..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithInitalLocation.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithMapNMarkerCenteringOff.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithMapNMarkerCenteringOff.snap.png deleted file mode 100644 index 7efb7e7d5c97..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithMapNMarkerCenteringOff.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithPickLocationOff.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithPickLocationOff.snap.png deleted file mode 100644 index 7efb7e7d5c97..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithPickLocationOff.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithVisibilityOff.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithVisibilityOff.snap.png deleted file mode 100644 index 3c8da7146c52..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithVisibilityOff.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithVisibilityOnWithJS.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithVisibilityOnWithJS.snap.png deleted file mode 100644 index af196e948dcf..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithVisibilityOnWithJS.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithinItalLocationAsJS.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithinItalLocationAsJS.snap.png deleted file mode 100644 index f84ce5da5d77..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapWithinItalLocationAsJS.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapsimple.snap.png b/app/client/cypress/snapshots/MapWidget_Spec.ts/mapsimple.snap.png deleted file mode 100644 index 7e1c9ff5cbcd..000000000000 Binary files a/app/client/cypress/snapshots/MapWidget_Spec.ts/mapsimple.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalLargeSize.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalLargeSize.snap.png new file mode 100644 index 000000000000..9463ec2e5896 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalLargeSize.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalMediumSize.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalMediumSize.snap.png new file mode 100644 index 000000000000..6f94d696ccda Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalMediumSize.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalSmallSize.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalSmallSize.snap.png new file mode 100644 index 000000000000..ec393d25b650 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/AnvilModal_spec.ts/anvilModalSmallSize.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvas.snap.png new file mode 100644 index 000000000000..25023e98beb7 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..66edaec229ff Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeploy.snap.png new file mode 100644 index 000000000000..934fdb11e4d4 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..121be741e383 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..9118ba24c502 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..98e938085d1b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetPreview.snap.png new file mode 100644 index 000000000000..4b779afa39d3 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts/anvilButtonWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvas.snap.png new file mode 100644 index 000000000000..41d4689649c5 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..3d7ca9eab179 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeploy.snap.png new file mode 100644 index 000000000000..a9adb76bfc92 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..ce552cb59281 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..0fe8d596c38d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..aaf91616a9a0 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts/anvilCheckboxGroupWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvas.snap.png new file mode 100644 index 000000000000..0f05f8d0974d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..cf32059a4cb3 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeploy.snap.png new file mode 100644 index 000000000000..99bfed718b49 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..71e0170835e0 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..35f2bde97ca5 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..567798ad701d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetPreview.snap.png new file mode 100644 index 000000000000..f5fa0e7cf41b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxWidgetSnapshot_spec.ts/anvilCheckboxWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvas.snap.png new file mode 100644 index 000000000000..1d2b88880bcf Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..e6da12d25f7e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeploy.snap.png new file mode 100644 index 000000000000..30e68c9f54ef Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..f2a2277ef8cb Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..d13f6a5d69af Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..1156fec3cd66 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetPreview.snap.png new file mode 100644 index 000000000000..4c5dd46951ed Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts/anvilCurrencyInputWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvas.snap.png new file mode 100644 index 000000000000..2240a03aa2d6 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..9a35eee05e42 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeploy.snap.png new file mode 100644 index 000000000000..36b635e45749 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIpad2.snap.png similarity index 100% rename from app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIpad2.snap.png rename to app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIpad2.snap.png diff --git a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIphone6.snap.png similarity index 98% rename from app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIphone6.snap.png rename to app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIphone6.snap.png index 5ee863013c9d..09eea5aff625 100644 Binary files a/app/client/cypress/snapshots/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIphone6.snap.png and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..2c6b1c81f92d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetPreview.snap.png new file mode 100644 index 000000000000..20221f9f8cab Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilHeadingWidgetSnapshot_spec.ts/anvilHeadingWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvas.snap.png new file mode 100644 index 000000000000..4883384e7233 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..7dca08d168e6 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeploy.snap.png new file mode 100644 index 000000000000..01dcfe8b1e4c Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..3451b93426ab Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..5803ea4b0356 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..1cb1173205d2 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetPreview.snap.png new file mode 100644 index 000000000000..60b8dcb85a12 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts/anvilIconButtonWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvas.snap.png new file mode 100644 index 000000000000..209fb85f801c Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..afb5e42c6329 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeploy.snap.png new file mode 100644 index 000000000000..6dcb85b24673 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..1b36e211edd0 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..d5fbb6086f64 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..9cfd79f79afb Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetPreview.snap.png new file mode 100644 index 000000000000..5263cb3cb8b3 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts/anvilInlineButtonWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvas.snap.png new file mode 100644 index 000000000000..7080d45fa0ef Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..133cb81d4b09 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeploy.snap.png new file mode 100644 index 000000000000..fbfaa33d91c6 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..7492788cbc03 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..22d96e7b18e3 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..5000bea12a5a Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetPreview.snap.png new file mode 100644 index 000000000000..ed6cc44e8c16 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts/anvilInputWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvas.snap.png new file mode 100644 index 000000000000..2a4b7c8f83ba Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..7da01788fbc2 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeploy.snap.png new file mode 100644 index 000000000000..3660687c1aed Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIpad2.snap.png similarity index 100% rename from app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIpad2.snap.png rename to app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIpad2.snap.png diff --git a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIphone6.snap.png similarity index 86% rename from app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIphone6.snap.png rename to app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIphone6.snap.png index b8a7e60a817c..811631dab378 100644 Binary files a/app/client/cypress/snapshots/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIphone6.snap.png and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..dcc485135125 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetPreview.snap.png new file mode 100644 index 000000000000..d085c85040cf Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts/anvilParagraphWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvas.snap.png new file mode 100644 index 000000000000..0e970ec7d0a8 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..f76c4c1073c0 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeploy.snap.png new file mode 100644 index 000000000000..cf6755af8981 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..15937f55bcc8 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..335ff2294b05 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..1a8ccfc73e10 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetPreview.snap.png new file mode 100644 index 000000000000..d82f7264a446 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts/anvilPhoneInputWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvas.snap.png new file mode 100644 index 000000000000..a015c796c7fb Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..e9c9dbf33967 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeploy.snap.png new file mode 100644 index 000000000000..36580ae1afde Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..19bf761e036b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..4e5273cac29e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..5270ba9514ab Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetPreview.snap.png new file mode 100644 index 000000000000..96630edb4991 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilRadioGroupWidgetSnapshot_spec.ts/anvilRadioGroupWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvas.snap.png new file mode 100644 index 000000000000..ce9ca7be2e6e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..228508d8f16f Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeploy.snap.png new file mode 100644 index 000000000000..60d986fc3d20 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..d0be224e5a4e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..41c2f86bf270 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..1b7c113b65c9 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts/anvilStatsWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvas.snap.png new file mode 100644 index 000000000000..f0881060a3e6 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..f4216611960e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeploy.snap.png new file mode 100644 index 000000000000..2c135a3b11b7 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..95f8176ff473 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..b72580b5b415 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..bb542f34c34d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetPreview.snap.png new file mode 100644 index 000000000000..5861230d4fbf Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts/anvilSwitchGroupWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvas.snap.png new file mode 100644 index 000000000000..6ba6ce0809eb Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..727b9d824e99 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeploy.snap.png new file mode 100644 index 000000000000..3e9db0f73616 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..33cb60aaabbd Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..42940debaff5 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..b40fcb197bbf Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetPreview.snap.png new file mode 100644 index 000000000000..f50b7d7f9cc6 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts/anvilSwitchWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvas.snap.png new file mode 100644 index 000000000000..fe2a2fb8ce0a Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..b5f35e5ecf75 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeploy.snap.png new file mode 100644 index 000000000000..fecb64643ea4 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..0a2e11d0433e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..1cc436e5ccc0 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..a72fabeb58a8 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetPreview.snap.png new file mode 100644 index 000000000000..e3610e3153f6 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts/anvilTableWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvas.snap.png new file mode 100644 index 000000000000..615d84517603 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..30c67d22efe9 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeploy.snap.png new file mode 100644 index 000000000000..f9e5ce37ea21 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIpad2.snap.png new file mode 100644 index 000000000000..2eec1d8dddfd Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIphone6.snap.png new file mode 100644 index 000000000000..96a7f9a9be5f Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..18ff6ccb1c2d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetPreview.snap.png new file mode 100644 index 000000000000..c1a2674a2fe9 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts/anvilToolbarButtonWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvas.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvas.snap.png new file mode 100644 index 000000000000..d13b97292b32 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvas.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvasDark.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvasDark.snap.png new file mode 100644 index 000000000000..83fa678e5473 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetCanvasDark.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeploy.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeploy.snap.png new file mode 100644 index 000000000000..4b7bb96d499b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeploy.snap.png differ diff --git a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIpad2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIpad2.snap.png similarity index 54% rename from app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIpad2.snap.png rename to app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIpad2.snap.png index 56f7024dd737..ac378604807e 100644 Binary files a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIpad2.snap.png and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIpad2.snap.png differ diff --git a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIphone6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIphone6.snap.png similarity index 95% rename from app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIphone6.snap.png rename to app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIphone6.snap.png index 5625ecb033f5..63401b63e778 100644 Binary files a/app/client/cypress/snapshots/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIphone6.snap.png and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployIphone6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployMacbook13.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployMacbook13.snap.png new file mode 100644 index 000000000000..5690194f739b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetDeployMacbook13.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetPreview.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetPreview.snap.png new file mode 100644 index 000000000000..20b70b64e6de Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts/anvilZoneSectionWidgetPreview.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Expired Token.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Expired Token.snap.png new file mode 100644 index 000000000000..076f4d2416e9 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Expired Token.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Unknown error.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Unknown error.snap.png new file mode 100644 index 000000000000..f76f066dd39b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Unknown error.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/VerificationPendingScreen.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/VerificationPendingScreen.snap.png new file mode 100644 index 000000000000..7a04f830344f Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/VerificationPendingScreen.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Verified Token.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Verified Token.snap.png new file mode 100644 index 000000000000..d7200474d6a0 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/Verified Token.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/WrongToken.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/WrongToken.snap.png new file mode 100644 index 000000000000..068bd08f10f8 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/FormLogin/EmailVerfication_spec.ts/WrongToken.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/EmptyApp.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/EmptyApp.snap.png new file mode 100644 index 000000000000..26f7d7bfea03 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/EmptyApp.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/Profile.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/Profile.snap.png new file mode 100644 index 000000000000..c6b1b3e71acf Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/Profile.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/apppage.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/apppage.snap.png new file mode 100644 index 000000000000..997046761a4b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/apppage.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/emptyAppBuilder.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/emptyAppBuilder.snap.png new file mode 100644 index 000000000000..997046761a4b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/emptyAppBuilder.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/loginpage.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/loginpage.snap.png new file mode 100644 index 000000000000..4f6200eda289 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/loginpage.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/quickPageWizard.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/quickPageWizard.snap.png new file mode 100644 index 000000000000..3176277428fa Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/AppPageLayout_spec.js/quickPageWizard.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js/emptydatasourcepage.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js/emptydatasourcepage.snap.png new file mode 100644 index 000000000000..81f625eaf03d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js/emptydatasourcepage.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorComment_spec.js/jsObjAfterCommenting1.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorComment_spec.js/jsObjAfterCommenting1.snap.png new file mode 100644 index 000000000000..18fd0e21a8ce Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorComment_spec.js/jsObjAfterCommenting1.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorComment_spec.js/jsObjBeforeCommenting1.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorComment_spec.js/jsObjBeforeCommenting1.snap.png new file mode 100644 index 000000000000..681fa19dddd3 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorComment_spec.js/jsObjBeforeCommenting1.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/formattedJSONBodyAfterSave.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/formattedJSONBodyAfterSave.snap.png new file mode 100644 index 000000000000..1a2d1f29be65 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/formattedJSONBodyAfterSave.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterGoLineStartSmart5.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterGoLineStartSmart5.snap.png new file mode 100644 index 000000000000..2f41c0c7bc88 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterGoLineStartSmart5.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify1.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify1.snap.png new file mode 100644 index 000000000000..b44855e6ec1b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify1.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify3.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify3.snap.png new file mode 100644 index 000000000000..83b57a605209 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify3.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify4.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify4.snap.png new file mode 100644 index 000000000000..31a0b5f3aa75 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify4.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify4_1.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify4_1.snap.png new file mode 100644 index 000000000000..ccc934d643b0 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjAfterPrettify4_1.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforeGoLineStartSmart5.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforeGoLineStartSmart5.snap.png new file mode 100644 index 000000000000..6920c5aba492 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforeGoLineStartSmart5.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify1.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify1.snap.png new file mode 100644 index 000000000000..74077f7389ee Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify1.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify2.snap.png new file mode 100644 index 000000000000..7108da59a4d2 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify3.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify3.snap.png new file mode 100644 index 000000000000..e6fedaa8626d Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify3.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify4.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify4.snap.png new file mode 100644 index 000000000000..61b330fcd0c3 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify4.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify6.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify6.snap.png new file mode 100644 index 000000000000..f321f76db33e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify6.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify7.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify7.snap.png new file mode 100644 index 000000000000..c53f61612fd4 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js/jsObjBeforePrettify7.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js/jsObjBeforeSaveAndPrettify.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js/jsObjBeforeSaveAndPrettify.snap.png new file mode 100644 index 000000000000..f321f76db33e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js/jsObjBeforeSaveAndPrettify.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js/inlineDisabled.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js/inlineDisabled.snap.png new file mode 100644 index 000000000000..01652bb72690 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js/inlineDisabled.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js/inlineEnabled.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js/inlineEnabled.snap.png new file mode 100644 index 000000000000..920c6825c68a Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js/inlineEnabled.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/2DCustomECharts.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/2DCustomECharts.snap.png new file mode 100644 index 000000000000..0b0303f400c2 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/2DCustomECharts.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/3DCustomECharts-2.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/3DCustomECharts-2.snap.png new file mode 100644 index 000000000000..5cf983b9e74b Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/3DCustomECharts-2.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/3DCustomECharts.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/3DCustomECharts.snap.png new file mode 100644 index 000000000000..a9b387047775 Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/3DCustomECharts.snap.png differ diff --git a/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/FusionCharts.snap.png b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/FusionCharts.snap.png new file mode 100644 index 000000000000..87e166130f9e Binary files /dev/null and b/app/client/cypress/snapshots/Regression/ClientSide/Widgets/Chart/Custom3DChartSpec.ts/FusionCharts.snap.png differ diff --git a/app/client/cypress/snapshots/Unknown error.snap.png b/app/client/cypress/snapshots/Unknown error.snap.png deleted file mode 100644 index d697a8dc8b73..000000000000 Binary files a/app/client/cypress/snapshots/Unknown error.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/VerificationPendingScreen.snap.png b/app/client/cypress/snapshots/VerificationPendingScreen.snap.png deleted file mode 100644 index ca5147576582..000000000000 Binary files a/app/client/cypress/snapshots/VerificationPendingScreen.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/Verified Token.snap.png b/app/client/cypress/snapshots/Verified Token.snap.png deleted file mode 100644 index 62763e0df339..000000000000 Binary files a/app/client/cypress/snapshots/Verified Token.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/WidgetsLayout_spec.js/inlineDisabled.snap.png b/app/client/cypress/snapshots/WidgetsLayout_spec.js/inlineDisabled.snap.png deleted file mode 100644 index b77ef05696a1..000000000000 Binary files a/app/client/cypress/snapshots/WidgetsLayout_spec.js/inlineDisabled.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/WidgetsLayout_spec.js/inlineEnabled.snap.png b/app/client/cypress/snapshots/WidgetsLayout_spec.js/inlineEnabled.snap.png deleted file mode 100644 index 4ef9d6efe187..000000000000 Binary files a/app/client/cypress/snapshots/WidgetsLayout_spec.js/inlineEnabled.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/WrongToken.snap.png b/app/client/cypress/snapshots/WrongToken.snap.png deleted file mode 100644 index 2410734218a4..000000000000 Binary files a/app/client/cypress/snapshots/WrongToken.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/areachartsnapshot.snap.png b/app/client/cypress/snapshots/chartwidget/areachartsnapshot.snap.png deleted file mode 100644 index 19f12d0e4e46..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/areachartsnapshot.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/areachartsnapshotwithlabels.snap.png b/app/client/cypress/snapshots/chartwidget/areachartsnapshotwithlabels.snap.png deleted file mode 100644 index d7168ce30819..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/areachartsnapshotwithlabels.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/columnchartsnapshot.snap.png b/app/client/cypress/snapshots/chartwidget/columnchartsnapshot.snap.png deleted file mode 100644 index ed10abc96733..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/columnchartsnapshot.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithadaptiveaxis.snap.png b/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithadaptiveaxis.snap.png deleted file mode 100644 index d67bf8abb713..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithadaptiveaxis.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithlabels.snap.png b/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithlabels.snap.png deleted file mode 100644 index 85ea6e291726..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithlabels.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithoutadaptiveaxis.snap.png b/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithoutadaptiveaxis.snap.png deleted file mode 100644 index c184abd328ec..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/columnchartsnapshotwithoutadaptiveaxis.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/linechartWithAutoXAxisLabelOrientation.snap.png b/app/client/cypress/snapshots/chartwidget/linechartWithAutoXAxisLabelOrientation.snap.png deleted file mode 100644 index 983bd2fac3b1..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/linechartWithAutoXAxisLabelOrientation.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/linechartWithRotateXAxisLabelOrientation.snap.png b/app/client/cypress/snapshots/chartwidget/linechartWithRotateXAxisLabelOrientation.snap.png deleted file mode 100644 index e0a524f6e2b7..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/linechartWithRotateXAxisLabelOrientation.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/linechartWithSlantXAxisLabelOrientation.snap.png b/app/client/cypress/snapshots/chartwidget/linechartWithSlantXAxisLabelOrientation.snap.png deleted file mode 100644 index 99f54011aa2c..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/linechartWithSlantXAxisLabelOrientation.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/linechartsnapshot.snap.png b/app/client/cypress/snapshots/chartwidget/linechartsnapshot.snap.png deleted file mode 100644 index 4ce11795c651..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/linechartsnapshot.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/linechartsnapshotwithlabels.snap.png b/app/client/cypress/snapshots/chartwidget/linechartsnapshotwithlabels.snap.png deleted file mode 100644 index c07975dbfc4e..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/linechartsnapshotwithlabels.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/piechartsnapshot.snap.png b/app/client/cypress/snapshots/chartwidget/piechartsnapshot.snap.png deleted file mode 100644 index 646158018126..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/piechartsnapshot.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/piechartsnapshotwithlabels.snap.png b/app/client/cypress/snapshots/chartwidget/piechartsnapshotwithlabels.snap.png deleted file mode 100644 index d84973a5e466..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/piechartsnapshotwithlabels.snap.png and /dev/null differ diff --git a/app/client/cypress/snapshots/chartwidget/piechartsnapshotwithtitle.snap.png b/app/client/cypress/snapshots/chartwidget/piechartsnapshotwithtitle.snap.png deleted file mode 100644 index 05acfe7fbe9d..000000000000 Binary files a/app/client/cypress/snapshots/chartwidget/piechartsnapshotwithtitle.snap.png and /dev/null differ diff --git a/app/client/cypress/support/Objects/CommonLocators.ts b/app/client/cypress/support/Objects/CommonLocators.ts index 3152737bfa05..3db2224e7c1f 100644 --- a/app/client/cypress/support/Objects/CommonLocators.ts +++ b/app/client/cypress/support/Objects/CommonLocators.ts @@ -338,4 +338,5 @@ export class CommonLocators { errorPageDescription = ".t--error-page-description"; _selectClearButton_testId = "selectbutton.btn.cancel"; _selectClearButton_dataTestId = `[data-testid="${this._selectClearButton_testId}"]`; + _saveDatasource = `[data-testid='t--store-as-datasource']`; } diff --git a/app/client/cypress/support/Pages/Anvil/AnvilSnapshot.ts b/app/client/cypress/support/Pages/Anvil/AnvilSnapshot.ts index ff0e6f378454..356e16994c36 100644 --- a/app/client/cypress/support/Pages/Anvil/AnvilSnapshot.ts +++ b/app/client/cypress/support/Pages/Anvil/AnvilSnapshot.ts @@ -19,7 +19,6 @@ export class AnvilSnapshot { densityOptions: "[data-testid=t--anvil-theme-settings-density] > div", sizingOptions: "[data-testid=t--anvil-theme-settings-sizing] > div", cornersOptions: "[data-testid=t--anvil-theme-settings-corners] > div", - iconStyleOptions: "[data-testid=t--anvil-theme-settings-icon-style] > div", }; /** @@ -40,11 +39,7 @@ export class AnvilSnapshot { `anvil_${name}$_${mode}${theme == "dark" ? "_dark" : ""}${size ? `_${size}` : ""}`, ); - this.agHelper.GetElement(locator).matchImageSnapshot(snapshotName, { - comparisonMethod: "ssim", - failureThreshold: 0.01, - failureThresholdType: "percent", - }); + this.agHelper.GetElement(locator).matchImageSnapshot(snapshotName); } public matchSnapshotForCanvasMode = ( @@ -167,14 +162,6 @@ export class AnvilSnapshot { }); }; - public setIconStyle = (iconStyle: string) => { - this.updateThemeOption(() => { - cy.get(this.locators.iconStyleOptions) - .contains(iconStyle) - .click({ force: true }); - }); - }; - public updateThemeOption = (callback: () => void) => { this.appSettings.OpenAppSettings(); this.appSettings.GoToThemeSettings(); diff --git a/app/client/cypress/support/Pages/DataSources.ts b/app/client/cypress/support/Pages/DataSources.ts index 11865a352994..35777482759a 100644 --- a/app/client/cypress/support/Pages/DataSources.ts +++ b/app/client/cypress/support/Pages/DataSources.ts @@ -201,7 +201,7 @@ export class DataSources { ".t--datasource-name:contains('" + dsName + "')"; _mandatoryMark = "//span[text()='*']"; _deleteDSHostPort = ".t--delete-field"; - + _dsTabSchema = "[data-testid='t--tab-schema']"; private _pageSelectionMenu = "[data-testId='t--page-selection']"; private _pageSelectMenuItem = ".ads-v2-menu__menu-item"; @@ -1371,7 +1371,7 @@ export class DataSources { expectedTableName = search, ) { this.agHelper.Sleep(2500); //for query editor to load - this.agHelper.TypeText(this._datasourceStructureSearchInput, search); + this.agHelper.ClearNType(this._datasourceStructureSearchInput, search); this.agHelper.Sleep(1000); //for search result to load this.VerifyTableSchemaOnQueryEditor(expectedTableName); } diff --git a/app/client/cypress/support/Pages/Table.ts b/app/client/cypress/support/Pages/Table.ts index c82f7e9a0548..2f90efb052c7 100644 --- a/app/client/cypress/support/Pages/Table.ts +++ b/app/client/cypress/support/Pages/Table.ts @@ -59,6 +59,15 @@ export class Table { _tableRow = (rowNum: number, colNum: number, version: "v1" | "v2") => this._tableWidgetVersion(version) + ` .tbody .td[data-rowindex=${rowNum}][data-colindex=${colNum}]`; + _tableColumnDataWithText = ( + colNum: number, + columnText: string, + version: "v1" | "v2", + ) => + this._tableWidgetVersion(version) + + ` .tbody .td[data-colindex=${colNum}]` + + this._tableRowColumnDataVersion(version) + + ` div:contains("${columnText}")`; _editCellIconDiv = ".t--editable-cell-icon"; _editCellEditor = ".t--inlined-cell-editor"; _editCellEditorInput = this._editCellEditor + " input"; diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 97c4b996ed0f..eaf1a4c86ca7 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -12,16 +12,11 @@ import EditorNavigation, { require("cy-verify-downloads").addCustomCommand(); require("cypress-file-upload"); -//require('cy-verify-downloads').addCustomCommand(); const path = require("path"); import { v4 as uuidv4 } from "uuid"; const dayjs = require("dayjs"); -const { - addMatchImageSnapshotCommand, -} = require("cypress-image-snapshot/command"); const loginPage = require("../locators/LoginPage.json"); -const signupPage = require("../locators/SignupPage.json"); import homePage from "../locators/HomePage"; const commonlocators = require("../locators/commonlocators.json"); @@ -32,11 +27,9 @@ import { CURRENT_REPO, REPO } from "../fixtures/REPO"; const apiwidget = require("../locators/apiWidgetslocator.json"); const explorer = require("../locators/explorerlocators.json"); const datasource = require("../locators/DatasourcesEditor.json"); -const viewWidgetsPage = require("../locators/ViewWidgets.json"); const jsEditorLocators = require("../locators/JSEditor.json"); const queryLocators = require("../locators/QueryEditor.json"); const welcomePage = require("../locators/welcomePage.json"); -const publishWidgetspage = require("../locators/publishWidgetspage.json"); import { ObjectsRegistry } from "../support/Objects/Registry"; import RapidMode from "./RapidMode"; import { featureFlagIntercept } from "./Objects/FeatureFlags"; @@ -51,7 +44,6 @@ const assertHelper = ObjectsRegistry.AssertHelper; const homePageTS = ObjectsRegistry.HomePage; const table = ObjectsRegistry.Table; -let pageidcopy = " "; const chainStart = Symbol(); export const initLocalstorage = () => { @@ -99,16 +91,6 @@ export const addIndexedDBKey = (key, value) => { }); }; -// Cypress.Commands.add("goToEditFromPublish", () => { -// cy.url().then((url) => { -// const urlObject = new URL(url); -// if (!urlObject.pathname.includes("edit")) { -// urlObject.pathname = urlObject.pathname + "/edit"; -// cy.visit(urlObject.toString()); -// } -// }); -// }); - Cypress.Commands.add("stubPostHeaderReq", () => { cy.intercept("POST", "/api/v1/users/invite", (req) => { req.headers["origin"] = "Cypress"; @@ -234,13 +216,6 @@ Cypress.Commands.add("LoginFromAPI", (uname, pword) => { Cypress.Commands.add("LogOut", (toCheckgetPluginForm = true) => { agHelper.WaitUntilAllToastsDisappear(); - //Since these are coming in every self-hosted 1st time login, commenting for CI runs - // agHelper.AssertElementAbsence( - // locators._specificToast("There was an unexpected error"), - // ); - // agHelper.AssertElementAbsence( - // locators._specificToast("Internal server error while processing request"), - // ); // Logout is a POST request in CE let httpMethod = "POST"; @@ -323,28 +298,6 @@ Cypress.Commands.add( }, ); -// Cypress.Commands.add("PublishtheApp", (validateSavedState = true) => { -// //cy.server(); -// cy.intercept("POST", "/api/v1/applications/publish/*").as("publishApp"); -// // Wait before publish -// // eslint-disable-next-line cypress/no-unnecessary-waiting -// cy.wait(2000); -// cy.assertPageSave(validateSavedState); - -// // 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); -// window.location.target = "_self"; -// }); -// }); - -// cy.get(homePage.publishButton).click(); -// cy.wait("@publishApp"); -// cy.log("pagename: " + localStorage.getItem("PageName")); -// cy.wait(1000); //wait time for page to load! -// }); - Cypress.Commands.add("tabPopertyUpdate", (tabId, newTabName) => { cy.get("[data-rbd-draggable-id='" + tabId + "'] input") .scrollIntoView() @@ -760,10 +713,6 @@ Cypress.Commands.add("startServerAndRoutes", () => { }, ).as("connectGitLocalRepo"); - // cy.intercept({ - // method: "PUT", - // }).as("sucessSave"); - cy.intercept("POST", "https://api.segment.io/v1/b", (req) => { req.reply({ statusCode: 200, @@ -1026,12 +975,6 @@ Cypress.Commands.add( }); } cy.EvaluateCurrentValue(valueToType, isDynamic); - // cy.xpath("//p[text()='" + fieldName + "']/following-sibling::div//div[@class='CodeMirror-code']//span/span").should((fieldValue) => { - // textF = fieldValue.innerText - // fieldValue.innerText = "" - // }).then(() => { - // cy.log("current field value is : '" + textF + "'") - // }) }, ); @@ -1061,15 +1004,6 @@ Cypress.Commands.add( cy.wrap($field).invoke("text"); }); } - //cy.wait(3000); //Increasing wait time to evaluate non-undefined values - // if (isDynamicValue) { - // const val = cy - // .get(commonlocators.evaluatedCurrentValue) - // .first() - // .should("be.visible") - // .invoke("text"); - // if (toValidate) expect(val).to.eq(currentValue); - // } if (currentValue) expect(val).to.eq(currentValue); return val; @@ -1113,8 +1047,6 @@ Cypress.Commands.add("getEntityName", () => { }); Cypress.Commands.add("VerifyErrorMsgAbsence", (errorMsgToVerifyAbsence) => { - // Give this element 10 seconds to appear - //cy.wait(10000) cy.xpath( "//div[@class='Toastify']//span[contains(text(),'" + errorMsgToVerifyAbsence + @@ -1124,8 +1056,6 @@ Cypress.Commands.add("VerifyErrorMsgAbsence", (errorMsgToVerifyAbsence) => { }); Cypress.Commands.add("VerifyErrorMsgPresence", (errorMsgToVerifyAbsence) => { - // Give this element 10 seconds to appear - //cy.wait(10000) cy.xpath( "//div[@class='Toastify']//span[contains(text(),'" + errorMsgToVerifyAbsence + @@ -1140,18 +1070,6 @@ Cypress.Commands.add("setQueryTimeout", (timeout) => { cy.xpath(queryLocators.query).click(); }); -// Cypress.Commands.add('isNotInViewport', element => { -// cy.xpath(element).then($el => { -// const bottom = Cypress.$(cy.state('window')).height() -// const rect = $el[0].getBoundingClientRect() - -// expect(rect.top).to.be.greaterThan(bottom) -// expect(rect.bottom).to.be.greaterThan(bottom) -// expect(rect.top).to.be.greaterThan(bottom) -// expect(rect.bottom).to.be.greaterThan(bottom) -// }) -// }) - Cypress.Commands.add("isInViewport", (element) => { cy.xpath(element) .scrollIntoView() @@ -1170,16 +1088,6 @@ Cypress.Commands.add("validateEvaluatedValue", (value) => { cy.get(".t-property-evaluated-value").should("contain", value); }); -// Cypress.Commands.overwrite("type", (originalFn, element, text, options) => { -// const clearedText = '{selectall}{backspace}'+`${text}`; -// return originalFn(element, clearedText, options); -// }); - -addMatchImageSnapshotCommand({ - failureThreshold: 0.15, // threshold for entire image - failureThresholdType: "percent", -}); - Cypress.Commands.add("DeleteEntityStateLocalStorage", () => { let currentURL; let appId; diff --git a/app/client/cypress/support/e2e.js b/app/client/cypress/support/e2e.js index eb8b6adae26b..166329ed8e0c 100644 --- a/app/client/cypress/support/e2e.js +++ b/app/client/cypress/support/e2e.js @@ -21,7 +21,6 @@ import "cypress-network-idle"; import "cypress-xpath"; import * as MESSAGES from "../../src/ce/constants/messages.ts"; import "./ApiCommands"; -// Import commands.js using ES2015 syntax: import "./commands"; import { initLocalstorage, addIndexedDBKey } from "./commands"; import "./dataSourceCommands"; @@ -31,6 +30,7 @@ import RapidMode from "./RapidMode.ts"; import "cypress-mochawesome-reporter/register"; import installLogsCollector from "cypress-terminal-report/src/installLogsCollector"; import { CURRENT_REPO, REPO } from "../fixtures/REPO"; +import { addMatchImageSnapshotCommand } from "@simonsmith/cypress-image-snapshot/command"; import "./WorkspaceCommands"; import "./queryCommands"; @@ -48,8 +48,13 @@ const registerCypressGrep = require("@cypress/grep"); registerCypressGrep(); installLogsCollector(); +addMatchImageSnapshotCommand({ + comparisonMethod: "ssim", + failureThreshold: 0.01, + failureThresholdType: "percent", +}); + Cypress.on("uncaught:exception", (error) => { - //cy.log(error.message); return false; // returning false here prevents Cypress from failing the test }); @@ -59,7 +64,6 @@ Cypress.on("fail", (error) => { }); Cypress.env("MESSAGES", MESSAGES); -let dataSet; // Declare a variable to hold the test data before(function () { if (RapidMode.config.enabled) { @@ -70,7 +74,6 @@ before(function () { } }); - //Cypress.Cookies.preserveOnce("SESSION", "remember_token"); if (!RapidMode.config.usesDSL) { cy.visit(RapidMode.url()); cy.wait("@getWorkspace"); @@ -82,7 +85,6 @@ before(function () { if (RapidMode.config.enabled) { return; } - //console.warn = () => {}; //to remove all warnings in cypress console initLocalstorage(); initLocalstorageRegistry(); cy.startServerAndRoutes(); @@ -144,7 +146,6 @@ before(function () { binding_widget: true, }); } - //console.warn = () => {}; cy.CreateNewAppInNewWorkspace(); //Creating new workspace and app cy.fixture("TestDataSet1").then(function (data) { @@ -153,12 +154,10 @@ before(function () { }); beforeEach(function () { - //cy.window().then((win) => (win.onbeforeunload = undefined)); if (!navigator.userAgent.includes("Cypress")) { window.addEventListener("beforeunload", this.beforeunloadFunction); } initLocalstorage(); - //Cypress.Cookies.preserveOnce("SESSION", "remember_token"); cy.startServerAndRoutes(); //-- Delete local storage data of entity explorer cy.DeleteEntityStateLocalStorage(); @@ -174,10 +173,4 @@ after(function () { //-- Deleting the application by Api---// cy.DeleteAppByApi(); cy.DeleteWorkspaceByApi(); - //-- LogOut Application---// - //cy.LogOut(false); - // Commenting until Upgrade Appsmith cases are fixed - // const tedUrl = "http://localhost:5001/v1/parent/cmd"; - // cy.log("Start the appsmith container"); - // cy.StartContainer(tedUrl, "appsmith"); // start the old container }); diff --git a/app/client/cypress/tsconfig.json b/app/client/cypress/tsconfig.json index 1e80a45b6ef7..81a096eaeabe 100644 --- a/app/client/cypress/tsconfig.json +++ b/app/client/cypress/tsconfig.json @@ -30,7 +30,13 @@ "sourceMap": true, "baseUrl": "./cypress", "noFallthroughCasesInSwitch": true, - "types": ["cypress", "node", "cypress-tags", "cypress-real-events"] + "types": [ + "cypress", + "node", + "cypress-tags", + "cypress-real-events", + "@simonsmith/cypress-image-snapshot/types" + ] }, "include": ["./", "../packages/rts/src/version.js"] } diff --git a/app/client/cypress_ci.config.ts b/app/client/cypress_ci.config.ts index 3b27c62ba63a..7216004148a0 100644 --- a/app/client/cypress_ci.config.ts +++ b/app/client/cypress_ci.config.ts @@ -1,3 +1,4 @@ +import { addMatchImageSnapshotPlugin } from "@simonsmith/cypress-image-snapshot/plugin"; import { defineConfig } from "cypress"; export default defineConfig({ @@ -25,6 +26,7 @@ export default defineConfig({ e2e: { baseUrl: "http://localhost/", setupNodeEvents(on, config) { + addMatchImageSnapshotPlugin(on); require("@cypress/grep/src/plugin")(config); return require("./cypress/plugins/index.js")(on, config); }, diff --git a/app/client/cypress_ci_custom.config.ts b/app/client/cypress_ci_custom.config.ts index 48eff0a0adb3..4d1538bca259 100644 --- a/app/client/cypress_ci_custom.config.ts +++ b/app/client/cypress_ci_custom.config.ts @@ -1,3 +1,4 @@ +import { addMatchImageSnapshotPlugin } from "@simonsmith/cypress-image-snapshot/plugin"; import { defineConfig } from "cypress"; import fs from "fs"; @@ -34,6 +35,7 @@ export default defineConfig({ grepOmitFiltered: true, }, setupNodeEvents(on, config) { + addMatchImageSnapshotPlugin(on); require("cypress-mochawesome-reporter/plugin")(on); on( "after:spec", diff --git a/app/client/cypress_ci_hosted.config.ts b/app/client/cypress_ci_hosted.config.ts index 2bcd5a382aa0..ba4fa4b155c0 100644 --- a/app/client/cypress_ci_hosted.config.ts +++ b/app/client/cypress_ci_hosted.config.ts @@ -1,3 +1,4 @@ +import { addMatchImageSnapshotPlugin } from "@simonsmith/cypress-image-snapshot/plugin"; import { defineConfig } from "cypress"; import fs from "fs"; @@ -31,6 +32,7 @@ export default defineConfig({ e2e: { baseUrl: "https://regression.test.appsmith.com/", setupNodeEvents(on, config) { + addMatchImageSnapshotPlugin(on); require("cypress-mochawesome-reporter/plugin")(on); on( "after:spec", diff --git a/app/client/package.json b/app/client/package.json index 592cf597a377..500d3c2a328d 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -89,7 +89,6 @@ "@tanstack/virtual-core": "^3.0.0-beta.18", "@tinymce/tinymce-react": "^5.1.1", "@types/babel__standalone": "^7.1.7", - "@types/cypress-image-snapshot": "^3.1.9", "@types/d3-geo": "^3.1.0", "@types/google.maps": "^3.51.0", "@types/react-page-visibility": "^6.4.1", @@ -164,7 +163,7 @@ "node-forge": "^1.3.0", "normalizr": "^3.3.0", "object-hash": "^3.0.0", - "path-to-regexp": "^6.2.0", + "path-to-regexp": "^6.3.0", "popper.js": "^1.15.0", "prismjs": "^1.27.0", "proxy-memoize": "^1.2.0", @@ -262,6 +261,7 @@ "@peculiar/webcrypto": "^1.4.3", "@redux-saga/testing-utils": "^1.1.5", "@sentry/webpack-plugin": "^1.18.9", + "@simonsmith/cypress-image-snapshot": "^9.1.0", "@testing-library/jest-dom": "5.16.1", "@testing-library/react": "12.1.2", "@testing-library/react-hooks": "^8.0.1", @@ -322,7 +322,6 @@ "cy-verify-downloads": "^0.0.5", "cypress": "13.13.0", "cypress-file-upload": "^4.1.1", - "cypress-image-snapshot": "^4.0.1", "cypress-mochawesome-reporter": "^3.5.1", "cypress-multi-reporters": "^1.2.4", "cypress-network-idle": "^1.14.2", diff --git a/app/client/packages/design-system/theming/src/hooks/src/index.ts b/app/client/packages/design-system/theming/src/hooks/src/index.ts index f8d6541c98fa..7c0c56efa008 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/index.ts +++ b/app/client/packages/design-system/theming/src/hooks/src/index.ts @@ -3,3 +3,5 @@ export * from "./useSpacing"; export * from "./useTypography"; export * from "./useTheme"; export * from "./useCssTokens"; +export * from "./useIconDensity"; +export * from "./useIconSizing"; diff --git a/app/client/packages/design-system/theming/src/hooks/src/useCssTokens.tsx b/app/client/packages/design-system/theming/src/hooks/src/useCssTokens.tsx index 56deb1ea41db..b5e30df72fe3 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/useCssTokens.tsx +++ b/app/client/packages/design-system/theming/src/hooks/src/useCssTokens.tsx @@ -1,22 +1,21 @@ import { css } from "@emotion/css"; -import { useEffect, useState } from "react"; -import { cssRule, getTypographyClassName } from "../../utils"; +import { useMemo } from "react"; +import { objectKeys } from "@appsmith/utils"; import type { Theme } from "../../theme"; -import type { FontFamily, ThemeToken, Typography } from "../../token"; +import type { ThemeToken, Typography } from "../../token"; +import { cssRule, getTypographyClassName } from "../../utils"; -const fontFamilyCss = (fontFamily?: FontFamily) => { +const fontFamilyCss = () => { const fontFamilyCss = - fontFamily && fontFamily !== "System Default" - ? `${fontFamily}, sans-serif` - : "-apple-system, 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Ubuntu', sans-serif"; + "-apple-system, 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Ubuntu', sans-serif"; return `font-family: ${fontFamilyCss}; --font-family: ${fontFamilyCss}`; }; const getTypographyCss = (typography: Typography) => { return css` - ${Object.keys(typography).reduce((prev, key) => { + ${objectKeys(typography).reduce((prev, key) => { const currentKey = key as keyof Typography; const { after, before, fontSize, lineHeight } = typography[currentKey]; return ( @@ -55,47 +54,39 @@ const getColorCss = (color: ThemeToken["color"]) => { }; export function useCssTokens(props: Theme) { - const { color, colorMode, fontFamily, typography, ...restTokens } = props; + const { color, colorMode, typography, ...restTokens } = props; - const [colorClassName, setColorClassName] = useState(); - const [colorModeClassName, setColorModeClassName] = useState(); - const [fontFamilyClassName, setFontFamilyClassName] = useState(); - const [typographyClassName, setTypographyClassName] = useState(); - const [providerClassName, setProviderClassName] = useState(); - - useEffect(() => { + const colorClassName = useMemo(() => { if (color != null) { - setColorClassName(css` + return css` ${getColorCss(color)} - `); + `; } }, [color]); - useEffect(() => { + const typographyClassName = useMemo(() => { if (typography != null) { - setTypographyClassName(css` + return css` ${getTypographyCss(typography)} - `); + `; } }, [typography]); - useEffect(() => { - setFontFamilyClassName(css` - ${fontFamilyCss(fontFamily)} - `); - }, [fontFamily]); + const fontFamilyClassName = css` + ${fontFamilyCss()} + `; - useEffect(() => { - setProviderClassName(css` + const providerClassName = useMemo(() => { + return css` ${cssRule(restTokens)}; - `); + `; }, [restTokens]); - useEffect(() => { + const colorModeClassName = useMemo(() => { if (colorMode != null) { - setColorModeClassName(css` + return css` color-scheme: ${colorMode}; - `); + `; } }, [colorMode]); diff --git a/app/client/packages/design-system/theming/src/hooks/src/useIconDensity.tsx b/app/client/packages/design-system/theming/src/hooks/src/useIconDensity.tsx index 8d4b3dad0e1b..e8e170a1994c 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/useIconDensity.tsx +++ b/app/client/packages/design-system/theming/src/hooks/src/useIconDensity.tsx @@ -1,23 +1,17 @@ -import { useEffect, useState } from "react"; -import type { IconDensity, TokenObj } from "../../token"; +import { useMemo } from "react"; +import type { IconDensity } from "../../token"; export const useIconDensity = (density: IconDensity, userDensity = 1) => { - const [strokeWidth, setStrokeWidth] = useState(); - - useEffect(() => { + const strokeWidth = useMemo(() => { switch (true) { case userDensity < 1: - setStrokeWidth(density.tight); - break; + return density.tight; case userDensity === 1: - setStrokeWidth(density.regular); - break; + return density.regular; case userDensity > 1: - setStrokeWidth(density.loose); - break; + return density.loose; default: - setStrokeWidth(density.regular); - break; + return density.regular; } }, [userDensity, density]); diff --git a/app/client/packages/design-system/theming/src/hooks/src/useIconSizing.tsx b/app/client/packages/design-system/theming/src/hooks/src/useIconSizing.tsx index 51ddc60c7a71..02c1da490056 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/useIconSizing.tsx +++ b/app/client/packages/design-system/theming/src/hooks/src/useIconSizing.tsx @@ -1,23 +1,17 @@ -import { useEffect, useState } from "react"; -import type { IconSizing, TokenObj } from "../../token"; +import { useMemo } from "react"; +import type { IconSizing } from "../../token"; export const useIconSizing = (sizing: IconSizing, userSizing = 1) => { - const [iconSize, setIconSize] = useState(); - - useEffect(() => { + const iconSize = useMemo(() => { switch (true) { case userSizing < 1: - setIconSize(sizing.small); - break; + return sizing.small; case userSizing === 1: - setIconSize(sizing.regular); - break; + return sizing.regular; case userSizing > 1: - setIconSize(sizing.big); - break; + return sizing.big; default: - setIconSize(sizing.regular); - break; + return sizing.regular; } }, [userSizing, sizing]); diff --git a/app/client/packages/design-system/theming/src/hooks/src/useSizing.tsx b/app/client/packages/design-system/theming/src/hooks/src/useSizing.tsx index 047ed16f138a..14cde9b5f7ec 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/useSizing.tsx +++ b/app/client/packages/design-system/theming/src/hooks/src/useSizing.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useMemo } from "react"; import { calculateScales } from "./calculateScales"; import type { TokenObj, TokenScaleConfig } from "../../token"; @@ -8,7 +8,7 @@ export const getSizing = ( userDensity = 1, userSizing = 1, count = 200, -) => { +): TokenObj => { const { userDensityRatio = 1, userSizingRatio = 1, V, ...rest } = sizing; const ratio = userDensity * userDensityRatio + userSizing * userSizingRatio; @@ -35,11 +35,9 @@ export const useSizing = ( userDensity = 1, userSizing = 1, ) => { - const [sizing, setSizing] = useState(); - - useEffect(() => { - setSizing(getSizing(config, userDensity, userSizing)); - }, [userDensity, userSizing, config]); + const sizing = useMemo(() => { + return getSizing(config, userDensity, userSizing); + }, [config, userDensity, userSizing]); return { sizing, diff --git a/app/client/packages/design-system/theming/src/hooks/src/useSpacing.tsx b/app/client/packages/design-system/theming/src/hooks/src/useSpacing.tsx index 7cbc7bb65868..aeba5c8907b6 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/useSpacing.tsx +++ b/app/client/packages/design-system/theming/src/hooks/src/useSpacing.tsx @@ -1,7 +1,7 @@ -import { useEffect, useState } from "react"; +import { useMemo } from "react"; import { calculateScales } from "./calculateScales"; -import type { TokenObj, TokenScaleConfig } from "../../token"; +import type { TokenScaleConfig } from "../../token"; export const getSpacing = ( spacing: TokenScaleConfig, @@ -36,16 +36,13 @@ export const useSpacing = ( userDensity = 1, userSizing = 1, ) => { - const [outerSpacing, setOuterSpacing] = useState(); - const [innerSpacing, setInnerSpacing] = useState(); + const outerSpacing = useMemo(() => { + return getSpacing(outerSpacingConfig, userDensity, userSizing); + }, [outerSpacingConfig, userDensity, userSizing]); - useEffect(() => { - setOuterSpacing(getSpacing(outerSpacingConfig, userDensity, userSizing)); - }, [userDensity, userSizing, outerSpacingConfig]); - - useEffect(() => { - setInnerSpacing(getSpacing(innerSpacingConfig, userDensity, userSizing)); - }, [userDensity, userSizing, innerSpacingConfig]); + const innerSpacing = useMemo(() => { + return getSpacing(innerSpacingConfig, userDensity, userSizing); + }, [innerSpacingConfig, userDensity, userSizing]); return { outerSpacing, diff --git a/app/client/packages/design-system/theming/src/hooks/src/useTheme.tsx b/app/client/packages/design-system/theming/src/hooks/src/useTheme.tsx index 908f268f56eb..7cee09699342 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/useTheme.tsx +++ b/app/client/packages/design-system/theming/src/hooks/src/useTheme.tsx @@ -1,12 +1,16 @@ import Color from "colorjs.io"; -import { useEffect, useState } from "react"; +import { useMemo } from "react"; import { TokensAccessor, defaultTokens, tokensConfigs } from "../../token"; -import { useSizing, useSpacing, useTypography } from "./"; +import { + useSizing, + useSpacing, + useTypography, + useIconSizing, + useIconDensity, +} from "./"; import type { ColorMode } from "../../color"; -import type { TokenSource, FontFamily, IconStyle } from "../../token"; -import { useIconDensity } from "./useIconDensity"; -import { useIconSizing } from "./useIconSizing"; +import type { TokenSource } from "../../token"; const tokensAccessor = new TokensAccessor({ ...(defaultTokens as TokenSource), @@ -16,18 +20,14 @@ export interface UseThemeProps { seedColor?: string; colorMode?: ColorMode; borderRadius?: string; - fontFamily?: FontFamily; userDensity?: number; userSizing?: number; - iconStyle?: IconStyle; } export function useTheme(props: UseThemeProps = {}) { const { borderRadius, colorMode = "light", - fontFamily, - iconStyle = "outlined", seedColor, userDensity = 1, userSizing = 1, @@ -42,168 +42,83 @@ export function useTheme(props: UseThemeProps = {}) { ); const { typography } = useTypography( tokensConfigs.typography, - fontFamily, userDensity, userSizing, ); - const { iconSize } = useIconSizing(tokensConfigs.icon.sizing, userSizing); - const { strokeWidth } = useIconDensity( tokensConfigs.icon.density, userDensity, ); - const [theme, setTheme] = useState(tokensAccessor.getAllTokens); - - useEffect(() => { - if (colorMode) { - tokensAccessor.updateColorMode(colorMode); + const theme = useMemo(() => { + // Color mode + tokensAccessor.updateColorMode(colorMode); - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getColors(), - colorMode: tokensAccessor.getColorMode(), - }; - }); - } - }, [colorMode]); - - useEffect(() => { + // Border radius if (borderRadius != null) { tokensAccessor.updateBorderRadiusElevation({ ...defaultTokens.borderRadiusElevation, base: borderRadius, }); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getBorderRadiusElevation(), - }; - }); } - }, [borderRadius]); - useEffect(() => { + // Seed color if (seedColor != null) { - let color; - try { - color = Color.parse(seedColor); + Color.parse(seedColor); + tokensAccessor.updateSeedColor(seedColor); } catch (error) { // eslint-disable-next-line no-console console.error(error); - return; // Prevent further execution if color parsing fails - } - - if (color != null) { - tokensAccessor.updateSeedColor(seedColor); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getColors(), - }; - }); } } - }, [seedColor]); - useEffect(() => { - // Check typography, as fontFamily may be undefined + // Typography if (typography != null) { - tokensAccessor.updateFontFamily(fontFamily); tokensAccessor.updateTypography(typography); - - setTheme((prevState) => { - return { - ...prevState, - typography: tokensAccessor.getTypography(), - fontFamily: tokensAccessor.getFontFamily(), - }; - }); - } - }, [typography, fontFamily]); - - useEffect(() => { - if (sizing) { - tokensAccessor.updateSizing(sizing); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getSizing(), - }; - }); - } - }, [sizing]); - - useEffect(() => { - if (outerSpacing) { - tokensAccessor.updateOuterSpacing(outerSpacing); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getOuterSpacing(), - }; - }); - } - }, [outerSpacing]); - - useEffect(() => { - if (innerSpacing) { - tokensAccessor.updateInnerSpacing(innerSpacing); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getInnerSpacing(), - }; - }); } - }, [innerSpacing]); - useEffect(() => { - if (iconStyle) { - tokensAccessor.updateIconStyle(iconStyle); + // Sizing + tokensAccessor.updateSizing(sizing); - setTheme((prevState) => { - return { - ...prevState, - iconStyle: tokensAccessor.getIconStyle(), - }; - }); - } - }, [iconStyle]); + // Spacing + tokensAccessor.updateOuterSpacing(outerSpacing); + tokensAccessor.updateInnerSpacing(innerSpacing); - useEffect(() => { + // Icon size if (iconSize != null) { tokensAccessor.updateIconSize(iconSize); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getIconSize(), - }; - }); } - }, [iconSize]); - useEffect(() => { + // Stroke width if (strokeWidth != null) { tokensAccessor.updateStrokeWidth(strokeWidth); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getStrokeWidth(), - }; - }); } - }, [strokeWidth]); - return { theme, setTheme }; + return { + ...tokensAccessor.getAllTokens(), + ...tokensAccessor.getColors(), + colorMode: tokensAccessor.getColorMode(), + ...tokensAccessor.getBorderRadiusElevation(), + typography: tokensAccessor.getTypography(), + ...tokensAccessor.getSizing(), + ...tokensAccessor.getOuterSpacing(), + ...tokensAccessor.getInnerSpacing(), + ...tokensAccessor.getIconSize(), + ...tokensAccessor.getStrokeWidth(), + }; + }, [ + colorMode, + borderRadius, + seedColor, + typography, + sizing, + outerSpacing, + innerSpacing, + iconSize, + strokeWidth, + ]); + + return { theme }; } diff --git a/app/client/packages/design-system/theming/src/hooks/src/useTypography.tsx b/app/client/packages/design-system/theming/src/hooks/src/useTypography.tsx index 21cfaaa61258..05380e99d634 100644 --- a/app/client/packages/design-system/theming/src/hooks/src/useTypography.tsx +++ b/app/client/packages/design-system/theming/src/hooks/src/useTypography.tsx @@ -1,29 +1,20 @@ -import { useEffect, useState } from "react"; -import { FONT_METRICS, TYPOGRAPHY_VARIANTS } from "../../token"; +import { useMemo } from "react"; import { calculateScales } from "./calculateScales"; import { createStyleObject } from "@capsizecss/core"; import appleSystem from "@capsizecss/metrics/appleSystem"; import type { - FontFamily, Typography, TypographyVariantMetric, TokenScaleConfig, } from "../../token"; - -const getFontMetrics = (fontFamily?: FontFamily) => { - return !Boolean(fontFamily) || - fontFamily == null || - fontFamily === "System Default" - ? appleSystem - : FONT_METRICS[fontFamily]; -}; +import { TYPOGRAPHY_VARIANTS } from "../../token/src/types"; +import { objectKeys } from "@appsmith/utils"; export const getTypography = ( typography: TokenScaleConfig, userDensity = 1, userSizing = 1, - fontFamily?: FontFamily, ) => { const { userDensityRatio = 1, userSizingRatio = 1, V, ...rest } = typography; const ratio = userDensity * userDensityRatio + userSizing * userSizingRatio; @@ -37,7 +28,7 @@ export const getTypography = ( const typographyStyle = createStyleObject({ capHeight: currentValue, lineGap: currentValue, - fontMetrics: getFontMetrics(fontFamily), + fontMetrics: appleSystem, }); metrics.push({ @@ -46,12 +37,13 @@ export const getTypography = ( before: typographyStyle["::before"], after: typographyStyle["::after"], }); + return metrics; }, [], ); - return Object.keys(TYPOGRAPHY_VARIANTS).reduce((prev, current, index) => { + return objectKeys(TYPOGRAPHY_VARIANTS).reduce((prev, current, index) => { return { ...prev, [current]: styles[index], @@ -61,15 +53,12 @@ export const getTypography = ( export const useTypography = ( config: TokenScaleConfig, - fontFamily?: FontFamily, userDensity = 1, userSizing = 1, ) => { - const [typography, setTypography] = useState(null); - - useEffect(() => { - setTypography(getTypography(config, userDensity, userSizing, fontFamily)); - }, [userDensity, userSizing, fontFamily, config]); + const typography = useMemo(() => { + return getTypography(config, userDensity, userSizing); + }, [config, userDensity, userSizing]); return { typography, diff --git a/app/client/packages/design-system/theming/src/theme/src/ThemeProvider.tsx b/app/client/packages/design-system/theming/src/theme/src/ThemeProvider.tsx index 8dddca61b732..1cfb2f1bb634 100644 --- a/app/client/packages/design-system/theming/src/theme/src/ThemeProvider.tsx +++ b/app/client/packages/design-system/theming/src/theme/src/ThemeProvider.tsx @@ -20,7 +20,7 @@ export const ThemeProvider = (props: ThemeProviderProps) => { fontFamilyClassName, providerClassName, typographyClassName, - } = useCssTokens({ ...theme }); + } = useCssTokens(theme); return ( diff --git a/app/client/packages/design-system/theming/src/theme/src/types.ts b/app/client/packages/design-system/theming/src/theme/src/types.ts index e7d56e2af57a..f2972c47453b 100644 --- a/app/client/packages/design-system/theming/src/theme/src/types.ts +++ b/app/client/packages/design-system/theming/src/theme/src/types.ts @@ -1,18 +1,12 @@ -import type { CSSProperties } from "react"; import type { ReactNode } from "react"; +import type { CSSProperties } from "react"; + import type { ColorMode } from "../../color"; -import type { - FontFamily, - Typography, - ThemeToken, - IconStyle, -} from "../../token"; +import type { Typography, ThemeToken } from "../../token"; export type Theme = ThemeToken & { typography?: Typography; - fontFamily?: FontFamily; colorMode?: ColorMode; - iconStyle?: IconStyle; }; export interface ThemeProviderProps { diff --git a/app/client/packages/design-system/theming/src/token/src/TokensAccessor.ts b/app/client/packages/design-system/theming/src/token/src/TokensAccessor.ts index 5e2c14d3d726..05c3bcbfb310 100644 --- a/app/client/packages/design-system/theming/src/token/src/TokensAccessor.ts +++ b/app/client/packages/design-system/theming/src/token/src/TokensAccessor.ts @@ -7,9 +7,7 @@ import type { TokenObj, TokenSource, TokenType, - FontFamily, Typography, - IconStyle, } from "./types"; export class TokensAccessor { @@ -20,12 +18,10 @@ export class TokensAccessor { private borderWidth?: TokenObj; private opacity?: TokenObj; private typography?: Typography; - private fontFamily?: FontFamily; private outerSpacing?: TokenObj; private innerSpacing?: TokenObj; private sizing?: TokenObj; private zIndex?: TokenObj; - private iconStyle?: IconStyle; private strokeWidth?: TokenObj; private iconSize?: TokenObj; @@ -34,9 +30,7 @@ export class TokensAccessor { borderWidth, boxShadow, colorMode, - fontFamily, iconSize, - iconStyle, innerSpacing, opacity, outerSpacing, @@ -52,21 +46,15 @@ export class TokensAccessor { this.boxShadow = boxShadow; this.borderWidth = borderWidth; this.opacity = opacity; - this.fontFamily = fontFamily; this.sizing = sizing; this.outerSpacing = outerSpacing; this.innerSpacing = innerSpacing; this.typography = typography; this.zIndex = zIndex; - this.iconStyle = iconStyle; this.strokeWidth = strokeWidth; this.iconSize = iconSize; } - updateFontFamily = (fontFamily?: FontFamily) => { - this.fontFamily = fontFamily; - }; - updateTypography = (typography: Typography) => { this.typography = typography; }; @@ -120,10 +108,6 @@ export class TokensAccessor { this.sizing = sizing; }; - updateIconStyle = (iconStyle: IconStyle) => { - this.iconStyle = iconStyle; - }; - updateStrokeWidth = (strokeWidth: TokenObj) => { this.strokeWidth = strokeWidth; }; @@ -135,7 +119,6 @@ export class TokensAccessor { getAllTokens = () => { return { typography: this.getTypography(), - fontFamily: this.getFontFamily(), ...this.getOuterSpacing(), ...this.getInnerSpacing(), ...this.getSizing(), @@ -148,7 +131,6 @@ export class TokensAccessor { ...this.getStrokeWidth(), ...this.getIconSize(), colorMode: this.getColorMode(), - iconStyle: this.getIconStyle(), }; }; @@ -156,10 +138,6 @@ export class TokensAccessor { return this.typography; }; - getFontFamily = () => { - return this.fontFamily; - }; - getColors = () => { if (this.seedColor == null) return {} as ThemeToken; @@ -237,10 +215,6 @@ export class TokensAccessor { return this.colorMode; }; - getIconStyle = () => { - return this.iconStyle; - }; - getStrokeWidth = () => { if (this.strokeWidth == null) return {} as ThemeToken; diff --git a/app/client/packages/design-system/theming/src/token/src/types.ts b/app/client/packages/design-system/theming/src/token/src/types.ts index e94859a4ab3c..5a457153f690 100644 --- a/app/client/packages/design-system/theming/src/token/src/types.ts +++ b/app/client/packages/design-system/theming/src/token/src/types.ts @@ -1,17 +1,3 @@ -import arial from "@capsizecss/metrics/arial"; -import inter from "@capsizecss/metrics/inter"; -import rubik from "@capsizecss/metrics/rubik"; -import roboto from "@capsizecss/metrics/roboto"; -import ubuntu from "@capsizecss/metrics/ubuntu"; -import poppins from "@capsizecss/metrics/poppins"; -import segoeUI from "@capsizecss/metrics/segoeUI"; -import openSans from "@capsizecss/metrics/openSans"; -import notoSans from "@capsizecss/metrics/notoSans"; -import montserrat from "@capsizecss/metrics/montserrat"; -import nunitoSans from "@capsizecss/metrics/nunitoSans12pt"; -import appleSystem from "@capsizecss/metrics/appleSystem"; -import BlinkMacSystemFont from "@capsizecss/metrics/blinkMacSystemFont"; - import type { ColorMode, ColorTypes } from "../../color"; export type ThemeToken = { @@ -44,12 +30,10 @@ export interface TokenSource { boxShadow?: TokenObj; borderWidth?: TokenObj; opacity?: TokenObj; - fontFamily?: FontFamily; zIndex?: TokenObj; sizing?: TokenObj; outerSpacing?: TokenObj; innerSpacing?: TokenObj; - iconStyle?: IconStyle; strokeWidth?: TokenObj; iconSize?: TokenObj; } @@ -80,22 +64,6 @@ export interface TokenScaleConfig { userDensityRatio?: number; } -export const FONT_METRICS = { - Poppins: poppins, - Inter: inter, - Roboto: roboto, - Rubik: rubik, - Ubuntu: ubuntu, - "Noto Sans": notoSans, - "Open Sans": openSans, - Montserrat: montserrat, - "Nunito Sans": nunitoSans, - Arial: arial, - "-apple-system": appleSystem, - BlinkMacSystemFont: BlinkMacSystemFont, - "Segoe UI": segoeUI, -} as const; - // we use "as const" here because we need to iterate by variants export const TYPOGRAPHY_VARIANTS = { footnote: "footnote", @@ -118,8 +86,6 @@ export const TYPOGRAPHY_FONT_WEIGHTS = { 900: 900, } as const; -export type FontFamily = keyof typeof FONT_METRICS | "System Default"; - export interface TypographyVariantMetric { fontSize: string; lineHeight: string; @@ -139,8 +105,6 @@ export type Typography = { [key in keyof typeof TYPOGRAPHY_VARIANTS]: TypographyVariantMetric; }; -export type IconStyle = "outlined" | "filled"; - export const APP_MAX_WIDTH = { Unlimited: "UNLIMITED", Large: "LARGE", diff --git a/app/client/packages/design-system/widgets/src/components/Icon/src/Icon.tsx b/app/client/packages/design-system/widgets/src/components/Icon/src/Icon.tsx index ef7276806bdd..9dbcb8efb551 100644 --- a/app/client/packages/design-system/widgets/src/components/Icon/src/Icon.tsx +++ b/app/client/packages/design-system/widgets/src/components/Icon/src/Icon.tsx @@ -1,6 +1,5 @@ import type { Component, Ref } from "react"; import React, { Suspense, forwardRef, lazy, useMemo } from "react"; -import { useThemeContext } from "@appsmith/wds-theming"; import { ICONS } from "./icons"; import styles from "./styles.module.css"; @@ -8,25 +7,13 @@ import type { IconProps } from "./types"; import { FallbackIcon } from "./FallbackIcon"; const _Icon = (props: IconProps, ref: Ref) => { - const { color, filled: filledProp, name, size = "medium", ...rest } = props; - const theme = useThemeContext(); - const filled = theme.iconStyle === "filled" || filledProp; + const { color, name, size = "medium", ...rest } = props; const Icon = useMemo(() => { const pascalName = ICONS[name]; return lazy(async () => import("@tabler/icons-react").then((module) => { - if (Boolean(filled)) { - const filledVariant = `${pascalName}Filled`; - - if (filledVariant in module) { - return { - default: module[filledVariant] as React.ComponentType, - }; - } - } - if (pascalName in module) { return { default: module[pascalName] as React.ComponentType, @@ -36,7 +23,7 @@ const _Icon = (props: IconProps, ref: Ref) => { return { default: FallbackIcon }; }), ); - }, [name, filled]); + }, [name]); return ( ( - - - - - ), -}; - export const AllIcons: Story = { render: () => (
name !== "createReactComponent") - .filter((name) => !name.endsWith("Filled")) .map((name) => { content += `\n "${kebabCase(name).replace("icon-", "")}": "${name}",`; }); diff --git a/app/client/packages/rts/package.json b/app/client/packages/rts/package.json index bfd2be65e398..b2d5e490ce79 100644 --- a/app/client/packages/rts/package.json +++ b/app/client/packages/rts/package.json @@ -20,7 +20,7 @@ "astravel": "^0.6.1", "axios": "^1.7.4", "escodegen": "^2.0.0", - "express": "^4.19.2", + "express": "^4.20.0", "express-validator": "^6.14.2", "http-status-codes": "^2.2.0", "klona": "^2.0.5", diff --git a/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx b/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx index 390763d83558..f7ebfb17dde9 100644 --- a/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx +++ b/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx @@ -61,8 +61,6 @@ export const ThemingPopup: React.FC = ({ leftShift, onClose }) => { setBorderRadius={(value) => updateGlobal("borderRadius", value)} seedColor={globals.seedColor} setSeedColor={(value) => updateGlobal("seedColor", value)} - fontFamily={globals.fontFamily} - setFontFamily={(value) => updateGlobal("fontFamily", value)} userDensity={globals.userDensity} userSizing={globals.userSizing} setUserDensity={(value) => updateGlobal("userDensity", value)} diff --git a/app/client/packages/storybook/.storybook/decorators/theming.tsx b/app/client/packages/storybook/.storybook/decorators/theming.tsx index 23b58e53a837..9efe5e3cd2ec 100644 --- a/app/client/packages/storybook/.storybook/decorators/theming.tsx +++ b/app/client/packages/storybook/.storybook/decorators/theming.tsx @@ -18,7 +18,6 @@ export const theming = (Story, args) => { seedColor: args.globals.seedColor, colorMode: args.parameters.colorMode || args.globals.colorMode, borderRadius: args.globals.borderRadius, - fontFamily: args.globals.fontFamily, userDensity: args.globals.userDensity, userSizing: args.globals.userSizing, }); diff --git a/app/client/packages/storybook/src/components/ThemeSettings.tsx b/app/client/packages/storybook/src/components/ThemeSettings.tsx index f9b227934de0..b3d77aa3b3db 100644 --- a/app/client/packages/storybook/src/components/ThemeSettings.tsx +++ b/app/client/packages/storybook/src/components/ThemeSettings.tsx @@ -2,7 +2,6 @@ import { Form } from "@storybook/components"; import React, { useCallback } from "react"; import { Flex, Text } from "@appsmith/wds"; import { ColorControl, BooleanControl, RangeControl } from "@storybook/blocks"; -import { FONT_METRICS } from "@appsmith/wds-theming"; import styled from "styled-components"; import { debounce } from "lodash"; import { AddonPanel } from "@storybook/components"; @@ -42,12 +41,10 @@ interface ThemeSettingsProps { export const ThemeSettings = ({ borderRadius, direction = "column", - fontFamily, isDarkMode, seedColor, setBorderRadius, setDarkMode, - setFontFamily, setSeedColor, setUserDensity, setUserSizing, @@ -106,36 +103,6 @@ export const ThemeSettings = ({ )} - {setFontFamily && ( - - Font Family - setFontFamily(e.target.value)} - size="100%" - title="Font Family" - > - - {Object.keys(FONT_METRICS) - .filter((item) => { - return ( - [ - "-apple-system", - "BlinkMacSystemFont", - "Segoe UI", - ].includes(item) === false - ); - }) - .map((font) => ( - - ))} - - - )} - {setUserDensity && ( Density diff --git a/app/client/src/IDE/Structure/Toolbar.tsx b/app/client/src/IDE/Structure/Toolbar.tsx new file mode 100644 index 000000000000..bd2f4f0ce7aa --- /dev/null +++ b/app/client/src/IDE/Structure/Toolbar.tsx @@ -0,0 +1,52 @@ +import React from "react"; +import { Flex } from "@appsmith/ads"; + +interface ToolbarProps { + children?: React.ReactNode[] | React.ReactNode; +} + +const Toolbar = (props: ToolbarProps) => { + return ( + + {props.children} + + ); +}; + +const Left = (props: ToolbarProps) => { + return ( + + {props.children} + + ); +}; + +const Right = (props: ToolbarProps) => { + return ( + + {props.children} + + ); +}; + +Toolbar.Left = Left; +Toolbar.Right = Right; + +export default Toolbar; diff --git a/app/client/src/IDE/hooks/index.ts b/app/client/src/IDE/hooks/index.ts index 50897137a667..8fe85b2a9d84 100644 --- a/app/client/src/IDE/hooks/index.ts +++ b/app/client/src/IDE/hooks/index.ts @@ -1 +1,2 @@ export { useIsInSideBySideEditor } from "./useIsInSideBySideEditor"; +export { useIsEditorInitialised } from "ee/IDE/hooks/useIsEditorInitialised"; diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index 8a12a855b8ec..c57c8ea1872f 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -12,6 +12,14 @@ export { IDE_HEADER_HEIGHT } from "./Structure/constants"; export { default as IDEHeader } from "./Structure/Header"; +/** + * The IDEToolbar gets exported with 2 layout subsections. + * IDEToolbar.Left and IDEToolbar.Right + * These are composable components that you can use to spread the content of the toolbar + * It is possible to use the Toolbar without using these subsections + */ +export { default as IDEToolbar } from "./Structure/Toolbar"; + /* ==================================================== **** UI Components **** Components that are smaller UI abstractions for easy use and standardisation within the IDE diff --git a/app/client/src/PluginActionEditor/PluginActionContext.tsx b/app/client/src/PluginActionEditor/PluginActionContext.tsx new file mode 100644 index 000000000000..21c76f6c8985 --- /dev/null +++ b/app/client/src/PluginActionEditor/PluginActionContext.tsx @@ -0,0 +1,62 @@ +import React, { + type ReactNode, + createContext, + useContext, + useMemo, +} from "react"; +import type { Action } from "entities/Action"; +import type { Plugin } from "api/PluginApi"; +import type { Datasource } from "entities/Datasource"; + +interface PluginActionContextType { + action: Action; + editorConfig: unknown[]; + settingsConfig: unknown[]; + plugin: Plugin; + datasource?: Datasource; +} + +// No need to export this context to use it. Use the hook defined below instead +const PluginActionContext = createContext(null); + +interface ChildrenProps { + children: ReactNode | ReactNode[]; +} + +export const PluginActionContextProvider = ( + props: ChildrenProps & PluginActionContextType, +) => { + const { action, children, datasource, editorConfig, plugin, settingsConfig } = + props; + + // using useMemo to avoid unnecessary renders + const contextValue = useMemo( + () => ({ + action, + datasource, + editorConfig, + plugin, + settingsConfig, + }), + [action, datasource, editorConfig, plugin, settingsConfig], + ); + + return ( + + {children} + + ); +}; + +// By using this hook, you are guaranteed that the states are correctly +// typed and set. +// Without this, consumers of the context would need to keep doing a null check +export const usePluginActionContext = () => { + const context = useContext(PluginActionContext); + if (!context) { + throw new Error( + "usePluginActionContext must be used within usePluginActionContextProvider", + ); + } + return context; +}; diff --git a/app/client/src/PluginActionEditor/PluginActionEditor.tsx b/app/client/src/PluginActionEditor/PluginActionEditor.tsx new file mode 100644 index 000000000000..40470b7bd837 --- /dev/null +++ b/app/client/src/PluginActionEditor/PluginActionEditor.tsx @@ -0,0 +1,89 @@ +import React from "react"; +import { useLocation } from "react-router"; +import { identifyEntityFromPath } from "../navigation/FocusEntity"; +import { useSelector } from "react-redux"; +import { + getActionByBaseId, + getDatasource, + getEditorConfig, + getPlugin, + getPluginSettingConfigs, +} from "ee/selectors/entitiesSelector"; +import { PluginActionContextProvider } from "./PluginActionContext"; +import { get } from "lodash"; +import EntityNotFoundPane from "pages/Editor/EntityNotFoundPane"; +import Spinner from "components/editorComponents/Spinner"; +import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper"; +import { Text } from "@appsmith/ads"; +import { useIsEditorInitialised } from "IDE/hooks"; + +interface ChildrenProps { + children: React.ReactNode | React.ReactNode[]; +} + +const PluginActionEditor = (props: ChildrenProps) => { + const { pathname } = useLocation(); + + const isEditorInitialized = useIsEditorInitialised(); + + const entity = identifyEntityFromPath(pathname); + const action = useSelector((state) => getActionByBaseId(state, entity.id)); + + const pluginId = get(action, "pluginId", ""); + const plugin = useSelector((state) => getPlugin(state, pluginId)); + + const datasourceId = get(action, "datasource.id", ""); + const datasource = useSelector((state) => getDatasource(state, datasourceId)); + + const settingsConfig = useSelector((state) => + getPluginSettingConfigs(state, pluginId), + ); + + const editorConfig = useSelector((state) => getEditorConfig(state, pluginId)); + + if (!isEditorInitialized) { + return ( + + + + ); + } + + if (!action) { + return ; + } + + if (!plugin) { + return ( + + + Plugin not installed! + + + ); + } + + if (!settingsConfig || !editorConfig) { + return ( + + + Editor config not found! + + + ); + } + + return ( + + {props.children} + + ); +}; + +export default PluginActionEditor; diff --git a/app/client/src/PluginActionEditor/components/PluginActionForm/PluginActionForm.tsx b/app/client/src/PluginActionEditor/components/PluginActionForm/PluginActionForm.tsx new file mode 100644 index 000000000000..17db33e698a3 --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionForm/PluginActionForm.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +const PluginActionForm = () => { + return
; +}; + +export default PluginActionForm; diff --git a/app/client/src/PluginActionEditor/components/PluginActionForm/index.ts b/app/client/src/PluginActionEditor/components/PluginActionForm/index.ts new file mode 100644 index 000000000000..bb106d466ee2 --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionForm/index.ts @@ -0,0 +1 @@ +export { default } from "./PluginActionForm"; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponsePane.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponsePane.tsx new file mode 100644 index 000000000000..5a0be861970c --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionResponsePane.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +const PluginActionResponsePane = () => { + return
; +}; + +export default PluginActionResponsePane; diff --git a/app/client/src/PluginActionEditor/components/PluginActionToolbar.tsx b/app/client/src/PluginActionEditor/components/PluginActionToolbar.tsx new file mode 100644 index 000000000000..0d2e4f718d78 --- /dev/null +++ b/app/client/src/PluginActionEditor/components/PluginActionToolbar.tsx @@ -0,0 +1,79 @@ +import React, { useCallback } from "react"; +import { IDEToolbar } from "IDE"; +import { Button, Menu, MenuContent, MenuTrigger, Tooltip } from "@appsmith/ads"; +import { modText } from "utils/helpers"; +import { usePluginActionContext } from "../PluginActionContext"; +import { useDispatch } from "react-redux"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import { runAction } from "../../actions/pluginActionActions"; + +interface PluginActionToolbarProps { + runOptions?: React.ReactNode; + children?: React.ReactNode[] | React.ReactNode; + menuContent?: React.ReactNode[] | React.ReactNode; +} + +const PluginActionToolbar = (props: PluginActionToolbarProps) => { + const { action, datasource, plugin } = usePluginActionContext(); + const dispatch = useDispatch(); + const handleRunClick = useCallback(() => { + AnalyticsUtil.logEvent("RUN_QUERY_CLICK", { + actionName: action.name, + actionId: action.id, + pluginName: plugin.name, + datasourceId: datasource?.id, + isMock: datasource?.isMock, + }); + dispatch(runAction(action.id)); + }, [ + action.id, + action.name, + datasource?.id, + datasource?.isMock, + dispatch, + plugin.name, + ]); + return ( + + {props.children} + + {props.runOptions} + + + + - - - ); -}; - -export default ActionToolbar; diff --git a/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx b/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx index a3c97d624f12..0721f3ae2950 100644 --- a/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx +++ b/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx @@ -11,7 +11,6 @@ import styled from "styled-components"; import FormRow from "components/editorComponents/FormRow"; import { createMessage, - DEBUGGER_RESPONSE, DOCUMENTATION, DOCUMENTATION_TOOLTIP, } from "ee/constants/messages"; @@ -29,17 +28,12 @@ import { setQueryPaneConfigSelectedTabIndex } from "actions/queryPaneActions"; import type { SourceEntity } from "entities/AppsmithConsole"; import { ENTITY_TYPE as SOURCE_ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils"; import { DocsLink, openDoc } from "../../../constants/DocumentationLinks"; -import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; -import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; import { QueryEditorContext } from "./QueryEditorContext"; import QueryDebuggerTabs from "./QueryDebuggerTabs"; import useShowSchema from "components/editorComponents/ActionRightPane/useShowSchema"; import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers"; import FormRender from "./FormRender"; import QueryEditorHeader from "./QueryEditorHeader"; -import ActionEditor from "../IDE/EditorPane/components/ActionEditor"; -import QueryResponseTab from "./QueryResponseTab"; -import DatasourceSelector from "./DatasourceSelector"; import RunHistory from "ee/components/RunHistory"; const QueryFormContainer = styled.form` @@ -227,10 +221,6 @@ export function EditorJSONtoForm(props: Props) { useShowSchema(currentActionConfig?.pluginId || "") && pluginRequireDatasource; - const isActionRedesignEnabled = useFeatureFlag( - FEATURE_FLAG.release_actions_redesign_enabled, - ); - const dispatch = useDispatch(); const handleDocumentationClick = () => { @@ -256,59 +246,6 @@ export function EditorJSONtoForm(props: Props) { return null; } - if (isActionRedesignEnabled && plugin) { - const responseTabs = []; - if (currentActionConfig) { - responseTabs.push({ - key: "response", - title: createMessage(DEBUGGER_RESPONSE), - panelComponent: ( - - ), - }); - } - return ( - - } - settingsRender={ - - - - } - tabs={responseTabs} - > - - - ); - } - return ( <> {closeEditorLink} diff --git a/app/client/src/pages/Editor/QueryEditor/index.tsx b/app/client/src/pages/Editor/QueryEditor/index.tsx index c6135365eca6..58cfb59d5ceb 100644 --- a/app/client/src/pages/Editor/QueryEditor/index.tsx +++ b/app/client/src/pages/Editor/QueryEditor/index.tsx @@ -41,6 +41,7 @@ import { resolveIcon } from "../utils"; import { ENTITY_ICON_SIZE, EntityIcon } from "../Explorer/ExplorerIcons"; import { getIDEViewMode } from "selectors/ideSelectors"; import { EditorViewMode } from "ee/entities/IDE/constants"; +import { AppPluginActionEditor } from "../AppPluginActionEditor"; type QueryEditorProps = RouteComponentProps; @@ -188,6 +189,14 @@ function QueryEditor(props: QueryEditorProps) { ); }, [action?.name, isConverting]); + const isActionRedesignEnabled = useFeatureFlag( + FEATURE_FLAG.release_actions_redesign_enabled, + ); + + if (isActionRedesignEnabled) { + return ; + } + return ( ({ label: ( @@ -185,49 +175,6 @@ function WDSThemePropertyPane() { - -
- -
-
- {/* Dimensions */} - {/* Icon Style */} - -
- Icon Style - { - updateTheme({ - ...theme, - iconStyle: value as ThemeSetting["iconStyle"], - }); - }} - options={THEME_SETTINGS_ICON_STYLE_OPTIONS} - value={theme.iconStyle} - /> -
-
- {/* Layout Style */} ({ fetchGlobalGitConfigInit: jest.fn(), })); -const mockHistoryPush = jest.fn(); - -jest.mock("react-router-dom", () => ({ - ...jest.requireActual("react-router-dom"), - useHistory: () => ({ - push: mockHistoryPush, - }), -})); - const mockStore = configureStore([]); describe("Git config ", () => { // TODO: Fix this the next time the file is edited @@ -137,22 +128,6 @@ describe("Git config ", () => { expect(getAllByText("Sign in to your account")).toBeInTheDocument; }); - it("should call history push when user goes back to applications", () => { - store = mockStore(defaultStoreState); - render( - - - - - - - , - ); - const backButton = screen.getByText("Back"); - fireEvent.click(backButton); - expect(mockHistoryPush).toHaveBeenCalledWith("/applications"); - }); - afterAll(() => { jest.clearAllMocks(); store.clearActions(); diff --git a/app/client/src/pages/UserProfile/index.tsx b/app/client/src/pages/UserProfile/index.tsx index bf7de701ef78..2cfb2fee9fb3 100644 --- a/app/client/src/pages/UserProfile/index.tsx +++ b/app/client/src/pages/UserProfile/index.tsx @@ -56,7 +56,7 @@ function UserProfile() { return ( - + {tabs.map((tab) => { diff --git a/app/client/src/pages/workspace/__tests__/settings.test.tsx b/app/client/src/pages/workspace/__tests__/settings.test.tsx index 3e488f3fb4c4..fdcbea9eb15e 100644 --- a/app/client/src/pages/workspace/__tests__/settings.test.tsx +++ b/app/client/src/pages/workspace/__tests__/settings.test.tsx @@ -1,17 +1,9 @@ import React from "react"; import "@testing-library/jest-dom"; import Router from "react-router-dom"; -import { BrowserRouter } from "react-router-dom"; import { render, screen } from "test/testUtils"; -import { - render as testRender, - screen as testScreen, -} from "@testing-library/react"; -import { fireEvent } from "@testing-library/react"; import Settings from "../settings"; import * as reactRedux from "react-redux"; -import configureStore from "redux-mock-store"; -import { Provider } from "react-redux"; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -159,16 +151,9 @@ const mockWorkspaceData = { new: false, }; -const mockHistoryPush = jest.fn(); - -const mockStore = configureStore([]); - jest.mock("react-router-dom", () => ({ ...jest.requireActual("react-router-dom"), useParams: jest.fn(), - useHistory: () => ({ - push: mockHistoryPush, - }), })); function renderComponent() { @@ -205,19 +190,4 @@ describe("", () => { expect(tabList.length).toBeGreaterThanOrEqual(2); expect(tabList.length).toBeLessThanOrEqual(3); }); - - it("should redirect to workspace page if user wants to go back", () => { - testRender( - - - - - , - ); - const backBtn = testScreen.getByText("Back"); - fireEvent.click(backBtn); - expect(mockHistoryPush).toHaveBeenCalledWith( - `/applications?workspaceId=${mockWorkspaceData.id}`, - ); - }); }); diff --git a/app/client/src/pages/workspace/settings.tsx b/app/client/src/pages/workspace/settings.tsx index 1c5ab878d554..0d4567c9325d 100644 --- a/app/client/src/pages/workspace/settings.tsx +++ b/app/client/src/pages/workspace/settings.tsx @@ -127,7 +127,7 @@ export default function Settings() { <> - + { return initialState; }, + [ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG_SUCCESS]: ( + state: ErrorReduxState, + ) => { + if ( + state?.currentError?.sourceAction === "FETCH_CURRENT_TENANT_CONFIG_ERROR" + ) { + return { + ...state, + ...initialState, + }; + } + return state; + }, + [ReduxActionTypes.UPDATE_TENANT_CONFIG_SUCCESS]: (state: ErrorReduxState) => { + if (state?.currentError?.sourceAction === "UPDATE_TENANT_CONFIG_ERROR") { + return { + ...state, + ...initialState, + }; + } + return state; + }, }); export interface ErrorReduxState { diff --git a/app/client/src/sagas/ActionSagas.ts b/app/client/src/sagas/ActionSagas.ts index a5f88ef14e0d..94f7cfe44d63 100644 --- a/app/client/src/sagas/ActionSagas.ts +++ b/app/client/src/sagas/ActionSagas.ts @@ -795,13 +795,19 @@ function* copyActionSaga( // @ts-expect-error: type mismatch Action vs ActionCreateUpdateResponse yield put(copyActionSuccess(payload)); - } catch (e) { + } catch (e: unknown) { const actionName = actionObject ? actionObject.name : ""; + const errorMessage = + e instanceof Error + ? e.message + : createMessage(ERROR_ACTION_COPY_FAIL, actionName); yield put( copyActionError({ ...action.payload, show: true, - error: { message: createMessage(ERROR_ACTION_COPY_FAIL, actionName) }, + error: { + message: errorMessage, + }, }), ); } diff --git a/app/client/src/sagas/DatasourcesSagas.ts b/app/client/src/sagas/DatasourcesSagas.ts index b05c609664ed..8d9b77bf4e32 100644 --- a/app/client/src/sagas/DatasourcesSagas.ts +++ b/app/client/src/sagas/DatasourcesSagas.ts @@ -929,7 +929,7 @@ function* testDatasourceSaga(actionPayload: ReduxAction) { id: datasource.id, environmentId: currentEnvironment, show: true, - error: { message: responseData.invalids.join(", ") }, + error: { message: responseData.invalids.join("\n") }, }, }); AppsmithConsole.error({ diff --git a/app/client/src/sagas/ErrorSagas.tsx b/app/client/src/sagas/ErrorSagas.tsx index 3a690ce17ebe..559c0b9d6e9b 100644 --- a/app/client/src/sagas/ErrorSagas.tsx +++ b/app/client/src/sagas/ErrorSagas.tsx @@ -112,7 +112,16 @@ export function* validateResponse( } if (!response.responseMeta && response.status) { - throw Error(getErrorMessage(response.status, response.resourceType)); + yield put({ + type: ReduxActionErrorTypes.API_ERROR, + payload: { + error: new Error( + getErrorMessage(response.status, response.resourceType), + ), + logToSentry, + show, + }, + }); } if (response.responseMeta.success) { @@ -218,22 +227,20 @@ export interface ErrorActionPayload { export function* errorSaga(errorAction: ReduxAction) { const effects = [ErrorEffectTypes.LOG_TO_CONSOLE]; const { payload, type } = errorAction; - const { - error, - logToDebugger, - logToSentry, - show = true, - sourceEntity, - } = payload || {}; + const { error, logToDebugger, logToSentry, show, sourceEntity } = + payload || {}; const appMode: APP_MODE = yield select(getAppMode); // "show" means show a toast. We check if the error has been asked to not been shown - // By making the default behaviour "true" we are ensuring undefined actions still pass through this check - if (show) { + // By checking undefined, undecided actions still pass through this check + if (show === undefined) { // We want to show toasts for certain actions only so we avoid issues or if it is outside edit mode if (shouldShowToast(type) || appMode !== APP_MODE.EDIT) { effects.push(ErrorEffectTypes.SHOW_ALERT); } + // If true is passed, show the error no matter what + } else if (show) { + effects.push(ErrorEffectTypes.SHOW_ALERT); } if (logToDebugger) { diff --git a/app/client/src/sagas/WidgetDeletionSagas.ts b/app/client/src/sagas/WidgetDeletionSagas.ts index 518d122bc88f..96cd9089480f 100644 --- a/app/client/src/sagas/WidgetDeletionSagas.ts +++ b/app/client/src/sagas/WidgetDeletionSagas.ts @@ -327,9 +327,23 @@ export function* deleteSaga(deleteAction: ReduxAction) { if (!disallowUndo) { // close property pane after delete yield put(closePropertyPane()); - yield put( - selectWidgetInitAction(SelectionRequestType.Unselect, [widgetId]), - ); + + if (isAnvilLayout) { + yield put( + selectWidgetInitAction( + SelectionRequestType.Unselect, + [widgetId], + undefined, + undefined, + parentId, + ), + ); + } else { + yield put( + selectWidgetInitAction(SelectionRequestType.Unselect, [widgetId]), + ); + } + yield call(postDelete, widgetId, widgetName, otherWidgetsToDelete); } } diff --git a/app/client/src/sagas/WidgetSelectionSagas.ts b/app/client/src/sagas/WidgetSelectionSagas.ts index 0398c4be37de..48078f270454 100644 --- a/app/client/src/sagas/WidgetSelectionSagas.ts +++ b/app/client/src/sagas/WidgetSelectionSagas.ts @@ -66,6 +66,7 @@ function* selectWidgetSaga(action: ReduxAction) { const { basePageId, invokedBy, + parentId, payload = [], selectionRequestType, } = action.payload; @@ -93,8 +94,9 @@ function* selectWidgetSaga(action: ReduxAction) { // It is possible that the payload is empty. // These properties can be used for a finding sibling widgets for certain types of selections const widgetId = payload[0]; - const parentId: string | undefined = - widgetId in allWidgets ? allWidgets[widgetId].parentId : undefined; + const finalParentId: string | undefined = + parentId || + (widgetId in allWidgets ? allWidgets[widgetId].parentId : undefined); if ( widgetId && @@ -115,7 +117,7 @@ function* selectWidgetSaga(action: ReduxAction) { } case SelectionRequestType.One: case SelectionRequestType.Create: { - assertParentId(parentId); + assertParentId(finalParentId); newSelection = selectOneWidget(payload); break; } @@ -124,10 +126,10 @@ function* selectWidgetSaga(action: ReduxAction) { break; } case SelectionRequestType.ShiftSelect: { - assertParentId(parentId); + assertParentId(finalParentId); const siblingWidgets: string[] = yield select( getWidgetImmediateChildren, - parentId, + finalParentId, ); newSelection = shiftSelectWidgets( payload, @@ -138,10 +140,10 @@ function* selectWidgetSaga(action: ReduxAction) { break; } case SelectionRequestType.PushPop: { - assertParentId(parentId); + assertParentId(finalParentId); const siblingWidgets: string[] = yield select( getWidgetImmediateChildren, - parentId, + finalParentId, ); newSelection = pushPopWidgetSelection( payload, @@ -151,7 +153,16 @@ function* selectWidgetSaga(action: ReduxAction) { break; } case SelectionRequestType.Unselect: { - newSelection = unselectWidget(payload, selectedWidgets); + const isParentExists = finalParentId + ? finalParentId in allWidgets + : false; + + if (isParentExists) { + assertParentId(finalParentId); + newSelection = [finalParentId]; + } else { + newSelection = unselectWidget(payload, selectedWidgets); + } break; } case SelectionRequestType.All: { diff --git a/app/client/src/widgets/TableWidgetV2/widget/derived.js b/app/client/src/widgets/TableWidgetV2/widget/derived.js index ad69270fa977..aa5873dd5481 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/derived.js +++ b/app/client/src/widgets/TableWidgetV2/widget/derived.js @@ -342,12 +342,46 @@ export default { const newRow = { ...row }; selectColumnKeysWithSortByLabel.forEach((key) => { const value = row[key]; - const selectOptions = - primaryColumns[key].selectOptions[row.__originalIndex__]; - const option = selectOptions.find((option) => option.value === value); + const isSelectOptionsAnArray = _.isArray( + primaryColumns[key].selectOptions, + ); + + let selectOptions; - if (option) { - newRow[key] = option.label; + /* + * If selectOptions is an array, check if it contains nested arrays. + * This is to handle situations where selectOptons is a javascript object and computes as a nested array. + */ + if (isSelectOptionsAnArray) { + if (_.some(primaryColumns[key].selectOptions, _.isArray)) { + /* Handle the case where selectOptions contains nested arrays - selectOptions is javascript */ + selectOptions = + primaryColumns[key].selectOptions[row.__originalIndex__]; + const option = selectOptions.find((option) => { + return option.value === value; + }); + if (option) { + newRow[key] = option.label; + } + } else { + /* Handle the case where selectOptions is a flat array - selectOptions is plain JSON */ + selectOptions = primaryColumns[key].selectOptions; + const option = selectOptions.find( + (option) => option.value === value, + ); + if (option) { + newRow[key] = option.label; + } + } + } else { + /* If selectOptions is not an array, parse it as JSON - not evaluated yet, so returns as string */ + selectOptions = JSON.parse(primaryColumns[key].selectOptions); + const option = selectOptions.find( + (option) => option.value === value, + ); + if (option) { + newRow[key] = option.label; + } } }); @@ -450,18 +484,55 @@ export default { } }); + /* + * When sorting is done, transform the data back to its original state + * where table data shows value instead of label + */ if (selectColumnKeysWithSortByLabel.length) { const transformedLabelToValueData = sortedTableData.map((row) => { const newRow = { ...row }; selectColumnKeysWithSortByLabel.forEach((key) => { const label = row[key]; - const selectOptions = - primaryColumns[key].selectOptions[row.__originalIndex__]; - const option = selectOptions.find( - (option) => option.label === label, + const isSelectOptionsAnArray = _.isArray( + primaryColumns[key].selectOptions, ); - if (option) { - newRow[key] = option.value; + + let selectOptions; + + /* + * If selectOptions is an array, check if it contains nested arrays. + * This is to handle situations where selectOptons is a javascript object and computes as a nested array. + */ + if (isSelectOptionsAnArray) { + if (_.some(primaryColumns[key].selectOptions, _.isArray)) { + /* Handle the case where selectOptions contains nested arrays - selectOptions is javascript */ + selectOptions = + primaryColumns[key].selectOptions[row.__originalIndex__]; + const option = selectOptions.find((option) => { + return option.label === label; + }); + if (option) { + newRow[key] = option.value; + } + } else { + /* Handle the case where selectOptions is a flat array - selectOptions is plain JSON */ + selectOptions = primaryColumns[key].selectOptions; + const option = selectOptions.find( + (option) => option.label === label, + ); + if (option) { + newRow[key] = option.value; + } + } + } else { + /* If selectOptions is not an array, parse it as JSON - not evaluated yet, so returns as string */ + selectOptions = JSON.parse(primaryColumns[key].selectOptions); + const option = selectOptions.find( + (option) => option.label === label, + ); + if (option) { + newRow[key] = option.value; + } } }); @@ -587,8 +658,83 @@ export default { const columnWithDisplayText = Object.values(props.primaryColumns).filter( (column) => column.columnType === "url" && column.displayText, ); + + /* + * For select columns with label and values, we need to include the label value + * in the search + */ + let labelValueForSelectCell = ""; + /* + * Initialize an array to store keys for columns that have the 'select' column type + * and contain selectOptions. + */ + const selectColumnKeys = []; + /* + * Iterate over the primary columns to identify which columns are of type 'select' + * and have selectOptions. These keys are pushed into the selectColumnKeys array. + */ + Object.entries(props.primaryColumns).forEach(([id, column]) => { + const isColumnSelectColumnType = + column?.columnType === "select" && column?.selectOptions?.length; + if (isColumnSelectColumnType) { + selectColumnKeys.push(id); + } + }); + /* + * If there are any select columns, iterate over them to find the label value + * associated with the selected value in each row. + */ + if (selectColumnKeys.length) { + selectColumnKeys.forEach((key) => { + const value = row[key]; + + const isSelectOptionsAnArray = _.isArray( + primaryColumns[key].selectOptions, + ); + + let selectOptions; + + /* + * If selectOptions is an array, check if it contains nested arrays. + * This is to handle situations where selectOptons is a javascript object and computes as a nested array. + */ + if (isSelectOptionsAnArray) { + if (_.some(primaryColumns[key].selectOptions, _.isArray)) { + /* Handle the case where selectOptions contains nested arrays - selectOptions is javascript */ + selectOptions = + primaryColumns[key].selectOptions[row.__originalIndex__]; + const option = selectOptions.find((option) => { + return option.value === value; + }); + if (option) { + labelValueForSelectCell = option.label; + } + } else { + /* Handle the case where selectOptions is a flat array - selectOptions is plain JSON */ + selectOptions = primaryColumns[key].selectOptions; + const option = selectOptions.find( + (option) => option.value === value, + ); + if (option) { + labelValueForSelectCell = option.label; + } + } + } else { + /* If selectOptions is not an array, parse it as JSON - not evaluated yet, so returns as string */ + selectOptions = JSON.parse(primaryColumns[key].selectOptions); + const option = selectOptions.find( + (option) => option.value === value, + ); + if (option) { + labelValueForSelectCell = option.label; + } + } + }); + } + const displayedRow = { ...row, + labelValueForSelectCell, ...columnWithDisplayText.reduce((acc, column) => { let displayText; if (_.isArray(column.displayText)) { diff --git a/app/client/src/widgets/wds/WDSComboBoxWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts b/app/client/src/widgets/wds/WDSComboBoxWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts index 830674837392..356d2155a85d 100644 --- a/app/client/src/widgets/wds/WDSComboBoxWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts +++ b/app/client/src/widgets/wds/WDSComboBoxWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts @@ -77,6 +77,22 @@ export function optionsCustomValidation( }); } + const isValidKeys = options.every((option) => { + return ( + _.isPlainObject(option) && + _.has(option, "label") && + _.has(option, "value") + ); + }); + + if (!isValidKeys) { + return createErrorValidationResponse(options, { + name: "ValidationError", + message: + 'This value does not evaluate to type Array<{ "label": "string", "value": "string" | number }>', + }); + } + for (let i = 0; i < options.length; i++) { const option = options[i]; diff --git a/app/client/src/widgets/wds/WDSComboBoxWidget/widget/index.tsx b/app/client/src/widgets/wds/WDSComboBoxWidget/widget/index.tsx index 116fe24ee6ac..e75189a06f58 100644 --- a/app/client/src/widgets/wds/WDSComboBoxWidget/widget/index.tsx +++ b/app/client/src/widgets/wds/WDSComboBoxWidget/widget/index.tsx @@ -152,7 +152,11 @@ class WDSComboBoxWidget extends BaseWidget< id: option["value"] as string, })); - return items; + const isValidItems = items.every( + (item) => item.label !== undefined && item.id !== undefined, + ); + + return isValidItems ? items : []; } return []; diff --git a/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/contentConfig.ts b/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/contentConfig.ts index ef68eec86d75..9466f1c8a93d 100644 --- a/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/contentConfig.ts +++ b/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/contentConfig.ts @@ -1,237 +1,16 @@ -import { - ValidationTypes, - type ValidationResponse, -} from "constants/WidgetValidation"; -import { get, isPlainObject, uniq, type LoDashStatic } from "lodash"; -import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType"; - +import { ValidationTypes } from "constants/WidgetValidation"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; -import { EVAL_VALUE_PATH } from "../../../../../utils/DynamicBindingUtils"; -import type { PropertyUpdates } from "../../../../../WidgetProvider/constants"; -import type { WidgetProps } from "../../../../BaseWidget"; +import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType"; import type { WDSSelectWidgetProps } from "../../widget/types"; import { defaultOptionValidation, optionsCustomValidation, } from "./validations"; +import type { WidgetProps } from "../../../../BaseWidget"; +import type { PropertyUpdates } from "../../../../../WidgetProvider/constants"; type WidgetTypeValue = "SELECT" | "COMBOBOX"; -interface ValidationErrorMessage { - name: string; - message: string; -} - -export const getOptionLabelValueExpressionPrefix = (widget: WidgetProps) => - `{{${widget.widgetName}.sourceData.map((item) => (`; - -export const optionLabelValueExpressionSuffix = `))}}`; - -export function getLabelValueKeyOptions( - widget: WidgetProps, -): Record[] { - // UTILS - const isTrueObject = (item: unknown): item is Record => { - return Object.prototype.toString.call(item) === "[object Object]"; - }; - - const sourceData = get(widget, `${EVAL_VALUE_PATH}.options`); - const widgetOptions = get(widget, "options"); - const options = sourceData || widgetOptions; - - // Is Form mode, otherwise it is JS mode - if (Array.isArray(widgetOptions)) { - return options.map((option: Record | string) => { - if (isTrueObject(option)) { - return { - label: option[widget.optionLabel], - value: option[widget.optionValue], - }; - } - - return []; - }); - } - - if (Array.isArray(options)) { - const x = uniq( - options.reduce((keys, obj) => { - if (isPlainObject(obj)) { - Object.keys(obj).forEach((d) => keys.push(d)); - } - - return keys; - }, []), - ).map((d: unknown) => ({ - label: d, - value: d, - })); - - return x; - } else { - return []; - } -} - -export function labelKeyValidation( - value: unknown, - widgetProps: WDSSelectWidgetProps, - _: LoDashStatic, -) { - // UTILS - const hasDuplicates = (array: unknown[]): boolean => { - const set = new Set(array); - - return set.size !== array.length; - }; - - const createErrorValidationResponse = ( - value: unknown, - message: ValidationErrorMessage, - ): ValidationResponse => ({ - isValid: false, - parsed: value, - messages: [message], - }); - - const createSuccessValidationResponse = ( - value: unknown, - ): ValidationResponse => ({ - isValid: true, - parsed: value, - }); - - if (value === "" || _.isNil(value)) { - return createErrorValidationResponse(value, { - name: "ValidationError", - message: `value does not evaluate to type: string | Array`, - }); - } - - if (Array.isArray(widgetProps.options)) { - const values = _.map(widgetProps.options, (option) => { - return option[widgetProps.optionLabel]; - }).filter((d) => d); - - if (values.length && hasDuplicates(values)) { - return createErrorValidationResponse(value, { - name: "ValidationError", - message: "Duplicate values found, value must be unique", - }); - } - } - - if (_.isString(value)) { - const keys = _.map(widgetProps.options, _.keys).flat(); - - if (!keys.includes(value)) { - return createErrorValidationResponse(value, { - name: "ValidationError", - message: "value key should be present in the options", - }); - } - - return createSuccessValidationResponse(value); - } else if (_.isArray(value)) { - const errorIndex = value.findIndex((d) => !_.isString(d)); - - if (errorIndex === -1) { - return createSuccessValidationResponse(value); - } - - return createErrorValidationResponse(value, { - name: "ValidationError", - message: `Invalid entry at index: ${errorIndex}. This value does not evaluate to type: string`, - }); - } else { - return createErrorValidationResponse(value, { - name: "ValidationError", - message: `value does not evaluate to type: string | Array`, - }); - } -} - -export function getLabelValueAdditionalAutocompleteData(props: WidgetProps) { - const keys = getLabelValueKeyOptions(props); - - return { - item: keys - .map((d) => d.label) - .reduce((prev: Record, curr: unknown) => { - prev[curr as string] = ""; - - return prev; - }, {}), - }; -} - -export function valueKeyValidation( - value: unknown, - widgetProps: WDSSelectWidgetProps, - _: LoDashStatic, -) { - // UTILS - const isTrueObject = (item: unknown): item is Record => { - return Object.prototype.toString.call(item) === "[object Object]"; - }; - - const hasDuplicates = (array: unknown[]): boolean => { - const set = new Set(array); - - return set.size !== array.length; - }; - - const createErrorValidationResponse = ( - value: unknown, - message: ValidationErrorMessage, - ): ValidationResponse => ({ - isValid: false, - parsed: value, - messages: [message], - }); - - const createSuccessValidationResponse = ( - value: unknown, - ): ValidationResponse => ({ - isValid: true, - parsed: value, - }); - - if (value === "" || _.isNil(value) || !_.isString(value)) { - return createErrorValidationResponse(value, { - name: "ValidationError", - message: - "value does not evaluate to type: string | Array", - }); - } - - if (!_.flatMap(widgetProps.options, _.keys).includes(value)) { - return createErrorValidationResponse(value, { - name: "ValidationError", - message: "value key should be present in the options", - }); - } - - if (!isTrueObject(widgetProps.options)) { - return createSuccessValidationResponse(value); - } - - const values = _.map(widgetProps.options, (option) => { - if (isTrueObject(option)) { - return option[widgetProps.optionValue]; - } - }).filter((d) => d); - - if (values.length && hasDuplicates(values)) { - return createErrorValidationResponse(value, { - name: "ValidationError", - message: "Duplicate values found, value must be unique", - }); - } - - return createSuccessValidationResponse(value); -} - export const propertyPaneContentConfig = [ { sectionName: "Data", @@ -306,82 +85,6 @@ export const propertyPaneContentConfig = [ }, evaluationSubstitutionType: EvaluationSubstitutionType.SMART_SUBSTITUTE, }, - { - helpText: "Choose or set a field from source data as the display label", - propertyName: "optionLabel", - label: "Label key", - controlType: "DROP_DOWN", - customJSControl: "WRAPPED_CODE_EDITOR", - controlConfig: { - wrapperCode: { - prefix: getOptionLabelValueExpressionPrefix, - suffix: optionLabelValueExpressionSuffix, - }, - }, - placeholderText: "", - isBindProperty: true, - isTriggerProperty: false, - isJSConvertible: true, - evaluatedDependencies: ["options"], - options: getLabelValueKeyOptions, - alwaysShowSelected: true, - validation: { - type: ValidationTypes.FUNCTION, - params: { - fn: labelKeyValidation, - expected: { - type: "String or Array", - example: `color | ["blue", "green"]`, - autocompleteDataType: AutocompleteDataType.STRING, - }, - }, - }, - dependencies: ["options", "dynamicPropertyPathList"], - additionalAutoComplete: getLabelValueAdditionalAutocompleteData, - hidden: (props: WDSSelectWidgetProps) => { - return !(props.dynamicPropertyPathList || []).some( - ({ key }) => key === "options", - ); - }, - }, - { - helpText: "Choose or set a field from source data as the value", - propertyName: "optionValue", - label: "Value key", - controlType: "DROP_DOWN", - customJSControl: "WRAPPED_CODE_EDITOR", - controlConfig: { - wrapperCode: { - prefix: getOptionLabelValueExpressionPrefix, - suffix: optionLabelValueExpressionSuffix, - }, - }, - placeholderText: "", - isBindProperty: true, - isTriggerProperty: false, - isJSConvertible: true, - evaluatedDependencies: ["options"], - options: getLabelValueKeyOptions, - alwaysShowSelected: true, - validation: { - type: ValidationTypes.FUNCTION, - params: { - fn: valueKeyValidation, - expected: { - type: "String or Array", - example: `color | [1, "orange"]`, - autocompleteDataType: AutocompleteDataType.STRING, - }, - }, - }, - dependencies: ["options", "dynamicPropertyPathList"], - additionalAutoComplete: getLabelValueAdditionalAutocompleteData, - hidden: (props: WDSSelectWidgetProps) => { - return !(props.dynamicPropertyPathList || []).some( - ({ key }) => key === "options", - ); - }, - }, { helpText: "Sets a default selected option", propertyName: "defaultOptionValue", diff --git a/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/defaultOptionValidation.ts b/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/defaultOptionValidation.ts index 4f4458fe9604..463f49d9cc4a 100644 --- a/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/defaultOptionValidation.ts +++ b/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/defaultOptionValidation.ts @@ -48,7 +48,7 @@ export function defaultOptionValidation( if (Array.isArray(options)) { const values = _.map(widgetProps.options, (option) => { if (isTrueObject(option)) { - return option[widgetProps.optionValue]; + return option["value"]; } }); diff --git a/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts b/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts index 5b526639e758..356d2155a85d 100644 --- a/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts +++ b/app/client/src/widgets/wds/WDSSelectWidget/config/propertyPaneConfig/validations/optionsCustomValidation.ts @@ -38,8 +38,23 @@ export function optionsCustomValidation( const hasDuplicates = (array: unknown[]): boolean => new Set(array).size !== array.length; - // Is Form mode, otherwise it is JS mode if (Array.isArray(options)) { + const isValidKeys = options.every((option) => { + return ( + _.isPlainObject(option) && + _.has(option, "label") && + _.has(option, "value") + ); + }); + + if (!isValidKeys) { + return createErrorValidationResponse(options, { + name: "ValidationError", + message: + 'This value does not evaluate to type Array<{ "label": "string", "value": "string" | number }>', + }); + } + return createSuccessValidationResponse(options); } @@ -62,6 +77,22 @@ export function optionsCustomValidation( }); } + const isValidKeys = options.every((option) => { + return ( + _.isPlainObject(option) && + _.has(option, "label") && + _.has(option, "value") + ); + }); + + if (!isValidKeys) { + return createErrorValidationResponse(options, { + name: "ValidationError", + message: + 'This value does not evaluate to type Array<{ "label": "string", "value": "string" | number }>', + }); + } + for (let i = 0; i < options.length; i++) { const option = options[i]; diff --git a/app/client/src/widgets/wds/WDSSelectWidget/widget/index.tsx b/app/client/src/widgets/wds/WDSSelectWidget/widget/index.tsx index 7d7048f1092e..a5e3d7e0d2cd 100644 --- a/app/client/src/widgets/wds/WDSSelectWidget/widget/index.tsx +++ b/app/client/src/widgets/wds/WDSSelectWidget/widget/index.tsx @@ -137,10 +137,16 @@ class WDSSelectWidget extends BaseWidget { options: WDSSelectWidgetProps["options"], ): SelectItem[] => { if (Array.isArray(options)) { - return options.map((option) => ({ + const items = options.map((option) => ({ label: option[this.props.optionLabel || "label"] as string, id: option[this.props.optionValue || "value"] as string, })); + + const isValidItems = items.every( + (item) => item.label !== undefined && item.id !== undefined, + ); + + return isValidItems ? items : []; } return []; diff --git a/app/client/src/workers/common/DependencyMap/index.ts b/app/client/src/workers/common/DependencyMap/index.ts index 54a23eafb455..52f5bc8a46d8 100644 --- a/app/client/src/workers/common/DependencyMap/index.ts +++ b/app/client/src/workers/common/DependencyMap/index.ts @@ -29,6 +29,7 @@ import { } from "ee/workers/Evaluation/Actions"; import { isWidgetActionOrJsObject } from "ee/entities/DataTree/utils"; import { getValidEntityType } from "workers/common/DataTreeEvaluator/utils"; +import type DependencyMap from "entities/DependencyMap"; export function createDependencyMap( dataTreeEvalRef: DataTreeEvaluator, @@ -72,6 +73,30 @@ export function createDependencyMap( inverseDependencies: dependencyMap.inverseDependencies, }; } +const addingAffectedNodesToList = ( + affectedNodes: Set, + addedNodes: string[], +) => { + addedNodes.forEach((v) => affectedNodes.add(v)); +}; + +const addNodesToDependencyMap = + (affectedNodes: Set, dependencyMap: DependencyMap) => + (addedNodes: Record, strict?: boolean) => { + const didUpdateDep = dependencyMap.addNodes(addedNodes, strict); + if (didUpdateDep) { + addingAffectedNodesToList(affectedNodes, Object.keys(addedNodes)); + } + return didUpdateDep; + }; + +const setDependenciesToDependencyMap = + (affectedNodes: Set, dependencyMap: DependencyMap) => + (node: string, dependencies: string[]) => { + dependencyMap.addDependency(node, dependencies); + + addingAffectedNodesToList(affectedNodes, [node, ...dependencies]); + }; export const updateDependencyMap = ({ configTree, @@ -91,7 +116,15 @@ export const updateDependencyMap = ({ const { allKeys, dependencyMap, oldConfigTree, oldUnEvalTree } = dataTreeEvalRef; let { errors: dataTreeEvalErrors } = dataTreeEvalRef; - + const affectedNodes: Set = new Set(); + const addNodesToDepedencyMapFn = addNodesToDependencyMap( + affectedNodes, + dependencyMap, + ); + const setDependenciesToDepedencyMapFn = setDependenciesToDependencyMap( + affectedNodes, + dependencyMap, + ); translatedDiffs.forEach((dataTreeDiff) => { const { event, @@ -117,15 +150,18 @@ export const updateDependencyMap = ({ }); // If a new entity is added, add setter functions to all nodes if (entityName === fullPropertyPath) { - const didUpdateDep = dependencyMap.addNodes( - getEntitySetterFunctions(entityConfig, entityName, entity), + const addedNodes = getEntitySetterFunctions( + entityConfig, + entityName, + entity, ); - if (didUpdateDep) didUpdateDependencyMap = true; + didUpdateDependencyMap = + addNodesToDepedencyMapFn(addedNodes) || didUpdateDependencyMap; } - const didUpdateDep = dependencyMap.addNodes(allAddedPaths, false); - - if (didUpdateDep) didUpdateDependencyMap = true; + didUpdateDependencyMap = + addNodesToDepedencyMapFn(allAddedPaths, false) || + didUpdateDependencyMap; if (isWidgetActionOrJsObject(entity)) { if (!isDynamicLeaf(unEvalDataTree, fullPropertyPath, configTree)) { @@ -141,7 +177,9 @@ export const updateDependencyMap = ({ ([path, pathDependencies]) => { const { errors: extractDependencyErrors, references } = extractInfoFromBindings(pathDependencies, allKeys); - dependencyMap.addDependency(path, references); + + setDependenciesToDepedencyMapFn(path, references); + didUpdateDependencyMap = true; dataTreeEvalErrors = dataTreeEvalErrors.concat( extractDependencyErrors, @@ -158,7 +196,9 @@ export const updateDependencyMap = ({ ); const { errors: extractDependencyErrors, references } = extractInfoFromBindings(entityPathDependencies, allKeys); - dependencyMap.addDependency(fullPropertyPath, references); + + setDependenciesToDepedencyMapFn(fullPropertyPath, references); + didUpdateDependencyMap = true; dataTreeEvalErrors = dataTreeEvalErrors.concat( extractDependencyErrors, @@ -218,7 +258,8 @@ export const updateDependencyMap = ({ ); const { errors: extractDependencyErrors, references } = extractInfoFromBindings(entityPathDependencies, allKeys); - dependencyMap.addDependency(fullPropertyPath, references); + setDependenciesToDepedencyMapFn(fullPropertyPath, references); + didUpdateDependencyMap = true; dataTreeEvalErrors = dataTreeEvalErrors.concat( extractDependencyErrors, @@ -237,7 +278,10 @@ export const updateDependencyMap = ({ const updateChangedDependenciesStart = performance.now(); if (didUpdateDependencyMap) { - DependencyMapUtils.makeParentsDependOnChildren(dependencyMap); + DependencyMapUtils.linkAffectedChildNodesToParent( + dependencyMap, + affectedNodes, + ); dataTreeEvalRef.sortedDependencies = dataTreeEvalRef.sortDependencies( dependencyMap, translatedDiffs, diff --git a/app/client/yarn.lock b/app/client/yarn.lock index 8294edca4d7a..cbd1c58cd4bb 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -8585,6 +8585,19 @@ __metadata: languageName: node linkType: hard +"@simonsmith/cypress-image-snapshot@npm:^9.1.0": + version: 9.1.0 + resolution: "@simonsmith/cypress-image-snapshot@npm:9.1.0" + dependencies: + "@types/jest-image-snapshot": ^6.1.0 + chalk: ^4.1.2 + jest-image-snapshot: ^6.1.0 + peerDependencies: + cypress: ">10.0.0" + checksum: cb81eb96f0dbe29627f3bf555b3fadb16fbbcc276c0f682bb3800261d3287093eda2ce0a13778ef73e9ee052ae0a6cb2c46cee3640d4145f22ebed1e8fc2b56d + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.23.3": version: 0.23.5 resolution: "@sinclair/typebox@npm:0.23.5" @@ -10585,13 +10598,6 @@ __metadata: languageName: node linkType: hard -"@types/cypress-image-snapshot@npm:^3.1.9": - version: 3.1.9 - resolution: "@types/cypress-image-snapshot@npm:3.1.9" - checksum: 8afbeb26c575275d02861cfafde5bfae3a7d25f35d0c18bbc1c70a72b45a8bc021ff73de3b5d4a36c7cb22bc86442fee14308ef096f9650dc5eddd941f923f2f - languageName: node - linkType: hard - "@types/d3-geo@npm:^3.1.0": version: 3.1.0 resolution: "@types/d3-geo@npm:3.1.0" @@ -10923,6 +10929,17 @@ __metadata: languageName: node linkType: hard +"@types/jest-image-snapshot@npm:^6.1.0": + version: 6.4.0 + resolution: "@types/jest-image-snapshot@npm:6.4.0" + dependencies: + "@types/jest": "*" + "@types/pixelmatch": "*" + ssim.js: ^3.1.1 + checksum: db751a487f3a8aef7a6f7d4209378fb147670a8d5f7bb08739426ce6cc6a034bc02dca12b9eefcb7a9fe0deec4dc0a809d436445ca405d3e796d6058da4e0568 + languageName: node + linkType: hard + "@types/jest@npm:*, @types/jest@npm:^29.2.3": version: 29.5.12 resolution: "@types/jest@npm:29.5.12" @@ -11170,6 +11187,15 @@ __metadata: languageName: node linkType: hard +"@types/pixelmatch@npm:*": + version: 5.2.6 + resolution: "@types/pixelmatch@npm:5.2.6" + dependencies: + "@types/node": "*" + checksum: 8299207286913414bfd95ac980418342f58e7bc93dc78befbd48ccab110b0341b400712f89fea2b0f0a3a4ad0b1aed18e98e26100b529abe60d4bcc14e11d2e3 + languageName: node + linkType: hard + "@types/prettier@npm:^2.1.5": version: 2.7.0 resolution: "@types/prettier@npm:2.7.0" @@ -12980,7 +13006,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.1.0, ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.1": +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.1": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -13042,13 +13068,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^2.2.1": - version: 2.2.1 - resolution: "ansi-styles@npm:2.2.1" - checksum: ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c - languageName: node - linkType: hard - "ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" @@ -13098,15 +13117,6 @@ __metadata: languageName: node linkType: hard -"app-path@npm:^3.2.0": - version: 3.3.0 - resolution: "app-path@npm:3.3.0" - dependencies: - execa: ^1.0.0 - checksum: 4a0f64c05b9033b96ddfc28067ec72b04903929e3bbdafd3309fa96b1ec77ded06613c84e984cffe043572ead0d257830077012bd36892bdbdb28a818e362ef0 - languageName: node - linkType: hard - "append-transform@npm:^2.0.0": version: 2.0.0 resolution: "append-transform@npm:2.0.0" @@ -13141,7 +13151,7 @@ __metadata: axios: ^1.7.4 esbuild: ^0.19.4 escodegen: ^2.0.0 - express: ^4.19.2 + express: ^4.20.0 express-validator: ^6.14.2 http-status-codes: ^2.2.0 jest: ^29.3.1 @@ -13209,6 +13219,7 @@ __metadata: "@sentry/webpack-plugin": ^1.18.9 "@shared/ast": "workspace:^" "@shared/dsl": "workspace:^" + "@simonsmith/cypress-image-snapshot": ^9.1.0 "@tanstack/virtual-core": ^3.0.0-beta.18 "@testing-library/jest-dom": 5.16.1 "@testing-library/react": 12.1.2 @@ -13217,7 +13228,6 @@ __metadata: "@tinymce/tinymce-react": ^5.1.1 "@types/babel__standalone": ^7.1.7 "@types/codemirror": ^0.0.96 - "@types/cypress-image-snapshot": ^3.1.9 "@types/d3-geo": ^3.1.0 "@types/deep-diff": ^1.0.0 "@types/dom-mediacapture-record": ^1.0.11 @@ -13302,7 +13312,6 @@ __metadata: cy-verify-downloads: ^0.0.5 cypress: 13.13.0 cypress-file-upload: ^4.1.1 - cypress-image-snapshot: ^4.0.1 cypress-log-to-output: ^1.1.2 cypress-mochawesome-reporter: ^3.5.1 cypress-multi-reporters: ^1.2.4 @@ -13382,7 +13391,7 @@ __metadata: node-forge: ^1.3.0 normalizr: ^3.3.0 object-hash: ^3.0.0 - path-to-regexp: ^6.2.0 + path-to-regexp: ^6.3.0 pg: ^8.11.3 plop: ^3.1.1 popper.js: ^1.15.0 @@ -14362,7 +14371,7 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.0.2, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": +"base64-js@npm:^1.0.2, base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 @@ -14501,9 +14510,9 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.2": - version: 1.20.2 - resolution: "body-parser@npm:1.20.2" +"body-parser@npm:1.20.3": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" dependencies: bytes: 3.1.2 content-type: ~1.0.5 @@ -14513,11 +14522,11 @@ __metadata: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 + qs: 6.13.0 raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 + checksum: 1a35c59a6be8d852b00946330141c4f142c6af0f970faa87f10ad74f1ee7118078056706a05ae3093c54dabca9cd3770fa62a170a85801da1a4324f04381167d languageName: node linkType: hard @@ -15044,13 +15053,16 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": - version: 1.0.2 - resolution: "call-bind@npm:1.0.2" +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" dependencies: - function-bind: ^1.1.1 - get-intrinsic: ^1.0.2 - checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.1 + checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 languageName: node linkType: hard @@ -15164,19 +15176,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^1.1.3": - version: 1.1.3 - resolution: "chalk@npm:1.1.3" - dependencies: - ansi-styles: ^2.2.1 - escape-string-regexp: ^1.0.2 - has-ansi: ^2.0.0 - strip-ansi: ^3.0.0 - supports-color: ^2.0.0 - checksum: 9d2ea6b98fc2b7878829eec223abcf404622db6c48396a9b9257f6d0ead2acf18231ae368d6a664a83f272b0679158da12e97b5229f794939e555cc574478acd - languageName: node - linkType: hard - "chalk@npm:^2.4.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -16337,19 +16336,6 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^6.0.0": - version: 6.0.5 - resolution: "cross-spawn@npm:6.0.5" - dependencies: - nice-try: ^1.0.4 - path-key: ^2.0.1 - semver: ^5.5.0 - shebang-command: ^1.2.0 - which: ^1.2.9 - checksum: f893bb0d96cd3d5751d04e67145bdddf25f99449531a72e82dcbbd42796bbc8268c1076c6b3ea51d4d455839902804b94bc45dfb37ecbb32ea8e54a6741c3ab9 - languageName: node - linkType: hard - "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -16859,22 +16845,6 @@ __metadata: languageName: node linkType: hard -"cypress-image-snapshot@npm:^4.0.1": - version: 4.0.1 - resolution: "cypress-image-snapshot@npm:4.0.1" - dependencies: - chalk: ^2.4.1 - fs-extra: ^7.0.1 - glob: ^7.1.3 - jest-image-snapshot: 4.2.0 - pkg-dir: ^3.0.0 - term-img: ^4.0.0 - peerDependencies: - cypress: ^4.5.0 - checksum: 0921e39acbd92f49d58c88e95b212148cc2b74d7fc5b08ab6bdfcfcc1601a74889ddde680504140a522d6b9674e8535eab813830ad853e1fb858dbac88607c6d - languageName: node - linkType: hard - "cypress-log-to-output@npm:^1.1.2": version: 1.1.2 resolution: "cypress-log-to-output@npm:1.1.2" @@ -17352,14 +17322,14 @@ __metadata: languageName: node linkType: hard -"define-data-property@npm:^1.0.1": - version: 1.1.0 - resolution: "define-data-property@npm:1.1.0" +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" dependencies: - get-intrinsic: ^1.2.1 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 gopd: ^1.0.1 - has-property-descriptors: ^1.0.0 - checksum: 7ad4ee84cca8ad427a4831f5693526804b62ce9dfd4efac77214e95a4382aed930072251d4075dc8dc9fc949a353ed51f19f5285a84a788ba9216cc51472a093 + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b languageName: node linkType: hard @@ -18129,6 +18099,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -18368,6 +18345,22 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: ^1.2.4 + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + "es-get-iterator@npm:^1.1.3": version: 1.1.3 resolution: "es-get-iterator@npm:1.1.3" @@ -18648,7 +18641,7 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": +"escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 @@ -19274,21 +19267,6 @@ __metadata: languageName: node linkType: hard -"execa@npm:^1.0.0": - version: 1.0.0 - resolution: "execa@npm:1.0.0" - dependencies: - cross-spawn: ^6.0.0 - get-stream: ^4.0.0 - is-stream: ^1.1.0 - npm-run-path: ^2.0.0 - p-finally: ^1.0.0 - signal-exit: ^3.0.0 - strip-eof: ^1.0.0 - checksum: ddf1342c1c7d02dd93b41364cd847640f6163350d9439071abf70bf4ceb1b9b2b2e37f54babb1d8dc1df8e0d8def32d0e81e74a2e62c3e1d70c303eb4c306bc4 - languageName: node - linkType: hard - "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -19396,42 +19374,42 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.16.3, express@npm:^4.17.3, express@npm:^4.19.2": - version: 4.19.2 - resolution: "express@npm:4.19.2" +"express@npm:^4.16.3, express@npm:^4.17.3, express@npm:^4.19.2, express@npm:^4.20.0": + version: 4.21.0 + resolution: "express@npm:4.21.0" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: ~1.0.4 cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 etag: ~1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: ~1.1.2 on-finished: 2.4.1 parseurl: ~1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.10 proxy-addr: ~2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: ~1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 + checksum: 1c5212993f665809c249bf00ab550b989d1365a5b9171cdfaa26d93ee2ef10cd8add520861ec8d5da74b3194d8374e1d9d53e85ef69b89fd9c4196b87045a5d4 languageName: node linkType: hard @@ -19775,18 +19753,18 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: debug: 2.6.9 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 on-finished: 2.4.1 parseurl: ~1.3.3 statuses: 2.0.1 unpipe: ~1.0.0 - checksum: 92effbfd32e22a7dff2994acedbd9bcc3aa646a3e919ea6a53238090e87097f8ef07cced90aa2cc421abdf993aefbdd5b00104d55c7c5479a8d00ed105b45716 + checksum: a8c58cd97c9cd47679a870f6833a7b417043f5a288cd6af6d0f49b476c874a506100303a128b6d3b654c3d74fa4ff2ffed68a48a27e8630cda5c918f2977dcf4 languageName: node linkType: hard @@ -20317,10 +20295,10 @@ __metadata: languageName: node linkType: hard -"function-bind@npm:^1.1.1": - version: 1.1.1 - resolution: "function-bind@npm:1.1.1" - checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a +"function-bind@npm:^1.1.1, function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 languageName: node linkType: hard @@ -20425,15 +20403,16 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1": - version: 1.2.1 - resolution: "get-intrinsic@npm:1.2.1" +"get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" dependencies: - function-bind: ^1.1.1 - has: ^1.0.3 + es-errors: ^1.3.0 + function-bind: ^1.1.2 has-proto: ^1.0.1 has-symbols: ^1.0.3 - checksum: 5b61d88552c24b0cf6fa2d1b3bc5459d7306f699de060d76442cce49a4721f52b8c560a33ab392cf5575b7810277d54ded9d4d39a1ea61855619ebc005aa7e5f + hasown: ^2.0.0 + checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 languageName: node linkType: hard @@ -20465,15 +20444,6 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^4.0.0": - version: 4.1.0 - resolution: "get-stream@npm:4.1.0" - dependencies: - pump: ^3.0.0 - checksum: 443e1914170c15bd52ff8ea6eff6dfc6d712b031303e36302d2778e3de2506af9ee964d6124010f7818736dcfde05c04ba7ca6cc26883106e084357a17ae7d73 - languageName: node - linkType: hard - "get-stream@npm:^5.0.0, get-stream@npm:^5.1.0": version: 5.2.0 resolution: "get-stream@npm:5.2.0" @@ -20893,15 +20863,6 @@ __metadata: languageName: node linkType: hard -"has-ansi@npm:^2.0.0": - version: 2.0.0 - resolution: "has-ansi@npm:2.0.0" - dependencies: - ansi-regex: ^2.0.0 - checksum: 1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec - languageName: node - linkType: hard - "has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": version: 1.0.2 resolution: "has-bigints@npm:1.0.2" @@ -20923,12 +20884,12 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0": - version: 1.0.0 - resolution: "has-property-descriptors@npm:1.0.0" +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" dependencies: - get-intrinsic: ^1.1.1 - checksum: a6d3f0a266d0294d972e354782e872e2fe1b6495b321e6ef678c9b7a06a40408a6891817350c62e752adced73a94ac903c54734fee05bf65b1905ee1368194bb + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 languageName: node linkType: hard @@ -21009,6 +20970,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.0": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + languageName: node + linkType: hard + "hast-util-heading-rank@npm:^3.0.0": version: 3.0.0 resolution: "hast-util-heading-rank@npm:3.0.0" @@ -22326,13 +22296,6 @@ __metadata: languageName: node linkType: hard -"is-stream@npm:^1.1.0": - version: 1.1.0 - resolution: "is-stream@npm:1.1.0" - checksum: 063c6bec9d5647aa6d42108d4c59723d2bd4ae42135a2d4db6eadbd49b7ea05b750fd69d279e5c7c45cf9da753ad2c00d8978be354d65aa9f6bb434969c6a2ae - languageName: node - linkType: hard - "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -22629,16 +22592,6 @@ __metadata: languageName: node linkType: hard -"iterm2-version@npm:^4.1.0": - version: 4.2.0 - resolution: "iterm2-version@npm:4.2.0" - dependencies: - app-path: ^3.2.0 - plist: ^3.0.1 - checksum: 3a83c748775712a056333a0c226f75d6fa961c125a64cd4d60994f7d14dbbcf3f801fee67777f568b0eb1e998864086e6148fddece0fd341e4123e5ade7fc5b2 - languageName: node - linkType: hard - "jake@npm:^10.8.5": version: 10.8.5 resolution: "jake@npm:10.8.5" @@ -23040,22 +22993,24 @@ __metadata: languageName: node linkType: hard -"jest-image-snapshot@npm:4.2.0": - version: 4.2.0 - resolution: "jest-image-snapshot@npm:4.2.0" +"jest-image-snapshot@npm:^6.1.0": + version: 6.4.0 + resolution: "jest-image-snapshot@npm:6.4.0" dependencies: - chalk: ^1.1.3 + chalk: ^4.0.0 get-stdin: ^5.0.1 glur: ^1.1.2 lodash: ^4.17.4 - mkdirp: ^0.5.1 pixelmatch: ^5.1.0 pngjs: ^3.4.0 rimraf: ^2.6.2 ssim.js: ^3.1.1 peerDependencies: - jest: ">=20 <=26" - checksum: 55c696955a75ef79a4a06fb18910a1238510fd4458a5322e1d82149c07bb7588762623730e9f8613c90fd0ab142f105809676f3ef787558ed6336a967a7ec021 + jest: ">=20 <=29" + peerDependenciesMeta: + jest: + optional: true + checksum: f3b8a0cbba6e4bd4c19080e8cb807b4dd03e60d43bc69e0bf5898c09dbbb0ee812c04ad66d027ee64121f169bb5ef0cd81d5903efd2772e085e619aa6415676b languageName: node linkType: hard @@ -25214,10 +25169,10 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 +"merge-descriptors@npm:1.0.3": + version: 1.0.3 + resolution: "merge-descriptors@npm:1.0.3" + checksum: 52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 languageName: node linkType: hard @@ -26160,13 +26115,6 @@ __metadata: languageName: node linkType: hard -"nice-try@npm:^1.0.4": - version: 1.0.5 - resolution: "nice-try@npm:1.0.5" - checksum: 0b4af3b5bb5d86c289f7a026303d192a7eb4417231fe47245c460baeabae7277bcd8fd9c728fb6bd62c30b3e15cd6620373e2cf33353b095d8b403d3e8a15aff - languageName: node - linkType: hard - "no-case@npm:^3.0.4": version: 3.0.4 resolution: "no-case@npm:3.0.4" @@ -26354,15 +26302,6 @@ __metadata: languageName: node linkType: hard -"npm-run-path@npm:^2.0.0": - version: 2.0.2 - resolution: "npm-run-path@npm:2.0.2" - dependencies: - path-key: ^2.0.0 - checksum: acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 - languageName: node - linkType: hard - "npm-run-path@npm:^4.0.0, npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -26486,10 +26425,10 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.12.3, object-inspect@npm:^1.9.0": - version: 1.12.3 - resolution: "object-inspect@npm:1.12.3" - checksum: dabfd824d97a5f407e6d5d24810d888859f6be394d8b733a77442b277e0808860555176719c5905e765e3743a7cada6b8b0a3b85e5331c530fd418cc8ae991db +"object-inspect@npm:^1.12.3, object-inspect@npm:^1.13.1": + version: 1.13.2 + resolution: "object-inspect@npm:1.13.2" + checksum: 9f850b3c045db60e0e97746e809ee4090d6ce62195af17dd1e9438ac761394a7d8ec4f7906559aea5424eaf61e35d3e53feded2ccd5f62fcc7d9670d3c8eb353 languageName: node linkType: hard @@ -26834,13 +26773,6 @@ __metadata: languageName: node linkType: hard -"p-finally@npm:^1.0.0": - version: 1.0.0 - resolution: "p-finally@npm:1.0.0" - checksum: 93a654c53dc805dd5b5891bab16eb0ea46db8f66c4bfd99336ae929323b1af2b70a8b0654f8f1eae924b2b73d037031366d645f1fd18b3d30cbd15950cc4b1d4 - languageName: node - linkType: hard - "p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" @@ -27120,13 +27052,6 @@ __metadata: languageName: node linkType: hard -"path-key@npm:^2.0.0, path-key@npm:^2.0.1": - version: 2.0.1 - resolution: "path-key@npm:2.0.1" - checksum: f7ab0ad42fe3fb8c7f11d0c4f849871e28fbd8e1add65c370e422512fc5887097b9cf34d09c1747d45c942a8c1e26468d6356e2df3f740bf177ab8ca7301ebfd - languageName: node - linkType: hard - "path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -27171,10 +27096,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 69a14ea24db543e8b0f4353305c5eac6907917031340e5a8b37df688e52accd09e3cebfe1660b70d76b6bd89152f52183f28c74813dbf454ba1a01c82a38abce +"path-to-regexp@npm:0.1.10": + version: 0.1.10 + resolution: "path-to-regexp@npm:0.1.10" + checksum: ab7a3b7a0b914476d44030340b0a65d69851af2a0f33427df1476100ccb87d409c39e2182837a96b98fb38c4ef2ba6b87bdad62bb70a2c153876b8061760583c languageName: node linkType: hard @@ -27187,10 +27112,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^6.2.0": - version: 6.2.0 - resolution: "path-to-regexp@npm:6.2.0" - checksum: a6aca74d2d6e2e7594d812f653cf85e9cb5054d3a8d80f099722a44ef6ad22639b02078e5ea83d11db16321c3e4359e3f1ab0274fa78dad0754a6e53f630b0fc +"path-to-regexp@npm:^6.3.0": + version: 6.3.0 + resolution: "path-to-regexp@npm:6.3.0" + checksum: eca78602e6434a1b6799d511d375ec044e8d7e28f5a48aa5c28d57d8152fb52f3fc62fb1cfc5dfa2198e1f041c2a82ed14043d75740a2fe60e91b5089a153250 languageName: node linkType: hard @@ -27469,16 +27394,6 @@ __metadata: languageName: node linkType: hard -"plist@npm:^3.0.1": - version: 3.0.5 - resolution: "plist@npm:3.0.5" - dependencies: - base64-js: ^1.5.1 - xmlbuilder: ^9.0.7 - checksum: f8b82816f66559965a4dabf139bd8dd95cdec7e51f32742bb353af276ea8228b9807113743b860eda3e867f6ed70d2bcbc1e135b3204d92b5c37ac765f68444e - languageName: node - linkType: hard - "plop@npm:^3.1.1": version: 3.1.1 resolution: "plop@npm:3.1.1" @@ -29203,21 +29118,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.11.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" - dependencies: - side-channel: ^1.0.4 - checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297 - languageName: node - linkType: hard - -"qs@npm:^6.11.0": - version: 6.11.1 - resolution: "qs@npm:6.11.1" +"qs@npm:6.13.0, qs@npm:^6.11.0": + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: - side-channel: ^1.0.4 - checksum: 82ee78ef12a16f3372fae5b64f76f8aedecb000feea882bbff1af146c147f6eb66b08f9c3f34d7e076f28563586956318b9b2ca41141846cdd6d5ad6f241d52f + side-channel: ^1.0.6 + checksum: e9404dc0fc2849245107108ce9ec2766cde3be1b271de0bf1021d049dc5b98d1a2901e67b431ac5509f865420a7ed80b7acb3980099fe1c118a1c5d2e1432ad8 languageName: node linkType: hard @@ -31997,7 +31903,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0, semver@npm:^5.6.0": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -32024,9 +31930,9 @@ __metadata: languageName: node linkType: hard -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" +"send@npm:0.19.0": + version: 0.19.0 + resolution: "send@npm:0.19.0" dependencies: debug: 2.6.9 depd: 2.0.0 @@ -32041,7 +31947,7 @@ __metadata: on-finished: 2.4.1 range-parser: ~1.2.1 statuses: 2.0.1 - checksum: 74fc07ebb58566b87b078ec63e5a3e41ecd987e4272ba67b7467e86c6ad51bc6b0b0154133b6d8b08a2ddda360464f71382f7ef864700f34844a76c8027817a8 + checksum: 5ae11bd900c1c2575525e2aa622e856804e2f96a09281ec1e39610d089f53aa69e13fd8db84b52f001d0318cf4bb0b3b904ad532fc4c0014eb90d32db0cff55f languageName: node linkType: hard @@ -32089,15 +31995,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" +"serve-static@npm:1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 parseurl: ~1.3.3 - send: 0.18.0 - checksum: af57fc13be40d90a12562e98c0b7855cf6e8bd4c107fe9a45c212bf023058d54a1871b1c89511c3958f70626fff47faeb795f5d83f8cf88514dbaeb2b724464d + send: 0.19.0 + checksum: dffc52feb4cc5c68e66d0c7f3c1824d4e989f71050aefc9bd5f822a42c54c9b814f595fc5f2b717f4c7cc05396145f3e90422af31186a93f76cf15f707019759 languageName: node linkType: hard @@ -32115,6 +32021,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 + languageName: node + linkType: hard + "set-function-name@npm:^2.0.0, set-function-name@npm:^2.0.1": version: 2.0.1 resolution: "set-function-name@npm:2.0.1" @@ -32201,15 +32121,6 @@ __metadata: languageName: node linkType: hard -"shebang-command@npm:^1.2.0": - version: 1.2.0 - resolution: "shebang-command@npm:1.2.0" - dependencies: - shebang-regex: ^1.0.0 - checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -32219,13 +32130,6 @@ __metadata: languageName: node linkType: hard -"shebang-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "shebang-regex@npm:1.0.0" - checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 - languageName: node - linkType: hard - "shebang-regex@npm:^3.0.0": version: 3.0.0 resolution: "shebang-regex@npm:3.0.0" @@ -32258,14 +32162,15 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: - call-bind: ^1.0.0 - get-intrinsic: ^1.0.2 - object-inspect: ^1.9.0 - checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245 + call-bind: ^1.0.7 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + object-inspect: ^1.13.1 + checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 languageName: node linkType: hard @@ -33167,13 +33072,6 @@ __metadata: languageName: node linkType: hard -"strip-eof@npm:^1.0.0": - version: 1.0.0 - resolution: "strip-eof@npm:1.0.0" - checksum: 40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 - languageName: node - linkType: hard - "strip-final-newline@npm:^2.0.0": version: 2.0.0 resolution: "strip-final-newline@npm:2.0.0" @@ -33362,13 +33260,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^2.0.0": - version: 2.0.0 - resolution: "supports-color@npm:2.0.0" - checksum: 602538c5812b9006404370b5a4b885d3e2a1f6567d314f8b4a41974ffe7d08e525bf92ae0f9c7030e3b4c78e4e34ace55d6a67a74f1571bc205959f5972f88f0 - languageName: node - linkType: hard - "supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -33657,16 +33548,6 @@ __metadata: languageName: node linkType: hard -"term-img@npm:^4.0.0": - version: 4.1.0 - resolution: "term-img@npm:4.1.0" - dependencies: - ansi-escapes: ^4.1.0 - iterm2-version: ^4.1.0 - checksum: fda618b4a45c01bec0a5bc79f456ca1834ad88cbfde3a1bf14871373f555f7df3f40f7ed6d678600a7abebe454b3ab66604bf19dcc87004260677f088d6c7d18 - languageName: node - linkType: hard - "terminal-link@npm:^2.0.0": version: 2.1.1 resolution: "terminal-link@npm:2.1.1" @@ -35780,7 +35661,7 @@ __metadata: languageName: node linkType: hard -"which@npm:^1.2.12, which@npm:^1.2.14, which@npm:^1.2.9, which@npm:^1.3.1": +"which@npm:^1.2.12, which@npm:^1.2.14, which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" dependencies: @@ -36261,13 +36142,6 @@ __metadata: languageName: node linkType: hard -"xmlbuilder@npm:^9.0.7": - version: 9.0.7 - resolution: "xmlbuilder@npm:9.0.7" - checksum: 8193bb323806a002764f013bea0c6e9ff2dc26fd29109408761b16b59a8ad2214c2abe8e691755fd8b525586e3a0e1efeb92335947d7b0899032b779f1705a53 - languageName: node - linkType: hard - "xmlchars@npm:^2.2.0": version: 2.2.0 resolution: "xmlchars@npm:2.2.0" diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ApplicationSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ApplicationSpanCE.java index 6e27900e5920..57a8982e0e30 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ApplicationSpanCE.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ApplicationSpanCE.java @@ -1,7 +1,10 @@ package com.appsmith.external.constants.spans.ce; +import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.APPLICATION_ID_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.CONSOLIDATED_API_PREFIX; public class ApplicationSpanCE { public static final String APPLICATION_FETCH_FROM_DB = CONSOLIDATED_API_PREFIX + "app_db"; + public static final String APPLICATION_ID_FETCH_REDIS_SPAN = APPLICATION_ID_SPAN + ".read_redis"; + public static final String APPLICATION_ID_UPDATE_REDIS_SPAN = APPLICATION_ID_SPAN + ".update_redis"; } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceConfiguration.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceConfiguration.java index 5a81b66b730c..637879eb75b7 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceConfiguration.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceConfiguration.java @@ -34,8 +34,10 @@ public class DatasourceConfiguration implements AppsmithDomain { @JsonView({Views.Public.class, FromRequest.class}) AuthenticationDTO authentication; + @JsonView({Views.Public.class, FromRequest.class}) SSHConnection sshProxy; + @JsonView({Views.Public.class, FromRequest.class}) Boolean sshProxyEnabled; @JsonView({Views.Public.class, FromRequest.class, Git.class}) diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create.json index bd075899bcc1..e99b738928ce 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create.json @@ -1,13 +1,12 @@ { "identifier": "UPLOAD_FILE_FROM_BODY", - "controlType": "SECTION", + "controlType": "SECTION_V2", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'UPLOAD_FILE_FROM_BODY'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select bucket to query", + "controlType": "DOUBLE_COLUMN_ZONE", "children": [ { "label": "Bucket name", @@ -16,12 +15,17 @@ "evaluationSubstitutionType": "TEMPLATE", "isRequired": true, "initialValue": "" + }, + { + "label": "Expiry duration of signed URL (minutes)", + "configProperty": "actionConfiguration.formData.create.expiry.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "initialValue": "5" } ] }, { - "controlType": "SECTION", - "label": "Query", + "controlType": "DOUBLE_COLUMN_ZONE", "description": "Optional", "children": [ { @@ -45,13 +49,13 @@ "value": "NO" } ] - }, - { - "label": "Expiry duration of signed URL (minutes)", - "configProperty": "actionConfiguration.formData.create.expiry.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "initialValue": "5" - }, + } + ] + }, + { + "controlType": "SINGLE_COLUMN_ZONE", + "description": "Optional", + "children": [ { "label": "Content", "configProperty": "actionConfiguration.formData.body.data", diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create_many.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create_many.json index 712278db4716..1ed2d5fb59c2 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create_many.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/create_many.json @@ -1,13 +1,12 @@ { "identifier": "UPLOAD_MULTIPLE_FILES_FROM_BODY", - "controlType": "SECTION", + "controlType": "SECTION_V2", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'UPLOAD_MULTIPLE_FILES_FROM_BODY'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select bucket to query", + "controlType": "DOUBLE_COLUMN_ZONE", "children": [ { "label": "Bucket name", @@ -16,12 +15,17 @@ "evaluationSubstitutionType": "TEMPLATE", "isRequired": true, "initialValue": "" + }, + { + "label": "Expiry duration of signed URL (minutes)", + "configProperty": "actionConfiguration.formData.create.expiry.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "initialValue": "5" } ] }, { - "controlType": "SECTION", - "label": "Query", + "controlType": "DOUBLE_COLUMN_ZONE", "description": "Optional", "children": [ { @@ -45,13 +49,13 @@ "value": "NO" } ] - }, - { - "label": "Expiry duration of signed URL (minutes)", - "configProperty": "actionConfiguration.formData.create.expiry.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "initialValue": "5" - }, + } + ] + }, + { + "controlType": "SINGLE_COLUMN_ZONE", + "description": "Optional", + "children": [ { "label": "Content", "configProperty": "actionConfiguration.formData.body.data", diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete.json index 29ebcb00dd54..053132225d5f 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete.json @@ -1,13 +1,12 @@ { "identifier": "DELETE_FILE", - "controlType": "SECTION", + "controlType": "SECTION_V2", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'DELETE_FILE'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select bucket to query", + "controlType": "DOUBLE_COLUMN_ZONE", "children": [ { "label": "Bucket name", @@ -20,8 +19,7 @@ ] }, { - "controlType": "SECTION", - "label": "Query", + "controlType": "DOUBLE_COLUMN_ZONE", "description": "Optional", "children": [ { diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete_many.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete_many.json index e8b8fdb88871..1c4352297e3b 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete_many.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/delete_many.json @@ -1,13 +1,12 @@ { "identifier": "DELETE_MULTIPLE_FILES", - "controlType": "SECTION", + "controlType": "SECTION_V2", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'DELETE_MULTIPLE_FILES'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select bucket to query", + "controlType": "DOUBLE_COLUMN_ZONE", "children": [ { "label": "Bucket name", @@ -16,7 +15,12 @@ "evaluationSubstitutionType": "TEMPLATE", "isRequired": true, "initialValue": "" - }, + } + ] + }, + { + "controlType": "SINGLE_COLUMN_ZONE", + "children": [ { "label": "List of Files", "configProperty": "actionConfiguration.formData.path.data", diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/list.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/list.json index 0a85b2df4e73..c9fbfc4cf731 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/list.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/list.json @@ -1,13 +1,12 @@ { "identifier": "LIST", - "controlType": "SECTION", + "controlType": "SECTION_V2", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'LIST'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select bucket to query", + "controlType": "DOUBLE_COLUMN_ZONE", "children": [ { "label": "Bucket name", @@ -16,62 +15,17 @@ "evaluationSubstitutionType": "TEMPLATE", "isRequired": true, "initialValue": "" - } - ] - }, - { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", - "children": [ + }, { "label": "Prefix", "configProperty": "actionConfiguration.formData.list.prefix.data", "controlType": "QUERY_DYNAMIC_INPUT_TEXT", "initialValue": "" - }, - { - "label": "Where", - "configProperty": "actionConfiguration.formData.list.where.data", - "nestedLevels": 3, - "controlType": "WHERE_CLAUSE", - "-subtitle": "Array of Objects", - "-tooltipText": "Array of Objects", - "-alternateViewTypes": ["json"], - "logicalTypes": [ - { - "label": "AND", - "value": "AND" - }, - { - "label": "OR", - "value": "OR" - } - ], - "comparisonTypes": [ - { - "label": "==", - "value": "EQ" - }, - { - "label": "!=", - "value": "NOT_EQ" - }, - { - "label": "in", - "value": "IN" - }, - { - "label": "not in", - "value": "NOT_IN" - } - ] } ] }, { - "controlType": "SECTION", - "label": "Options", + "controlType": "DOUBLE_COLUMN_ZONE", "children": [ { "label": "Generate signed URL", @@ -122,9 +76,52 @@ "value": "NO" } ] + } + ] + }, + { + "controlType": "SINGLE_COLUMN_ZONE", + "description": "Optional", + "children": [ + { + "label": "Filter data", + "configProperty": "actionConfiguration.formData.list.where.data", + "nestedLevels": 3, + "controlType": "WHERE_CLAUSE", + "-subtitle": "Array of Objects", + "-tooltipText": "Array of Objects", + "-alternateViewTypes": ["json"], + "logicalTypes": [ + { + "label": "AND", + "value": "AND" + }, + { + "label": "OR", + "value": "OR" + } + ], + "comparisonTypes": [ + { + "label": "==", + "value": "EQ" + }, + { + "label": "!=", + "value": "NOT_EQ" + }, + { + "label": "in", + "value": "IN" + }, + { + "label": "not in", + "value": "NOT_IN" + } + ] }, { - "label": "Sort By", + "label": "Sort data", "configProperty": "actionConfiguration.formData.list.sortBy.data", "controlType": "SORTING", "-subtitle": "Array of Objects", @@ -132,7 +129,7 @@ "-alternateViewTypes": ["json"] }, { - "label": "Paginate By", + "label": "Paginate data", "configProperty": "actionConfiguration.formData.list.pagination.data", "controlType": "PAGINATION", "-subtitle": "Object", diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/read.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/read.json index ca069a97380f..749f86709c27 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/read.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/read.json @@ -1,13 +1,12 @@ { "identifier": "READ_FILE", - "controlType": "SECTION", + "controlType": "SECTION_V2", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'READ_FILE'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select bucket to query", + "controlType": "DOUBLE_COLUMN_ZONE", "children": [ { "label": "Bucket name", @@ -20,8 +19,7 @@ ] }, { - "controlType": "SECTION", - "label": "Query", + "controlType": "DOUBLE_COLUMN_ZONE", "description": "Optional", "children": [ { diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/root.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/root.json index 82d8d5d91d12..0a1976bf8f15 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/root.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/editor/root.json @@ -1,39 +1,44 @@ { "editor": [ { - "controlType": "SECTION", + "controlType": "SECTION_V2", "identifier": "SELECTOR", "children": [ { - "label": "Command", - "description": "Choose the method you would like to use", - "configProperty": "actionConfiguration.formData.command.data", - "controlType": "DROP_DOWN", - "initialValue": "LIST", - "options": [ + "controlType": "DOUBLE_COLUMN_ZONE", + "children": [ { - "label": "List files in bucket", - "value": "LIST" - }, - { - "label": "Create a new file", - "value": "UPLOAD_FILE_FROM_BODY" - }, - { - "label": "Create multiple new files", - "value": "UPLOAD_MULTIPLE_FILES_FROM_BODY" - }, - { - "label": "Read file", - "value": "READ_FILE" - }, - { - "label": "Delete file", - "value": "DELETE_FILE" - }, - { - "label": "Delete multiple files", - "value": "DELETE_MULTIPLE_FILES" + "label": "Command", + "description": "Choose the method you would like to use", + "configProperty": "actionConfiguration.formData.command.data", + "controlType": "DROP_DOWN", + "initialValue": "LIST", + "options": [ + { + "label": "List files in bucket", + "value": "LIST" + }, + { + "label": "Create a new file", + "value": "UPLOAD_FILE_FROM_BODY" + }, + { + "label": "Create multiple new files", + "value": "UPLOAD_MULTIPLE_FILES_FROM_BODY" + }, + { + "label": "Read file", + "value": "READ_FILE" + }, + { + "label": "Delete file", + "value": "DELETE_FILE" + }, + { + "label": "Delete multiple files", + "value": "DELETE_MULTIPLE_FILES" + } + ] } ] } diff --git a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/chat.json b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/chat.json new file mode 100644 index 000000000000..a1621376380e --- /dev/null +++ b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/chat.json @@ -0,0 +1,130 @@ +{ + "identifier": "CHAT", + "controlType": "SECTION_V2", + "conditionals": { + "show": "{{actionConfiguration.formData.command.data === 'CHAT'}}" + }, + "children": [ + { + "controlType": "DOUBLE_COLUMN_ZONE", + "children": [ + { + "label": "Models", + "tooltipText": "Select the model for response generation", + "subtitle": "ID of the model to use.", + "isRequired": true, + "propertyName": "chat_model_id", + "configProperty": "actionConfiguration.formData.chatModel.data", + "controlType": "DROP_DOWN", + "initialValue": "", + "options": [], + "placeholderText": "All models will be fetched.", + "fetchOptionsConditionally": true, + "setFirstOptionAsDefault": true, + "alternateViewTypes": ["json"], + "conditionals": { + "enable": "{{true}}", + "fetchDynamicValues": { + "condition": "{{actionConfiguration.formData.command.data === 'CHAT'}}", + "config": { + "params": { + "requestType": "CHAT_MODELS", + "displayType": "DROP_DOWN" + } + } + } + } + }, + { + "label": "Max Tokens", + "tooltipText": "The maximum number of tokens to generate in the chat completion.", + "subtitle": "The maximum number of tokens to generate in the chat completion.", + "Description": "Put a positive integer value", + "configProperty": "actionConfiguration.formData.maxTokens", + "controlType": "INPUT_TEXT", + "initialValue": "256", + "isRequired": true, + "dataType": "NUMBER", + "customStyles": { + "width": "270px", + "minWidth": "270px" + } + } + ] + }, + { + "controlType": "SINGLE_COLUMN_ZONE", + "children": [ + { + "label": "System Prompt", + "Description": "Provide additional instructions for the AI model as system prompt", + "subtitle": "Provide additional instructions for the AI model as system prompt", + "configProperty": "actionConfiguration.formData.systemPrompt.data", + "controlType": "QUERY_DYNAMIC_TEXT", + "placeholderText": "Write some text or use {{ }} to reference a dynamic text value", + "initialValue": "", + "isRequired": false, + "customStyles": { + "width": "590px", + "minWidth": "400px" + } + }, + { + "label": "Messages", + "tooltipText": "Ask a question", + "subtitle": "A list of messages comprising the conversation so far.", + "propertyName": "messages", + "isRequired": true, + "configProperty": "actionConfiguration.formData.messages.data", + "controlType": "ARRAY_FIELD", + "addMoreButtonLabel": "Add message", + "alternateViewTypes": ["json"], + "schema": [ + { + "label": "Role", + "key": "role", + "controlType": "DROP_DOWN", + "initialValue": "Human", + "options": [ + { + "label": "Human", + "value": "Human" + }, + { + "label": "Assistant", + "value": "Assistant" + } + ] + }, + { + "label": "Content", + "key": "content", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "placeholderText": "{{ UserInput.text }}" + } + ] + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "children": [ + { + "label": "Temperature", + "tooltipText": "Put a value between 0 and 1", + "Description": "Put a value between 0 and 1", + "subtitle": "Defaults to 1. Ranges from 0 to 1. Use temp closer to 0 for analytical / multiple choice, and closer to 1 for creative and generative tasks.", + "configProperty": "actionConfiguration.formData.temperature", + "controlType": "INPUT_TEXT", + "dataType": "NUMBER", + "initialValue": "1", + "isRequired": false, + "customStyles": { + "width": "270px", + "minWidth": "270px" + } + } + ] + } + ] +} diff --git a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/root.json b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/root.json index 2b674a2fc49d..abc010dddc76 100644 --- a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/root.json +++ b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/root.json @@ -2,7 +2,7 @@ "editor": [ { "controlType": "SECTION_V2", - "identifier": "SECTION-ONE", + "identifier": "SELECTOR", "children": [ { "controlType": "DOUBLE_COLUMN_ZONE", @@ -27,316 +27,9 @@ ] } ] - }, - { - "controlType": "DOUBLE_COLUMN_ZONE", - "identifier": "SO-Z2", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'CHAT'}}" - }, - "children": [ - { - "label": "Models", - "tooltipText": "Select the model for response generation", - "subtitle": "ID of the model to use.", - "isRequired": true, - "propertyName": "chat_model_id", - "configProperty": "actionConfiguration.formData.chatModel.data", - "controlType": "DROP_DOWN", - "initialValue": "", - "options": [], - "placeholderText": "All models will be fetched.", - "fetchOptionsConditionally": true, - "setFirstOptionAsDefault": true, - "alternateViewTypes": ["json"], - "conditionals": { - "enable": "{{true}}", - "fetchDynamicValues": { - "condition": "{{actionConfiguration.formData.command.data === 'CHAT'}}", - "config": { - "params": { - "requestType": "CHAT_MODELS", - "displayType": "DROP_DOWN" - } - } - } - } - }, - { - "label": "Max Tokens", - "tooltipText": "The maximum number of tokens to generate in the chat completion.", - "subtitle": "The maximum number of tokens to generate in the chat completion.", - "Description": "Put a positive integer value", - "configProperty": "actionConfiguration.formData.maxTokens", - "controlType": "INPUT_TEXT", - "initialValue": "256", - "isRequired": true, - "dataType": "NUMBER", - "customStyles": { - "width": "270px", - "minWidth": "270px" - } - } - ] - }, - { - "controlType": "SINGLE_COLUMN_ZONE", - "identifier": "SO-Z3", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'CHAT'}}" - }, - "children": [ - { - "label": "System Prompt", - "Description": "Provide additional instructions for the AI model as system prompt", - "subtitle": "Provide additional instructions for the AI model as system prompt", - "configProperty": "actionConfiguration.formData.systemPrompt.data", - "controlType": "QUERY_DYNAMIC_TEXT", - "placeholderText": "Write some text or use {{ }} to reference a dynamic text value", - "initialValue": "", - "isRequired": false, - "customStyles": { - "width": "590px", - "minWidth": "400px" - } - } - ] - }, - { - "controlType": "DOUBLE_COLUMN_ZONE", - "identifier": "SO-Z4", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'VISION'}}" - }, - "children": [ - { - "label": "Models", - "tooltipText": "Select the model for response generation", - "subtitle": "ID of the model to use.", - "isRequired": true, - "propertyName": "vision_model_id", - "configProperty": "actionConfiguration.formData.visionModel.data", - "controlType": "DROP_DOWN", - "initialValue": "", - "options": [], - "placeholderText": "All models will be fetched.", - "fetchOptionsConditionally": true, - "setFirstOptionAsDefault": true, - "alternateViewTypes": ["json"], - "conditionals": { - "enable": "{{true}}", - "fetchDynamicValues": { - "condition": "{{actionConfiguration.formData.command.data === 'VISION'}}", - "config": { - "params": { - "requestType": "VISION_MODELS", - "displayType": "DROP_DOWN" - } - } - } - } - }, - { - "label": "Max Tokens", - "tooltipText": "The maximum number of tokens to generate in the chat completion.", - "subtitle": "The maximum number of tokens to generate in the chat completion.", - "Description": "Put a positive integer value", - "configProperty": "actionConfiguration.formData.maxTokens", - "controlType": "INPUT_TEXT", - "initialValue": "256", - "isRequired": true, - "dataType": "NUMBER", - "customStyles": { - "width": "270px", - "minWidth": "270px" - } - } - ] - }, - { - "controlType": "SINGLE_COLUMN_ZONE", - "identifier": "SO-Z5", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'VISION'}}" - }, - "children": [ - { - "label": "System Prompt", - "Description": "Provide additional instructions for the AI model as system prompt", - "subtitle": "Provide additional instructions for the AI model as system prompt", - "configProperty": "actionConfiguration.formData.systemPrompt.data", - "controlType": "QUERY_DYNAMIC_TEXT", - "placeholderText": "Write some text or use {{ }} to reference a dynamic text value", - "initialValue": "", - "isRequired": false - } - ] - } - ] - }, - { - "controlType": "SECTION_V2", - "identifier": "SECTION-TWO", - "children": [ - { - "controlType": "SINGLE_COLUMN_ZONE", - "identifier": "ST-Z1", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'CHAT'}}" - }, - "children": [ - { - "label": "Messages", - "tooltipText": "Ask a question", - "subtitle": "A list of messages comprising the conversation so far.", - "propertyName": "messages", - "isRequired": true, - "configProperty": "actionConfiguration.formData.messages.data", - "controlType": "ARRAY_FIELD", - "addMoreButtonLabel": "Add message", - "alternateViewTypes": ["json"], - "schema": [ - { - "label": "Role", - "key": "role", - "controlType": "DROP_DOWN", - "initialValue": "Human", - "options": [ - { - "label": "Human", - "value": "Human" - }, - { - "label": "Assistant", - "value": "Assistant" - } - ] - }, - { - "label": "Content", - "key": "content", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "placeholderText": "{{ UserInput.text }}" - } - ] - } - ] - }, - { - "controlType": "SINGLE_COLUMN_ZONE", - "identifier": "ST-Z2", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'VISION'}}" - }, - "children": [ - { - "label": "Messages", - "tooltipText": "Ask a question", - "subtitle": "A list of messages comprising the conversation so far. You can pass base64 encoded image directly in the request.", - "propertyName": "messages", - "isRequired": true, - "configProperty": "actionConfiguration.formData.messages.data", - "controlType": "ARRAY_FIELD", - "addMoreButtonLabel": "Add message", - "alternateViewTypes": ["json"], - "schema": [ - { - "label": "Role", - "key": "role", - "controlType": "DROP_DOWN", - "initialValue": "Human", - "options": [ - { - "label": "Human", - "value": "Human" - }, - { - "label": "Assistant", - "value": "Assistant" - } - ] - }, - { - "label": "Type", - "key": "type", - "controlType": "DROP_DOWN", - "initialValue": "text", - "options": [ - { - "label": "Text", - "value": "text" - }, - { - "label": "Image", - "value": "image" - } - ] - }, - { - "label": "Content", - "key": "content", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "placeholderText": "{{Img1.image}} or {{Input1.text}}" - } - ] - } - ] - } - ] - }, - { - "controlType": "SECTION_V2", - "identifier": "SECTION-THREE", - "children": [ - { - "controlType": "DOUBLE_COLUMN_ZONE", - "identifier": "STH-Z1", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'CHAT'}}" - }, - "children": [ - { - "label": "Temperature", - "tooltipText": "Put a value between 0 and 1", - "Description": "Put a value between 0 and 1", - "subtitle": "Defaults to 1. Ranges from 0 to 1. Use temp closer to 0 for analytical / multiple choice, and closer to 1 for creative and generative tasks.", - "configProperty": "actionConfiguration.formData.temperature", - "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "initialValue": "1", - "isRequired": false, - "customStyles": { - "width": "270px", - "minWidth": "270px" - } - } - ] - }, - { - "controlType": "DOUBLE_COLUMN_ZONE", - "identifier": "STH-Z2", - "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'VISION'}}" - }, - "children": [ - { - "label": "Temperature", - "tooltipText": "Put a value between 0 and 1", - "Description": "Put a value between 0 and 1", - "subtitle": "Defaults to 1. Ranges from 0 to 1. Use temp closer to 0 for analytical / multiple choice, and closer to 1 for creative and generative tasks.", - "configProperty": "actionConfiguration.formData.temperature", - "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "initialValue": "1", - "isRequired": false, - "customStyles": { - "width": "270px", - "minWidth": "270px" - } - } - ] } ] } - ] + ], + "files": ["chat.json", "vision.json"] } diff --git a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/vision.json b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/vision.json new file mode 100644 index 000000000000..282ddac5355b --- /dev/null +++ b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/vision.json @@ -0,0 +1,142 @@ +{ + "identifier": "VISION", + "controlType": "SECTION_V2", + "conditionals": { + "show": "{{actionConfiguration.formData.command.data === 'VISION'}}" + }, + "children": [ + { + "controlType": "DOUBLE_COLUMN_ZONE", + "children": [ + { + "label": "Models", + "tooltipText": "Select the model for response generation", + "subtitle": "ID of the model to use.", + "isRequired": true, + "propertyName": "vision_model_id", + "configProperty": "actionConfiguration.formData.visionModel.data", + "controlType": "DROP_DOWN", + "initialValue": "", + "options": [], + "placeholderText": "All models will be fetched.", + "fetchOptionsConditionally": true, + "setFirstOptionAsDefault": true, + "alternateViewTypes": ["json"], + "conditionals": { + "enable": "{{true}}", + "fetchDynamicValues": { + "condition": "{{actionConfiguration.formData.command.data === 'VISION'}}", + "config": { + "params": { + "requestType": "VISION_MODELS", + "displayType": "DROP_DOWN" + } + } + } + } + }, + { + "label": "Max Tokens", + "tooltipText": "The maximum number of tokens to generate in the chat completion.", + "subtitle": "The maximum number of tokens to generate in the chat completion.", + "Description": "Put a positive integer value", + "configProperty": "actionConfiguration.formData.maxTokens", + "controlType": "INPUT_TEXT", + "initialValue": "256", + "isRequired": true, + "dataType": "NUMBER", + "customStyles": { + "width": "270px", + "minWidth": "270px" + } + } + ] + }, + { + "controlType": "SINGLE_COLUMN_ZONE", + "children": [ + { + "label": "System Prompt", + "Description": "Provide additional instructions for the AI model as system prompt", + "subtitle": "Provide additional instructions for the AI model as system prompt", + "configProperty": "actionConfiguration.formData.systemPrompt.data", + "controlType": "QUERY_DYNAMIC_TEXT", + "placeholderText": "Write some text or use {{ }} to reference a dynamic text value", + "initialValue": "", + "isRequired": false + }, + { + "label": "Messages", + "tooltipText": "Ask a question", + "subtitle": "A list of messages comprising the conversation so far. You can pass base64 encoded image directly in the request.", + "propertyName": "messages", + "isRequired": true, + "configProperty": "actionConfiguration.formData.messages.data", + "controlType": "ARRAY_FIELD", + "addMoreButtonLabel": "Add message", + "alternateViewTypes": ["json"], + "schema": [ + { + "label": "Role", + "key": "role", + "controlType": "DROP_DOWN", + "initialValue": "Human", + "options": [ + { + "label": "Human", + "value": "Human" + }, + { + "label": "Assistant", + "value": "Assistant" + } + ] + }, + { + "label": "Type", + "key": "type", + "controlType": "DROP_DOWN", + "initialValue": "text", + "options": [ + { + "label": "Text", + "value": "text" + }, + { + "label": "Image", + "value": "image" + } + ] + }, + { + "label": "Content", + "key": "content", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "placeholderText": "{{Img1.image}} or {{Input1.text}}" + } + ] + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "children": [ + { + "label": "Temperature", + "tooltipText": "Put a value between 0 and 1", + "Description": "Put a value between 0 and 1", + "subtitle": "Defaults to 1. Ranges from 0 to 1. Use temp closer to 0 for analytical / multiple choice, and closer to 1 for creative and generative tasks.", + "configProperty": "actionConfiguration.formData.temperature", + "controlType": "INPUT_TEXT", + "dataType": "NUMBER", + "initialValue": "1", + "isRequired": false, + "customStyles": { + "width": "270px", + "minWidth": "270px" + } + } + ] + } + ] +} diff --git a/app/server/appsmith-plugins/databricksPlugin/src/main/resources/editor/root.json b/app/server/appsmith-plugins/databricksPlugin/src/main/resources/editor/root.json index 49a61e3faf81..bab24a7605cd 100644 --- a/app/server/appsmith-plugins/databricksPlugin/src/main/resources/editor/root.json +++ b/app/server/appsmith-plugins/databricksPlugin/src/main/resources/editor/root.json @@ -1,14 +1,20 @@ { "editor": [ { - "controlType": "SECTION", + "controlType": "SECTION_V2", "identifier": "SELECTOR", "children": [ { - "label": "", - "configProperty": "actionConfiguration.body", - "controlType": "QUERY_DYNAMIC_TEXT", - "evaluationSubstitutionType": "TEMPLATE" + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "SELECTOR-Z1", + "children": [ + { + "label": "", + "configProperty": "actionConfiguration.body", + "controlType": "QUERY_DYNAMIC_TEXT", + "evaluationSubstitutionType": "TEMPLATE" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/addToCollection.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/addToCollection.json index 00c1dee01838..c8394db1e544 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/addToCollection.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/addToCollection.json @@ -1,32 +1,50 @@ { + "controlType": "SECTION_V2", "identifier": "ADD_TO_COLLECTION", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'ADD_TO_COLLECTION'}}" }, "children": [ { - "label": "Collection/Document path", - "configProperty": "actionConfiguration.formData.path.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "initialValue": "" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "ADD-TO-COLLECTION-Z1", + "children": [ + { + "label": "Collection/Document path", + "configProperty": "actionConfiguration.formData.path.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "initialValue": "" + } + ] }, { - "label": "Body", - "configProperty": "actionConfiguration.formData.body.data", - "controlType": "QUERY_DYNAMIC_TEXT", - "initialValue": "", - "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "ADD-TO-COLLECTION-Z2", + "children": [ + { + "label": "Body", + "configProperty": "actionConfiguration.formData.body.data", + "controlType": "QUERY_DYNAMIC_TEXT", + "initialValue": "", + "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + } + ] }, { - "label": "Timestamp Path", - "configProperty": "actionConfiguration.formData.timestampValuePath.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "initialValue": "", - "placeholderText": "[ \"checkinLog.timestampKey\" ]" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "ADD-TO-COLLECTION-Z3", + "children": [ + { + "label": "Timestamp Path", + "configProperty": "actionConfiguration.formData.timestampValuePath.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "initialValue": "", + "placeholderText": "[ \"checkinLog.timestampKey\" ]" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/createDocument.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/createDocument.json index 2da8632fd281..18fc12a2f3b5 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/createDocument.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/createDocument.json @@ -1,32 +1,50 @@ { + "controlType": "SECTION_V2", "identifier": "CREATE_DOCUMENT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'CREATE_DOCUMENT'}}" }, "children": [ { - "label": "Collection Name", - "configProperty": "actionConfiguration.formData.path.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "initialValue": "" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "CREATE-DOCUMENT-Z1", + "children": [ + { + "label": "Collection Name", + "configProperty": "actionConfiguration.formData.path.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "initialValue": "" + } + ] }, { - "label": "Body", - "configProperty": "actionConfiguration.formData.body.data", - "controlType": "QUERY_DYNAMIC_TEXT", - "initialValue": "", - "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "CREATE-DOCUMENT-Z2", + "children": [ + { + "label": "Body", + "configProperty": "actionConfiguration.formData.body.data", + "controlType": "QUERY_DYNAMIC_TEXT", + "initialValue": "", + "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + } + ] }, { - "label": "Timestamp Path", - "configProperty": "actionConfiguration.formData.timestampValuePath.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "initialValue": "", - "placeholderText": "[ \"checkinLog.timestampKey\" ]" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "CREATE-DOCUMENT-Z3", + "children": [ + { + "label": "Timestamp Path", + "configProperty": "actionConfiguration.formData.timestampValuePath.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "initialValue": "", + "placeholderText": "[ \"checkinLog.timestampKey\" ]" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/deleteDocument.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/deleteDocument.json index 651fc4cd2943..5943ec682a37 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/deleteDocument.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/deleteDocument.json @@ -1,18 +1,24 @@ { + "controlType": "SECTION_V2", "identifier": "DELETE_DOCUMENT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'DELETE_DOCUMENT'}}" }, "children": [ { - "label": "Collection/Document path", - "configProperty": "actionConfiguration.formData.path.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "placeholderText": "collection/{{Table1.selectedRow._ref}}", - "initialValue": "" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "DELETE-DOCUMENT-Z1", + "children": [ + { + "label": "Collection/Document path", + "configProperty": "actionConfiguration.formData.path.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "placeholderText": "collection/{{Table1.selectedRow._ref}}", + "initialValue": "" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getCollection.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getCollection.json index ef11956f380e..b1e5d07b5364 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getCollection.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getCollection.json @@ -1,101 +1,131 @@ { + "controlType": "SECTION_V2", "identifier": "GET_COLLECTION", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'GET_COLLECTION'}}" }, "children": [ { - "label": "Collection Name", - "configProperty": "actionConfiguration.formData.path.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "initialValue": "" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "GET-COLLECTION-Z1", + "children": [ + { + "label": "Collection Name", + "configProperty": "actionConfiguration.formData.path.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "initialValue": "" + } + ] }, { - "label": "Where", - "configProperty": "actionConfiguration.formData.where.data", - "nestedLevels": 1, - "controlType": "WHERE_CLAUSE", - "-subtitle": "Array of Objects", - "-tooltipText": "Array of Objects", - "-alternateViewTypes": ["json"], - "logicalTypes": [ + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "GET-COLLECTION-Z2", + "children": [ { - "label": "AND", - "value": "AND" + "label": "Where", + "configProperty": "actionConfiguration.formData.where.data", + "nestedLevels": 1, + "controlType": "WHERE_CLAUSE", + "-subtitle": "Array of Objects", + "-tooltipText": "Array of Objects", + "-alternateViewTypes": ["json"], + "logicalTypes": [ + { + "label": "AND", + "value": "AND" + } + ], + "comparisonTypes": [ + { + "label": "==", + "value": "EQ" + }, + { + "label": "<", + "value": "LT" + }, + { + "label": "<=", + "value": "LTE" + }, + { + "label": ">=", + "value": "GTE" + }, + { + "label": ">", + "value": "GT" + }, + { + "label": "in", + "value": "IN" + }, + { + "label": "Contains", + "value": "ARRAY_CONTAINS" + }, + { + "label": "Contains Any", + "value": "ARRAY_CONTAINS_ANY" + } + ] } - ], - "comparisonTypes": [ - { - "label": "==", - "value": "EQ" - }, - { - "label": "<", - "value": "LT" - }, - { - "label": "<=", - "value": "LTE" - }, - { - "label": ">=", - "value": "GTE" - }, - { - "label": ">", - "value": "GT" - }, + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "GET-COLLECTION-Z3", + "children": [ { - "label": "in", - "value": "IN" - }, + "label": "Order By", + "configProperty": "actionConfiguration.formData.orderBy.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": false, + "initialValue": "", + "placeholderText": "[\"ascKey\", \"-descKey\"]" + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "GET-COLLECTION-Z4", + "children": [ { - "label": "Contains", - "value": "ARRAY_CONTAINS" + "label": "Start After", + "configProperty": "actionConfiguration.formData.next.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": false, + "initialValue": "", + "palceholderText": "" }, { - "label": "Contains Any", - "value": "ARRAY_CONTAINS_ANY" + "label": "End Before", + "configProperty": "actionConfiguration.formData.prev.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": false, + "initialValue": "" } ] }, { - "label": "Order By", - "configProperty": "actionConfiguration.formData.orderBy.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": false, - "initialValue": "", - "placeholderText": "[\"ascKey\", \"-descKey\"]" - }, - { - "label": "Start After", - "configProperty": "actionConfiguration.formData.next.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": false, - "initialValue": "", - "palceholderText": "" - }, - { - "label": "End Before", - "configProperty": "actionConfiguration.formData.prev.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": false, - "initialValue": "" - }, - { - "label": "Limit", - "configProperty": "actionConfiguration.formData.limitDocuments.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": false, - "palceholderText": "{{Table1.pageSize}}", - "initialValue": "10" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "GET-COLLECTION-Z5", + "children": [ + { + "label": "Limit", + "configProperty": "actionConfiguration.formData.limitDocuments.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": false, + "palceholderText": "{{Table1.pageSize}}", + "initialValue": "10" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getDocument.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getDocument.json index 2f1aa00bfc35..8422d805738e 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getDocument.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/getDocument.json @@ -1,17 +1,23 @@ { + "controlType": "SECTION_V2", "identifier": "GET_DOCUMENT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'GET_DOCUMENT'}}" }, "children": [ { - "label": "Collection/Document path", - "configProperty": "actionConfiguration.formData.path.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "initialValue": "" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "GET-DOCUMENT-Z1", + "children": [ + { + "label": "Collection/Document path", + "configProperty": "actionConfiguration.formData.path.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "initialValue": "" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/root.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/root.json index e15b769264c8..c0986810e99b 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/root.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/root.json @@ -1,43 +1,49 @@ { "editor": [ { - "controlType": "SECTION", + "controlType": "SECTION_V2", "identifier": "SELECTOR", "children": [ { - "label": "Command", - "description": "Choose method you would like to use", - "configProperty": "actionConfiguration.formData.command.data", - "controlType": "DROP_DOWN", - "initialValue": "GET_COLLECTION", - "options": [ + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "SELECTOR-Z1", + "children": [ { - "label": "List Documents", - "value": "GET_COLLECTION" - }, - { - "label": "Create document", - "value": "CREATE_DOCUMENT" - }, - { - "label": "Update document", - "value": "UPDATE_DOCUMENT" - }, - { - "label": "Delete document", - "value": "DELETE_DOCUMENT" - }, - { - "label": "Get Document", - "value": "GET_DOCUMENT" - }, - { - "label": "Upsert Document", - "value": "SET_DOCUMENT" - }, - { - "label": "Add document to collection", - "value": "ADD_TO_COLLECTION" + "label": "Command", + "description": "Choose method you would like to use", + "configProperty": "actionConfiguration.formData.command.data", + "controlType": "DROP_DOWN", + "initialValue": "GET_COLLECTION", + "options": [ + { + "label": "List Documents", + "value": "GET_COLLECTION" + }, + { + "label": "Create document", + "value": "CREATE_DOCUMENT" + }, + { + "label": "Update document", + "value": "UPDATE_DOCUMENT" + }, + { + "label": "Delete document", + "value": "DELETE_DOCUMENT" + }, + { + "label": "Get Document", + "value": "GET_DOCUMENT" + }, + { + "label": "Upsert Document", + "value": "SET_DOCUMENT" + }, + { + "label": "Add document to collection", + "value": "ADD_TO_COLLECTION" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/setDocument.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/setDocument.json index a874402b7f94..25dd8b0da1f5 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/setDocument.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/setDocument.json @@ -1,32 +1,50 @@ { + "controlType": "SECTION_V2", "identifier": "SET_DOCUMENT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'SET_DOCUMENT'}}" }, "children": [ { - "label": "Collection/Document path", - "configProperty": "actionConfiguration.formData.path.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "initialValue": "" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "SET-DOCUMENT-Z1", + "children": [ + { + "label": "Collection/Document path", + "configProperty": "actionConfiguration.formData.path.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "initialValue": "" + } + ] }, { - "label": "Body", - "configProperty": "actionConfiguration.formData.body.data", - "controlType": "QUERY_DYNAMIC_TEXT", - "initialValue": "", - "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "SET-DOCUMENT-Z2", + "children": [ + { + "label": "Body", + "configProperty": "actionConfiguration.formData.body.data", + "controlType": "QUERY_DYNAMIC_TEXT", + "initialValue": "", + "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + } + ] }, { - "label": "Timestamp Path", - "configProperty": "actionConfiguration.formData.timestampValuePath.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "initialValue": "", - "placeholderText": "[ \"checkinLog.timestampKey\" ]" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "SET-DOCUMENT-Z3", + "children": [ + { + "label": "Timestamp Path", + "configProperty": "actionConfiguration.formData.timestampValuePath.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "initialValue": "", + "placeholderText": "[ \"checkinLog.timestampKey\" ]" + } + ] } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/updateDocument.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/updateDocument.json index 6bb8ef57d3af..3cdbda305dc0 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/updateDocument.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/editor/updateDocument.json @@ -1,41 +1,59 @@ { + "controlType": "SECTION_V2", "identifier": "UPDATE_DOCUMENT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'UPDATE_DOCUMENT'}}" }, "children": [ { - "label": "Collection/Document path", - "configProperty": "actionConfiguration.formData.path.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "initialValue": "" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "UPDATE-DOCUMENT-Z1", + "children": [ + { + "label": "Collection/Document path", + "configProperty": "actionConfiguration.formData.path.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "initialValue": "" + } + ] }, { - "label": "Body", - "configProperty": "actionConfiguration.formData.body.data", - "controlType": "QUERY_DYNAMIC_TEXT", - "initialValue": "", - "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "UPDATE-DOCUMENT-Z2", + "children": [ + { + "label": "Body", + "configProperty": "actionConfiguration.formData.body.data", + "controlType": "QUERY_DYNAMIC_TEXT", + "initialValue": "", + "placeholderText": "{\n \"name\": {{nameInput.text}},\n \"dob\": {{dobPicker.formattedDate}},\n \"gender\": {{genderSelect.selectedOptionValue}} \n}" + } + ] }, { - "label": "Delete Key Path", - "configProperty": "actionConfiguration.formData.deleteKeyPath.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "isRequired": true, - "initialValue": "", - "placeholderText": "[\"userKey.nestedNamekey\"]" - }, - { - "label": "Timestamp Path", - "configProperty": "actionConfiguration.formData.timestampValuePath.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "initialValue": "", - "placeholderText": "[ \"checkinLog.timestampKey\" ]" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "UPDATE-DOCUMENT-Z3", + "children": [ + { + "label": "Delete Key Path", + "configProperty": "actionConfiguration.formData.deleteKeyPath.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "isRequired": true, + "initialValue": "", + "placeholderText": "[\"userKey.nestedNamekey\"]" + }, + { + "label": "Timestamp Path", + "configProperty": "actionConfiguration.formData.timestampValuePath.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "initialValue": "", + "placeholderText": "[ \"checkinLog.timestampKey\" ]" + } + ] } ] } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/delete.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/delete.json index 4c143852ebb2..09b6132fe647 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/delete.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/delete.json @@ -1,18 +1,24 @@ { + "controlType": "SECTION_V2", "identifier": "DELETE", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'DELETE_ONE' && actionConfiguration.formData.entityType.data == 'ROWS'}}" }, "children": [ { - "label": "Row Index", - "tooltipText": "The rowIndex property of the row object returned by the fetch query", - "propertyName": "rows_delete_rowIndex", - "configProperty": "actionConfiguration.formData.rowIndex.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "isRequired": true, - "placeholderText": "{{Table1.selectedRow.rowIndex}}" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "DELETE-Z1", + "children": [ + { + "label": "Row Index", + "tooltipText": "The rowIndex property of the row object returned by the fetch query", + "propertyName": "rows_delete_rowIndex", + "configProperty": "actionConfiguration.formData.rowIndex.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "isRequired": true, + "placeholderText": "{{Table1.selectedRow.rowIndex}}" + } + ] } ] } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/entity_data.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/entity_data.json new file mode 100644 index 000000000000..873f705c8541 --- /dev/null +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/entity_data.json @@ -0,0 +1,108 @@ +{ + "controlType": "SECTION_V2", + "identifier": "ENTITY_SELECTOR", + "children": [ + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "ENTITY-SELECTOR-Z1", + "children": [ + { + "label": "Entity", + "tooltipText": "The entity to query on the datasource", + "description": "Select the entity that you would like to work with", + "propertyName": "entityType", + "configProperty": "actionConfiguration.formData.entityType.data", + "controlType": "DROP_DOWN", + "initialValue": "ROWS", + "isRequired": true, + "setFirstOptionAsDefault": true, + "options": [ + { + "disabled": "{{ ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'UPDATE_MANY', 'INSERT_MANY'].includes(actionConfiguration.formData.command.data) === false }}", + "label": "Sheet Row(s)", + "value": "ROWS" + }, + { + "disabled": "{{ ['FETCH_MANY', 'FETCH_DETAILS', 'INSERT_ONE', 'DELETE_ONE'].includes(actionConfiguration.formData.command.data) === false || (['INSERT_ONE', 'DELETE_ONE'].includes(actionConfiguration.formData.command.data) === true && ['https://www.googleapis.com/auth/drive.file'].includes(datasourceConfiguration.authentication.scopeString) === true)}}", + "label": "Spreadsheet", + "value": "SPREADSHEET" + }, + { + "disabled": "{{ ['DELETE_ONE'].includes(actionConfiguration.formData.command.data) === false }}", + "label": "Sheet", + "value": "SHEET" + } + ], + "conditionals": { + "evaluateFormConfig": { + "condition": "{{true}}", + "paths": ["options"] + } + } + }, + { + "label": "Spreadsheet", + "tooltipText": "The URL of the spreadsheet in your Google Drive", + "propertyName": "rows_get_spreadsheetUrl", + "configProperty": "actionConfiguration.formData.sheetUrl.data", + "controlType": "DROP_DOWN", + "isSearchable": true, + "isRequired": true, + "-placeholderText": "https://docs.google.com/spreadsheets/d/xyz/edit#gid=0", + "fetchOptionsConditionally": true, + "alternateViewTypes": ["json"], + "conditionals": { + "show": "{{ !!actionConfiguration.formData.entityType.data && (new Object({ 'SPREADSHEET': ['FETCH_DETAILS', 'DELETE_ONE'], 'SHEET': ['DELETE_ONE'], 'ROWS': ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'INSERT_MANY', 'UPDATE_MANY'] })[actionConfiguration.formData.entityType.data].includes(actionConfiguration.formData.command.data)) }}", + "fetchDynamicValues": { + "condition": "{{true}}", + "config": { + "params": { + "requestType": "SPREADSHEET_SELECTOR", + "displayType": "DROP_DOWN" + } + } + } + } + }, + { + "label": "Sheet name", + "propertyName": "rows_get_sheetName", + "tooltipText": "The name of the sheet inside the spreadsheet", + "configProperty": "actionConfiguration.formData.sheetName.data", + "controlType": "DROP_DOWN", + "isSearchable": true, + "isRequired": true, + "fetchOptionsConditionally": true, + "alternateViewTypes": ["json"], + "conditionals": { + "show": "{{ new Object({ 'SPREADSHEET': [], 'SHEET': ['DELETE_ONE'], 'ROWS': ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'INSERT_MANY', 'UPDATE_MANY'] })[actionConfiguration.formData.entityType.data].includes(actionConfiguration.formData.command.data) && !!actionConfiguration.formData.sheetUrl.data }}", + "fetchDynamicValues": { + "condition": "{{ !!actionConfiguration.formData.sheetUrl.data }}", + "config": { + "params": { + "requestType": "SHEET_SELECTOR", + "displayType": "DROP_DOWN", + "parameters": { + "sheetUrl": "{{actionConfiguration.formData.sheetUrl.data}}" + } + } + } + } + } + }, + { + "label": "Table heading row index", + "tooltipText": "The index of the column names in the sheet (starts from 1)", + "propertyName": "rows_get_tableHeadingRowIndex", + "configProperty": "actionConfiguration.formData.tableHeaderIndex.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "initialValue": "1", + "isRequired": true, + "conditionals": { + "show": "{{ new Object({ 'SPREADSHEET': [], 'SHEET': [], 'ROWS': ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'INSERT_MANY', 'UPDATE_MANY'] })[actionConfiguration.formData.entityType.data].includes(actionConfiguration.formData.command.data) && !!actionConfiguration.formData.sheetName.data }}" + } + } + ] + } + ] +} diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/fetch_many.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/fetch_many.json index c516b1b5a77e..cbb21cb0f91f 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/fetch_many.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/fetch_many.json @@ -1,165 +1,220 @@ { - "identifier": "FETCH_MANY", "controlType": "SECTION", + "identifier": "FETCH_MANY", "conditionals": { "show": "{{!!actionConfiguration.formData.entityType.data && actionConfiguration.formData.entityType.data !== 'SPREADSHEET' && actionConfiguration.formData.command.data === 'FETCH_MANY' && !!actionConfiguration.formData.sheetName.data}}" }, "children": [ { - "label": "Columns", - "tooltipText": "The columns to fetch from the google sheet", - "propertyName": "rows_get_projection", - "configProperty": "actionConfiguration.formData.projection.data", - "controlType": "PROJECTION", - "initialValue": [], - "options": [], - "placeholderText": "All columns will be fetched.", - "fetchOptionsConditionally": true, - "alternateViewTypes": ["json"], - "conditionals": { - "enable": "{{!!actionConfiguration.formData.sheetUrl.data && !!actionConfiguration.formData.sheetName.data && !!actionConfiguration.formData.tableHeaderIndex.data}}", - "fetchDynamicValues": { - "condition": "{{!!actionConfiguration.formData.sheetUrl.data && !!actionConfiguration.formData.sheetName.data && !!actionConfiguration.formData.tableHeaderIndex.data}}", - "config": { - "params": { - "requestType": "COLUMNS_SELECTOR", - "displayType": "DROP_DOWN", - "parameters": { - "sheetUrl": "{{actionConfiguration.formData.sheetUrl.data}}", - "sheetName": "{{actionConfiguration.formData.sheetName.data}}", - "tableHeaderIndex": "{{actionConfiguration.formData.tableHeaderIndex.data}}" + "controlType": "SECTION_V2", + "identifier": "FETCH_MANY_SECTION_ONE", + "children": [ + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "FETCH_MANY-Z1", + "children": [ + { + "label": "Columns", + "tooltipText": "The columns to fetch from the google sheet", + "propertyName": "rows_get_projection", + "configProperty": "actionConfiguration.formData.projection.data", + "controlType": "PROJECTION", + "initialValue": [], + "options": [], + "placeholderText": "All columns will be fetched.", + "fetchOptionsConditionally": true, + "alternateViewTypes": ["json"], + "conditionals": { + "enable": "{{!!actionConfiguration.formData.sheetUrl.data && !!actionConfiguration.formData.sheetName.data && !!actionConfiguration.formData.tableHeaderIndex.data}}", + "fetchDynamicValues": { + "condition": "{{!!actionConfiguration.formData.sheetUrl.data && !!actionConfiguration.formData.sheetName.data && !!actionConfiguration.formData.tableHeaderIndex.data}}", + "config": { + "params": { + "requestType": "COLUMNS_SELECTOR", + "displayType": "DROP_DOWN", + "parameters": { + "sheetUrl": "{{actionConfiguration.formData.sheetUrl.data}}", + "sheetName": "{{actionConfiguration.formData.sheetName.data}}", + "tableHeaderIndex": "{{actionConfiguration.formData.tableHeaderIndex.data}}" + } + } + } + } } } - } - } - } - }, - { - "label": "Filter Format", - "tooltipText": "The format of the filter to be applied on the data", - "propertyName": "rows_get_queryFormat", - "conditionals": { - "show": "{{actionConfiguration.formData.entityType.data === 'ROWS'}}" - }, - "configProperty": "actionConfiguration.formData.queryFormat.data", - "controlType": "DROP_DOWN", - "initialValue": "ROWS", - "options": [ - { - "label": "Where Clause", - "value": "ROWS" + ] }, { - "label": "Cell range", - "value": "RANGE" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "FETCH_MANY-Z2", + "children": [ + { + "label": "Filter Format", + "tooltipText": "The format of the filter to be applied on the data", + "propertyName": "rows_get_queryFormat", + "conditionals": { + "show": "{{actionConfiguration.formData.entityType.data === 'ROWS'}}" + }, + "configProperty": "actionConfiguration.formData.queryFormat.data", + "controlType": "DROP_DOWN", + "initialValue": "ROWS", + "options": [ + { + "label": "Where Clause", + "value": "ROWS" + }, + { + "label": "Cell range", + "value": "RANGE" + } + ] + }, + { + "label": "Cell range", + "propertyName": "rows_get_cellRange", + "tooltipText": "The Google Sheet notation of cells to filter (A1:B)", + "subtitle": "Specify the google sheet range of cells", + "configProperty": "actionConfiguration.formData.range.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "conditionals": { + "show": "{{actionConfiguration.formData.queryFormat.data === 'RANGE'}}" + }, + "initialValue": "", + "placeholderText": "A2:Z" + } + ] } ] }, { - "label": "Cell range", - "propertyName": "rows_get_cellRange", - "tooltipText": "The Google Sheet notation of cells to filter (A1:B)", - "subtitle": "Specify the google sheet range of cells", - "configProperty": "actionConfiguration.formData.range.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "conditionals": { - "show": "{{actionConfiguration.formData.queryFormat.data === 'RANGE'}}" - }, - "initialValue": "", - "placeholderText": "A2:Z" - }, - { - "identifier": "ROWS_SECTION", - "controlType": "SECTION", - "label": "Rows Section", - "conditionals": { - "show": "{{actionConfiguration.formData.queryFormat.data === 'ROWS'}}" - }, + "controlType": "SECTION_V2", + "identifier": "FETCH_MANY_SECTION_TWO", "children": [ { - "label": "Filter By", - "tooltipText": "Filters data returned", - "subtitle": "The filter applied on the data. Can be empty", - "propertyName": "rows_get_rowSheetName", - "configProperty": "actionConfiguration.formData.where.data", - "nestedLevels": 3, - "controlType": "WHERE_CLAUSE", - "logicalTypes": [ - { - "label": "AND", - "value": "AND" - }, + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "ROWS-SECTION-Z2", + "label": "Rows Section", + "conditionals": { + "show": "{{actionConfiguration.formData.queryFormat.data === 'ROWS'}}" + }, + "children": [ { - "label": "OR", - "value": "OR" + "label": "Filter By", + "tooltipText": "Filters data returned", + "subtitle": "The filter applied on the data. Can be empty", + "propertyName": "rows_get_rowSheetName", + "configProperty": "actionConfiguration.formData.where.data", + "nestedLevels": 3, + "controlType": "WHERE_CLAUSE", + "logicalTypes": [ + { + "label": "AND", + "value": "AND" + }, + { + "label": "OR", + "value": "OR" + } + ], + "comparisonTypes": [ + { + "label": "<", + "value": "LT" + }, + { + "label": "<=", + "value": "LTE" + }, + { + "label": "==", + "value": "EQ" + }, + { + "label": "!=", + "value": "NOT_EQ" + }, + { + "label": ">=", + "value": "GTE" + }, + { + "label": ">", + "value": "GT" + }, + { + "label": "in", + "value": "IN" + }, + { + "label": "contains", + "value": "CONTAINS" + }, + { + "label": "not in", + "value": "NOT_IN" + } + ], + "alternateViewTypes": ["json"] } - ], - "comparisonTypes": [ - { - "label": "<", - "value": "LT" - }, - { - "label": "<=", - "value": "LTE" - }, - { - "label": "==", - "value": "EQ" - }, - { - "label": "!=", - "value": "NOT_EQ" - }, - { - "label": ">=", - "value": "GTE" - }, - { - "label": ">", - "value": "GT" - }, - { - "label": "in", - "value": "IN" - }, - { - "label": "contains", - "value": "CONTAINS" - }, + ] + } + ] + }, + { + "controlType": "SECTION_V2", + "identifier": "FETCH_MANY_SECTION_THREE", + "children": [ + { + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "ROWS-SECTION-Z3", + "label": "Rows Section", + "conditionals": { + "show": "{{actionConfiguration.formData.queryFormat.data === 'ROWS'}}" + }, + "children": [ { - "label": "not in", - "value": "NOT_IN" + "label": "Sort By", + "tooltipText": "The parameters to sort the data by", + "configProperty": "actionConfiguration.formData.sortBy.data", + "controlType": "SORTING", + "-subtitle": "Array of Objects", + "-tooltipText": "Array of Objects", + "alternateViewTypes": ["json"] } - ], - "alternateViewTypes": ["json"] - }, - { - "label": "Sort By", - "tooltipText": "The parameters to sort the data by", - "configProperty": "actionConfiguration.formData.sortBy.data", - "controlType": "SORTING", - "-subtitle": "Array of Objects", - "-tooltipText": "Array of Objects", - "alternateViewTypes": ["json"] - }, + ] + } + ] + }, + { + "controlType": "SECTION_V2", + "identifier": "FETCH_MANY_SECTION_FOUR", + "children": [ { - "label": "", - "configProperty": "actionConfiguration.formData.pagination.data", - "controlType": "PAGINATION", - "-subtitle": "Object", - "placeholderText": { - "limit": "{{Table1.pageSize}}", - "offset": "{{(Table1.pageNo - 1)*Table1.pageSize}}" - }, - "initialValue": { - "limit": "20", - "offset": "0" + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "ROWS-SECTION-Z4", + "label": "Rows Section", + "conditionals": { + "show": "{{actionConfiguration.formData.queryFormat.data === 'ROWS'}}" }, - "tooltipText": { - "limit": "Bind to the pageSize property of your widget {{Table1.pageSize}}", - "offset": "Bind to the index of the first row to display {{(Table1.pageNo-1)*Table1.pageSize}}" - } + "children": [ + { + "configProperty": "actionConfiguration.formData.pagination.data", + "controlType": "PAGINATION", + "-subtitle": "Object", + "placeholderText": { + "limit": "{{Table1.pageSize}}", + "offset": "{{(Table1.pageNo - 1)*Table1.pageSize}}" + }, + "initialValue": { + "limit": "20", + "offset": "0" + }, + "tooltipText": { + "limit": "Bind to the pageSize property of your widget {{Table1.pageSize}}", + "offset": "Bind to the index of the first row to display {{(Table1.pageNo-1)*Table1.pageSize}}" + } + } + ] } ] } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/insert.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/insert.json index 6363ddc8b8ee..7d166273390d 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/insert.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/insert.json @@ -1,24 +1,31 @@ { + "controlType": "SECTION_V2", "identifier": "INSERT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'INSERT_ONE' || actionConfiguration.formData.command.data === 'INSERT_MANY'}}" }, "children": [ { - "label": "Spreadsheet Name", - "tooltipText": "The name of the sheet to be created", - "propertyName": "file_create_spreadsheetName", - "configProperty": "actionConfiguration.formData.spreadsheetName.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "isRequired": true, + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "INSERT-Z1", "conditionals": { "show": "{{actionConfiguration.formData.entityType.data === 'SPREADSHEET'}}" }, - "placeholderText": "Goals" + "children": [ + { + "label": "Spreadsheet Name", + "tooltipText": "The name of the sheet to be created", + "propertyName": "file_create_spreadsheetName", + "configProperty": "actionConfiguration.formData.spreadsheetName.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "isRequired": true, + "placeholderText": "Goals" + } + ] }, { - "controlType": "SECTION", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "INSERT-Z2", "label": "Row objects", "description": "", "conditionals": { diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/root.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/root.json index 07b2bff2ab95..cf2ff07beccf 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/root.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/root.json @@ -1,156 +1,63 @@ { "editor": [ { - "controlType": "SECTION", + "controlType": "SECTION_V2", "identifier": "SELECTOR", "children": [ { - "label": "Operation", - "tooltipText": "The command to run on the datasource", - "description": "Select the operation you would like to execute", - "propertyName": "rows_commands", - "configProperty": "actionConfiguration.formData.command.data", - "controlType": "DROP_DOWN", - "initialValue": "FETCH_MANY", - "isRequired": true, - "options": [ - { - "label": "Fetch Details", - "value": "FETCH_DETAILS" - }, - { - "label": "Insert One", - "value": "INSERT_ONE" - }, - { - "label": "Update One", - "value": "UPDATE_ONE" - }, - { - "label": "Delete One", - "value": "DELETE_ONE" - }, - { - "label": "Fetch Many", - "value": "FETCH_MANY" - }, - { - "label": "Insert Many", - "value": "INSERT_MANY" - }, - { - "label": "Update Many", - "value": "UPDATE_MANY" - } - ] - }, - { - "label": "Entity", - "tooltipText": "The entity to query on the datasource", - "description": "Select the entity that you would like to work with", - "propertyName": "entityType", - "configProperty": "actionConfiguration.formData.entityType.data", - "controlType": "DROP_DOWN", - "initialValue": "ROWS", - "isRequired": true, - "setFirstOptionAsDefault": true, - "options": [ - { - "disabled": "{{ ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'UPDATE_MANY', 'INSERT_MANY'].includes(actionConfiguration.formData.command.data) === false }}", - "label": "Sheet Row(s)", - "value": "ROWS" - }, - { - "disabled": "{{ ['FETCH_MANY', 'FETCH_DETAILS', 'INSERT_ONE', 'DELETE_ONE'].includes(actionConfiguration.formData.command.data) === false || (['INSERT_ONE', 'DELETE_ONE'].includes(actionConfiguration.formData.command.data) === true && ['https://www.googleapis.com/auth/drive.file'].includes(datasourceConfiguration.authentication.scopeString) === true)}}", - "label": "Spreadsheet", - "value": "SPREADSHEET" - }, - { - "disabled": "{{ ['DELETE_ONE'].includes(actionConfiguration.formData.command.data) === false }}", - "label": "Sheet", - "value": "SHEET" - } - ], - "conditionals": { - "evaluateFormConfig": { - "condition": "{{true}}", - "paths": ["options"] - } - } - }, - { - "label": "", - "configProperty": "actionConfiguration.formData.selector.data", - "controlType": "ENTITY_SELECTOR", - "conditionals": { - "show": "{{ !!actionConfiguration.formData.entityType.data && (new Object({ 'SPREADSHEET': ['FETCH_DETAILS', 'DELETE_ONE'], 'SHEET': ['DELETE_ONE'], 'ROWS': ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'INSERT_MANY', 'UPDATE_MANY'] })[actionConfiguration.formData.entityType.data].includes(actionConfiguration.formData.command.data)) }}" - }, - "schema": [ - { - "label": "Spreadsheet", - "tooltipText": "The URL of the spreadsheet in your Google Drive", - "propertyName": "rows_get_spreadsheetUrl", - "configProperty": "actionConfiguration.formData.sheetUrl.data", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "SELECTOR-Z1", + "children": [ + { + "label": "Operation", + "tooltipText": "The command to run on the datasource", + "description": "Select the operation you would like to execute", + "propertyName": "rows_commands", + "configProperty": "actionConfiguration.formData.command.data", "controlType": "DROP_DOWN", - "isSearchable": true, + "initialValue": "FETCH_MANY", "isRequired": true, - "-placeholderText": "https://docs.google.com/spreadsheets/d/xyz/edit#gid=0", - "fetchOptionsConditionally": true, - "alternateViewTypes": ["json"], - "conditionals": { - "fetchDynamicValues": { - "condition": "{{true}}", - "config": { - "params": { - "requestType": "SPREADSHEET_SELECTOR", - "displayType": "DROP_DOWN" - } - } + "options": [ + { + "label": "Fetch Details", + "value": "FETCH_DETAILS" + }, + { + "label": "Insert One", + "value": "INSERT_ONE" + }, + { + "label": "Update One", + "value": "UPDATE_ONE" + }, + { + "label": "Delete One", + "value": "DELETE_ONE" + }, + { + "label": "Fetch Many", + "value": "FETCH_MANY" + }, + { + "label": "Insert Many", + "value": "INSERT_MANY" + }, + { + "label": "Update Many", + "value": "UPDATE_MANY" } - } - }, - { - "label": "Sheet name", - "propertyName": "rows_get_sheetName", - "tooltipText": "The name of the sheet inside the spreadsheet", - "configProperty": "actionConfiguration.formData.sheetName.data", - "controlType": "DROP_DOWN", - "isSearchable": true, - "isRequired": true, - "fetchOptionsConditionally": true, - "alternateViewTypes": ["json"], - "conditionals": { - "show": "{{ new Object({ 'SPREADSHEET': [], 'SHEET': ['DELETE_ONE'], 'ROWS': ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'INSERT_MANY', 'UPDATE_MANY'] })[actionConfiguration.formData.entityType.data].includes(actionConfiguration.formData.command.data) && !!actionConfiguration.formData.sheetUrl.data }}", - "fetchDynamicValues": { - "condition": "{{ !!actionConfiguration.formData.sheetUrl.data }}", - "config": { - "params": { - "requestType": "SHEET_SELECTOR", - "displayType": "DROP_DOWN", - "parameters": { - "sheetUrl": "{{actionConfiguration.formData.sheetUrl.data}}" - } - } - } - } - } - }, - { - "label": "Table heading row index", - "tooltipText": "The index of the column names in the sheet (starts from 1)", - "propertyName": "rows_get_tableHeadingRowIndex", - "configProperty": "actionConfiguration.formData.tableHeaderIndex.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "initialValue": "1", - "isRequired": true, - "conditionals": { - "show": "{{ new Object({ 'SPREADSHEET': [], 'SHEET': [], 'ROWS': ['INSERT_ONE', 'UPDATE_ONE', 'DELETE_ONE', 'FETCH_MANY', 'INSERT_MANY', 'UPDATE_MANY'] })[actionConfiguration.formData.entityType.data].includes(actionConfiguration.formData.command.data) && !!actionConfiguration.formData.sheetName.data }}" - } + ] } ] } ] } ], - "files": ["insert.json", "delete.json", "fetch_many.json", "update.json"] + "files": [ + "entity_data.json", + "insert.json", + "delete.json", + "fetch_many.json", + "update.json" + ] } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/update.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/update.json index 327563dd8cb5..7a65002e9733 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/update.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/editor/update.json @@ -1,17 +1,15 @@ { + "controlType": "SECTION_V2", "identifier": "UPDATE", - "controlType": "SECTION", "conditionals": { - "show": "{{actionConfiguration.formData.command.data === 'UPDATE_ONE' || actionConfiguration.formData.command.data === 'UPDATE_MANY'}}" + "show": "{{(actionConfiguration.formData.command.data === 'UPDATE_ONE' || actionConfiguration.formData.command.data === 'UPDATE_MANY') && (!!actionConfiguration.formData.sheetName.data && actionConfiguration.formData.entityType.data === 'ROWS')}}" }, + "label": "Row objects", + "description": "", "children": [ { - "controlType": "SECTION", - "label": "Row objects", - "description": "", - "conditionals": { - "show": "{{!!actionConfiguration.formData.sheetName.data && actionConfiguration.formData.entityType.data === 'ROWS'}}" - }, + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "UPDATE-Z1", "children": [ { "label": "Update row object", diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json index 66447b9f563a..d5f7709c310d 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json @@ -38,21 +38,9 @@ { "label": "Read / Write / Delete | Selected google sheets", "value": "https://www.googleapis.com/auth/drive.file" - }, - { - "label": "Read / Write / Delete | All google sheets", - "value": "https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/drive" - }, - { - "label": "Read / Write | All google sheets", - "value": "https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/drive.readonly" - }, - { - "label": "Read | All google sheets", - "value": "https://www.googleapis.com/auth/spreadsheets.readonly,https://www.googleapis.com/auth/drive.readonly" } ], - "initialValue": "https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/drive", + "initialValue": "https://www.googleapis.com/auth/drive.file", "customStyles": { "width": "340px" } diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/aggregate.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/aggregate.json index 323f7f760c4b..1241370d274f 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/aggregate.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/aggregate.json @@ -1,13 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "AGGREGATE", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'AGGREGATE'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select collection to query", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "AGGREGATE-Z1", "children": [ { "label": "Collection", @@ -32,9 +32,8 @@ ] }, { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "AGGREGATE-Z2", "children": [ { "label": "Array of pipelines", @@ -47,11 +46,17 @@ ] }, { - "label": "Limit", - "configProperty": "actionConfiguration.formData.aggregate.limit.data", - "controlType": "QUERY_DYNAMIC_INPUT_TEXT", - "evaluationSubstitutionType": "TEMPLATE", - "initialValue": "10" + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "AGGREGATE-Z3", + "children": [ + { + "label": "Limit", + "configProperty": "actionConfiguration.formData.aggregate.limit.data", + "controlType": "QUERY_DYNAMIC_INPUT_TEXT", + "evaluationSubstitutionType": "TEMPLATE", + "initialValue": "10" + } + ] } ] } diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/count.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/count.json index 70a9ddc79895..e8848d8ca2e5 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/count.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/count.json @@ -1,13 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "COUNT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'COUNT'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select collection to query", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "COUNT-Z1", "children": [ { "label": "Collection", @@ -32,9 +32,8 @@ ] }, { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "COUNT-Z2", "children": [ { "label": "Query", diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/delete.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/delete.json index d5fce44dbbe1..8a3ada65124e 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/delete.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/delete.json @@ -1,13 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "DELETE", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'DELETE'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select collection to query", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "DELETE-Z1", "children": [ { "label": "Collection", @@ -32,9 +32,8 @@ ] }, { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "DELETE-Z2", "children": [ { "label": "Query", @@ -43,7 +42,13 @@ "inputType": "JSON", "evaluationSubstitutionType": "TEMPLATE", "placeholderText": "{rating : {$gte : 9}}" - }, + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "DELETE-Z3", + "children": [ { "label": "Limit", "configProperty": "actionConfiguration.formData.delete.limit.data", diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/distinct.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/distinct.json index ab4bfc4fb0d0..240c8edff7a7 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/distinct.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/distinct.json @@ -1,13 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "DISTINCT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'DISTINCT'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select collection to query", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "DISTINCT-Z1", "children": [ { "label": "Collection", @@ -32,9 +32,8 @@ ] }, { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "DISTINCT-Z2", "children": [ { "label": "Query", @@ -43,7 +42,13 @@ "inputType": "JSON", "evaluationSubstitutionType": "TEMPLATE", "placeholderText": "{rating : {$gte : 9}}" - }, + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "DISTINCT-Z3", + "children": [ { "label": "Key", "configProperty": "actionConfiguration.formData.distinct.key.data", diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/find.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/find.json index 741a77885283..3dfec0d2c602 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/find.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/find.json @@ -1,13 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "FIND", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'FIND'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select collection to query", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "FIND-Z1", "children": [ { "label": "Collection", @@ -32,9 +32,8 @@ ] }, { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "FIND-Z2", "children": [ { "label": "Query", @@ -42,7 +41,13 @@ "controlType": "QUERY_DYNAMIC_TEXT", "evaluationSubstitutionType": "TEMPLATE", "placeholderText": "{rating : {$gte : 9}}" - }, + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "FIND-Z3", + "children": [ { "label": "Sort", "configProperty": "actionConfiguration.formData.find.sort.data", @@ -58,7 +63,13 @@ "inputType": "JSON", "evaluationSubstitutionType": "TEMPLATE", "placeholderText": "{name : 1}" - }, + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "FIND-Z4", + "children": [ { "label": "Limit", "configProperty": "actionConfiguration.formData.find.limit.data", diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/insert.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/insert.json index e70f7f903bc9..488553124586 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/insert.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/insert.json @@ -1,13 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "INSERT", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'INSERT'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select collection to query", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "INSERT-Z1", "children": [ { "label": "Collection", @@ -32,9 +32,8 @@ ] }, { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "INSERT-Z2", "children": [ { "label": "Documents", diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/raw.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/raw.json index 6829311c3817..609dd4b991ef 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/raw.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/raw.json @@ -1,14 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "RAW", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'RAW'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "RAW-Z1", "children": [ { "label": "", diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/root.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/root.json index 7d1c79dc8ef9..2f7f7b68b407 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/root.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/root.json @@ -1,47 +1,53 @@ { "editor": [ { - "controlType": "SECTION", + "controlType": "SECTION_V2", "identifier": "SELECTOR", "children": [ { - "label": "Command", - "description": "Choose method you would like to use to query the database", - "configProperty": "actionConfiguration.formData.command.data", - "controlType": "DROP_DOWN", - "initialValue": "FIND", - "options": [ + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "SELECTOR-Z1", + "children": [ { - "label": "Find document(s)", - "value": "FIND" - }, - { - "label": "Insert document(s)", - "value": "INSERT" - }, - { - "label": "Update document(s)", - "value": "UPDATE" - }, - { - "label": "Delete document(s)", - "value": "DELETE" - }, - { - "label": "Count", - "value": "COUNT" - }, - { - "label": "Distinct", - "value": "DISTINCT" - }, - { - "label": "Aggregate", - "value": "AGGREGATE" - }, - { - "label": "Raw", - "value": "RAW" + "label": "Command", + "description": "Choose method you would like to use to query the database", + "configProperty": "actionConfiguration.formData.command.data", + "controlType": "DROP_DOWN", + "initialValue": "FIND", + "options": [ + { + "label": "Find document(s)", + "value": "FIND" + }, + { + "label": "Insert document(s)", + "value": "INSERT" + }, + { + "label": "Update document(s)", + "value": "UPDATE" + }, + { + "label": "Delete document(s)", + "value": "DELETE" + }, + { + "label": "Count", + "value": "COUNT" + }, + { + "label": "Distinct", + "value": "DISTINCT" + }, + { + "label": "Aggregate", + "value": "AGGREGATE" + }, + { + "label": "Raw", + "value": "RAW" + } + ] } ] } diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/update.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/update.json index bcd4aae93c70..4f9a19c52f9c 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/update.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/editor/update.json @@ -1,13 +1,13 @@ { + "controlType": "SECTION_V2", "identifier": "UPDATE", - "controlType": "SECTION", "conditionals": { "show": "{{actionConfiguration.formData.command.data === 'UPDATE'}}" }, "children": [ { - "controlType": "SECTION", - "label": "Select collection to query", + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "UPDATE-Z1", "children": [ { "label": "Collection", @@ -32,9 +32,8 @@ ] }, { - "controlType": "SECTION", - "label": "Query", - "description": "Optional", + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "UPDATE-Z2", "children": [ { "label": "Query", @@ -43,7 +42,13 @@ "inputType": "JSON", "evaluationSubstitutionType": "TEMPLATE", "placeholderText": "{rating : {$gte : 9}}" - }, + } + ] + }, + { + "controlType": "SINGLE_COLUMN_ZONE", + "identifier": "UPDATE-Z3", + "children": [ { "label": "Update", "configProperty": "actionConfiguration.formData.updateMany.update.data", @@ -51,7 +56,13 @@ "inputType": "JSON", "evaluationSubstitutionType": "TEMPLATE", "placeholderText": "{ $inc: { score: 1 } }" - }, + } + ] + }, + { + "controlType": "DOUBLE_COLUMN_ZONE", + "identifier": "UPDATE-Z4", + "children": [ { "label": "Limit", "configProperty": "actionConfiguration.formData.updateMany.limit.data", diff --git a/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java b/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java index 8a6db99d5a6d..a27e2ecc8e9b 100644 --- a/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java +++ b/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/PostgresPlugin.java @@ -47,6 +47,8 @@ import org.pf4j.Extension; import org.pf4j.PluginWrapper; import org.postgresql.util.PGobject; +import org.postgresql.util.PSQLException; +import org.postgresql.util.PSQLState; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import reactor.core.publisher.Mono; @@ -1347,10 +1349,21 @@ private static HikariDataSource createConnectionPool( try { datasource = new HikariDataSource(config); } catch (PoolInitializationException e) { + Throwable cause = e.getCause(); + if (cause instanceof PSQLException) { + PSQLException psqlException = (PSQLException) cause; + String sqlState = psqlException.getSQLState(); + if (PSQLState.CONNECTION_UNABLE_TO_CONNECT.getState().equals(sqlState)) { + throw new AppsmithPluginException( + AppsmithPluginError.PLUGIN_DATASOURCE_ARGUMENT_ERROR, + PostgresErrorMessages.DS_INVALID_HOSTNAME_AND_PORT_MSG, + psqlException.getMessage()); + } + } throw new AppsmithPluginException( AppsmithPluginError.PLUGIN_DATASOURCE_ARGUMENT_ERROR, PostgresErrorMessages.CONNECTION_POOL_CREATION_FAILED_ERROR_MSG, - e.getMessage()); + cause != null ? cause.getMessage() : e.getMessage()); } return datasource; diff --git a/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/exceptions/PostgresErrorMessages.java b/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/exceptions/PostgresErrorMessages.java index daee36541178..8cee7970b58a 100644 --- a/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/exceptions/PostgresErrorMessages.java +++ b/app/server/appsmith-plugins/postgresPlugin/src/main/java/com/external/plugins/exceptions/PostgresErrorMessages.java @@ -49,4 +49,6 @@ public class PostgresErrorMessages extends BasePluginErrorMessages { public static final String DS_MISSING_PASSWORD_ERROR_MSG = "Missing password for authentication."; public static final String DS_MISSING_DATABASE_NAME_ERROR_MSG = "Missing database name."; + + public static final String DS_INVALID_HOSTNAME_AND_PORT_MSG = "Please check the host and port."; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/ce/PolicyGeneratorCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/ce/PolicyGeneratorCE.java index 9a7effb48bf2..2ff250583026 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/ce/PolicyGeneratorCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/ce/PolicyGeneratorCE.java @@ -317,6 +317,9 @@ public Set getAllChildPolicies( Set policySet, Class sourceEntity, Class destinationEntity) { + if (policySet == null) { + return new HashSet<>(); + } Set policies = policySet.stream() .map(policy -> { AclPermission aclPermission = diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java index 7b062f630587..f87bc9af4ea1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java @@ -533,7 +533,9 @@ protected Mono createJsAction(ActionCollection actionCollection, Acti newAction.setUnpublishedAction(action); Set actionCollectionPolicies = new HashSet<>(); - actionCollection.getPolicies().forEach(policy -> { + Set existingPolicies = + actionCollection.getPolicies() == null ? Set.of() : actionCollection.getPolicies(); + existingPolicies.forEach(policy -> { Policy actionPolicy = Policy.builder() .permission(policy.getPermission()) .permissionGroups(policy.getPermissionGroups()) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java index b04292a75406..50872df66db3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java @@ -1037,7 +1037,9 @@ public Mono findByBaseIdBranchNameAndApplicationMode( ? applicationPermission.getReadPermission() : applicationPermission.getEditPermission(); - return findByBranchNameAndBaseApplicationId(branchName, defaultApplicationId, permissionForApplication); + return findByBranchNameAndBaseApplicationId(branchName, defaultApplicationId, permissionForApplication) + .name(APPLICATION_FETCH_FROM_DB) + .tap(Micrometer.observation(observationRegistry)); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java index 39a87d72fac6..99333df7b92c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java @@ -362,7 +362,8 @@ public Mono reconstructArtifactExchangeJsonFromFilesInRepo getApplicationResource(applicationReference.getMetadata(), ApplicationJson.class); ApplicationJson applicationJson = getApplicationJsonFromGitReference(applicationReference); copyNestedNonNullProperties(metadata, applicationJson); - return jsonSchemaMigration.migrateApplicationJsonToLatestSchema(applicationJson); + return jsonSchemaMigration.migrateApplicationJsonToLatestSchema( + applicationJson, baseArtifactId, branchName); }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java index a082e6acf48b..4f14435df62c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java @@ -15,7 +15,8 @@ public class UserPermissionUtils { public static boolean validateDomainObjectPermissionExists( BaseDomain baseDomain, AclPermission aclPermission, Set permissionGroups) { - Optional permissionPolicy = baseDomain.getPolicies().stream() + Set basePolicies = baseDomain.getPolicies() == null ? Set.of() : baseDomain.getPolicies(); + Optional permissionPolicy = basePolicies.stream() .filter(policy -> policy.getPermission().equals(aclPermission.getValue())) .findFirst(); return permissionPolicy.isPresent() diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/PolicyUtil.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/PolicyUtil.java index bc0a32dcb886..bd1314a29929 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/PolicyUtil.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/PolicyUtil.java @@ -15,6 +15,9 @@ public class PolicyUtil { public static boolean isPermissionPresentInPolicies( String permission, Set policies, Set userPermissionGroupIds) { + if (policies == null) { + return FALSE; + } Optional interestingPolicyOptional = policies.stream() .filter(policy -> policy.getPermission().equals(permission)) .findFirst(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaMigration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaMigration.java index 047c037e6c4f..badec22d19e5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaMigration.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaMigration.java @@ -6,35 +6,27 @@ import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.CollectionUtils; +import com.appsmith.server.migrations.utils.JsonSchemaMigrationHelper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; +import java.util.Map; + @Slf4j @Component @RequiredArgsConstructor public class JsonSchemaMigration { private final JsonSchemaVersions jsonSchemaVersions; + private final JsonSchemaMigrationHelper jsonSchemaMigrationHelper; private boolean isCompatible(ApplicationJson applicationJson) { return (applicationJson.getClientSchemaVersion() <= jsonSchemaVersions.getClientVersion()) && (applicationJson.getServerSchemaVersion() <= jsonSchemaVersions.getServerVersion()); } - /** - * This is a temporary check which is being placed for the compatibility of server versions in scenarios - * where user is moving a json from an instance which has - * release_autocommit_feature_enabled true to an instance which has the flag as false. In that case the server - * version number of json would be 8 and in new instance it would be not compatible. - * @param applicationJson - * @return - */ - private boolean isAutocommitVersionBump(ApplicationJson applicationJson) { - return jsonSchemaVersions.getServerVersion() == 7 && applicationJson.getServerSchemaVersion() == 8; - } - private void setSchemaVersions(ApplicationJson applicationJson) { applicationJson.setServerSchemaVersion(getCorrectSchemaVersion(applicationJson.getServerSchemaVersion())); applicationJson.setClientSchemaVersion(getCorrectSchemaVersion(applicationJson.getClientSchemaVersion())); @@ -53,24 +45,63 @@ public Mono migrateArtifactExchangeJsonToLatestS ArtifactExchangeJson artifactExchangeJson) { if (ArtifactType.APPLICATION.equals(artifactExchangeJson.getArtifactJsonType())) { - return migrateApplicationJsonToLatestSchema((ApplicationJson) artifactExchangeJson); + return migrateApplicationJsonToLatestSchema((ApplicationJson) artifactExchangeJson, null, null); } return Mono.fromCallable(() -> artifactExchangeJson); } - public Mono migrateApplicationJsonToLatestSchema(ApplicationJson applicationJson) { + public Mono migrateApplicationJsonToLatestSchema( + ApplicationJson applicationJson, String baseApplicationId, String branchName) { return Mono.fromCallable(() -> { setSchemaVersions(applicationJson); - if (isCompatible(applicationJson)) { - return migrateServerSchema(applicationJson); - } - - if (isAutocommitVersionBump(applicationJson)) { - return migrateServerSchema(applicationJson); + return applicationJson; + }) + .flatMap(appJson -> { + if (!isCompatible(appJson)) { + return Mono.empty(); } - return null; + // Taking a tech debt over here for import of file application. + // All migration above version 9 is reactive + // TODO: make import flow migration reactive + return Mono.just(migrateServerSchema(appJson)) + .flatMap(migratedApplicationJson -> { + // In Server version 9, there was a bug where the Embedded REST API datasource URL + // was not being persisted correctly. Once the bug was fixed, + // any previously uncommitted changes started appearing as uncommitted modifications + // in the apps. To automatically commit these changes + // (which were now appearing as uncommitted), a migration process was needed. + // This migration fetches the datasource URL from the database + // and serializes it in Git if the URL exists. + // If the URL is missing, it copies the empty datasource configuration + // if the configuration is present in the database. + // Otherwise, it leaves the configuration unchanged. + // Due to an update in the migration logic after version 10 was shipped, + // the entire migration process was moved to version 11. + // This adjustment ensures that the same operation can be + // performed again for the changes introduced in version 10. + if (migratedApplicationJson.getServerSchemaVersion() == 9) { + migratedApplicationJson.setServerSchemaVersion(10); + } + + if (migratedApplicationJson.getServerSchemaVersion() == 10) { + if (Boolean.TRUE.equals(MigrationHelperMethods.doesRestApiRequireMigration( + migratedApplicationJson))) { + return jsonSchemaMigrationHelper + .addDatasourceConfigurationToDefaultRestApiActions( + baseApplicationId, branchName, migratedApplicationJson); + } + + migratedApplicationJson.setServerSchemaVersion(11); + } + + return Mono.just(migratedApplicationJson); + }) + .map(migratedAppJson -> { + applicationJson.setServerSchemaVersion(jsonSchemaVersions.getServerVersion()); + return applicationJson; + }); }) .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.INCOMPATIBLE_IMPORTED_JSON))); } @@ -81,7 +112,7 @@ public Mono migrateApplicationJsonToLatestSchema(ApplicationJso * @param artifactExchangeJson : the json to be imported * @return transformed artifact exchange json */ - @Deprecated + @Deprecated(forRemoval = true, since = "Use migrateArtifactJsonToLatestSchema") public ArtifactExchangeJson migrateArtifactToLatestSchema(ArtifactExchangeJson artifactExchangeJson) { if (!ArtifactType.APPLICATION.equals(artifactExchangeJson.getArtifactJsonType())) { @@ -91,11 +122,11 @@ public ArtifactExchangeJson migrateArtifactToLatestSchema(ArtifactExchangeJson a ApplicationJson applicationJson = (ApplicationJson) artifactExchangeJson; setSchemaVersions(applicationJson); if (!isCompatible(applicationJson)) { - if (!isAutocommitVersionBump(applicationJson)) { - throw new AppsmithException(AppsmithError.INCOMPATIBLE_IMPORTED_JSON); - } + throw new AppsmithException(AppsmithError.INCOMPATIBLE_IMPORTED_JSON); } - return migrateServerSchema(applicationJson); + + applicationJson = migrateServerSchema(applicationJson); + return nonReactiveServerMigrationForImport(applicationJson); } /** @@ -145,17 +176,41 @@ private ApplicationJson migrateServerSchema(ApplicationJson applicationJson) { MigrationHelperMethods.ensureXmlParserPresenceInCustomJsLibList(applicationJson); applicationJson.setServerSchemaVersion(7); case 7: + applicationJson.setServerSchemaVersion(8); case 8: MigrationHelperMethods.migrateThemeSettingsForAnvil(applicationJson); applicationJson.setServerSchemaVersion(9); + + // This is not supposed to have anymore additions to the schema. default: // Unable to detect the serverSchema + } - if (applicationJson.getServerSchemaVersion().equals(jsonSchemaVersions.getServerVersion())) { + return applicationJson; + } + + /** + * This method is an alternative to reactive way of adding migrations to application json. + * this is getting used by flows which haven't implemented the reactive way yet. + * @param applicationJson : application json for which migration has to be done. + * @return return application json after migration + */ + private ApplicationJson nonReactiveServerMigrationForImport(ApplicationJson applicationJson) { + if (jsonSchemaVersions.getServerVersion().equals(applicationJson.getServerSchemaVersion())) { return applicationJson; } + switch (applicationJson.getServerSchemaVersion()) { + case 9: + applicationJson.setServerSchemaVersion(10); + case 10: + // this if for cases where we have empty datasource configs + MigrationHelperMethods.migrateApplicationJsonToVersionTen(applicationJson, Map.of()); + applicationJson.setServerSchemaVersion(11); + default: + } + applicationJson.setServerSchemaVersion(jsonSchemaVersions.getServerVersion()); return applicationJson; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaVersionsFallback.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaVersionsFallback.java index 63b6c7e7d4e3..c85b95bed5de 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaVersionsFallback.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/JsonSchemaVersionsFallback.java @@ -4,7 +4,7 @@ @Component public class JsonSchemaVersionsFallback { - private static final Integer serverVersion = 9; + private static final Integer serverVersion = 11; public static final Integer clientVersion = 1; public Integer getServerVersion() { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java index cf18759a867a..277a3ac5768e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java @@ -1,8 +1,11 @@ package com.appsmith.server.migrations; +import com.appsmith.external.constants.PluginConstants; import com.appsmith.external.helpers.MustacheHelper; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.BaseDomain; +import com.appsmith.external.models.Datasource; +import com.appsmith.external.models.DatasourceConfiguration; import com.appsmith.external.models.InvisibleActionFields; import com.appsmith.external.models.Property; import com.appsmith.server.constants.ApplicationConstants; @@ -41,6 +44,8 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +import static com.appsmith.external.constants.PluginConstants.PackageName.GRAPHQL_PLUGIN; +import static com.appsmith.external.constants.PluginConstants.PackageName.REST_API_PLUGIN; import static com.appsmith.server.constants.ResourceModes.EDIT; import static com.appsmith.server.constants.ResourceModes.VIEW; import static org.springframework.data.mongodb.core.query.Criteria.where; @@ -1231,4 +1236,134 @@ public static void setThemeSettings(Application.ThemeSetting themeSetting) { themeSetting.setSizing(1); } } + + public static boolean conditionForDefaultRestDatasource(NewAction action) { + if (action.getUnpublishedAction() == null + || action.getUnpublishedAction().getDatasource() == null) { + return false; + } + + Datasource actionDatasource = action.getUnpublishedAction().getDatasource(); + + // probable check for the default rest datasource action is. + // it has no datasource id and action's plugin id is either rest-api or graphql plugin. + boolean probableCheckForDefaultRestDatasource = !org.springframework.util.StringUtils.hasText( + actionDatasource.getId()) + && (REST_API_PLUGIN.equals(action.getPluginId()) || GRAPHQL_PLUGIN.equals(action.getPluginId())); + + // condition to check if the action is default rest datasource. + // it has no datasource id and name is equal to DEFAULT_REST_DATASOURCE + boolean certainCheckForDefaultRestDatasource = + !org.springframework.util.StringUtils.hasText(actionDatasource.getId()) + && PluginConstants.DEFAULT_REST_DATASOURCE.equals(actionDatasource.getName()); + + // Two separate types of checks over here, it's either the obvious certain way to identify or + // the likely chance that the datasource is present. + return certainCheckForDefaultRestDatasource || probableCheckForDefaultRestDatasource; + } + + private static boolean conditionForDefaultRestDatasourceMigration(NewAction action) { + boolean isActionDefaultRestDatasource = conditionForDefaultRestDatasource(action); + Datasource actionDatasource = action.getUnpublishedAction().getDatasource(); + + // condition to check if the action has missing url or has no config at all + boolean isDatasourceConfigurationOrUrlMissing = actionDatasource.getDatasourceConfiguration() == null + || !org.springframework.util.StringUtils.hasText( + actionDatasource.getDatasourceConfiguration().getUrl()); + + return isActionDefaultRestDatasource && isDatasourceConfigurationOrUrlMissing; + } + + /** + * Adds datasource configuration and relevant url to the embedded datasource actions. + * @param applicationJson: ApplicationJson for which the migration has to be performed + * @param defaultDatasourceActionMap: gitSyncId to actions with default rest datasource map + */ + public static void migrateApplicationJsonToVersionTen( + ApplicationJson applicationJson, Map defaultDatasourceActionMap) { + List actionList = applicationJson.getActionList(); + if (CollectionUtils.isNullOrEmpty(actionList)) { + return; + } + + for (NewAction action : actionList) { + if (action.getUnpublishedAction() == null + || action.getUnpublishedAction().getDatasource() == null) { + continue; + } + + Datasource actionDatasource = action.getUnpublishedAction().getDatasource(); + if (conditionForDefaultRestDatasourceMigration(action)) { + // Idea is to add datasourceConfiguration to existing DEFAULT_REST_DATASOURCE apis, + // for which the datasource configuration is missing + // the url would be set to empty string as right url is not present over here. + setDatasourceConfigDetailsInDefaultRestDatasourceForActions(action, defaultDatasourceActionMap); + } + } + } + + /** + * Finds if the applicationJson has any default rest datasource which has a null datasource configuration + * or an unset url. + * @param applicationJson : Application Json for which requirement is to be checked. + * @return true if the application has a rest api which doesn't have a valid datasource configuration. + */ + public static Boolean doesRestApiRequireMigration(ApplicationJson applicationJson) { + List actionList = applicationJson.getActionList(); + if (CollectionUtils.isNullOrEmpty(actionList)) { + return Boolean.FALSE; + } + + for (NewAction action : actionList) { + if (action.getUnpublishedAction() == null + || action.getUnpublishedAction().getDatasource() == null) { + continue; + } + + Datasource actionDatasource = action.getUnpublishedAction().getDatasource(); + if (conditionForDefaultRestDatasourceMigration(action)) { + return Boolean.TRUE; + } + } + + return Boolean.FALSE; + } + + /** + * Adds the relevant url in the default rest datasource for the given action from an action in the db + * otherwise sets the url to empty + * it's established that action doesn't have the datasource. + * @param action : default rest datasource actions which doesn't have valid datasource configuration. + * @param defaultDatasourceActionMap : gitSyncId to actions with default rest datasource map + */ + public static void setDatasourceConfigDetailsInDefaultRestDatasourceForActions( + NewAction action, Map defaultDatasourceActionMap) { + + ActionDTO actionDTO = action.getUnpublishedAction(); + Datasource actionDatasource = actionDTO.getDatasource(); + DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration(); + + if (defaultDatasourceActionMap.containsKey(action.getGitSyncId())) { + NewAction actionFromMap = defaultDatasourceActionMap.get(action.getGitSyncId()); + // NPE check to avoid migration failures + if (actionFromMap.getUnpublishedAction() == null + || actionFromMap.getUnpublishedAction().getDatasource() == null + || actionFromMap.getUnpublishedAction().getDatasource().getDatasourceConfiguration() == null) { + return; + } + + // set the datasource config in the json action only if the datasource config from db is not null, + // else it'll start to show as uncommited changes. + DatasourceConfiguration datasourceConfigurationFromDBAction = + actionFromMap.getUnpublishedAction().getDatasource().getDatasourceConfiguration(); + + // At this point it's established that datasource config of db action is not null. + datasourceConfiguration.setUrl(datasourceConfigurationFromDBAction.getUrl()); + actionDatasource.setDatasourceConfiguration(datasourceConfiguration); + + } else { + datasourceConfiguration.setUrl(""); + actionDatasource.setDatasourceConfiguration(datasourceConfiguration); + } + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration025RemoveUnassignPermissionFromUnnecessaryRoles.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration025RemoveUnassignPermissionFromUnnecessaryRoles.java index d0f579426e77..b87594614020 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration025RemoveUnassignPermissionFromUnnecessaryRoles.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration025RemoveUnassignPermissionFromUnnecessaryRoles.java @@ -14,6 +14,7 @@ import org.springframework.data.mongodb.core.query.Update; import java.util.Optional; +import java.util.Set; import static com.appsmith.server.migrations.constants.DeprecatedFieldName.POLICIES; import static com.appsmith.server.migrations.constants.FieldName.POLICY_MAP; @@ -49,7 +50,9 @@ public void executeMigration() { mongoTemplate.stream(optimizedQueryForInterestingPermissionGroups, PermissionGroup.class) .forEach(permissionGroup -> { - Optional optionalUnassignPolicy = permissionGroup.getPolicies().stream() + Set policies = + permissionGroup.getPolicies() == null ? Set.of() : permissionGroup.getPolicies(); + Optional optionalUnassignPolicy = policies.stream() .filter(policy -> policy.getPermission().equals("unassign:permissionGroups")) .findFirst(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration028TagUserManagementRolesWithoutDefaultDomainTypeAndId.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration028TagUserManagementRolesWithoutDefaultDomainTypeAndId.java index bfe4dcbacb2d..c2004407a5db 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration028TagUserManagementRolesWithoutDefaultDomainTypeAndId.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration028TagUserManagementRolesWithoutDefaultDomainTypeAndId.java @@ -51,7 +51,8 @@ public void tagUserManagementRolesWithoutDefaultDomainTypeAndId() { */ Set userManagementRoleIds = new HashSet<>(); existingUsers.forEach(existingUser -> { - Optional resetPasswordPolicyOptional = existingUser.getPolicies().stream() + Set policies = existingUser.getPolicies() == null ? Set.of() : existingUser.getPolicies(); + Optional resetPasswordPolicyOptional = policies.stream() .filter(policy1 -> RESET_PASSWORD_USERS.getValue().equals(policy1.getPermission())) .findFirst(); resetPasswordPolicyOptional.ifPresent(resetPasswordPolicy -> { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration029PopulateDefaultDomainIdInUserManagementRoles.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration029PopulateDefaultDomainIdInUserManagementRoles.java index 0d930522f8ad..882e1a1ad1b0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration029PopulateDefaultDomainIdInUserManagementRoles.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration029PopulateDefaultDomainIdInUserManagementRoles.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import static com.appsmith.server.acl.AclPermission.RESET_PASSWORD_USERS; import static com.appsmith.server.migrations.constants.DeprecatedFieldName.POLICIES; @@ -51,7 +52,8 @@ public void populateDefaultDomainIdInUserManagementRoles() { Map userManagementRoleIdToUserIdMap = new HashMap<>(); mongoTemplate.stream(queryExistingUsersWithResetPasswordPolicy, User.class) .forEach(existingUser -> { - Optional resetPasswordPolicyOptional = existingUser.getPolicies().stream() + Set policies = existingUser.getPolicies() == null ? Set.of() : existingUser.getPolicies(); + Optional resetPasswordPolicyOptional = policies.stream() .filter(policy1 -> RESET_PASSWORD_USERS.getValue().equals(policy1.getPermission())) .findFirst(); resetPasswordPolicyOptional.ifPresent(resetPasswordPolicy -> { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/utils/JsonSchemaMigrationHelper.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/utils/JsonSchemaMigrationHelper.java new file mode 100644 index 000000000000..1f1e27de8c7c --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/utils/JsonSchemaMigrationHelper.java @@ -0,0 +1,90 @@ +package com.appsmith.server.migrations.utils; + +import com.appsmith.external.constants.PluginConstants; +import com.appsmith.external.models.Datasource; +import com.appsmith.external.models.PluginType; +import com.appsmith.server.applications.base.ApplicationService; +import com.appsmith.server.domains.Application; +import com.appsmith.server.domains.NewAction; +import com.appsmith.server.dtos.ApplicationJson; +import com.appsmith.server.migrations.MigrationHelperMethods; +import com.appsmith.server.newactions.base.NewActionService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import reactor.core.publisher.Mono; + +import java.util.Map; +import java.util.Optional; + +@Component +@Slf4j +@RequiredArgsConstructor +public class JsonSchemaMigrationHelper { + + private final ApplicationService applicationService; + private final NewActionService newActionService; + + public Mono addDatasourceConfigurationToDefaultRestApiActions( + String baseApplicationId, String branchName, ApplicationJson applicationJson) { + + Mono contingencyMigrationJson = Mono.defer(() -> Mono.fromCallable(() -> { + MigrationHelperMethods.migrateApplicationJsonToVersionTen(applicationJson, Map.of()); + return applicationJson; + })); + + if (!StringUtils.hasText(baseApplicationId) || !StringUtils.hasText(branchName)) { + return contingencyMigrationJson; + } + + Mono applicationMono = applicationService + .findByBranchNameAndBaseApplicationId(branchName, baseApplicationId, null) + .cache(); + + return applicationMono + .flatMap(branchedApplication -> { + return newActionService + .findAllByApplicationIdAndViewMode( + branchedApplication.getId(), Boolean.FALSE, Optional.empty(), Optional.empty()) + .filter(action -> { + if (action.getUnpublishedAction() == null + || action.getUnpublishedAction().getDatasource() == null) { + return false; + } + + Datasource actionDatasource = + action.getUnpublishedAction().getDatasource(); + + // lenient probable check for the default rest datasource action is. + // As we don't have any harm in the allowing API actions present in db. + // it has no datasource id and action's plugin type is API + boolean probableCheckForDefaultRestDatasource = + !org.springframework.util.StringUtils.hasText(actionDatasource.getId()) + && PluginType.API.equals(action.getPluginType()); + + // condition to check if the action is default rest datasource. + // it has no datasource id and name is equal to DEFAULT_REST_DATASOURCE + boolean certainCheckForDefaultRestDatasource = + !org.springframework.util.StringUtils.hasText(actionDatasource.getId()) + && PluginConstants.DEFAULT_REST_DATASOURCE.equals( + actionDatasource.getName()); + + // Two separate types of checks over here, it's either the obvious certain way to + // identify or + // the likely chance that the datasource is present. + return certainCheckForDefaultRestDatasource || probableCheckForDefaultRestDatasource; + }) + .collectMap(NewAction::getGitSyncId); + }) + .map(newActionMap -> { + MigrationHelperMethods.migrateApplicationJsonToVersionTen(applicationJson, newActionMap); + return applicationJson; + }) + .switchIfEmpty(contingencyMigrationJson) + .onErrorResume(error -> { + log.error("Error occurred while migrating actions of application json. {}", error.getMessage()); + return contingencyMigrationJson; + }); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java index 41586161539a..12b787c4dfb8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java @@ -1012,7 +1012,7 @@ public Flux getUnpublishedActions( Mono branchedPageMono = !StringUtils.hasLength(params.getFirst(FieldName.PAGE_ID)) ? Mono.just(new NewPage()) : newPageService.findByBranchNameAndBasePageId( - branchName, params.getFirst(FieldName.PAGE_ID), pagePermission.getReadPermission()); + branchName, params.getFirst(FieldName.PAGE_ID), pagePermission.getReadPermission(), null); Mono branchedApplicationMono = !StringUtils.hasLength(params.getFirst(FieldName.APPLICATION_ID)) ? Mono.just(new Application()) : applicationService.findByBranchNameAndBaseApplicationId( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java index d8c1192de9ba..b669c91a4142 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java @@ -30,8 +30,6 @@ public interface NewPageServiceCE extends CrudService { Flux findNewPagesByApplicationId( String applicationId, AclPermission permission, List includeFields); - Mono findByIdAndBranchName(String id, String branchName); - Mono saveUnpublishedPage(PageDTO page); Mono createDefault(PageDTO object); @@ -71,7 +69,8 @@ Mono findByNameAndApplicationIdAndViewMode( Mono getNameByPageId(String pageId, boolean isPublishedName); - Mono findByBranchNameAndBasePageId(String branchName, String defaultPageId, AclPermission permission); + Mono findByBranchNameAndBasePageId( + String branchName, String defaultPageId, AclPermission permission, List projectedFieldNames); Mono findByBranchNameAndBasePageIdAndApplicationMode( String branchName, String basePageId, ApplicationMode mode); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java index e8f418d39289..594e94d033e8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java @@ -136,11 +136,6 @@ public Flux findByApplicationId(String applicationId, AclPermission per return findNewPagesByApplicationId(applicationId, permission).flatMap(page -> getPageByViewMode(page, view)); } - @Override - public Mono findByIdAndBranchName(String id, String branchName) { - return this.findByBranchNameAndBasePageId(branchName, id, pagePermission.getReadPermission()); - } - @Override public Mono saveUnpublishedPage(PageDTO page) { @@ -511,19 +506,21 @@ public Mono getNameByPageId(String pageId, boolean isPublishedName) { } @Override - public Mono findByBranchNameAndBasePageId(String branchName, String basePageId, AclPermission permission) { + public Mono findByBranchNameAndBasePageId( + String branchName, String basePageId, AclPermission permission, List projectedFieldNames) { if (!StringUtils.hasText(basePageId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID)); } else if (!StringUtils.hasText(branchName)) { - return this.findById(basePageId, permission) + return repository + .findById(basePageId, permission, projectedFieldNames) .name(GET_PAGE_WITHOUT_BRANCH) .tap(Micrometer.observation(observationRegistry)) .switchIfEmpty(Mono.error( new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, basePageId))); } return repository - .findPageByBranchNameAndBasePageId(branchName, basePageId, permission) + .findPageByBranchNameAndBasePageId(branchName, basePageId, permission, projectedFieldNames) .name(GET_PAGE_WITH_BRANCH) .tap(Micrometer.observation(observationRegistry)) .switchIfEmpty(Mono.error(new AppsmithException( @@ -541,7 +538,8 @@ public Mono findByBranchNameAndBasePageIdAndApplicationMode( permission = pagePermission.getReadPermission(); } - return this.findByBranchNameAndBasePageId(branchName, basePageId, permission) + return this.findByBranchNameAndBasePageId( + branchName, basePageId, permission, List.of(NewPage.Fields.id, NewPage.Fields.applicationId)) .name(getQualifiedSpanName(GET_PAGE, mode)) .tap(Micrometer.observation(observationRegistry)); } @@ -556,7 +554,7 @@ public Mono findBranchedPageId(String branchName, String basePageId, Acl return Mono.just(basePageId); } return repository - .findPageByBranchNameAndBasePageId(branchName, basePageId, permission) + .findPageByBranchNameAndBasePageId(branchName, basePageId, permission, null) .switchIfEmpty(Mono.error(new AppsmithException( AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE_ID, basePageId + ", " + branchName))) .map(NewPage::getId); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java index 8bf2c469b9aa..fc66e5e2eeec 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java @@ -4,6 +4,7 @@ import com.appsmith.server.domains.User; import reactor.core.publisher.Mono; +import java.util.List; import java.util.Set; public interface CacheableRepositoryHelperCE { @@ -23,4 +24,25 @@ public interface CacheableRepositoryHelperCE { Mono fetchDefaultTenant(String tenantId); Mono evictCachedTenant(String tenantId); + + /** + * Retrieves the base application ID from the cache based on the provided base page ID. + * + *

If the cache contains the ID for the specified {@code basePageId}, it is returned as a {@code Mono} containing the {@code baseApplicationId}. + * If the cache does not contain the ID (cache miss) and {@code baseApplicationId} is {@code null} or empty, an empty {@code Mono} is returned.

+ * + *

If {@code baseApplicationId} is not {@code null} or empty and a cache miss occurs, the cache will be updated with the provided {@code baseApplicationId}.

+ * + *

Note that calling this method with a {@code null} {@code baseApplicationId} on a cache miss will not update the cache. + * In this case, the method will return an empty {@code Mono}, and no cache update will occur.

+ * + * @param basePageId the identifier for the base page used as the cache key + * @param baseApplicationId the base application ID to be returned or used to update the cache if not {@code null} or empty + * @return a {@code Mono} containing the {@code baseApplicationId} if it is present in the cache or provided; otherwise, an empty {@code Mono} on a cache miss with a {@code null} or empty {@code baseApplicationId}. + * + *

On a cache miss, if {@code baseApplicationId} is provided, the cache will be updated with the new value after performing additional database operations to fetch the application document.

+ */ + Mono fetchBaseApplicationId(String basePageId, String baseApplicationId); + + Mono evictCachedBasePageIds(List basePageIds); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java index 330ae848910c..3cdcc4e8b087 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java @@ -21,9 +21,11 @@ import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import reactor.core.observability.micrometer.Micrometer; import reactor.core.publisher.Mono; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -41,6 +43,7 @@ public class CacheableRepositoryHelperCEImpl implements CacheableRepositoryHelpe private final ReactiveMongoOperations mongoOperations; private final InMemoryCacheableRepositoryHelper inMemoryCacheableRepositoryHelper; private final ObservationRegistry observationRegistry; + private static final String CACHE_DEFAULT_PAGE_ID_TO_DEFAULT_APPLICATION_ID = "pageIdToAppId"; @Cache(cacheName = "permissionGroupsForUser", key = "{#user.email + #user.tenantId}") @Override @@ -199,4 +202,16 @@ public Mono fetchDefaultTenant(String tenantId) { public Mono evictCachedTenant(String tenantId) { return Mono.empty().then(); } + + @Cache(cacheName = CACHE_DEFAULT_PAGE_ID_TO_DEFAULT_APPLICATION_ID, key = "{#basePageId}") + @Override + public Mono fetchBaseApplicationId(String basePageId, String baseApplicationId) { + return !StringUtils.hasText(baseApplicationId) ? Mono.empty() : Mono.just(baseApplicationId); + } + + @CacheEvict(cacheName = CACHE_DEFAULT_PAGE_ID_TO_DEFAULT_APPLICATION_ID, keys = "#basePageIds") + @Override + public Mono evictCachedBasePageIds(List basePageIds) { + return Mono.just(Boolean.TRUE); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java index 43d30d5ea144..ca0beb98bec7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java @@ -12,6 +12,8 @@ public interface CustomNewPageRepositoryCE extends AppsmithRepository { + Mono findById(String id, AclPermission permission, List projectedFields); + Flux findByApplicationId(String applicationId, AclPermission aclPermission); Flux findByApplicationId(String applicationId, AclPermission aclPermission, List includeFields); @@ -30,7 +32,8 @@ Mono findByNameAndApplicationIdAndViewMode( Mono getNameByPageId(String pageId, boolean isPublishedName); - Mono findPageByBranchNameAndBasePageId(String branchName, String basePageId, AclPermission permission); + Mono findPageByBranchNameAndBasePageId( + String branchName, String basePageId, AclPermission permission, List projectedFieldNames); Flux findAllByApplicationIds(List branchedArtifactIds, List includedFields); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java index c1d59515075d..03b06fc065f2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java @@ -40,6 +40,15 @@ public class CustomNewPageRepositoryCEImpl extends BaseAppsmithRepositoryImpl findById(String id, AclPermission permission, List projectedFields) { + return queryBuilder() + .criteria(Bridge.equal(NewPage.Fields.id, id)) + .permission(permission) + .fields(projectedFields) + .one(); + } + @Override public Flux findByApplicationId(String applicationId, AclPermission aclPermission) { return queryBuilder() @@ -161,7 +170,7 @@ public Mono getNameByPageId(String pageId, boolean isPublishedName) { @Override public Mono findPageByBranchNameAndBasePageId( - String branchName, String basePageId, AclPermission permission) { + String branchName, String basePageId, AclPermission permission, List projectedFieldNames) { final BridgeQuery q = // defaultPageIdCriteria @@ -177,6 +186,7 @@ public Mono findPageByBranchNameAndBasePageId( return queryBuilder() .criteria(q) .permission(permission) + .fields(projectedFieldNames) .one() .name(FETCH_PAGE_FROM_DB) .tap(Micrometer.observation(observationRegistry)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java index 808a45405e4a..f31d8f50c3a4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java @@ -13,6 +13,7 @@ import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.repositories.ApplicationRepository; +import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.repositories.DatasourceRepository; import com.appsmith.server.repositories.NewActionRepository; import com.appsmith.server.repositories.NewPageRepository; @@ -60,7 +61,8 @@ public ApplicationPageServiceImpl( DSLMigrationUtils dslMigrationUtils, ClonePageService actionClonePageService, ClonePageService actionCollectionClonePageService, - ObservationRegistry observationRegistry) { + ObservationRegistry observationRegistry, + CacheableRepositoryHelper cacheableRepositoryHelper) { super( workspaceService, applicationService, @@ -89,6 +91,7 @@ public ApplicationPageServiceImpl( dslMigrationUtils, actionClonePageService, actionCollectionClonePageService, - observationRegistry); + observationRegistry, + cacheableRepositoryHelper); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java index f786ac90c1b9..9b0c48a44d0d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java @@ -7,6 +7,7 @@ import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; +import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.services.ce_compatible.ConsolidatedAPIServiceCECompatibleImpl; import com.appsmith.server.themes.base.ThemeService; import io.micrometer.observation.ObservationRegistry; @@ -33,7 +34,8 @@ public ConsolidatedAPIServiceImpl( PluginService pluginService, DatasourceService datasourceService, MockDataService mockDataService, - ObservationRegistry observationRegistry) { + ObservationRegistry observationRegistry, + CacheableRepositoryHelper cacheableRepositoryHelper) { super( sessionUserService, userService, @@ -50,6 +52,7 @@ public ConsolidatedAPIServiceImpl( pluginService, datasourceService, mockDataService, - observationRegistry); + observationRegistry, + cacheableRepositoryHelper); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java index cc3cfd047f08..1536ba67a357 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java @@ -43,6 +43,7 @@ import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.repositories.ApplicationRepository; +import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.repositories.DatasourceRepository; import com.appsmith.server.repositories.NewActionRepository; import com.appsmith.server.repositories.NewPageRepository; @@ -128,6 +129,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { private final ClonePageService actionClonePageService; private final ClonePageService actionCollectionClonePageService; private final ObservationRegistry observationRegistry; + private final CacheableRepositoryHelper cacheableRepositoryHelper; @Override public Mono createPage(PageDTO page) { @@ -311,7 +313,7 @@ public Mono getPageAndMigrateDslByBranchAndBasePageId( ApplicationMode applicationMode = viewMode ? ApplicationMode.PUBLISHED : ApplicationMode.EDIT; // Fetch the page with read permission in both editor and in viewer. return newPageService - .findByBranchNameAndBasePageId(branchName, defaultPageId, pagePermission.getReadPermission()) + .findByBranchNameAndBasePageId(branchName, defaultPageId, pagePermission.getReadPermission(), null) .flatMap(newPage -> getPageDTOAfterMigratingDSL(newPage, viewMode, migrateDsl) .name(getQualifiedSpanName(MIGRATE_DSL, applicationMode)) .tap(Micrometer.observation(observationRegistry))); @@ -1084,6 +1086,9 @@ protected Mono, ApplicationPublishingMetaDTO>> publishA Mono archivePageMono; + Mono evictDeletedDefaultPageIdsMono = + cacheableRepositoryHelper.evictCachedBasePageIds(new ArrayList<>(publishedPageIds)); + if (!publishedPageIds.isEmpty()) { archivePageMono = newPageService.archiveByIds(publishedPageIds); } else { @@ -1102,8 +1107,12 @@ protected Mono, ApplicationPublishingMetaDTO>> publishA newPageService.publishPages(editedPageIds, pagePermission.getEditPermission()); // Archive the deleted pages and save the application changes and then return the pages so that - // the pages can also be published - return Mono.when(archivePageMono, publishPagesMono, applicationService.save(application)) + // the pages can also be published; In addition invalidate the cache for the deleted page Ids + return Mono.when( + archivePageMono, + publishPagesMono, + applicationService.save(application), + evictDeletedDefaultPageIdsMono) .thenReturn(pages); }) .cache(); // caching as we'll need this to send analytics attributes after publishing the app diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java index 7ec347e840bf..1f046c8ba290 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java @@ -21,6 +21,7 @@ import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; +import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.services.ApplicationPageService; import com.appsmith.server.services.MockDataService; import com.appsmith.server.services.ProductAlertService; @@ -51,6 +52,8 @@ import java.util.stream.Collectors; import static com.appsmith.external.constants.PluginConstants.PLUGINS_THAT_ALLOW_QUERY_CREATION_WITHOUT_DATASOURCE; +import static com.appsmith.external.constants.spans.ApplicationSpan.APPLICATION_ID_FETCH_REDIS_SPAN; +import static com.appsmith.external.constants.spans.ApplicationSpan.APPLICATION_ID_UPDATE_REDIS_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.ACTIONS_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.ACTION_COLLECTIONS_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.APPLICATION_ID_SPAN; @@ -99,6 +102,7 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { private final DatasourceService datasourceService; private final MockDataService mockDataService; private final ObservationRegistry observationRegistry; + private final CacheableRepositoryHelper cacheableRepositoryHelper; ResponseDTO getSuccessResponse(T data) { return new ResponseDTO<>(HttpStatus.OK.value(), data, null); @@ -197,29 +201,57 @@ public Mono getConsolidatedInfoForPageLoad( boolean isViewMode = ApplicationMode.PUBLISHED.equals(mode); /* Fetch default application id if not provided */ + if (isBlank(basePageId)) { + return Mono.when(fetches).thenReturn(consolidatedAPIResponseDTO); + } Mono branchedApplicationMonoCached; - Mono branchedPageMonoCached = Mono.empty(); - if (!isBlank(basePageId)) { - branchedPageMonoCached = newPageService - .findByBranchNameAndBasePageIdAndApplicationMode(branchName, basePageId, mode) - .cache(); + Mono baseApplicationIdMono = Mono.just(""); + if (isViewMode) { + // Attempt to retrieve the application ID associated with the given base page ID from the cache. + baseApplicationIdMono = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId, baseApplicationId) + .switchIfEmpty(Mono.just("")) + .cast(String.class); } + baseApplicationIdMono = baseApplicationIdMono + .name(getQualifiedSpanName(APPLICATION_ID_FETCH_REDIS_SPAN, mode)) + .tap(Micrometer.observation(observationRegistry)) + .cache(); - if (isBlank(baseApplicationId)) { - branchedApplicationMonoCached = branchedPageMonoCached - .map(NewPage::getApplicationId) - .flatMap(applicationId -> - applicationService.findByBranchedApplicationIdAndApplicationMode(applicationId, mode)) - .name(getQualifiedSpanName(APPLICATION_ID_SPAN, mode)) - .tap(Micrometer.observation(observationRegistry)) - .cache(); - } else { - branchedApplicationMonoCached = applicationService - .findByBaseIdBranchNameAndApplicationMode(baseApplicationId, branchName, mode) - .name(getQualifiedSpanName(APPLICATION_ID_SPAN, mode)) - .tap(Micrometer.observation(observationRegistry)) - .cache(); - } + Mono branchedPageMonoCached = newPageService + .findByBranchNameAndBasePageIdAndApplicationMode(branchName, basePageId, mode) + .cache(); + + branchedApplicationMonoCached = baseApplicationIdMono.flatMap(cachedBaseApplicationId -> { + if (!StringUtils.hasText(cachedBaseApplicationId)) { + // Handle empty or null baseApplicationId + return branchedPageMonoCached.flatMap(branchedPage -> + // Use the application ID to find the complete application details. + applicationService + .findByBranchedApplicationIdAndApplicationMode(branchedPage.getApplicationId(), mode) + .flatMap(application -> { + if (isViewMode) { + // Update the cache with the new application’s base ID for future + // queries. + return cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId, application.getBaseId()) + .thenReturn(application) + .name(getQualifiedSpanName(APPLICATION_ID_UPDATE_REDIS_SPAN, mode)) + .tap(Micrometer.observation(observationRegistry)); + } + return Mono.just(application); + })); + } else { + // Handle non-empty baseApplicationId + return applicationService.findByBaseIdBranchNameAndApplicationMode( + cachedBaseApplicationId, branchName, mode); + } + }); + + branchedApplicationMonoCached = branchedApplicationMonoCached + .name(getQualifiedSpanName(APPLICATION_ID_SPAN, mode)) + .tap(Micrometer.observation(observationRegistry)) + .cache(); Mono> pagesFromCurrentApplicationMonoCached = branchedApplicationMonoCached .flatMap(branchedApplication -> diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java index 0a75c2f9d7bb..d4a473ae650e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java @@ -107,7 +107,8 @@ public Mono importAction( protected Mono getBranchedContextId(CreatorContextType contextType, String contextId, String branchName) { return newPageService - .findByBranchNameAndBasePageId(branchName, contextId, pagePermission.getActionCreatePermission()) + .findByBranchNameAndBasePageId( + branchName, contextId, pagePermission.getActionCreatePermission(), List.of(NewPage.Fields.id)) .map(NewPage::getId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java index 34976f8fa692..22e516476ef5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java @@ -309,7 +309,8 @@ public Mono getPublicPermissionGroupId() { @Override public boolean isEntityAccessible(BaseDomain object, String permission, String permissionGroupId) { - return object.getPolicies().stream() + Set policies = object.getPolicies() == null ? Set.of() : object.getPolicies(); + return policies.stream() .filter(policy -> policy.getPermission().equals(permission) && policy.getPermissionGroups().contains(permissionGroupId)) .findFirst() 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 ca6cb2f60446..1589daf14bde 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 @@ -1,6 +1,5 @@ package com.appsmith.server.services.ce; -import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.helpers.EncryptionHelper; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.configurations.CommonConfig; @@ -576,8 +575,7 @@ private Mono update(User existingUser, User userUpdate) { userUpdate.setPassword(passwordEncoder.encode(userUpdate.getPassword())); } - AppsmithBeanUtils.copyNewFieldValuesIntoOldObject(userUpdate, existingUser); - return repository.save(existingUser); + return repository.updateById(existingUser.getId(), userUpdate, null); } private boolean validateName(String name) { @@ -603,6 +601,8 @@ public Mono updateCurrentUser(final UserUpdateDTO allUpdates, ServerWebExc return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.NAME)); } updates.setName(inputName); + // Set policies to null to avoid overriding them. + updates.setPolicies(null); updatedUserMono = sessionUserService .getCurrentUser() .flatMap(user -> updateWithoutPermission(user.getId(), updates) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java index c41efc869570..c7cc66cc4360 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java @@ -7,6 +7,7 @@ import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; +import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.services.ApplicationPageService; import com.appsmith.server.services.MockDataService; import com.appsmith.server.services.ProductAlertService; @@ -36,7 +37,8 @@ public ConsolidatedAPIServiceCECompatibleImpl( PluginService pluginService, DatasourceService datasourceService, MockDataService mockDataService, - ObservationRegistry observationRegistry) { + ObservationRegistry observationRegistry, + CacheableRepositoryHelper cacheableRepositoryHelper) { super( sessionUserService, userService, @@ -53,6 +55,7 @@ public ConsolidatedAPIServiceCECompatibleImpl( pluginService, datasourceService, mockDataService, - observationRegistry); + observationRegistry, + cacheableRepositoryHelper); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitEventHandlerImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitEventHandlerImplTest.java index bf49502f0596..29265607ffd1 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitEventHandlerImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitEventHandlerImplTest.java @@ -442,7 +442,8 @@ public void autoCommitServerMigration_WhenServerHasNoChanges_NoCommitMade() thro doReturn(Mono.just(applicationJson1)) .when(jsonSchemaMigration) - .migrateApplicationJsonToLatestSchema(applicationJson); + .migrateApplicationJsonToLatestSchema( + Mockito.eq(applicationJson), Mockito.anyString(), Mockito.anyString()); doReturn(Mono.just("success")) .when(gitExecutor) @@ -574,7 +575,9 @@ public void autocommitServerMigration_WhenJsonSchemaMigrationPresent_CommitSucce AppsmithBeanUtils.copyNewFieldValuesIntoOldObject(applicationJson, applicationJson1); applicationJson1.setServerSchemaVersion(jsonSchemaVersions.getServerVersion() + 1); - doReturn(Mono.just(applicationJson1)).when(jsonSchemaMigration).migrateApplicationJsonToLatestSchema(any()); + doReturn(Mono.just(applicationJson1)) + .when(jsonSchemaMigration) + .migrateApplicationJsonToLatestSchema(any(), Mockito.anyString(), Mockito.anyString()); gitFileSystemTestHelper.setupGitRepository(autoCommitEvent, applicationJson); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java index 1c53aa243bb9..e18f8e66fe9b 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java @@ -284,7 +284,8 @@ public void testAutoCommit_whenOnlyServerIsEligibleForMigration_commitSuccess() doReturn(Mono.just(applicationJson1)) .when(jsonSchemaMigration) - .migrateApplicationJsonToLatestSchema(any(ApplicationJson.class)); + .migrateApplicationJsonToLatestSchema( + any(ApplicationJson.class), Mockito.anyString(), Mockito.anyString()); gitFileSystemTestHelper.setupGitRepository( WORKSPACE_ID, DEFAULT_APP_ID, BRANCH_NAME, REPO_NAME, applicationJson); @@ -571,7 +572,8 @@ public void testAutoCommit_whenAutoCommitEligibleButPrerequisiteNotComplete_retu doReturn(Mono.just(applicationJson1)) .when(jsonSchemaMigration) - .migrateApplicationJsonToLatestSchema(any(ApplicationJson.class)); + .migrateApplicationJsonToLatestSchema( + any(ApplicationJson.class), Mockito.anyString(), Mockito.anyString()); gitFileSystemTestHelper.setupGitRepository( WORKSPACE_ID, DEFAULT_APP_ID, BRANCH_NAME, REPO_NAME, applicationJson); @@ -644,7 +646,8 @@ public void testAutoCommit_whenServerIsRunningMigrationCallsAutocommitAgainOnDif doReturn(Mono.just(applicationJson1)) .when(jsonSchemaMigration) - .migrateApplicationJsonToLatestSchema(any(ApplicationJson.class)); + .migrateApplicationJsonToLatestSchema( + any(ApplicationJson.class), Mockito.anyString(), Mockito.anyString()); gitFileSystemTestHelper.setupGitRepository( WORKSPACE_ID, DEFAULT_APP_ID, BRANCH_NAME, REPO_NAME, applicationJson); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/migrations/JsonSchemaMigrationTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/migrations/JsonSchemaMigrationTest.java index d31c18fcdcbd..9fbbfbe61200 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/migrations/JsonSchemaMigrationTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/migrations/JsonSchemaMigrationTest.java @@ -97,7 +97,7 @@ public void migrateApplicationJsonToLatestSchema_whenFeatureFlagIsOn_returnsIncr gitFileSystemTestHelper.getApplicationJson(this.getClass().getResource("application.json")); Mono applicationJsonMono = - jsonSchemaMigration.migrateApplicationJsonToLatestSchema(applicationJson); + jsonSchemaMigration.migrateApplicationJsonToLatestSchema(applicationJson, null, null); StepVerifier.create(applicationJsonMono) .assertNext(appJson -> { assertThat(appJson.getServerSchemaVersion()).isEqualTo(jsonSchemaVersions.getServerVersion()); @@ -121,7 +121,7 @@ public void migrateApplicationJsonToLatestSchema_whenFeatureFlagIsOff_returnsFal gitFileSystemTestHelper.getApplicationJson(this.getClass().getResource("application.json")); Mono applicationJsonMono = - jsonSchemaMigration.migrateApplicationJsonToLatestSchema(applicationJson); + jsonSchemaMigration.migrateApplicationJsonToLatestSchema(applicationJson, null, null); StepVerifier.create(applicationJsonMono) .assertNext(appJson -> { assertThat(appJson.getClientSchemaVersion()).isEqualTo(jsonSchemaVersions.getClientVersion()); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java index 6cff70087a01..71da2c690722 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java @@ -101,7 +101,7 @@ void publishPages_WhenIdMatches_Published() { @Test void findPageWithoutBranchName() { StepVerifier.create(newPageRepository.findPageByBranchNameAndBasePageId( - null, "pageId", AclPermission.PAGE_CREATE_PAGE_ACTIONS)) + null, "pageId", AclPermission.PAGE_CREATE_PAGE_ACTIONS, null)) .verifyComplete(); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java index 716779b16535..43b0d91a0850 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java @@ -200,7 +200,8 @@ public void testCreateCollection_withRepeatedActionName_throwsError() throws IOE final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class); Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); - Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId( + Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(refactoringService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(false)); @@ -233,7 +234,8 @@ public void testCreateCollection_createActionFailure_returnsWithIncompleteCollec Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); - Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId( + Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(refactoringService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(true)); @@ -290,7 +292,8 @@ public void testCreateCollection_validCollection_returnsPopulatedCollection() th Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); - Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId( + Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(refactoringService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(true)); @@ -385,7 +388,8 @@ public void testUpdateUnpublishedActionCollection_withInvalidId_throwsError() th Mockito.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.any())) .thenReturn(Mono.empty()); - Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId( + Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java index fc702317864c..3ec766f804c9 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java @@ -863,7 +863,7 @@ public void clonePage_whenPageCloned_defaultIdsRetained() { final Mono pageMono = applicationPageService .clonePage(page.getId()) .flatMap(pageDTO -> - newPageService.findByBranchNameAndBasePageId(branchName, pageDTO.getId(), MANAGE_PAGES)) + newPageService.findByBranchNameAndBasePageId(branchName, pageDTO.getId(), MANAGE_PAGES, null)) .cache(); Mono> actionsMono = pageMono.flatMapMany( diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java index fe9647bf7dec..03b2cdd7105a 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java @@ -13,6 +13,7 @@ import com.appsmith.server.domains.TenantConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.domains.UserData; +import com.appsmith.server.domains.UserState; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.InviteUsersDTO; import com.appsmith.server.dtos.ResendEmailVerificationDTO; @@ -39,6 +40,9 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.test.annotation.DirtiesContext; @@ -748,4 +752,61 @@ public void updateNameProficiencyAndUseCaseOfUser() { }) .verifyComplete(); } + + private Mono runAs(Mono input, User user, String password) { + log.info("Running as user: {}", user.getEmail()); + return input.contextWrite((ctx) -> { + SecurityContext securityContext = new SecurityContextImpl( + new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities())); + return ctx.put(SecurityContext.class, Mono.just(securityContext)); + }); + } + + @Test + @WithUserDetails(value = "api_user") + public void testUpdateCurrentUser_shouldNotUpdatePolicies() { + String testName = "testUpdateName_shouldNotUpdatePolicies"; + User user = new User(); + user.setEmail(testName + "@test.com"); + user.setPassword(testName); + User createdUser = userService.create(user).block(); + Set policies = createdUser.getPolicies(); + + assertThat(createdUser.getName()).isNull(); + assertThat(createdUser.getPolicies()).isNotEmpty(); + + UserUpdateDTO updateUser = new UserUpdateDTO(); + updateUser.setName("Test Name"); + + User userUpdatedPostNameUpdate = runAs(userService.updateCurrentUser(updateUser, null), createdUser, testName) + .block(); + + assertThat(userUpdatedPostNameUpdate.getName()).isEqualTo("Test Name"); + userUpdatedPostNameUpdate.getPolicies().forEach(policy -> { + assertThat(policies).contains(policy); + }); + } + + @Test + @WithUserDetails(value = "api_user") + public void testUpdateWithoutPermission_shouldUpdateChangedFields() { + String testName = "testUpdateWithoutPermission_shouldUpdateChangedFields"; + User user = new User(); + user.setEmail(testName + "@test.com"); + user.setPassword(testName); + User createdUser = userService.create(user).block(); + Set policies = createdUser.getPolicies(); + + User update = new User(); + update.setName("Test Name"); + update.setState(UserState.ACTIVATED); + User updatedUser = + userService.updateWithoutPermission(createdUser.getId(), update).block(); + + assertThat(updatedUser.getName()).isEqualTo("Test Name"); + assertThat(updatedUser.getState()).isEqualTo(UserState.ACTIVATED); + policies.forEach(policy -> { + assertThat(updatedUser.getPolicies()).contains(policy); + }); + } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java index 001452bb0588..f71b19257321 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java @@ -19,6 +19,7 @@ import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.ApplicationDetail; +import com.appsmith.server.domains.ApplicationMode; import com.appsmith.server.domains.ApplicationPage; import com.appsmith.server.domains.Asset; import com.appsmith.server.domains.CustomJSLib; @@ -62,6 +63,7 @@ import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.repositories.UserRepository; +import com.appsmith.server.services.ConsolidatedAPIService; import com.appsmith.server.services.LayoutActionService; import com.appsmith.server.services.LayoutCollectionService; import com.appsmith.server.services.PermissionGroupService; @@ -124,6 +126,7 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import static com.appsmith.server.acl.AclPermission.CONNECT_TO_GIT; @@ -289,6 +292,9 @@ public class ApplicationServiceCETest { @Autowired private AssetRepository assetRepository; + @Autowired + private ConsolidatedAPIService consolidatedAPIService; + private Mono runAs(Mono input, User user) { log.info("Running as user: {}", user.getEmail()); return input.contextWrite((ctx) -> { @@ -1710,7 +1716,7 @@ public void cloneApplication_applicationWithGitMetadata_success() { Mono> srcNewPageListMono = Flux.fromIterable(gitConnectedApp.getPages()) .flatMap(applicationPage -> newPageService.findByBranchNameAndBasePageId( - branchName, applicationPage.getDefaultPageId(), READ_PAGES)) + branchName, applicationPage.getDefaultPageId(), READ_PAGES, null)) .collectList(); StepVerifier.create(Mono.zip(clonedNewPageListMono, srcNewPageListMono)) @@ -4392,4 +4398,126 @@ public void findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder_invalidWo }) .verify(); } + + @Test + @WithUserDetails(value = "api_user") + public void testCacheEviction_whenPagesDeletedInEditModeFollowedByAppPublish_shouldInvalidateCache() { + // Step 1: Initialize the test application and page identifiers + Application testApplication = new Application(); + String appName = "ApplicationServiceTest Publish Application Delete Page"; + testApplication.setName(appName); + AtomicReference basePageId1Ref = new AtomicReference<>(); + AtomicReference basePageId2Ref = new AtomicReference<>(); + + // Step 2: Create an application with a page and publish it + Mono applicationMono = applicationPageService + .createApplication(testApplication, workspaceId) + .flatMap(application -> { + // Step 2.1: Create a new page and set default layout + PageDTO page = new PageDTO(); + page.setName("New Page"); + page.setApplicationId(application.getId()); + Layout defaultLayout = newPageService.createDefaultLayout(); + List layouts = new ArrayList<>(); + layouts.add(defaultLayout); + page.setLayouts(layouts); + + // Step 2.2: Create and clone the page, then publish the application + return applicationPageService + .createPage(page) + .flatMap(page1 -> { + basePageId1Ref.set(page1.getBaseId()); + return applicationPageService + .clonePage(page1.getId()) + .flatMap(clonedPage -> { + basePageId2Ref.set(clonedPage.getId()); + return applicationPageService.publish(page1.getApplicationId(), true); + }); + }) + .then(applicationService.findById(application.getId(), MANAGE_APPLICATIONS)); + }) + .cache(); + + // Step 3: Fetch the new page and verify its existence + PageDTO newPage = applicationMono + .flatMap(application -> newPageService + .findByNameAndApplicationIdAndViewMode("New Page", application.getId(), READ_PAGES, false) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "page")))) + .block(); + + // Step 4: Assert that page IDs are not null + assertThat(basePageId1Ref.get()).isNotNull(); + assertThat(basePageId2Ref.get()).isNotNull(); + + // Step 5: Delete the pages in edit mode + applicationPageService.deleteUnpublishedPage(basePageId1Ref.get()).block(); + applicationPageService.deleteUnpublishedPage(basePageId2Ref.get()).block(); + + // Step 6: Verify basePageId1 is not cached before calling the consolidated API + String cachedBaseAppId1 = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId1Ref.get(), null) + .block(); + assertThat(cachedBaseAppId1).isNull(); + + // Step 7: Call the consolidated API to force cache update + consolidatedAPIService + .getConsolidatedInfoForPageLoad(basePageId1Ref.get(), null, null, ApplicationMode.PUBLISHED) + .block(); + + // Step 8: Verify basePageId1 is now cached after the consolidated API call + cachedBaseAppId1 = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId1Ref.get(), null) + .block(); + assertThat(cachedBaseAppId1).isNotNull(); + + // Step 9: Verify basePageId2 is not cached before calling the consolidated API + String cachedBaseAppId2 = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId2Ref.get(), null) + .block(); + assertThat(cachedBaseAppId2).isNull(); + + // Step 10: Call the consolidated API to force cache update for basePageId2 + consolidatedAPIService + .getConsolidatedInfoForPageLoad(basePageId2Ref.get(), null, null, ApplicationMode.PUBLISHED) + .block(); + + // Step 11: Verify basePageId2 is now cached after the consolidated API call + cachedBaseAppId2 = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId2Ref.get(), null) + .block(); + assertThat(cachedBaseAppId2).isNotNull(); + + // Step 12: Verify the application pages after deletion and publishing + ApplicationPage applicationPage = new ApplicationPage(); + applicationPage.setId(newPage.getId()); + applicationPage.setIsDefault(false); + applicationPage.setDefaultPageId(newPage.getId()); + + StepVerifier.create(applicationService.findById(newPage.getApplicationId(), MANAGE_APPLICATIONS)) + .assertNext(editedApplication -> { + // Step 12.1: Check the published pages and edited pages + List publishedPages = editedApplication.getPublishedPages(); + assertThat(publishedPages).size().isEqualTo(3); + assertThat(publishedPages).containsAnyOf(applicationPage); + + List editedApplicationPages = editedApplication.getPages(); + assertThat(editedApplicationPages).hasSize(1); + assertThat(editedApplicationPages).doesNotContain(applicationPage); + }) + .verifyComplete(); + + // Step 13: Publish the application again + applicationPageService.publish(newPage.getApplicationId(), true).block(); + + // Step 14: Verify that the cache entries for deleted pages are evicted + cachedBaseAppId1 = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId1Ref.get(), null) + .block(); + assertThat(cachedBaseAppId1).isNull(); + + cachedBaseAppId2 = cacheableRepositoryHelper + .fetchBaseApplicationId(basePageId2Ref.get(), null) + .block(); + assertThat(cachedBaseAppId2).isNull(); + } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ConsolidatedAPIServiceImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceImplTest.java similarity index 98% rename from app/server/appsmith-server/src/test/java/com/appsmith/server/services/ConsolidatedAPIServiceImplTest.java rename to app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceImplTest.java index c030539e9ce7..97e651a6b2ea 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ConsolidatedAPIServiceImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceImplTest.java @@ -1,4 +1,4 @@ -package com.appsmith.server.services; +package com.appsmith.server.services.ce; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.Datasource; @@ -32,6 +32,14 @@ import com.appsmith.server.plugins.base.PluginService; import com.appsmith.server.repositories.ApplicationRepository; import com.appsmith.server.repositories.NewPageRepository; +import com.appsmith.server.services.ApplicationPageService; +import com.appsmith.server.services.ConsolidatedAPIService; +import com.appsmith.server.services.MockDataService; +import com.appsmith.server.services.ProductAlertService; +import com.appsmith.server.services.SessionUserService; +import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.UserDataService; +import com.appsmith.server.services.UserService; import com.appsmith.server.themes.base.ThemeService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -225,7 +233,7 @@ public void testPageLoadResponseForViewMode() { mockNewPage.setId("mockPageId"); doReturn(Mono.just(mockNewPage)) .when(spyNewPageService) - .findByBranchNameAndBasePageId(anyString(), anyString(), any()); + .findByBranchNameAndBasePageId(anyString(), anyString(), any(), any()); doReturn(Mono.just(List.of(mockNewPage))) .when(spyApplicationPageService) @@ -268,7 +276,7 @@ public void testPageLoadResponseForViewMode() { Mono consolidatedInfoForPageLoad = consolidatedAPIService.getConsolidatedInfoForPageLoad( - "pageId", null, "branch", ApplicationMode.PUBLISHED); + "pageId123", null, "branch", ApplicationMode.PUBLISHED); StepVerifier.create(consolidatedInfoForPageLoad) .assertNext(consolidatedAPIResponseDTO -> { assertNotNull(consolidatedAPIResponseDTO.getPublishedActions()); @@ -416,7 +424,7 @@ public void testPageLoadResponseForEditMode() { mockNewPage.setApplicationId("mockApplicationId"); doReturn(Mono.just(mockNewPage)) .when(spyNewPageService) - .findByBranchNameAndBasePageId(anyString(), anyString(), any()); + .findByBranchNameAndBasePageId(anyString(), anyString(), any(), any()); doReturn(Mono.just(List.of(mockNewPage))) .when(spyApplicationPageService) @@ -721,7 +729,7 @@ public void testErrorResponseWhenAnonymousUserAccessPrivateApp() { when(mockProductAlertService.getSingleApplicableMessage()) .thenReturn(Mono.just(List.of(sampleProductAlertResponseDTO))); - when(mockNewPageRepository.findPageByBranchNameAndBasePageId(anyString(), anyString(), any())) + when(mockNewPageRepository.findPageByBranchNameAndBasePageId(anyString(), anyString(), any(), any())) .thenReturn(Mono.empty()); doReturn(Mono.empty()) .when(spyApplicationRepository) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java index ae1af27a4609..5ebba1803e6a 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java @@ -367,7 +367,7 @@ public void createPage_withValidBranch_validDefaultIds() { .flatMap(savedPage -> solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId)) .flatMap(crudPageResponseDTO -> newPageService.findByBranchNameAndBasePageId( - gitData.getBranchName(), crudPageResponseDTO.getPage().getId(), READ_PAGES)); + gitData.getBranchName(), crudPageResponseDTO.getPage().getId(), READ_PAGES, null)); StepVerifier.create(resultMono.zipWhen(newPage1 -> getActions(newPage1.getId()))) .assertNext(tuple -> { diff --git a/app/server/reactive-caching/src/main/java/com/appsmith/caching/annotations/CacheEvict.java b/app/server/reactive-caching/src/main/java/com/appsmith/caching/annotations/CacheEvict.java index 001aaa0b648a..7d307df03d8c 100644 --- a/app/server/reactive-caching/src/main/java/com/appsmith/caching/annotations/CacheEvict.java +++ b/app/server/reactive-caching/src/main/java/com/appsmith/caching/annotations/CacheEvict.java @@ -23,6 +23,13 @@ */ String key() default ""; + /** + * Array of keys for which cache entries should be evicted. + * Can be used to specify multiple keys for bulk eviction. + * If empty, a single key can be derived from the method arguments. + */ + String[] keys() default {}; + /** * Whether to evict all keys for a given cache name. */ diff --git a/app/server/reactive-caching/src/main/java/com/appsmith/caching/aspects/CacheAspect.java b/app/server/reactive-caching/src/main/java/com/appsmith/caching/aspects/CacheAspect.java index 0ef5e9410e8a..7e489e64c5d9 100644 --- a/app/server/reactive-caching/src/main/java/com/appsmith/caching/aspects/CacheAspect.java +++ b/app/server/reactive-caching/src/main/java/com/appsmith/caching/aspects/CacheAspect.java @@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.interceptor.SimpleKey; import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -19,6 +20,7 @@ import reactor.core.publisher.Mono; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; /** @@ -201,6 +203,7 @@ public Object cacheEvict(ProceedingJoinPoint joinPoint) throws Throwable { CacheEvict annotation = method.getAnnotation(CacheEvict.class); String cacheName = annotation.cacheName(); boolean all = annotation.all(); + String[] keys = annotation.keys(); // Get the array of keys Class returnType = method.getReturnType(); if (!returnType.isAssignableFrom(Mono.class)) { @@ -212,10 +215,55 @@ public Object cacheEvict(ProceedingJoinPoint joinPoint) throws Throwable { return cacheManager.evictAll(cacheName).then((Mono) joinPoint.proceed()); } + // Evict multiple keys + if (keys.length > 0) { // If there are specific keys, evict those + // Create a Flux from the array of keys and map each key to a Mono of eviction + + // Create the expression parser and evaluation context + ExpressionParser parser = new SpelExpressionParser(); + StandardEvaluationContext context = new StandardEvaluationContext(); + + // Bind method arguments to the context + String[] parameterNames = signature.getParameterNames(); + List> evictionMonos = new ArrayList<>(); + for (int i = 0; i < joinPoint.getArgs().length; i++) { + context.setVariable(parameterNames[i], joinPoint.getArgs()[i]); + } + + // Evaluate each key expression + for (String keyExpression : keys) { + // Parse and evaluate the expression + Expression expression = parser.parseExpression(keyExpression); + + Object keyObj = expression.getValue(context); + + // Handle case where the key value is a List + if (keyObj instanceof List) { + List keyList = (List) keyObj; + for (Object key : keyList) { + if (key != null) { + evictionMonos.add(cacheManager.evict(cacheName, key.toString())); + } + } + } else { + // Single key handling + if (keyObj != null) { + evictionMonos.add(cacheManager.evict(cacheName, keyObj.toString())); + } + } + } + return Flux.fromIterable(evictionMonos) + .flatMap(voidMono -> voidMono) + .collectList() + .then((Mono) joinPoint.proceed()); + } + + // Evict single key // derive key String[] parameterNames = signature.getParameterNames(); Object[] args = joinPoint.getArgs(); String key = deriveKey(annotation.key(), parameterNames, args); + // Evict key from the cache then call the original method return cacheManager.evict(cacheName, key).then((Mono) joinPoint.proceed()); } diff --git a/deploy/docker/fs/etc/supervisor/supervisord.conf b/deploy/docker/fs/etc/supervisor/supervisord.conf index e3b341fca69e..21d4f98d696a 100644 --- a/deploy/docker/fs/etc/supervisor/supervisord.conf +++ b/deploy/docker/fs/etc/supervisor/supervisord.conf @@ -39,3 +39,9 @@ command = python3 -m supervisor.appsmith_supervisor_stdout buffer_size = 10000 events = PROCESS_LOG result_handler = supervisor.appsmith_supervisor_stdout:event_handler +stdout_logfile=%(ENV_APPSMITH_LOG_DIR)s/supervisor/access-supervisor-%(ENV_HOSTNAME)s.log +stderr_logfile=%(ENV_APPSMITH_LOG_DIR)s/supervisor/error-supervisor-%(ENV_HOSTNAME)s.log +stdout_logfile_maxbytes=10MB +stderr_logfile_maxbytes=10MB +stdout_logfile_backups=10 +stderr_logfile_backups=10 diff --git a/deploy/docker/fs/opt/appsmith/JFR-recording-24-hours.sh b/deploy/docker/fs/opt/appsmith/JFR-recording-24-hours.sh new file mode 100644 index 000000000000..ea26f0247a51 --- /dev/null +++ b/deploy/docker/fs/opt/appsmith/JFR-recording-24-hours.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset +set -o noglob + +# Define the log file path +log_dir=$1 +log_file=$log_dir/loop.log + +# Ensure the log directory exists +mkdir -p $log_dir + +# Start logging +echo "Script started at $(date)" > $log_file + +echo "Sleep 180 seconds to wait for backend to be ready at $(date)" >> $log_file +sleep 180 + +# Run the loop for 24 hours (or 24 attempts) +for i in {1..24}; do + echo "Attempt $i at $(date)" >> $log_file + + location=$log_dir/heap_dumps/ad-hoc-24-hours/${HOSTNAME}/thread-profile/profile-$(date "+%Y_%m_%d_%H_%M_%S") + mkdir -p $location + echo "Created directory $location" >> $log_file + + # Get the PID of the Java process + pid=$(pgrep -f -- "-jar\sserver.jar") + echo "Found java process at $pid...." >> $log_file + if [ -z "$pid" ]; then + echo "Java process not found, skipping this attempt." >> $log_file + continue + fi + + echo "Found Java PID: $pid" >> $log_file + + # Stop any ongoing JFR recording + jcmd $pid JFR.stop name=profile || true + echo "Stopped previous JFR recording (if any)" >> $log_file + + # Start a new JFR recording + jcmd $pid JFR.start name=profile filename=$location.jfr + echo "Started new JFR recording: $location.jfr" >> $log_file + + # Wait for an hour before taking the next thread dump + echo "Sleeping for 1 hour..." >> $log_file + sleep 3600 + jcmd $pid JFR.stop name=profile || true +done >> $log_file 2>&1 & + +# Detach the process from the terminal +echo "Script disowned, running in background." >> $log_file \ No newline at end of file diff --git a/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs b/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs index c3a9fd51741b..4e6eeddc25c9 100644 --- a/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs +++ b/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs @@ -43,7 +43,7 @@ const parts = [] parts.push(` { debug - admin 127.0.0.1:2019 + admin 0.0.0.0:2019 persist_config off acme_ca_root /etc/ssl/certs/ca-certificates.crt servers { diff --git a/deploy/docker/fs/opt/appsmith/entrypoint.sh b/deploy/docker/fs/opt/appsmith/entrypoint.sh index 17eaf3a72dd6..1d5bd59fde6d 100644 --- a/deploy/docker/fs/opt/appsmith/entrypoint.sh +++ b/deploy/docker/fs/opt/appsmith/entrypoint.sh @@ -477,6 +477,14 @@ function setup_auto_heal(){ fi } +function setup_monitoring(){ + if [[ ${APPSMITH_MONITORING-} = 1 ]]; then + # By default APPSMITH_MONITORING=0 + # To enable auto heal set APPSMITH_MONITORING=1 + bash /opt/appsmith/JFR-recording-24-hours.sh $APPSMITH_LOG_DIR 2>&1 & + fi +} + print_appsmith_info(){ tr '\n' ' ' < /opt/appsmith/info.json } @@ -530,6 +538,7 @@ mkdir -p "$APPSMITH_LOG_DIR"/{supervisor,backend,cron,editor,rts,mongodb,redis,p setup_auto_heal capture_infra_details +setup_monitoring || echo true # Handle CMD command exec "$@" diff --git a/deploy/docker/fs/opt/appsmith/utils/bin/utils.js b/deploy/docker/fs/opt/appsmith/utils/bin/utils.js index 997ab2fbaf6a..8b70980adc0c 100644 --- a/deploy/docker/fs/opt/appsmith/utils/bin/utils.js +++ b/deploy/docker/fs/opt/appsmith/utils/bin/utils.js @@ -38,7 +38,7 @@ function getDburl() { let env_array = fs.readFileSync(Constants.ENV_PATH, 'utf8').toString().split("\n"); for (let i in env_array) { if (env_array[i].startsWith("APPSMITH_MONGODB_URI") || env_array[i].startsWith("APPSMITH_DB_URL")) { - dbUrl = env_array[i].toString().split("=")[1]; + dbUrl = env_array[i].toString().split("=")[1].trim(); break; // Break early when the desired line is found } } @@ -48,7 +48,7 @@ function getDburl() { let dbEnvUrl = process.env.APPSMITH_DB_URL || process.env.APPSMITH_MONGO_DB_URI; // Make sure dbEnvUrl takes precedence over dbUrl if (dbEnvUrl && dbEnvUrl !== "undefined") { - dbUrl = dbEnvUrl; + dbUrl = dbEnvUrl.trim(); } return dbUrl; }