diff --git a/.github/config.json b/.github/config.json index 9ae4641d96..5f90d48143 100644 --- a/.github/config.json +++ b/.github/config.json @@ -1 +1 @@ -{"runners":[{"versioning":{"source":"milestones","type":"SemVer"},"prereleaseName":"alpha","issue":{"labels":{"Widget design system":{"conditions":[{"label":"App Theming","type":"hasLabel","value":true},{"label":"Widget Styling","type":"hasLabel","value":true},{"label":"Checkbox Group widget","type":"hasLabel","value":true},{"label":"Checkbox Widget","type":"hasLabel","value":true},{"label":"Checkbox Component","type":"hasLabel","value":true},{"label":"WDS team","type":"hasLabel","value":true}],"requires":1},"Performance Pod":{"conditions":[{"label":"Performance","type":"hasLabel","value":true},{"label":"Performance infra","type":"hasLabel","value":true}],"requires":1},"Billing & Usage Pod":{"conditions":[{"label":"BE Instance","type":"hasLabel","value":true},{"label":"CE Instance","type":"hasLabel","value":true},{"label":"Customer Portal","type":"hasLabel","value":true},{"label":"Cloud Services","type":"hasLabel","value":true},{"label":"Billing Integrations","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":"In-app ramps","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":"1-click upgrade","type":"hasLabel","value":true}],"requires":1},"Mobile Pod":{"conditions":[],"requires":1},"Git Pod":{"conditions":[{"label":"Git Version Control","type":"hasLabel","value":true},{"label":"Import-Export-App","type":"hasLabel","value":true}],"requires":1},"Integrations Pod":{"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":"REST API plugin","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":"Datasources","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}],"requires":1},"Data Platform Pod":{"conditions":[{"label":"Datasource Environments","type":"hasLabel","value":true},{"label":"Datatype issue","type":"hasLabel","value":true},{"label":"Entity Refactor","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":"SmartSubstitution","type":"hasLabel","value":true},{"label":"Query Generation","type":"hasLabel","value":true},{"label":"Query performance","type":"hasLabel","value":true},{"label":"Suggested Widgets","type":"hasLabel","value":true},{"label":"Page load executions","type":"hasLabel","value":true},{"label":"Error Handling","type":"hasLabel","value":true},{"label":"DSL Update","type":"hasLabel","value":true},{"label":"AST-backend","type":"hasLabel","value":true},{"label":"Deploy App","type":"hasLabel","value":true},{"label":"File upload issues","type":"hasLabel","value":true}],"requires":1},"Design System Pod":{"conditions":[{"label":"Design System Pod","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}],"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}],"requires":1},"Team Managers Pod":{"conditions":[{"label":"Settings","type":"hasLabel","value":true},{"label":"Home Page","type":"hasLabel","value":true},{"label":"Invite users","type":"hasLabel","value":true},{"label":"Realtime Commenting","type":"hasLabel","value":true},{"label":"SSO","type":"hasLabel","value":true},{"label":"Multi User Realtime","type":"hasLabel","value":true},{"label":"Business Edition","type":"hasLabel","value":true},{"label":"RBAC","type":"hasLabel","value":true},{"label":"ABAC","type":"hasLabel","value":true},{"label":"Audit Logs","type":"hasLabel","value":true},{"label":"Multitenancy","type":"hasLabel","value":true},{"label":"Appsmith Business Cloud","type":"hasLabel","value":true},{"label":"Airgap","type":"hasLabel","value":true},{"label":"Enterprise Edition","type":"hasLabel","value":true},{"label":"SCIM","type":"hasLabel","value":true}],"requires":1},"New Developers Pod":{"conditions":[{"label":"Fork App","type":"hasLabel","value":true},{"label":"Omnibar","type":"hasLabel","value":true},{"label":"Onboarding","type":"hasLabel","value":true},{"label":"Telemetry","type":"hasLabel","value":true},{"label":"Entity Explorer","type":"hasLabel","value":true},{"label":"Generate Page","type":"hasLabel","value":true},{"label":"IDE","type":"hasLabel","value":true},{"label":"Sniping Mode","type":"hasLabel","value":true},{"label":"Example Apps","type":"hasLabel","value":true},{"label":"i18n","type":"hasLabel","value":true},{"label":"Welcome Screen","type":"hasLabel","value":true},{"label":"IDE Navigation","type":"hasLabel","value":true},{"label":"Login / Signup","type":"hasLabel","value":true},{"label":"Clean URLs","type":"hasLabel","value":true},{"label":"Embedding Apps","type":"hasLabel","value":true},{"label":"Feature Flagging","type":"hasLabel","value":true},{"label":"In App Comms","type":"hasLabel","value":true},{"label":"In App Comms","type":"hasLabel","value":true},{"label":"Templates","type":"hasLabel","value":true}],"requires":1},"BE Coders Pod":{"conditions":[{"label":"SAAS Plugins","type":"hasLabel","value":true},{"label":"SAAS Manager App","type":"hasLabel","value":true},{"label":"Data Platform Pod","type":"hasLabel","value":true},{"label":"Integrations Pod","type":"hasLabel","value":true}],"requires":1},"FE Coders Pod":{"conditions":[{"label":"JS Linting & Errors","type":"hasLabel","value":true},{"label":"Debugger","type":"hasLabel","value":true},{"label":"JS Snippets","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 Promises","type":"hasLabel","value":true},{"label":"JS Usability","type":"hasLabel","value":true},{"label":"Code Refactoring","type":"hasLabel","value":true},{"label":"storeValue","type":"hasLabel","value":true},{"label":"OnPageLoad","type":"hasLabel","value":true},{"label":"Framework Functions","type":"hasLabel","value":true},{"label":"Code Editor","type":"hasLabel","value":true},{"label":"JS Objects","type":"hasLabel","value":true},{"label":"JS Evaluation","type":"hasLabel","value":true},{"label":"AST-frontend","type":"hasLabel","value":true},{"label":"Custom JS Libraries","type":"hasLabel","value":true},{"label":"Action Selector","type":"hasLabel","value":true},{"label":"JS Function execution","type":"hasLabel","value":true},{"label":"Widget setter method","type":"hasLabel","value":true}],"requires":1},"App Viewers Pod":{"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":"reallabel","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":"App Navigation","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":"Branding","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":"Widget design system","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}],"requires":1},"UI Builders Pod":{"conditions":[{"label":"Property Pane","type":"hasLabel","value":true},{"label":"Pages","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":"Canvas Zooms","type":"hasLabel","value":true},{"label":"Frontend Libraries Upgrade","type":"hasLabel","value":true},{"label":"Auto Height","type":"hasLabel","value":true},{"label":"Responsive Canvas","type":"hasLabel","value":true},{"label":"Responsive Widget","type":"hasLabel","value":true},{"label":"Responsive Viewport","type":"hasLabel","value":true},{"label":"Conversion Algorithm","type":"hasLabel","value":true},{"label":"Spacing","type":"hasLabel","value":true},{"label":"Browser specific","type":"hasLabel","value":true},{"label":"widget vertical alignment","type":"hasLabel","value":true}],"requires":1},"User Education Pod":{"conditions":[{"label":"Content","type":"hasLabel","value":true},{"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":"88054d","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":"e2ca68","name":"QA","description":""},"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":"9c0c8e","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"},"Settings":{"color":"f7ff60","name":"Settings","description":"organization, team & user settings"},"Fork App":{"color":"5369db","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":""},"Onboarding":{"color":"d5794b","name":"Onboarding","description":"Issues related to onboarding new developers"},"Pages":{"color":"d7fd80","name":"Pages","description":"Issues related to configuring pages"},"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"},"Widget Styling":{"color":"905420","name":"Widget Styling","description":"all about widget styling"},"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"},"App Viewers Pod":{"color":"cd8ef9","name":"App Viewers Pod","description":"This label assigns issues to the app viewers pod"},"Checkbox Widget":{"color":"88054d","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":"d73a4a","name":"Bug","description":"Something isn't working"},"Widget Validation":{"color":"6990BC","name":"Widget Validation","description":"Issues related to widget property validation"},"Generate Page":{"color":"f14274","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":""},"Team Managers Pod":{"color":"bddb81","name":"Team Managers Pod","description":"Issues that team managers care about for the security and efficiency of their teams"},"Import-Export-App":{"color":"15076d","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":"10b5ce","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":"771e69","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"},"Critical":{"color":"9b1b28","name":"Critical","description":"This issue needs immediate attention. Drop everything else"},"IDE":{"color":"61b2ee","name":"IDE","description":"Issues related to the IDE"},"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":"f28253","name":"TestGap","description":"Issues identified for test plan improvement"},"keyboard shortcut":{"color":"0688B6","name":"keyboard shortcut","description":""},"Git Version Control":{"color":"858172","name":"Git Version Control","description":"Issues related to version control"},"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":"a2e2f9","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},"Debugger":{"color":"e79062","name":"Debugger","description":"Issues related to the debugger"},"Quick effort":{"color":"95ED65","name":"Quick effort","description":"Something that'll take a few hours to build"},"Text Widget":{"color":"d130d1","name":"Text Widget","description":""},"Video Widget":{"color":"23dd4b","name":"Video Widget","description":""},"Datasources":{"color":"2cc0d4","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"},"UI Builders Pod":{"color":"517fba","name":"UI Builders Pod","description":"Issues that UI Builders face using appsmith"},"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"},"In App Comms":{"name":"In App Comms","description":"Issues around communication with appsmith instances","color":"463cca"},"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"},"BE Coders Pod":{"color":"5d9848","name":"BE Coders Pod","description":"Issues related to users writing code to fetch and update data"},"FE Coders Pod":{"color":"a7effc","name":"FE Coders Pod","description":"Issues related to users writing javascript in appsmith"},"New Developers Pod":{"color":"6310da","name":"New Developers Pod","description":"Issues that new developers face while exploring the IDE"},"Sniping Mode":{"name":"Sniping Mode","description":"Issues related to sniping mode","color":"6310da"},"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":"12b715"},"Responsive Viewport":{"color":"d12d2e","name":"Responsive Viewport","description":"Issues seen on different viewports like mobile"},"Widgets Pane":{"name":"Widgets Pane","description":"Issues related to the discovery and organisation of widgets","color":"ad5d78"},"Invite users":{"color":"1799b0","name":"Invite users","description":"Invite users flow and any associated actions"},"View Mode":{"color":"1799b0","name":"View Mode","description":"Issues related to the view mode"},"User Education Pod":{"name":"User Education Pod","description":"Issues related to user education","color":"1799b0"},"Content":{"name":"Content","description":"For content related topics i.e blogs, templates, videos","color":"a8dff7"},"Embedding Apps":{"name":"Embedding Apps","description":"Issues related to embedding","color":"26ef4f"},"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"},"REST API plugin":{"name":"REST API plugin","description":"REST API plugin 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":"ef9c9d"},"JS Promises":{"name":"JS Promises","description":"Issues related to promises","color":"d7771f"},"OnPageLoad":{"name":"OnPageLoad","description":"OnPageLoad issues on functions and queries","color":"50559d"},"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":"3897be"},"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"},"App Theming":{"name":"App Theming","description":"Items that are related to the App level theming controls epic","color":"905420"},"SSO":{"name":"SSO","description":"Issues, requests and enhancements around Single sign-on.","color":"bf019b"},"Multi User Realtime":{"name":"Multi User Realtime","description":"Issues related to multiple users using or editing an application","color":"e7b6ce"},"Templates":{"name":"Templates","description":"Issues related to templates","color":"31a0e5"},"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"},"RBAC":{"name":"RBAC","description":"Issues, requests and enhancements around RBAC.","color":"9211c3"},"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":"55184d"},"storeValue":{"name":"storeValue","description":"Issues related to the store value function","color":"5d3e66"},"Tests":{"name":"Tests","description":"test item","color":"1c6990"},"DynamoDB":{"name":"DynamoDB","description":"Issues that are related to DynamoDB should have this label","color":"60885f"},"Design System Pod":{"name":"Design System Pod","description":"Appsmith design system related issues","color":"706f03"},"ABAC":{"color":"e009a5","name":"ABAC","description":"User permissions and access controls"},"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":"60885f"},"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":"bc0cba"},"Query performance":{"name":"Query performance","description":"Issues that have to do with lack in performance of query execution","color":"e4d966"},"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":"418fa4"},"Branding":{"name":"Branding","description":"All issues under branding and whitelabelling appsmith ecosystem","color":"7aaaf1"},"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"},"Audit Logs":{"name":"Audit Logs","description":"Audit trails to ensure data security","color":"f3fd62"},"MsSQL":{"name":"MsSQL","description":"Issues related to MsSQL plugin","color":"8078b0"},"Data Platform Pod":{"name":"Data Platform Pod","description":"Issues related to the underlying data platform","color":"3f8c3a"},"Integrations Pod":{"name":"Integrations Pod","description":"Issues related to a specific integration","color":"5dbbb1"},"Datasource Environments":{"name":"Datasource Environments","description":"Issues related to datasource environments","color":"bb7a14"},"Elastic Search":{"name":"Elastic Search","description":"Issues related to the elastic search datasource","color":"8078b0"},"Core Query Execution":{"color":"418fa4","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":"6a5b42"},"Query Settings":{"name":"Query Settings","description":"Issues related to the settings of all queries","color":"c7da7a"},"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":"e4d966"},"Query Generation":{"name":"Query Generation","description":"Issues related to query generation","color":"e4d966"},"Suggested Widgets":{"name":"Suggested Widgets","description":"Issues related to suggesting widgets based on query response","color":"e4d966"},"Page load executions":{"name":"Page load executions","description":"Issues related to page load execution","color":"5696b2"},"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"},"Git Pod":{"name":"Git Pod","description":"Anything related to git sync","color":"2e5ba4"},"Mobile Pod":{"name":"Mobile Pod","description":"All issues related to mobile responsiveness","color":"6c97fd"},"Responsive Widget":{"name":"Responsive Widget","description":"All issues related to widget responsiveness","color":"d12d2e"},"Responsive Canvas":{"name":"Responsive Canvas","description":"All issues related to canvas responsiveness","color":"45a0a8"},"Conversion Algorithm":{"name":"Conversion Algorithm","description":"All issue related to converting app from fixed to flex mode & vice versa","color":"d12d2e"},"Spacing":{"name":"Spacing","description":"All issue related to spacing between widgets in auto layout","color":"d12d2e"},"Browser specific":{"name":"Browser specific","description":"All issue related to browser","color":"d12d2e"},"Error Handling":{"name":"Error Handling","description":"Issues related to error handling","color":"6ad8d9"},"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":"434a3a"},"AST-backend":{"name":"AST-backend","description":"Backend issues related to AST parsing","color":"c476eb"},"MariaDB":{"name":"MariaDB","description":"MariaDB datasource","color":"8428c3"},"Billing & Usage Pod":{"name":"Billing & Usage Pod","description":"Issues pertaining to licensing, billing, usage across self serve and enterprise customers","color":"256808"},"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":"8154df"},"Action Selector":{"name":"Action Selector","description":"Issues related to action selector on the property pane","color":"2f9e20"},"Widget design system":{"name":"Widget design system","description":"","color":"11cc90"},"Deploy App":{"name":"Deploy App","description":"Issues related to app deployment","color":"6f6152"},"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"},"BE Instance":{"name":"BE Instance","description":"For all issues relating to usage, licensing or billing on the BE instance","color":"d2bc40"},"CE Instance":{"name":"CE Instance","description":"For all issues relating to usage, licensing or billing on the CE instance","color":"d2bc40"},"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"},"Billing Integrations":{"name":"Billing Integrations","description":"For all issues relating to 3P integrations Appsmith is using for billing & usage","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"},"Appsmith Business Cloud":{"name":"Appsmith Business Cloud","description":"Issues related to our business cloud offering","color":"1cb294"},"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"},"In-app ramps":{"name":"In-app ramps","description":"For all tasks/issues relating to adding in-app ramps in the community edition of the product","color":"8abae0"},"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"},"1-click upgrade":{"name":"1-click upgrade","description":"For all issues/tasks related to 1-click upgrade & downgrade project","color":"129082"},"Feature Flagging":{"name":"Feature Flagging","description":"Anything related feature flagging flagsmith","color":"728126"},"SCIM":{"name":"SCIM","description":"Label to collate our SCIM issues","color":"61a852"},"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"}},"success":true} \ No newline at end of file +{"runners":[{"versioning":{"source":"milestones","type":"SemVer"},"prereleaseName":"alpha","issue":{"labels":{"Widget design system":{"conditions":[{"label":"App Theming","type":"hasLabel","value":true},{"label":"Widget Styling","type":"hasLabel","value":true},{"label":"Checkbox Group widget","type":"hasLabel","value":true},{"label":"Checkbox Widget","type":"hasLabel","value":true},{"label":"Checkbox Component","type":"hasLabel","value":true},{"label":"WDS team","type":"hasLabel","value":true}],"requires":1},"Performance Pod":{"conditions":[{"label":"Performance","type":"hasLabel","value":true},{"label":"Performance infra","type":"hasLabel","value":true}],"requires":1},"Billing & Usage Pod":{"conditions":[{"label":"BE Instance","type":"hasLabel","value":true},{"label":"CE Instance","type":"hasLabel","value":true},{"label":"Customer Portal","type":"hasLabel","value":true},{"label":"Cloud Services","type":"hasLabel","value":true},{"label":"Billing Integrations","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":"In-app ramps","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":"1-click upgrade","type":"hasLabel","value":true},{"label":"Appsmith Business Cloud","type":"hasLabel","value":true}],"requires":1},"Mobile Pod":{"conditions":[],"requires":1},"Git Pod":{"conditions":[{"label":"Git Version Control","type":"hasLabel","value":true},{"label":"Import-Export-App","type":"hasLabel","value":true}],"requires":1},"Integrations Pod":{"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":"REST API plugin","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}],"requires":1},"Data Platform Pod":{"conditions":[{"label":"Datasource Environments","type":"hasLabel","value":true},{"label":"Datatype issue","type":"hasLabel","value":true},{"label":"Entity Refactor","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":"SmartSubstitution","type":"hasLabel","value":true},{"label":"Query Generation","type":"hasLabel","value":true},{"label":"Query performance","type":"hasLabel","value":true},{"label":"Suggested Widgets","type":"hasLabel","value":true},{"label":"Page load executions","type":"hasLabel","value":true},{"label":"Error Handling","type":"hasLabel","value":true},{"label":"DSL Update","type":"hasLabel","value":true},{"label":"AST-backend","type":"hasLabel","value":true},{"label":"Deploy App","type":"hasLabel","value":true},{"label":"File upload issues","type":"hasLabel","value":true},{"label":"Datasources","type":"hasLabel","value":true}],"requires":1},"Design System Pod":{"conditions":[{"label":"Design System Pod","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}],"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}],"requires":1},"Team Managers Pod":{"conditions":[{"label":"Settings","type":"hasLabel","value":true},{"label":"Home Page","type":"hasLabel","value":true},{"label":"Invite users","type":"hasLabel","value":true},{"label":"Realtime Commenting","type":"hasLabel","value":true},{"label":"SSO","type":"hasLabel","value":true},{"label":"Multi User Realtime","type":"hasLabel","value":true},{"label":"RBAC","type":"hasLabel","value":true},{"label":"ABAC","type":"hasLabel","value":true},{"label":"Audit Logs","type":"hasLabel","value":true},{"label":"Multitenancy","type":"hasLabel","value":true},{"label":"Airgap","type":"hasLabel","value":true},{"label":"Enterprise Edition","type":"hasLabel","value":true},{"label":"SCIM","type":"hasLabel","value":true}],"requires":1},"New Developers Pod":{"conditions":[{"label":"Fork App","type":"hasLabel","value":true},{"label":"Omnibar","type":"hasLabel","value":true},{"label":"Onboarding","type":"hasLabel","value":true},{"label":"Telemetry","type":"hasLabel","value":true},{"label":"Entity Explorer","type":"hasLabel","value":true},{"label":"Generate Page","type":"hasLabel","value":true},{"label":"IDE","type":"hasLabel","value":true},{"label":"Sniping Mode","type":"hasLabel","value":true},{"label":"Example Apps","type":"hasLabel","value":true},{"label":"i18n","type":"hasLabel","value":true},{"label":"Welcome Screen","type":"hasLabel","value":true},{"label":"IDE Navigation","type":"hasLabel","value":true},{"label":"Login / Signup","type":"hasLabel","value":true},{"label":"Clean URLs","type":"hasLabel","value":true},{"label":"Embedding Apps","type":"hasLabel","value":true},{"label":"Feature Flagging","type":"hasLabel","value":true},{"label":"In App Comms","type":"hasLabel","value":true},{"label":"In App Comms","type":"hasLabel","value":true},{"label":"Templates","type":"hasLabel","value":true}],"requires":1},"BE Coders Pod":{"conditions":[{"label":"SAAS Plugins","type":"hasLabel","value":true},{"label":"SAAS Manager App","type":"hasLabel","value":true},{"label":"Data Platform Pod","type":"hasLabel","value":true},{"label":"Integrations Pod","type":"hasLabel","value":true}],"requires":1},"FE Coders Pod":{"conditions":[{"label":"JS Linting & Errors","type":"hasLabel","value":true},{"label":"Debugger","type":"hasLabel","value":true},{"label":"JS Snippets","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 Promises","type":"hasLabel","value":true},{"label":"JS Usability","type":"hasLabel","value":true},{"label":"Code Refactoring","type":"hasLabel","value":true},{"label":"storeValue","type":"hasLabel","value":true},{"label":"OnPageLoad","type":"hasLabel","value":true},{"label":"Framework Functions","type":"hasLabel","value":true},{"label":"Code Editor","type":"hasLabel","value":true},{"label":"JS Objects","type":"hasLabel","value":true},{"label":"JS Evaluation","type":"hasLabel","value":true},{"label":"AST-frontend","type":"hasLabel","value":true},{"label":"Custom JS Libraries","type":"hasLabel","value":true},{"label":"Action Selector","type":"hasLabel","value":true},{"label":"JS Function execution","type":"hasLabel","value":true},{"label":"Widget setter method","type":"hasLabel","value":true}],"requires":1},"App Viewers Pod":{"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":"reallabel","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":"App Navigation","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":"Branding","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":"Widget design system","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}],"requires":1},"UI Builders Pod":{"conditions":[{"label":"Property Pane","type":"hasLabel","value":true},{"label":"Pages","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":"Canvas Zooms","type":"hasLabel","value":true},{"label":"Frontend Libraries Upgrade","type":"hasLabel","value":true},{"label":"Auto Height","type":"hasLabel","value":true},{"label":"Responsive Canvas","type":"hasLabel","value":true},{"label":"Responsive Widget","type":"hasLabel","value":true},{"label":"Responsive Viewport","type":"hasLabel","value":true},{"label":"Conversion Algorithm","type":"hasLabel","value":true},{"label":"Spacing","type":"hasLabel","value":true},{"label":"Browser specific","type":"hasLabel","value":true},{"label":"widget vertical alignment","type":"hasLabel","value":true}],"requires":1},"User Education Pod":{"conditions":[{"label":"Content","type":"hasLabel","value":true},{"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":"88054d","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":"e2ca68","name":"QA","description":""},"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":"9c0c8e","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"},"Settings":{"color":"f7ff60","name":"Settings","description":"organization, team & user settings"},"Fork App":{"color":"5369db","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":""},"Onboarding":{"color":"d5794b","name":"Onboarding","description":"Issues related to onboarding new developers"},"Pages":{"color":"d7fd80","name":"Pages","description":"Issues related to configuring pages"},"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"},"Widget Styling":{"color":"905420","name":"Widget Styling","description":"all about widget styling"},"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"},"App Viewers Pod":{"color":"cd8ef9","name":"App Viewers Pod","description":"This label assigns issues to the app viewers pod"},"Checkbox Widget":{"color":"88054d","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":"d73a4a","name":"Bug","description":"Something isn't working"},"Widget Validation":{"color":"6990BC","name":"Widget Validation","description":"Issues related to widget property validation"},"Generate Page":{"color":"f14274","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":""},"Team Managers Pod":{"color":"bddb81","name":"Team Managers Pod","description":"Issues that team managers care about for the security and efficiency of their teams"},"Import-Export-App":{"color":"15076d","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":"10b5ce","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":"771e69","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"},"Critical":{"color":"9b1b28","name":"Critical","description":"This issue needs immediate attention. Drop everything else"},"IDE":{"color":"61b2ee","name":"IDE","description":"Issues related to the IDE"},"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":"f28253","name":"TestGap","description":"Issues identified for test plan improvement"},"keyboard shortcut":{"color":"0688B6","name":"keyboard shortcut","description":""},"Git Version Control":{"color":"858172","name":"Git Version Control","description":"Issues related to version control"},"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":"a2e2f9","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},"Debugger":{"color":"e79062","name":"Debugger","description":"Issues related to the debugger"},"Quick effort":{"color":"95ED65","name":"Quick effort","description":"Something that'll take a few hours to build"},"Text Widget":{"color":"d130d1","name":"Text Widget","description":""},"Video Widget":{"color":"23dd4b","name":"Video Widget","description":""},"Datasources":{"color":"5052f6","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"},"UI Builders Pod":{"color":"517fba","name":"UI Builders Pod","description":"Issues that UI Builders face using appsmith"},"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"},"In App Comms":{"name":"In App Comms","description":"Issues around communication with appsmith instances","color":"463cca"},"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"},"BE Coders Pod":{"color":"5d9848","name":"BE Coders Pod","description":"Issues related to users writing code to fetch and update data"},"FE Coders Pod":{"color":"a7effc","name":"FE Coders Pod","description":"Issues related to users writing javascript in appsmith"},"New Developers Pod":{"color":"6310da","name":"New Developers Pod","description":"Issues that new developers face while exploring the IDE"},"Sniping Mode":{"name":"Sniping Mode","description":"Issues related to sniping mode","color":"6310da"},"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":"12b715"},"Responsive Viewport":{"color":"d12d2e","name":"Responsive Viewport","description":"Issues seen on different viewports like mobile"},"Widgets Pane":{"name":"Widgets Pane","description":"Issues related to the discovery and organisation of widgets","color":"ad5d78"},"Invite users":{"color":"1799b0","name":"Invite users","description":"Invite users flow and any associated actions"},"View Mode":{"color":"1799b0","name":"View Mode","description":"Issues related to the view mode"},"User Education Pod":{"name":"User Education Pod","description":"Issues related to user education","color":"1799b0"},"Content":{"name":"Content","description":"For content related topics i.e blogs, templates, videos","color":"a8dff7"},"Embedding Apps":{"name":"Embedding Apps","description":"Issues related to embedding","color":"26ef4f"},"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"},"REST API plugin":{"name":"REST API plugin","description":"REST API plugin 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":"ef9c9d"},"JS Promises":{"name":"JS Promises","description":"Issues related to promises","color":"d7771f"},"OnPageLoad":{"name":"OnPageLoad","description":"OnPageLoad issues on functions and queries","color":"50559d"},"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":"3897be"},"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"},"App Theming":{"name":"App Theming","description":"Items that are related to the App level theming controls epic","color":"905420"},"SSO":{"name":"SSO","description":"Issues, requests and enhancements around Single sign-on.","color":"bf019b"},"Multi User Realtime":{"name":"Multi User Realtime","description":"Issues related to multiple users using or editing an application","color":"e7b6ce"},"Templates":{"name":"Templates","description":"Issues related to templates","color":"31a0e5"},"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"},"RBAC":{"name":"RBAC","description":"Issues, requests and enhancements around RBAC.","color":"9211c3"},"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"},"Tests":{"name":"Tests","description":"test item","color":"1c6990"},"DynamoDB":{"name":"DynamoDB","description":"Issues that are related to DynamoDB should have this label","color":"60885f"},"Design System Pod":{"name":"Design System Pod","description":"Appsmith design system related issues","color":"706f03"},"ABAC":{"color":"e009a5","name":"ABAC","description":"User permissions and access controls"},"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":"60885f"},"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":"bc0cba"},"Query performance":{"name":"Query performance","description":"Issues that have to do with lack in performance of query execution","color":"e4d966"},"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":"418fa4"},"Branding":{"name":"Branding","description":"All issues under branding and whitelabelling appsmith ecosystem","color":"7aaaf1"},"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"},"Audit Logs":{"name":"Audit Logs","description":"Audit trails to ensure data security","color":"f3fd62"},"MsSQL":{"name":"MsSQL","description":"Issues related to MsSQL plugin","color":"8078b0"},"Data Platform Pod":{"name":"Data Platform Pod","description":"Issues related to the underlying data platform","color":"3f8c3a"},"Integrations Pod":{"name":"Integrations Pod","description":"Issues related to a specific integration","color":"5dbbb1"},"Datasource Environments":{"name":"Datasource Environments","description":"Issues related to datasource environments","color":"bb7a14"},"Elastic Search":{"name":"Elastic Search","description":"Issues related to the elastic search datasource","color":"8078b0"},"Core Query Execution":{"color":"418fa4","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":"6a5b42"},"Query Settings":{"name":"Query Settings","description":"Issues related to the settings of all queries","color":"c7da7a"},"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":"e4d966"},"Query Generation":{"name":"Query Generation","description":"Issues related to query generation","color":"e4d966"},"Suggested Widgets":{"name":"Suggested Widgets","description":"Issues related to suggesting widgets based on query response","color":"e4d966"},"Page load executions":{"name":"Page load executions","description":"Issues related to page load execution","color":"5696b2"},"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"},"Git Pod":{"name":"Git Pod","description":"Anything related to git sync","color":"2e5ba4"},"Mobile Pod":{"name":"Mobile Pod","description":"All issues related to mobile responsiveness","color":"6c97fd"},"Responsive Widget":{"name":"Responsive Widget","description":"All issues related to widget responsiveness","color":"d12d2e"},"Responsive Canvas":{"name":"Responsive Canvas","description":"All issues related to canvas responsiveness","color":"45a0a8"},"Conversion Algorithm":{"name":"Conversion Algorithm","description":"All issue related to converting app from fixed to flex mode & vice versa","color":"d12d2e"},"Spacing":{"name":"Spacing","description":"All issue related to spacing between widgets in auto layout","color":"d12d2e"},"Browser specific":{"name":"Browser specific","description":"All issue related to browser","color":"d12d2e"},"Error Handling":{"name":"Error Handling","description":"Issues related to error handling","color":"6ad8d9"},"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":"434a3a"},"AST-backend":{"name":"AST-backend","description":"Backend issues related to AST parsing","color":"c476eb"},"MariaDB":{"name":"MariaDB","description":"MariaDB datasource","color":"8428c3"},"Billing & Usage Pod":{"name":"Billing & Usage Pod","description":"Issues pertaining to licensing, billing, usage across self serve and enterprise customers","color":"256808"},"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":"8154df"},"Action Selector":{"name":"Action Selector","description":"Issues related to action selector on the property pane","color":"2f9e20"},"Widget design system":{"name":"Widget design system","description":"","color":"11cc90"},"Deploy App":{"name":"Deploy App","description":"Issues related to app deployment","color":"6f6152"},"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"},"BE Instance":{"name":"BE Instance","description":"For all issues relating to usage, licensing or billing on the BE instance","color":"d2bc40"},"CE Instance":{"name":"CE Instance","description":"For all issues relating to usage, licensing or billing on the CE instance","color":"d2bc40"},"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"},"Billing Integrations":{"name":"Billing Integrations","description":"For all issues relating to 3P integrations Appsmith is using for billing & usage","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"},"Appsmith Business Cloud":{"name":"Appsmith Business Cloud","description":"Issues related to our business cloud offering","color":"89bb6c"},"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"},"In-app ramps":{"name":"In-app ramps","description":"For all tasks/issues relating to adding in-app ramps in the community edition of the product","color":"8abae0"},"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"},"1-click upgrade":{"name":"1-click upgrade","description":"For all issues/tasks related to 1-click upgrade & downgrade project","color":"129082"},"Feature Flagging":{"name":"Feature Flagging","description":"Anything related feature flagging flagsmith","color":"728126"},"SCIM":{"name":"SCIM","description":"Label to collate our SCIM issues","color":"61a852"},"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"}},"success":true} \ No newline at end of file diff --git a/.github/workflows/ad-hoc-deploy-preview.yml b/.github/workflows/ad-hoc-deploy-preview.yml new file mode 100644 index 0000000000..05b94dcd4d --- /dev/null +++ b/.github/workflows/ad-hoc-deploy-preview.yml @@ -0,0 +1,243 @@ +name: Ad-hoc DP | Build Push Deploy from branch ( To be used by ops.appsmith.com API layer only) + +on: + # This workflow is only triggered by the `/build-deploy-preview` command dispatch + workflow_dispatch: + inputs: + branch: + description: "Github Branch to be deployed" + required: true + default: "release" + skip-tests: + description: "Flag to skip Cypress tests" + required: true + default: "true" + uid: + description: "Unique ID to store the run data in the db" + required: false + sub-domain-name: + description: "Sub-domain for dp.appsmith.com to by used by this deploy preview (This will also be the image name and the k8s namespace identifier)" + required: true +jobs: + # write-job-details-to-db: + # runs-on: ubuntu-latest + # steps: + # - name: Install mongosh + # run: | + # sudo apt-get update + # sudo apt-get install -y wget gnupg + # wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add - + # echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list + # sudo apt-get update + # sudo apt-get install -y mongodb-mongosh + # - name: Update job data to mongoDB + # run: | + # # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.insert( { run_id: ${{ github.run_id }}, uid: ${{ github.event.inputs.uid }}, status: "Started" } )' + # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.update( + # { _id: ${{ github.event.inputs.uid }} }, + # { + # $set: { + # run_id: ${{ github.run_id }}, + # status: "BUILD IN PROGRESS" + # } + # } + # )' + # #TODO Add mongo URI as secret + + server-build: + name: server-build + uses: ./.github/workflows/server-build.yml + secrets: inherit + with: + branch: ${{ github.event.inputs.branch }} + skip-tests: ${{ github.event.inputs.skip-tests }} + + client-build: + name: client-build + uses: ./.github/workflows/client-build.yml + secrets: inherit + with: + branch: ${{ github.event.inputs.branch }} + skip-tests: ${{ github.event.inputs.skip-tests }} + + rts-build: + name: rts-build + uses: ./.github/workflows/rts-build.yml + secrets: inherit + with: + branch: ${{ github.event.inputs.branch }} + + push-image: + needs: [client-build, rts-build, server-build] + runs-on: ubuntu-latest + if: success() + steps: + # - name: Install mongosh + # run: | + # sudo apt-get update + # sudo apt-get install -y wget gnupg + # wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add - + # echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list + # sudo apt-get update + # sudo apt-get install -y mongodb-mongosh + # - name: Update job data to mongoDB + # run: | + # # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.insert( { run_id: ${{ github.run_id }}, uid: ${{ github.event.inputs.uid }}, status: "Started" } )' + # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.update( + # { _id: ${{ github.event.inputs.uid }} }, + # { + # $set: { + # status: "BUILD SUCCESSFUL" + # } + # } + # )' + - name: Set up Depot CLI + uses: depot/setup-action@v1 + + # Check out merge commit + - name: Checkout PR + uses: actions/checkout@v3 + with: + ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "timestamp=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_OUTPUT + + # get Git-hash will be used to create cache key + - id: git_hash + run: echo "git_hash=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Download the client build artifact + uses: actions/download-artifact@v3 + with: + name: client-build + path: app/client + + - name: Unpack the client build artifact + if: steps.run_result.outputs.run_result != 'success' + run: | + mkdir -p app/client/build + tar -xvf app/client/build.tar -C app/client/build + + - name: Download the server build artifact + uses: actions/download-artifact@v3 + with: + name: server-build + path: app/server/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v3 + with: + name: rts-dist + path: app/client/packages/rts/dist + + - name: Untar the rts folder + run: | + tar -xvf app/client/packages/rts/dist/rts-dist.tar -C app/client/packages/rts/ + echo "Cleaning up the tar files" + rm app/client/packages/rts/dist/rts-dist.tar + + - name: Push to Docker Hub + uses: docker/build-push-action@v1 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + repository: ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-dp + tags: ${{ github.event.inputs.sub-domain-name }} + outputs: + imageHash: ${{ github.event.inputs.sub-domain-name }} + + build-deploy-preview: + needs: [push-image] + runs-on: ubuntu-latest + defaults: + run: + working-directory: "." + + if: success() + steps: + - name: Install mongosh + run: | + sudo apt-get update + sudo apt-get install -y wget gnupg + wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add - + echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list + sudo apt-get update + sudo apt-get install -y mongodb-mongosh + - name: Update job data to mongoDB + run: | + # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.insert( { run_id: ${{ github.run_id }}, uid: ${{ github.event.inputs.uid }}, status: "Started" } )' + # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.update( + # { _id: ${{ github.event.inputs.uid }} }, + # { + # $set: { + # status: "DEPLOYMENT IN PROGRESS" + # } + # } + # )' + - name: Set up Depot CLI + uses: depot/setup-action@v1 + - name: Checkout PR + uses: actions/checkout@v3 + with: + ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" + fetch-depth: 0 + + - name: Install relevant packages + run: | + which aws + sudo apt update -q && sudo apt install -y curl unzip less jq + curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.6/bin/linux/amd64/kubectl && \ + sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl && \ + curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && \ + chmod 700 get_helm.sh; ./get_helm.sh + + - name: Deploy Helm chart + env: + AWS_ROLE_ARN: ${{ secrets.APPSMITH_EKS_AWS_ROLE_ARN }} + AWS_ACCESS_KEY_ID: ${{ secrets.APPSMITH_CI_AWS_SECRET_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.APPSMITH_CI_AWS_SECRET_ACCESS_KEY }} + IMAGE_HASH: ${{ needs.push-image.outputs.imageHash }} + AWS_RELEASE_CERT: ${{ secrets.APPSMITH_AWS_RELEASE_CERT_RELEASE }} + DOCKER_HUB_ORGANIZATION: ${{ vars.DOCKER_HUB_ORGANIZATION }} + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + SUB_DOMAIN_NAME: ${{ github.event.inputs.sub-domain-name }} + # RECREATE: ${{ github.event.client_payload.slash_command.args.named.recreate }} + DB_USERNAME: ${{ secrets.DB_USERNAME }} + DB_PASSWORD: ${{ secrets.DB_PASSWORD }} + DB_URL: ${{ secrets.DB_URL }} + run: | + echo "environment variables set to deploy the image" $IMAGE_HASH + /bin/bash ./scripts/build_dp_form_branch.sh + + update-db-on-completion: + needs: [build-deploy-preview] + runs-on: ubuntu-latest + if: success() + steps: + - run: echo "Workflow completed successfully!" + + # This step creates a comment on the PR with a link to this workflow run. + # - name: Install mongosh + # run: | + # sudo apt-get update + # sudo apt-get install -y wget gnupg + # wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add - + # echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list + # sudo apt-get update + # sudo apt-get install -y mongodb-mongosh + # - name: Update job data to mongoDB + # run: | + # # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.insert( { run_id: ${{ github.run_id }}, uid: ${{ github.event.inputs.uid }}, status: "Started" } )' + # mongosh '' --eval 'db.appsmiht-ce-github-dp-runs.update( + # { _id: ${{ github.event.inputs.uid }} }, + # { + # $set: { + # status: "DEPLOYMENT COMPLETE" + # url: https://${{ github.event.inputs.sub-domain-name }}.dp.appsmith.com + # } + # } + # )' + diff --git a/.github/workflows/build-chromatic.yml b/.github/workflows/build-chromatic.yml index c09ca7338c..82405ee8dc 100644 --- a/.github/workflows/build-chromatic.yml +++ b/.github/workflows/build-chromatic.yml @@ -46,3 +46,4 @@ jobs: projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} workingDir: ./app/client/packages/storybook exitOnceUploaded: true + buildScriptName: "build" diff --git a/.github/workflows/build-client-server.yml b/.github/workflows/build-client-server.yml index 9295363455..d4123245a6 100644 --- a/.github/workflows/build-client-server.yml +++ b/.github/workflows/build-client-server.yml @@ -179,8 +179,8 @@ jobs: ci-test-limited-result: needs: [file-check, ci-test-limited] - # Only run if the ci-test-limited with matrices step is successful - if: needs.ci-test-limited.result != 'skipped' + # Only run if the file-check.runId == 0 + if: always() && needs.file-check.outputs.runId == '0' runs-on: ubuntu-latest defaults: run: @@ -278,8 +278,8 @@ jobs: ci-test-limited-result-existing: needs: [file-check, ci-test-limited-existing-docker-image] - # Only run if the ci-test-limited with matrices step is successful - if: needs.ci-test-limited-existing-docker-image.result != 'skipped' + # Only run if the file-check.runId !=0 + if: always() && needs.file-check.outputs.runId != '0' runs-on: ubuntu-latest defaults: run: diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 3567c9456a..0eb08e8b35 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -77,7 +77,11 @@ jobs: if: steps.run_result.outputs.run_result != 'success' working-directory: "." run: | - docker build -t cicontainer . + declare -a args + if [[ "${{ inputs.pr }}" != 0 ]]; then + args+=(--cache-from "${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-${{ vars.EDITION }}:release") + fi + docker build -t cicontainer "${args[@]}" . # Saving the docker image to tar file - name: Save Docker image to tar file diff --git a/.github/workflows/ci-test-hosted.yml b/.github/workflows/ci-test-hosted.yml new file mode 100644 index 0000000000..a8dbdbf51d --- /dev/null +++ b/.github/workflows/ci-test-hosted.yml @@ -0,0 +1,449 @@ +name: Appsmith CI Test Workflow For Hosted Instance + +on: + # Schedule to run the workflow everyday at 7 AM or UTC (1.30 AM) only on weekday + schedule: + - cron: "30 1 * * 1-5" + # This line enables manual triggering of this workflow. + workflow_dispatch: + inputs: + pr: + description: "This is the PR number in case the workflow is being called in a pull request" + required: false + type: number + default: 0 + workflow_call: + inputs: + pr: + description: "This is the PR number in case the workflow is being called in a pull request" + required: false + type: number + +jobs: + ci-test: + runs-on: ubuntu-latest + if: | + github.event.pull_request.head.repo.full_name == github.repository || + github.event_name == 'push' || + github.event_name == 'workflow_dispatch' || + github.event_name == 'repository_dispatch' || + github.event_name == 'schedule' + defaults: + run: + shell: bash + + # Service containers to run with this job. Required for running tests + services: + # Label used to access the service container + redis: + # Docker Hub image for Redis + image: redis + ports: + # Opens tcp port 6379 on the host and service container + - 6379:6379 + mongo: + image: mongo + ports: + - 27017:27017 + + steps: + - name: Set up Depot CLI + uses: depot/setup-action@v1 + + # Check out merge commit + - name: Fork based /ok-to-test checkout + if: inputs.pr != 0 + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: "refs/pull/${{ inputs.pr }}/merge" + + # Checkout the code in the current branch in case the workflow is called because of a branch push event + - name: Checkout the head commit of the branch + if: inputs.pr == 0 || github.event_name == 'schedule' + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(date +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + id: cache-appsmith + uses: actions/cache@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + - name: Get the previous run result + if: steps.cache-appsmith.outputs.cache-hit == 'true' + id: run_result + run: | + run_result_env=$(cat ~/run_result) + echo "run_result=$run_result_env" >> $GITHUB_OUTPUT + + - name: Dump steps context + env: + STEPS_CONTEXT: ${{ toJson(steps) }} + run: echo "$STEPS_CONTEXT" + + # In case this is second attempt try restoring failed tests + - name: Restore the previous failed combine result + if: steps.run_result.outputs.run_result == 'failedtest' + uses: actions/download-artifact@v3 + with: + name: failed_spec_ci + path: ~/failed_spec_ci + + # failed_spec_env will contain list of all failed specs + # We are using environment variable instead of regular to support multiline + - name: Get failed_spec + id: failed_spec + if: steps.run_result.outputs.run_result == 'failedtest' + working-directory: app/client + run: | + echo "failed_spec_env<> $GITHUB_ENV + while IFS= read -r line + do + spec_name=$(echo $line | awk -F'/' '{print $NF}') + failed_spec_env=$(find . -name $spec_name | sed 's|./||') + echo "$failed_spec_env" >> $GITHUB_ENV + done < ~/failed_spec_ci/failed_spec_ci + echo "EOF" >> $GITHUB_ENV + + - if: steps.run_result.outputs.run_result != 'success' && steps.run_result.outputs.run_result != 'failedtest' + run: echo "Starting full run" && exit 0 + + - if: steps.run_result.outputs.run_result == 'failedtest' + run: echo "Rerunning failed tests" && exit 0 + + - name: cat run_result + run: echo ${{ steps.run_result.outputs.run_result }} + + - name: Use Node.js 16.14.0 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v3 + with: + node-version: "16.14.0" + + # actions/setup-node@v3 doesn’t work properly with Yarn 3 + # when the project lives in a subdirectory: https://github.com/actions/setup-node/issues/488 + # Restoring the cache manually instead + - name: Restore Yarn cache + if: steps.run_result.outputs.run_result != 'success' + uses: actions/cache@v3 + with: + path: app/client/.yarn/cache + key: v1-yarn3-${{ hashFiles('app/client/yarn.lock') }} + restore-keys: | + v1-yarn3- + + # Install all the dependencies + - name: Install dependencies + if: steps.run_result.outputs.run_result != 'success' + working-directory: app/client + run: | + yarn install --immutable + + - name: Setting up the cypress tests + if: steps.run_result.outputs.run_result != 'success' + shell: bash + env: + APPSMITH_SSL_CERTIFICATE: ${{ secrets.APPSMITH_SSL_CERTIFICATE }} + APPSMITH_SSL_KEY: ${{ secrets.APPSMITH_SSL_KEY }} + CYPRESS_URL: ${{ secrets.CYPRESS_URL }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME3: ${{ secrets.CYPRESS_TESTUSERNAME3 }} + CYPRESS_TESTPASSWORD3: ${{ secrets.CYPRESS_TESTPASSWORD3 }} + CYPRESS_TESTUSERNAME4: ${{ secrets.CYPRESS_TESTUSERNAME4 }} + CYPRESS_TESTPASSWORD4: ${{ secrets.CYPRESS_TESTPASSWORD4 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + CYPRESS_AIRTABLE_BEARER: ${{ secrets.AIRTABLE_BEARER }} + CYPRESS_FIRESTORE_PRIVATE_KEY: ${{ secrets.FIRESTORE_PRIVATE_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET }} + CYPRESS_OAUTH_SAML_EMAIL: ${{ secrets.CYPRESS_OAUTH_SAML_EMAIL }} + CYPRESS_OAUTH_SAML_ENTITY_ID: ${{ secrets.CYPRESS_OAUTH_SAML_ENTITY_ID }} + CYPRESS_OAUTH_SAML_METADATA_URL: ${{ secrets.CYPRESS_OAUTH_SAML_METADATA_URL }} + CYPRESS_OAUTH_SAML_METADATA_XML: ${{ secrets.CYPRESS_OAUTH_SAML_METADATA_XML }} + CYPRESS_OAUTH_SAML_PUB_CERT: ${{ secrets.CYPRESS_OAUTH_SAML_PUB_CERT }} + CYPRESS_OAUTH_SAML_SSO_URL: ${{ secrets.CYPRESS_OAUTH_SAML_SSO_URL }} + CYPRESS_OAUTH_SAML_REDIRECT_URL: ${{ secrets.CYPRESS_OAUTH_SAML_REDIRECT_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_SECRET }} + CYPRESS_APPSMITH_OAUTH2_OIDC_AUTH_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_AUTH_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_TOKEN_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_TOKEN_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_USER_INFO: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_USER_INFO }} + CYPRESS_APPSMITH_OAUTH2_OIDC_JWKS_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_JWKS_URL }} + CYPRESS_EXCLUDE_TAGS: "airgap" + CYPRESS_AIRGAPPED: false + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + POSTGRES_PASSWORD: postgres + CYPRESS_VERIFY_TIMEOUT: 100000 + run: | + cd app/client + chmod a+x ./cypress/setup-test-ci.sh + ./cypress/setup-test-ci.sh + + - uses: browser-actions/setup-chrome@latest + with: + chrome-version: stable + - run: | + echo "BROWSER_PATH=$(which chrome)" >> $GITHUB_ENV + + # - name: Set Pull Request Title + # env: + # EVENT_COMMITS: ${{ toJson(github.event.commits[0].message) }} + # run: | + # echo "${{ env.EVENT_COMMITS }}" | awk -F '\\\\n' '{print $1}' + + - name: Save Git values + # pass env variables from this step to other steps + # using GitHub Actions environment file + # https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#environment-files + run: | + PR_NUMBER=${{ inputs.pr }} + echo COMMIT_INFO_BRANCH=$(git rev-parse --abbrev-ref HEAD) >> $GITHUB_ENV + echo COMMIT_INFO_MESSAGE=OkToTest run on PR# ${{ inputs.pr }} >> $GITHUB_ENV + echo COMMIT_INFO_EMAIL=$(git show -s --pretty=%ae) >> $GITHUB_ENV + echo COMMIT_INFO_AUTHOR=$(git show -s --pretty=%an) >> $GITHUB_ENV + echo COMMIT_INFO_SHA=$(git show -s --pretty=%H) >> $GITHUB_ENV + echo COMMIT_INFO_TIMESTAMP=$(git show -s --pretty=%ct) >> $GITHUB_ENV + echo COMMIT_INFO_REMOTE=$(git config --get remote.origin.url) >> $GITHUB_ENV + # delete the .git folder afterwords to use the environment values + rm -rf .git + + - name: Show Git values + run: | + echo Branch $COMMIT_INFO_BRANCH + echo Message $COMMIT_INFO_MESSAGE + echo Email $COMMIT_INFO_EMAIL + echo Author $COMMIT_INFO_AUTHOR + echo SHA $COMMIT_INFO_SHA + echo Timestamp $COMMIT_INFO_TIMESTAMP + echo Remote $COMMIT_INFO_REMOTE + + - name: Set Commit Message + env: + EVENT_COMMITS: ${{ toJson(github.event.commits[0].message) }} + run: | + if [[ ${{ github.event_name }} == 'schedule' ]]; then + echo "COMMIT_INFO_MESSAGE=Scheduled workflow run for gsheet tests" >> $GITHUB_ENV + else + echo "COMMIT_INFO_MESSAGE=$(echo \"${{ env.EVENT_COMMITS }}\" | awk -F '\\\\n' '{print $1}' | sed 's/^\"//')" >> $GITHUB_ENV + fi + + - name: Run the cypress test + if: steps.run_result.outputs.run_result != 'success' && steps.run_result.outputs.run_result != 'failedtest' + id: cypress_test + uses: cypress-io/github-action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME3: ${{ secrets.CYPRESS_TESTUSERNAME3 }} + CYPRESS_TESTPASSWORD3: ${{ secrets.CYPRESS_TESTPASSWORD3 }} + CYPRESS_TESTUSERNAME4: ${{ secrets.CYPRESS_TESTUSERNAME4 }} + CYPRESS_TESTPASSWORD4: ${{ secrets.CYPRESS_TESTPASSWORD4 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + CYPRESS_AIRTABLE_BEARER: ${{ secrets.AIRTABLE_BEARER }} + CYPRESS_FIRESTORE_PRIVATE_KEY: ${{ secrets.FIRESTORE_PRIVATE_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET }} + CYPRESS_OAUTH_SAML_EMAIL: ${{ secrets.CYPRESS_OAUTH_SAML_EMAIL }} + CYPRESS_OAUTH_SAML_ENTITY_ID: ${{ secrets.CYPRESS_OAUTH_SAML_ENTITY_ID }} + CYPRESS_OAUTH_SAML_METADATA_URL: ${{ secrets.CYPRESS_OAUTH_SAML_METADATA_URL }} + CYPRESS_OAUTH_SAML_METADATA_XML: ${{ secrets.CYPRESS_OAUTH_SAML_METADATA_XML }} + CYPRESS_OAUTH_SAML_PUB_CERT: ${{ secrets.CYPRESS_OAUTH_SAML_PUB_CERT }} + CYPRESS_OAUTH_SAML_SSO_URL: ${{ secrets.CYPRESS_OAUTH_SAML_SSO_URL }} + CYPRESS_OAUTH_SAML_REDIRECT_URL: ${{ secrets.CYPRESS_OAUTH_SAML_REDIRECT_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_SECRET }} + CYPRESS_APPSMITH_OAUTH2_OIDC_AUTH_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_AUTH_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_TOKEN_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_TOKEN_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_USER_INFO: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_USER_INFO }} + CYPRESS_APPSMITH_OAUTH2_OIDC_JWKS_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_JWKS_URL }} + CYPRESS_EXCLUDE_TAGS: "airgap" + CYPRESS_AIRGAPPED: false + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ env.COMMIT_INFO_MESSAGE }} + CYPRESS_VERIFY_TIMEOUT: 100000 + with: + browser: ${{ env.BROWSER_PATH }} + record: true + install: false + parallel: true + config-file: cypress_ci_hosted.config.ts + group: "Chrome-Fat Container tests" + spec: "cypress/e2e/GSheet/**/**/*" + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + # In case of second attempt only run failed specs + - name: Run the cypress test with failed tests + if: steps.run_result.outputs.run_result == 'failedtest' + id: cypress_test_failedtest + uses: cypress-io/github-action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME3: ${{ secrets.CYPRESS_TESTUSERNAME3 }} + CYPRESS_TESTPASSWORD3: ${{ secrets.CYPRESS_TESTPASSWORD3 }} + CYPRESS_TESTUSERNAME4: ${{ secrets.CYPRESS_TESTUSERNAME4 }} + CYPRESS_TESTPASSWORD4: ${{ secrets.CYPRESS_TESTPASSWORD4 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + CYPRESS_AIRTABLE_BEARER: ${{ secrets.AIRTABLE_BEARER }} + CYPRESS_FIRESTORE_PRIVATE_KEY: ${{ secrets.FIRESTORE_PRIVATE_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET }} + CYPRESS_OAUTH_SAML_EMAIL: ${{ secrets.CYPRESS_OAUTH_SAML_EMAIL }} + CYPRESS_OAUTH_SAML_ENTITY_ID: ${{ secrets.CYPRESS_OAUTH_SAML_ENTITY_ID }} + CYPRESS_OAUTH_SAML_METADATA_URL: ${{ secrets.CYPRESS_OAUTH_SAML_METADATA_URL }} + CYPRESS_OAUTH_SAML_METADATA_XML: ${{ secrets.CYPRESS_OAUTH_SAML_METADATA_XML }} + CYPRESS_OAUTH_SAML_PUB_CERT: ${{ secrets.CYPRESS_OAUTH_SAML_PUB_CERT }} + CYPRESS_OAUTH_SAML_SSO_URL: ${{ secrets.CYPRESS_OAUTH_SAML_SSO_URL }} + CYPRESS_OAUTH_SAML_REDIRECT_URL: ${{ secrets.CYPRESS_OAUTH_SAML_REDIRECT_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_ID: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_ID }} + CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_SECRET: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_CLIENT_SECRET }} + CYPRESS_APPSMITH_OAUTH2_OIDC_AUTH_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_AUTH_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_TOKEN_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_TOKEN_URL }} + CYPRESS_APPSMITH_OAUTH2_OIDC_USER_INFO: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_USER_INFO }} + CYPRESS_APPSMITH_OAUTH2_OIDC_JWKS_URL: ${{ secrets.CYPRESS_APPSMITH_OAUTH2_OIDC_JWKS_URL }} + CYPRESS_EXCLUDE_TAGS: "airgap" + CYPRESS_AIRGAPPED: false + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ env.COMMIT_INFO_MESSAGE }} + with: + browser: ${{ env.BROWSER_PATH }} + record: true + install: false + parallel: true + config-file: cypress_ci_hosted.config.ts + group: "Chrome-Fat Container tests" + spec: ${{ env.failed_spec_env }} + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + - name: Collect CI container logs + if: failure() + working-directory: "." + run: | + mkdir -p ~/dockerlogs + docker logs appsmith 2>&1 > ~/dockerlogs.txt + + # Upload docker logs + - name: Upload failed test list artifact + if: failure() + uses: actions/upload-artifact@v3 + with: + name: dockerlogs + path: ~/dockerlogs.txt + + # Set status = failedtest + - name: Set fail if there are test failures + if: failure() + run: | + echo "run_result=failedtest" >> $GITHUB_OUTPUT + echo "failedtest" > ~/run_result + + # add list failed tests to a file + - name: In case of test failures copy them to a file + if: failure() + run: | + cd ${{ github.workspace }}/app/client/cypress/ + find screenshots -type f \( -iname "*\(attempt 2\).png" -o -iname "*before all hook*" -o -iname "*after all hook*" \) | sed 's/screenshots/cypress\/e2e/g'| sed 's:/[^/]*$::' | sort -u > ~/failed_spec_ci + + # reset the failed_spec_ci file in case of success + - name: In case of test success reset the failed_spec_ci file + if: success() + run: | + touch ~/failed_spec_ci + + # Upload failed test list using common path for all matrix job + - name: Upload failed test list artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: failed_spec_ci + path: ~/failed_spec_ci + + # Force store previous run result to cache + - name: Store the previous run result + if: failure() + uses: actions/cache/save@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }} + + - name: get cypress url dashboard url + id: dashboard_url + if: always() + run: | + if [[ "${{steps.run_result.outputs.run_result }}" != "success" && "${{steps.run_result.outputs.run_result }}" != "failedtest" ]]; then + echo ${{ steps.cypress_test.outputs.resultsUrl }} >> ~/cypress_url + elif [[ "${{steps.run_result.outputs.run_result }}" == "failedtest" ]]; then + echo ${{ steps.cypress_test_failedtest.outputs.resultsUrl }} >> ~/cypress_url + fi + + # 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@v3 + if: failure() + with: + name: server-logs-${{ matrix.job }} + path: app/server/server-logs.log + + # Set status = success + - name: Save the status of the run + run: | + echo "run_result=success" >> $GITHUB_OUTPUT + echo "success" > ~/run_result diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index c258a3b657..9e24c30449 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -44,6 +44,12 @@ jobs: - name: Set up Depot CLI uses: depot/setup-action@v1 + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + # Check out merge commit - name: Fork based /ok-to-test checkout if: inputs.pr != 0 @@ -135,22 +141,52 @@ jobs: run: | mkdir -p cicontainerlocal/stacks/configuration/ - - name: Run Appsmith & TED docker image + - name: Run Appsmith, CS & TED docker image if: steps.run_result.outputs.run_result != 'success' working-directory: "." run: | sudo /etc/init.d/ssh stop ; mkdir -p ~/git-server/keys mkdir -p ~/git-server/repos - docker run --name test-event-driver -d -p 22:22 -p 5001:5001 -p 3306:3306 \ - -p 5432:5432 -p 28017:27017 -p 25:25 -p 5000:5000 -p 3001:3000 -p 6001:6001 --privileged --pid=host --ipc=host --volume /:/host -v ~/git-server/keys:/git-server/keys \ - -v ~/git-server/repos:/git-server/repos appsmith/test-event-driver:latest + docker run --name test-event-driver -d \ + -p 22:22 -p 5001:5001 -p 3306:3306 -p 5432:5432 -p 28017:27017 -p 25:25 -p 5000:5000 -p 3001:3000 -p 6001:6001 \ + --privileged --pid=host --ipc=host --volume /:/host -v ~/git-server/keys:/git-server/keys \ + -v ~/git-server/repos:/git-server/repos \ + appsmith/test-event-driver:latest + docker run --name cloud-services -d -p 8000:80 -p 8090:8090 \ + --privileged --pid=host --ipc=host --add-host=host.docker.internal:host-gateway\ + -e APPSMITH_CLOUD_SERVICES_MONGODB_URI=mongodb://host.docker.internal:27017 \ + -e APPSMITH_CLOUD_SERVICES_MONGODB_DATABASE=cs \ + -e APPSMITH_CLOUD_SERVICES_MONGODB_AUTH_DATABASE=admin \ + -e APPSMITH_REDIS_URL=redis://host.docker.internal:6379/ \ + -e APPSMITH_APPS_API_KEY=dummy-api-key \ + -e APPSMITH_REMOTE_API_KEY=dummy-api-key \ + -e APPSMITH_GITHUB_API_KEY=dummy-appsmith-gh-api-key \ + -e APPSMITH_JWT_SECRET=appsmith-cloud-services-jwt-secret-dummy-key \ + -e APPSMITH_ENCRYPTION_SALT=encryption-salt \ + -e APPSMITH_ENCRYPTION_PASSWORD=encryption-password \ + -e APPSMITH_CLOUD_SERVICES_URL=https://cs-dev.appsmith.com \ + -e APPSMITH_CUSTOMER_PORTAL_URL=https://dev.appsmith.com \ + -e APPSMITH_CLOUD_SERVICES_BASE_URL=https://cs-dev.appsmith.com \ + -e APPSMITH_CLOUD_SERVER_BASE_URL=https://release.app.appsmith.com \ + -e AUTH0_ISSUER_URL=https://login.release-customer.appsmith.com/ \ + -e AUTH0_CLIENT_ID=dummy-client-id \ + -e AUTH0_CLIENT_SECRET=dummy-secret-id \ + -e AUTH0_AUDIENCE_URL=https://login.local-customer.appsmith.com/ \ + -e CLOUDSERVICES_URL=cs-dev.appsmith.com \ + -e CUSTOMER_URL=dev.appsmith.com \ + -e ENTERPRISE_USER_NAME=ent-user@appsmith.com \ + -e ENTERPRISE_USER_PASSWORD=ent_user_password \ + -e ENTERPRISE_ADMIN_NAME=ent-admin@appsmith.com \ + -e ENTERPRISE_ADMIN_PASSWORD=ent_admin_password \ + appsmith/cloud-services:release cd cicontainerlocal docker run -d --name appsmith -p 80:80 -p 9001:9001 \ -v "$PWD/stacks:/appsmith-stacks" \ -e APPSMITH_DISABLE_TELEMETRY=true \ -e APPSMITH_INTERCOM_APP_ID=DUMMY_VALUE \ -e APPSMITH_CLOUD_SERVICES_BASE_URL=http://host.docker.internal:5001 \ + -e APPSMITH_CLOUD_SERVICES_SIGNATURE_BASE_URL=http://host.docker.internal:8090 \ --add-host=host.docker.internal:host-gateway --add-host=api.segment.io:host-gateway --add-host=t.appsmith.com:host-gateway \ cicontainer diff --git a/.github/workflows/client-build.yml b/.github/workflows/client-build.yml index f8cc5226d4..02914cf982 100644 --- a/.github/workflows/client-build.yml +++ b/.github/workflows/client-build.yml @@ -1,8 +1,6 @@ name: Client Build on: - # This line enables manual triggering of this workflow. - workflow_dispatch: workflow_call: inputs: pr: @@ -19,12 +17,11 @@ on: required: false type: string default: "false" + branch: + description: "This is the branch to be used for the build." + required: false + type: string - pull_request: - branches: [release, master] - paths: - - "app/client/**" - - "!app/client/cypress/manual_TestSuite/**" # Change the working directory for all the jobs in this workflow defaults: @@ -32,7 +29,7 @@ defaults: working-directory: app/client jobs: - build: + client-build: runs-on: ubuntu-latest-8-cores # Only run this workflow for internally triggered events if: | @@ -58,10 +55,16 @@ jobs: fetch-depth: 0 ref: refs/pull/${{ inputs.pr }}/merge + # Check out the specified branch in case this workflow is called by another workflow + - name: Checkout the specified branch + if: inputs.pr == 0 && inputs.branch != '' + uses: actions/checkout@v3 + with: + ref: ${{ inputs.branch }} + # Checkout the code in the current branch in case the workflow is called because of a branch push event - name: Checkout the head commit of the branch - if: inputs.pr == 0 - + if: inputs.pr == 0 && inputs.branch == '' uses: actions/checkout@v3 with: fetch-depth: 0 diff --git a/.github/workflows/client-lint.yml b/.github/workflows/client-lint.yml index 26555ec021..a8fb261db5 100644 --- a/.github/workflows/client-lint.yml +++ b/.github/workflows/client-lint.yml @@ -1,8 +1,6 @@ name: Client Lint on: - # This line enables manual triggering of this workflow. - workflow_dispatch: workflow_call: inputs: pr: @@ -15,26 +13,14 @@ on: type: string default: "false" - pull_request: - branches: [release, master] - paths: - - "app/client/**" - - "!app/client/cypress/manual_TestSuite/**" - # Change the working directory for all the jobs in this workflow defaults: run: working-directory: app/client jobs: - build: + client-lint: runs-on: ubuntu-latest-8-cores - # Only run this workflow for internally triggered events - if: | - github.event.pull_request.head.repo.full_name == github.repository || - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' || - github.event_name == 'repository_dispatch' defaults: run: working-directory: app/client @@ -47,20 +33,11 @@ jobs: # Check out merge commit with the base branch in case this workflow is invoked via pull request - name: Checkout the merged commit from PR and base branch - if: inputs.pr != 0 uses: actions/checkout@v3 with: fetch-depth: 0 ref: refs/pull/${{ inputs.pr }}/merge - # Checkout the code in the current branch in case the workflow is called because of a branch push event - - name: Checkout the head commit of the branch - if: inputs.pr == 0 - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - # In case this is second attempt try restoring status of the prior attempt from cache - name: Restore the previous run result uses: actions/cache@v3 diff --git a/.github/workflows/client-unit-tests.yml b/.github/workflows/client-unit-tests.yml index 5b693c4ad2..b92ea2d7d0 100644 --- a/.github/workflows/client-unit-tests.yml +++ b/.github/workflows/client-unit-tests.yml @@ -1,8 +1,6 @@ name: Client Unit Tests on: - # This line enables manual triggering of this workflow. - workflow_dispatch: workflow_call: inputs: pr: @@ -15,26 +13,14 @@ on: type: string default: "false" - pull_request: - branches: [release, master] - paths: - - "app/client/**" - - "!app/client/cypress/manual_TestSuite/**" - # Change the working directory for all the jobs in this workflow defaults: run: working-directory: app/client jobs: - build: + client-unit-tests: runs-on: ubuntu-latest-8-cores - # Only run this workflow for internally triggered events - if: | - github.event.pull_request.head.repo.full_name == github.repository || - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' || - github.event_name == 'repository_dispatch' defaults: run: working-directory: app/client @@ -47,20 +33,11 @@ jobs: # Check out merge commit with the base branch in case this workflow is invoked via pull request - name: Checkout the merged commit from PR and base branch - if: inputs.pr != 0 uses: actions/checkout@v3 with: fetch-depth: 0 ref: refs/pull/${{ inputs.pr }}/merge - # Checkout the code in the current branch in case the workflow is called because of a branch push event - - name: Checkout the head commit of the branch - if: inputs.pr == 0 - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - # In case this is second attempt try restoring status of the prior attempt from cache - name: Restore the previous run result uses: actions/cache@v3 diff --git a/.github/workflows/docs/integration-tests-command.md b/.github/workflows/docs/integration-tests-command.md new file mode 100644 index 0000000000..79439ea699 --- /dev/null +++ b/.github/workflows/docs/integration-tests-command.md @@ -0,0 +1,53 @@ +# Appsmith External Integration Test Workflow + +## Workflow Triggers + +This workflow is triggered by the "ok to test" command dispatch. It listens for the `repository_dispatch` event with the type `ok-to-test-command`. + +## Workflow Jobs + +### `notify` + +This job is responsible for notifying about the ongoing test run. It creates a comment on the associated pull request with details about the workflow run, commit, and links to various test results. + +### `server-build` + +The `server-build` job builds the server-side code. It uses the configuration defined in the `.github/workflows/server-build.yml` file. The job is skipped for running tests. + +### `client-build` + +The `client-build` job builds the client-side codebase. It uses the configuration from the `.github/workflows/client-build.yml` file and checks for test files. + +### `rts-build` + +The `rts-build` job builds the "rts" (real-time suggestions) package of the client-side codebase. It uses the configuration defined in the `.github/workflows/rts-build.yml` file. + +### `test-shared-modules` + +The `test-shared-modules` job runs tests for shared modules. It uses the configuration from the `.github/workflows/shared-modules.yml` file. + +### `test-appsmithctl` + +The `test-appsmithctl` job runs tests for the `appsmithctl` utility. It uses the configuration from the `.github/workflows/appsmithctl.yml` file. + +### `build-docker-image` + +The `build-docker-image` job builds and pushes the Docker image for the application. It depends on the successful completion of the `client-build`, `server-build`, and `rts-build` jobs. The Docker image is built with support for both `linux/arm64` and `linux/amd64` platforms. + +### `ci-test` + +The `ci-test` job runs continuous integration tests on the Docker image. It depends on the successful completion of the `build-docker-image` job. + +### `perf-test` + +The `perf-test` job performs performance tests on the Docker image. It depends on the successful completion of the `build-docker-image` job. + +### `ci-test-result` + +The `ci-test-result` job collects the results from the `ci-test` and `perf-test` jobs and generates a report. It always runs, and it processes the test results against known failures. The results are then added as a comment on the associated pull request. + +### `package` + +The `package` job creates a package for release. It runs only if all previous steps are successful and the reference is either the `release` or `master` branch. The package result is then marked as complete. + +Please note that this documentation is based on the information provided in the workflow file. For any specific details and further customization, refer to the actual content of the included `.yml` files for each job. diff --git a/.github/workflows/docs/quality-checks.md b/.github/workflows/docs/quality-checks.md new file mode 100644 index 0000000000..b377c95d9b --- /dev/null +++ b/.github/workflows/docs/quality-checks.md @@ -0,0 +1,60 @@ +# GitHub Workflow Documentation: Quality Checks + +## Overview + +The "Quality checks" GitHub workflow is designed to perform various quality checks on your codebase, particularly when there's a pull request targeting the "release" or "master" branches. The workflow makes use of multiple jobs, each focusing on a specific quality check task. + +## Workflow Triggers + +The workflow is triggered automatically when a pull request is opened or updated, but only for pull requests targeting the "release" or "master" branches. + +```yaml +on: + pull_request: + branches: [release, master] +``` + +## Workflow Jobs + +### `path-filter` + +The first job, named `path-filter`, filters the files changed in the pull request to determine which quality checks are applicable. It identifies files related to the server, client, and Cypress tests and sets appropriate output variables accordingly. + +Steps: + +1. Checks out the merged commit from the pull request and the base branch. +2. Uses the `dorny/paths-filter` action to filter files and set output variables for "server," "client," and "cypress" changes. + +### `server-spotless` + +This job, named `server-spotless`, performs a code formatting check on the server-side codebase. It only runs if changes related to the server were detected by the `path-filter` job. + +### `server-unit-tests` + +The `server-unit-tests` job is responsible for running unit tests on the server-side code. It runs if changes related to the server were detected by the `path-filter` job. + +### `client-build` + +The `client-build` job handles the build process for the client-side codebase. It runs if changes related to the client were detected by the `path-filter` job. + +### `client-prettier` + +The `client-prettier` job performs code formatting checks on the client-side codebase using Prettier. It runs if changes related to the client were detected by the `path-filter` job. + +### `client-unit-tests` + +The `client-unit-tests` job runs unit tests for the client-side codebase. It runs if changes related to the client were detected by the `path-filter` job. + +### `client-lint` + +The `client-lint` job checks the client-side code for linting issues. It runs if changes related to the client were detected by the `path-filter` job. + +### `qc-result` + +The final job, `qc-result`, collects the results from all the previous jobs and determines whether the quality checks passed or failed. It always runs, regardless of the results of the previous jobs. + +Steps: + +1. Uses a Bash script to check the results of each job. +2. If any of the previous jobs' results are "failure," the script echoes "Quality checks failed" and exits with an error code (1). +3. In any other non-failing scenario (skipped steps or successful steps), the script echoes "Quality checks successful" and exits with a success code (0). \ No newline at end of file diff --git a/.github/workflows/docs/test-build-docker-image.md b/.github/workflows/docs/test-build-docker-image.md new file mode 100644 index 0000000000..1bc9a8e16e --- /dev/null +++ b/.github/workflows/docs/test-build-docker-image.md @@ -0,0 +1,60 @@ +# Test, build and push Docker Image + +This GitHub workflow is triggered manually (`workflow_dispatch`) and automatically for pushes to the `release` and `master` branches. It is designed to perform various steps, including building and pushing Docker images, running tests, and creating release images. + +## Workflow Triggers + +The workflow can be manually triggered via the GitHub Actions UI by selecting "Run Workflow" from the actions dropdown. Additionally, it is triggered automatically for pushes to the `release` and `master` branches. + +```yaml +on: + workflow_dispatch: + push: + branches: [release, master] + paths: + - "app/client/**" + - "app/server/**" + - "app/client/packages/rts/**" + - "!app/client/cypress/manual_TestSuite/**" +``` + +## Workflow Jobs + +### `server-build` + +This job, named `server-build`, is responsible for building the server-side code. It uses the configuration defined in `.github/workflows/server-build.yml`. It inherits secrets from the repository. + +### `client-build` + +The `client-build` job builds the client-side codebase. It uses the configuration from `.github/workflows/client-build.yml` and inherits secrets from the repository. + +### `rts-build` + +The `rts-build` job builds the "rts" (real-time suggestions) package of the client-side codebase. It uses the configuration defined in `.github/workflows/rts-build.yml` and inherits secrets from the repository. + +### `build-docker-image` + +This job, named `build-docker-image`, creates and pushes the Docker image for the application. It is dependent on the success of the `client-build`, `server-build`, and `rts-build` jobs. The Docker image is built with two platforms: `linux/arm64` and `linux/amd64`. + +### `perf-test` + +The `perf-test` job performs performance tests on the Docker image. It depends on the successful completion of the `build-docker-image` job. + +### `ci-test` + +The `ci-test` job runs continuous integration tests on the Docker image. It depends on the successful completion of the `build-docker-image` job. + +### `ci-test-result` + +The `ci-test-result` job collects the results from the `ci-test` job and determines whether the integration tests have passed or failed. It always runs, and it is triggered under the following conditions: +- Manual workflow dispatch. +- Push event to the repository. +- Pull request review event with an approved review and originating from the same repository. + +### `package-release` + +The `package-release` job is responsible for creating a Docker image for release. It runs as soon as the docker image is ready, but only for the `release` branch. It uses OIDC token authentication between Depot and GitHub. + +### `package-master` + +The `package-master` job creates a Docker image for the `master` branch. It runs only if the tests are successful and is used for nightly builds. It uses OIDC token authentication between Depot and GitHub. \ No newline at end of file diff --git a/.github/workflows/formatting-checks.yml b/.github/workflows/formatting-checks.yml deleted file mode 100644 index 939293b9db..0000000000 --- a/.github/workflows/formatting-checks.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Formatting checks - -on: - pull_request: - branches: [release, master] - -jobs: - path-filter: - runs-on: ubuntu-latest - outputs: - server: ${{ steps.filter.outputs.server }} - client: ${{ steps.filter.outputs.client }} - steps: - # Check out merge commit with the base branch in case this workflow is invoked via pull request - - name: Checkout the merged commit from PR and base branch - uses: actions/checkout@v3 - with: - ref: refs/pull/${{ github.event.pull_request.number }}/merge - - - uses: dorny/paths-filter@v2 - id: filter - with: - filters: | - server: - - 'app/server/**' - client: - - 'app/client/**' - - server-formatting: - name: server-formatting - needs: path-filter - if: needs.path-filter.outputs.server == 'true' - uses: ./.github/workflows/server-spotless.yml - secrets: inherit - with: - pr: ${{ github.event.pull_request.number }} - - client-formatting: - name: client-formatting - needs: path-filter - if: needs.path-filter.outputs.client == 'true' - uses: ./.github/workflows/client-prettier.yml - secrets: inherit - with: - pr: ${{ github.event.pull_request.number }} - - formatting-result: - name: formatting-result - needs: [server-formatting, client-formatting] - if: always() - runs-on: ubuntu-latest - defaults: - run: - shell: bash - steps: - - name: Return status for formatting checks - run: | - if [[ "${{ needs.server-formatting.result }}" == "failure" || "${{ needs.client-formatting.result }}" == "failure" ]]; then - echo "Formatting checks failed"; - exit 1; - else - echo "Formatting checks successful"; - exit 0; - fi diff --git a/.github/workflows/integration-tests-command.yml b/.github/workflows/integration-tests-command.yml index 948da85de4..69b7e39e32 100644 --- a/.github/workflows/integration-tests-command.yml +++ b/.github/workflows/integration-tests-command.yml @@ -20,35 +20,14 @@ jobs: Commit: `${{ github.event.client_payload.slash_command.args.named.sha }}`. PR: ${{ github.event.client_payload.pull_request.number }}. Perf tests will be available at - changeset: - runs-on: ubuntu-latest - # Required permissions - permissions: - pull-requests: read - # Set job outputs to values from filter step - outputs: - backend: ${{ steps.filter.outputs.backend }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: dorny/paths-filter@v2 - id: filter - with: - base: ${{ github.event.client_payload.pull_request.base.ref }} - ref: ${{ github.event.client_payload.pull_request.head.sha }} - filters: | - backend: - - 'app/server/**' - + server-build: name: server-build - needs: [changeset] uses: ./.github/workflows/server-build.yml secrets: inherit with: pr: ${{ github.event.client_payload.pull_request.number }} - skip-tests: ${{ needs.changeset.outputs.backend == 'false' }} + skip-tests: true client-build: name: client-build @@ -158,12 +137,18 @@ jobs: path: ~/failed_spec_ci # In case for any ci job failure, create combined failed spec - - name: "combine all specs for CI" + - name: combine all specs for CI + id: combine_ci if: needs.ci-test.result != 'success' run: | echo "Debugging: failed specs in ~/failed_spec_ci/failed_spec_ci*" cat ~/failed_spec_ci/failed_spec_ci* cat ~/failed_spec_ci/failed_spec_ci* | sort -u >> ~/combined_failed_spec_ci + if [[ -z $(grep '[^[:space:]]' ~/combined_failed_spec_ci) ]] ; then + echo "specs_failed=0" >> $GITHUB_OUTPUT + else + echo "specs_failed=1" >> $GITHUB_OUTPUT + fi # Upload combined failed CI spec list to a file # This is done for debugging. @@ -191,7 +176,7 @@ jobs: echo "EOF" >> $GITHUB_ENV - name: Add a comment on the PR with new CI failures - if: needs.ci-test.result != 'success' + if: needs.ci-test.result != 'success' && steps.combine_ci.outputs.specs_failed == '1' uses: peter-evans/create-or-update-comment@v1 with: issue-number: ${{ github.event.client_payload.pull_request.number }} @@ -203,7 +188,7 @@ jobs: To know the list of identified flaky tests - Refer here - name: Add a comment on the PR when ci-test is success - if: needs.ci-test.result == 'success' + if: needs.ci-test.result == 'success' || steps.combine_ci.outputs.specs_failed == '0' uses: peter-evans/create-or-update-comment@v1 with: issue-number: ${{ github.event.client_payload.pull_request.number }} 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 52cec34e9c..8d0e5c1d33 100644 --- a/.github/workflows/on-demand-build-docker-image-deploy-preview.yml +++ b/.github/workflows/on-demand-build-docker-image-deploy-preview.yml @@ -90,17 +90,28 @@ jobs: run: vercel build --yes --token=${{ secrets.VERCEL_TOKEN }} - name: Deploy Project Artifacts to Vercel - id: set-dpurl run: | - vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} >> ~/run_result.txt - echo "::set-output name=dpurl::$(cat ~/run_result.txt)" + vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} | tee -a ~/run_result.txt - - name: vercel-notify - uses: peter-evans/create-or-update-comment@v2 + - uses: actions/github-script@v6 with: - issue-number: ${{ github.event.client_payload.pull_request.number }} - body: | - Deploy-Preview-URL: ${{ steps.set-dpurl.outputs.dpurl }} + script: | + const dpUrl = require("fs").readFileSync(process.env.HOME + "/run_result.txt", "utf8") + const bodyLines = ["Deploy-Preview-URL: " + dpUrl] + if (context.repo.repo === "appsmith") { + bodyLines.push( + "", + "🚨 *Note*: The release environment runs EE code, so using a frontend-only DP on this repo, will", + "likely behave unexpectedly. Consider using a full DP instead.", + "[Learn more](https://notion.so/031b87bce3404e3a95240d4c14c82e46).", + ) + } + github.rest.issues.createComment({ + issue_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: bodyLines.join("\n"), + }) push-image: diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml new file mode 100644 index 0000000000..aa95a2a85c --- /dev/null +++ b/.github/workflows/quality-checks.yml @@ -0,0 +1,107 @@ +name: Quality checks + +on: + pull_request: + branches: [release, master] + +jobs: + path-filter: + runs-on: ubuntu-latest + outputs: + server: ${{ steps.filter.outputs.server }} + client: ${{ steps.filter.outputs.client == 'true' && steps.filter.outputs.not-cypress-manual == 'true' }} + steps: + # Check out merge commit with the base branch in case this workflow is invoked via pull request + - name: Checkout the merged commit from PR and base branch + uses: actions/checkout@v3 + with: + ref: refs/pull/${{ github.event.pull_request.number }}/merge + + - uses: dorny/paths-filter@v2 + id: filter + with: + filters: | + server: + - 'app/server/**' + client: + - 'app/client/**' + not-cypress-manual: + - '!app/client/cypress/manual_TestSuite/**' + + server-spotless: + name: server-spotless + needs: path-filter + if: needs.path-filter.outputs.server == 'true' + uses: ./.github/workflows/server-spotless.yml + secrets: inherit + with: + pr: ${{ github.event.pull_request.number }} + + server-unit-tests: + name: server-unit-tests + needs: path-filter + if: needs.path-filter.outputs.server == 'true' + uses: ./.github/workflows/server-build.yml + secrets: inherit + with: + pr: ${{ github.event.pull_request.number }} + + client-build: + name: client-build + needs: path-filter + if: needs.path-filter.outputs.client == 'true' + uses: ./.github/workflows/client-build.yml + secrets: inherit + with: + pr: ${{ github.event.pull_request.number }} + + client-prettier: + name: client-prettier + needs: path-filter + if: needs.path-filter.outputs.client == 'true' + uses: ./.github/workflows/client-prettier.yml + secrets: inherit + with: + pr: ${{ github.event.pull_request.number }} + + client-unit-tests: + name: client-unit-tests + needs: path-filter + if: needs.path-filter.outputs.client == 'true' + uses: ./.github/workflows/client-unit-tests.yml + secrets: inherit + with: + pr: ${{ github.event.pull_request.number }} + + client-lint: + name: client-lint + needs: path-filter + if: needs.path-filter.outputs.client == 'true' + uses: ./.github/workflows/client-lint.yml + secrets: inherit + with: + pr: ${{ github.event.pull_request.number }} + + qc-result: + name: qc-result + needs: [server-spotless, server-unit-tests, client-build, client-prettier, client-unit-tests, client-lint] + if: always() + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Return status for quality checks + run: | + if [[ "${{ needs.server-spotless.result }}" == "failure" || \ + "${{ needs.server-unit-tests.result }}" == "failure" || \ + "${{ needs.client-build.result }}" == "failure" || \ + "${{ needs.client-prettier.result }}" == "failure" || \ + "${{ needs.client-unit-tests.result }}" == "failure" || \ + "${{ needs.client-lint.result }}" == "failure" ]]; then + echo "Quality checks failed"; + exit 1; + else + echo "Quality checks successful"; + exit 0; + fi diff --git a/.github/workflows/rts-build.yml b/.github/workflows/rts-build.yml index a9c60c8079..c2c82c2499 100644 --- a/.github/workflows/rts-build.yml +++ b/.github/workflows/rts-build.yml @@ -10,6 +10,10 @@ on: description: "This is the PR number in case the workflow is being called in a pull request" required: false type: number + branch: + description: "This is the branch to be used for the build." + required: false + type: string pull_request: branches: [release, master] @@ -44,9 +48,17 @@ jobs: fetch-depth: 0 ref: refs/pull/${{ inputs.pr }}/merge + # Check out the specified branch in case this workflow is called by another workflow + - name: Checkout the specified branch + if: inputs.pr == 0 && inputs.branch != '' + uses: actions/checkout@v3 + with: + ref: ${{ inputs.branch }} + + # Checkout the code in the current branch in case the workflow is called because of a branch push event - name: Checkout the head commit of the branch - if: inputs.pr == 0 + if: inputs.pr == 0 && inputs.branch == '' uses: actions/checkout@v3 with: fetch-depth: 0 diff --git a/.github/workflows/server-build.yml b/.github/workflows/server-build.yml index 948f3c6fe5..95864330fa 100644 --- a/.github/workflows/server-build.yml +++ b/.github/workflows/server-build.yml @@ -2,8 +2,6 @@ name: Appsmith Server Workflow on: - # This line enables manual triggering of this workflow. - workflow_dispatch: workflow_call: inputs: pr: @@ -15,12 +13,10 @@ on: required: false type: string default: "false" - - - pull_request: - branches: [release, master] - paths: - - "app/server/**" + branch: + description: "This is the branch to be used for the build." + required: false + type: string # Change the working directory for all the jobs in this workflow defaults: @@ -28,14 +24,8 @@ defaults: working-directory: app/server jobs: - build: + server-unit-tests: runs-on: ubuntu-latest-8-cores - # Only run this workflow for internally triggered events - if: | - github.event.pull_request.head.repo.full_name == github.repository || - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' || - github.event_name == 'repository_dispatch' # Service containers to run with this job. Required for running tests services: @@ -60,10 +50,17 @@ jobs: fetch-depth: 0 ref: refs/pull/${{ inputs.pr }}/merge + # Check out the specified branch in case this workflow is called by another workflow + - name: Checkout the specified branch + if: inputs.pr == 0 && inputs.branch != '' + uses: actions/checkout@v3 + with: + ref: ${{ inputs.branch }} + # Checkout the code in the current branch in case the workflow is called because of a branch push event - name: Check out the head commit of the branch uses: actions/checkout@v3 - if: inputs.pr == 0 + if: inputs.pr == 0 && inputs.branch == '' with: fetch-depth: 0 diff --git a/.github/workflows/test-build-docker-image.yml b/.github/workflows/test-build-docker-image.yml index 341aab2572..f81dec2849 100644 --- a/.github/workflows/test-build-docker-image.yml +++ b/.github/workflows/test-build-docker-image.yml @@ -135,37 +135,19 @@ jobs: exit 1; fi - package: - needs: ci-test + + package-release: + needs: build-docker-image runs-on: ubuntu-latest # Set permissions since we're using OIDC token authentication between Depot and GitHub permissions: contents: read id-token: write - # Run this job irrespective of tests failing, if this is the release branch; or only if the tests pass, if this is the master branch. - if: (success() && github.ref == 'refs/heads/master') || - ( always() && - ( - github.event_name == 'workflow_dispatch' || - github.event_name == 'push' || - ( - github.event_name == 'pull_request_review' && - github.event.review.state == 'approved' && - github.event.pull_request.head.repo.full_name == github.repository - ) - ) && - github.ref == 'refs/heads/release' - ) + # Run this job as soon as the docker image is ready, if this is the release branch + if: ( always() && github.ref == 'refs/heads/release' ) steps: - # Checkout the code - - name: Checkout the merged commit from PR and base branch - if: github.event_name == 'pull_request_review' - uses: actions/checkout@v3 - with: - ref: refs/pull/${{ github.event.pull_request.number }}/merge - - name: Checkout the head commit of the branch if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' uses: actions/checkout@v3 @@ -200,12 +182,6 @@ jobs: echo "Cleaning up the tar files" rm app/client/packages/rts/dist/rts-dist.tar - # Here, the GITHUB_REF is of type /refs/head/. We extract branch_name from this by removing the - # first 11 characters. This can be used to build images for several branches - - name: Get the version to tag the Docker image - id: vars - run: echo tag=$(echo ${GITHUB_REF:11}) >> $GITHUB_OUTPUT - - name: Set up Depot CLI uses: depot/setup-action@v1 @@ -216,7 +192,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Build and push release image to Docker Hub - if: success() && github.ref == 'refs/heads/release' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + if: success() uses: depot/build-push-action@v1 with: context: . @@ -225,10 +201,65 @@ jobs: build-args: | APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY_RELEASE }} tags: | - ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:${{steps.vars.outputs.tag}} + ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:release + + package-master: + needs: ci-test + runs-on: ubuntu-latest + # Set permissions since we're using OIDC token authentication between Depot and GitHub + permissions: + contents: read + id-token: write + + # Run this job irrespective of tests failing, if this is the release branch; or only if the tests pass, if this is the master branch. + if: ( success() && github.ref == 'refs/heads/master' ) + + steps: + - name: Checkout the head commit of the branch + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + uses: actions/checkout@v3 + + - name: Download the react build artifact + uses: actions/download-artifact@v3 + with: + name: client-build + path: app/client + + - name: Unpack the client build artifact + if: steps.run_result.outputs.run_result != 'success' + run: | + mkdir -p app/client/build + tar -xvf app/client/build.tar -C app/client/build + + - name: Download the server build artifact + uses: actions/download-artifact@v3 + with: + name: server-build + path: app/server/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v3 + with: + name: rts-dist + path: app/client/packages/rts/dist + + - name: Untar the rts folder + run: | + tar -xvf app/client/packages/rts/dist/rts-dist.tar -C app/client/packages/rts/ + echo "Cleaning up the tar files" + rm app/client/packages/rts/dist/rts-dist.tar + + - name: Set up Depot CLI + uses: depot/setup-action@v1 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Build and push master image to Docker Hub with commit tag - if: success() && github.ref == 'refs/heads/master' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + if: success() uses: depot/build-push-action@v1 with: context: . @@ -238,26 +269,4 @@ jobs: APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY }} tags: | ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:${{ github.sha }} - ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:nightly - - # - name: Check and push CI image to Docker Hub with commit tag - # if: success() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/release') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') - # working-directory: "." - # run: | - # if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then - # tag=nightly - # else - # tag="${{ steps.vars.outputs.tag }}" - # fi - # docker run --detach --publish 80:80 --name appsmith \ - # "${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:$tag" - # sleep 180 - # cd deploy/docker - # if bash run-test.sh; then - # echo "Fat container test passed. Pushing image." - # docker push --all-tags ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce - # else - # echo "Fat container test FAILED. Not pushing image." - # # Temporarily pushing even if test fails. - # docker push --all-tags ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce - # fi + ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-ce:nightly \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0b95883070..87ae028399 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN curl --silent --show-error --location https://www.mongodb.org/static/pgp/ser && echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list \ && curl --silent --show-error --location https://deb.nodesource.com/setup_16.x | bash - \ && echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list \ - && curl --silent --show-error --location https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ + && curl --silent --show-error --location https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ && apt update \ && apt-get install --no-install-recommends --yes mongodb-org=5.0.14 nodejs redis build-essential postgresql-13 \ && apt-get clean \ @@ -51,6 +51,10 @@ VOLUME [ "/appsmith-stacks" ] # Add backend server - Application Layer ARG JAR_FILE=./app/server/dist/server-*.jar ARG PLUGIN_JARS=./app/server/dist/plugins/*.jar + +ARG APPSMITH_CLOUD_SERVICES_BASE_URL +ENV APPSMITH_CLOUD_SERVICES_BASE_URL=${APPSMITH_CLOUD_SERVICES_BASE_URL} + ARG APPSMITH_SEGMENT_CE_KEY ENV APPSMITH_SEGMENT_CE_KEY=${APPSMITH_SEGMENT_CE_KEY} #Create the plugins directory diff --git a/README.md b/README.md index 7cba1f0d9e..de427bb0ba 100644 --- a/README.md +++ b/README.md @@ -182,8 +182,8 @@ Lets build great software together. [![aswathkk](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/10436935?v=4&w=50&h=50&mask=circle)](https://github.com/aswathkk) [![sbalaji1192](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5328605?v=4&w=50&h=50&mask=circle)](https://github.com/sbalaji1192) [![SatishGandham](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/441914?v=4&w=50&h=50&mask=circle)](https://github.com/SatishGandham) -[![rahulramesha](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/71900764?v=4&w=50&h=50&mask=circle)](https://github.com/rahulramesha) [![sarojsarab](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/43822041?v=4&w=50&h=50&mask=circle)](https://github.com/sarojsarab) +[![rahulramesha](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/71900764?v=4&w=50&h=50&mask=circle)](https://github.com/rahulramesha) [![prsidhu](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/5424788?v=4&w=50&h=50&mask=circle)](https://github.com/prsidhu) [![yatinappsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/84702014?v=4&w=50&h=50&mask=circle)](https://github.com/yatinappsmith) [![somangshu](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/11089579?v=4&w=50&h=50&mask=circle)](https://github.com/somangshu) @@ -191,26 +191,26 @@ Lets build great software together. [![pranavkanade](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13262095?v=4&w=50&h=50&mask=circle)](https://github.com/pranavkanade) [![AmanAgarwal041](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/7565635?v=4&w=50&h=50&mask=circle)](https://github.com/AmanAgarwal041) [![Parthvi12](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/80334441?v=4&w=50&h=50&mask=circle)](https://github.com/Parthvi12) -[![albinAppsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/87797149?v=4&w=50&h=50&mask=circle)](https://github.com/albinAppsmith) [![ayushpahwa](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8526215?v=4&w=50&h=50&mask=circle)](https://github.com/ayushpahwa) +[![albinAppsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/87797149?v=4&w=50&h=50&mask=circle)](https://github.com/albinAppsmith) [![marks0351](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/35134347?v=4&w=50&h=50&mask=circle)](https://github.com/marks0351) [![berzerkeer](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/74818788?v=4&w=50&h=50&mask=circle)](https://github.com/berzerkeer) [![sneha122](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/30018882?v=4&w=50&h=50&mask=circle)](https://github.com/sneha122) +[![pratapaprasanna](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/15846947?v=4&w=50&h=50&mask=circle)](https://github.com/pratapaprasanna) [![ashit-rath](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/88306433?v=4&w=50&h=50&mask=circle)](https://github.com/ashit-rath) [![keyurparalkar](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/14138515?v=4&w=50&h=50&mask=circle)](https://github.com/keyurparalkar) -[![pratapaprasanna](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/15846947?v=4&w=50&h=50&mask=circle)](https://github.com/pratapaprasanna) [![Vijetha-Kaja](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/119562824?v=4&w=50&h=50&mask=circle)](https://github.com/Vijetha-Kaja) [![ChandanBalajiBP](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/104058110?v=4&w=50&h=50&mask=circle)](https://github.com/ChandanBalajiBP) [![vishnu-gp](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/9128194?v=4&w=50&h=50&mask=circle)](https://github.com/vishnu-gp) [![areyabhishek](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/30255708?v=4&w=50&h=50&mask=circle)](https://github.com/areyabhishek) [![nsarupr](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20905988?v=4&w=50&h=50&mask=circle)](https://github.com/nsarupr) -[![dhruvikn](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22471214?v=4&w=50&h=50&mask=circle)](https://github.com/dhruvikn) -[![sum35h](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20785806?v=4&w=50&h=50&mask=circle)](https://github.com/sum35h) [![sondermanish](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/107841575?v=4&w=50&h=50&mask=circle)](https://github.com/sondermanish) +[![sum35h](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20785806?v=4&w=50&h=50&mask=circle)](https://github.com/sum35h) +[![dhruvikn](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/22471214?v=4&w=50&h=50&mask=circle)](https://github.com/dhruvikn) [![NilanshBansal](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25542733?v=4&w=50&h=50&mask=circle)](https://github.com/NilanshBansal) +[![rajatagrawal](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1189106?v=4&w=50&h=50&mask=circle)](https://github.com/rajatagrawal) [![megaconfidence](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/17744578?v=4&w=50&h=50&mask=circle)](https://github.com/megaconfidence) [![tanvibhakta](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13763558?v=4&w=50&h=50&mask=circle)](https://github.com/tanvibhakta) -[![rajatagrawal](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/1189106?v=4&w=50&h=50&mask=circle)](https://github.com/rajatagrawal) [![subrata71](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/3524599?v=4&w=50&h=50&mask=circle)](https://github.com/subrata71) [![Druthi](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20187542?v=4&w=50&h=50&mask=circle)](https://github.com/Druthi) [![ichik](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/80973?v=4&w=50&h=50&mask=circle)](https://github.com/ichik) @@ -218,17 +218,17 @@ Lets build great software together. [![vsvamsi1](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/121419957?v=4&w=50&h=50&mask=circle)](https://github.com/vsvamsi1) [![rahulbarwal](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/6761673?v=4&w=50&h=50&mask=circle)](https://github.com/rahulbarwal) [![ankitsrivas14](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/67647761?v=4&w=50&h=50&mask=circle)](https://github.com/ankitsrivas14) +[![tkAppsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/131347120?v=4&w=50&h=50&mask=circle)](https://github.com/tkAppsmith) [![dipyamanbiswas07](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/26247571?v=4&w=50&h=50&mask=circle)](https://github.com/dipyamanbiswas07) [![rohitagarwal88](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/890915?v=4&w=50&h=50&mask=circle)](https://github.com/rohitagarwal88) -[![tkAppsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/131347120?v=4&w=50&h=50&mask=circle)](https://github.com/tkAppsmith) [![brayn003](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/8724051?v=4&w=50&h=50&mask=circle)](https://github.com/brayn003) [![ramsaptami](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/79509062?v=4&w=50&h=50&mask=circle)](https://github.com/ramsaptami) [![Pranay105](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/48308728?v=4&w=50&h=50&mask=circle)](https://github.com/Pranay105) [![gitstart-appsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/114667275?v=4&w=50&h=50&mask=circle)](https://github.com/gitstart-appsmith) [![rohan-arthur](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/94514895?v=4&w=50&h=50&mask=circle)](https://github.com/rohan-arthur) +[![sharanya-appsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/135708039?v=4&w=50&h=50&mask=circle)](https://github.com/sharanya-appsmith) [![vivonk](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/25587962?v=4&w=50&h=50&mask=circle)](https://github.com/vivonk) [![kocharrahul7](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/20532920?v=4&w=50&h=50&mask=circle)](https://github.com/kocharrahul7) -[![sharanya-appsmith](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/135708039?v=4&w=50&h=50&mask=circle)](https://github.com/sharanya-appsmith) [![abm17](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/13333024?v=4&w=50&h=50&mask=circle)](https://github.com/abm17) [![jacquesikot](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/40626453?v=4&w=50&h=50&mask=circle)](https://github.com/jacquesikot) [![RakshaKShetty](https://images.weserv.nl/?url=https://avatars.githubusercontent.com/u/45958978?v=4&w=50&h=50&mask=circle)](https://github.com/RakshaKShetty) diff --git a/app/client/cypress/e2e/GSheet/AllAccess_Spec.ts b/app/client/cypress/e2e/GSheet/AllAccess_Spec.ts new file mode 100644 index 0000000000..60e3046e1b --- /dev/null +++ b/app/client/cypress/e2e/GSheet/AllAccess_Spec.ts @@ -0,0 +1,300 @@ +/// +import { GSHEET_DATA } from "../../fixtures/test-data-gsheet"; +import { + homePage, + gsheetHelper, + dataSources, + agHelper, + entityExplorer, +} from "../../support/Objects/ObjectsCore"; + +const workspaceName = "gsheet apps"; +const dataSourceName = "gsheet"; +let appName = "gsheet-app"; +let spreadSheetName = "test-sheet"; +describe("GSheet-Functional Tests With All Access", function () { + before("Setup app and spreadsheet", function () { + //Add a new app and an add new spreadsheet query + //Setting up the spreadsheet name + const uuid = Cypress._.random(0, 10000); + spreadSheetName = spreadSheetName + "_" + uuid; + appName = appName + "-" + uuid; + + //Adding query to insert a new spreadsheet + homePage.NavigateToHome(); + homePage.CreateAppInWorkspace(workspaceName); + homePage.RenameApplication(appName); + gsheetHelper.AddNewSpreadsheetQuery( + dataSourceName, + spreadSheetName, + JSON.stringify([GSHEET_DATA[0]]), + ); + cy.get("@postExecute").then((interception: any) => { + expect( + interception.response.body.data.body.properties.title, + ).to.deep.equal(spreadSheetName); + }); + }); + + it("1. Add and verify fetch details query", () => { + entityExplorer.CreateNewDsQuery(dataSourceName); + agHelper.RenameWithInPane("Fetch_Details"); + dataSources.ValidateNSelectDropdown( + "Operation", + "Fetch Many", + "Fetch Details", + ); + dataSources.ValidateNSelectDropdown("Entity", "Spreadsheet"); + agHelper.Sleep(500); + dataSources.ValidateNSelectDropdown("Spreadsheet", "", spreadSheetName); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.name).to.deep.equal( + spreadSheetName, + ); + }); + }); + + it("2. Verify Insert one and Insert many queries", () => { + // add insert one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert One", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA[1]), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Inserted row successfully!", + ); + }); + + // add insert many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert Many", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(2, 10)), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Inserted rows successfully!", + ); + }); + }); + + it("3. Verify Update one and Update many queries", () => { + // add update one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update One", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA[1]), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Updated sheet successfully!", + ); + }); + + // add update many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update Many", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(2, 4)), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Updated sheet successfully!", + ); + }); + }); + + it("4. Verify Fetch many query", () => { + // Add simple Fetch many query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName, + spreadSheetName, + ); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].uniq_id); + dataSources.AssertQueryTableResponse(1, "ホーンビィ 2014 カタログ"); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + + // Update query to fetch only 1 column and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].product_name); + + //Remove column filter and add Sort By Ascending and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); //unselect the Columns dd value + agHelper.EnterValue("price", { + propFieldName: "", + directInput: false, + inputFieldName: "Sort By", + }); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, "5afbaf65680c9f378af5b3a3ae22427e"); + dataSources.AssertQueryTableResponse( + 1, + "ラーニング カーブ チャギントン インタラクティブ チャッツワース", + ); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + + // Sort by descending and verify + dataSources.ClearSortByOption(); //clearing previous sort option + dataSources.EnterSortByValues("price", "Descending"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse( + 1, + "ホーンビー ゲージ ウェスタン エクスプレス デジタル トレイン セット (eLink および TTS ロコ トレイン セット付き)", + ); // Asserting other language + dataSources.AssertQueryTableResponse( + 4, + "Hornby Gauge Western Express Digital Train Set with eLink and TTS Loco Train Set", + ); + + // Filter by where clause and verify + agHelper.TypeDynamicInputValueNValidate( + "price", + dataSources._nestedWhereClauseKey(0), + ); + agHelper.TypeDynamicInputValueNValidate( + "100", + dataSources._nestedWhereClauseValue(0), + ); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(8); + dataSources.AssertQueryTableResponse(0, "87bbb472ef9d90dcef140a551665c929"); + + // Currently commenting this until https://github.com/appsmithorg/appsmith/issues/25447 is fixed. + // Filter by cell range and verify + // dataSources.ValidateNSelectDropdown( + // "Filter Format", + // "Where Clause", + // "Cell range", + // ); + // agHelper.EnterValue("A2:A5", { + // propFieldName: "", + // directInput: false, + // inputFieldName: "Cell range", + // }); + // dataSources.RunQuery(); + // dataSources.RunQueryNVerifyResponseViews(8); + // dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("5. Update a record which is not present and verify the error", () => { + //preparing data + let data = GSHEET_DATA[1]; + data.rowIndex = "15"; + + // add update one query and verify + gsheetHelper.EnterBasicQueryValues( + "Update One", + dataSourceName, + spreadSheetName, + false, + ); + agHelper.EnterValue(JSON.stringify(data), { + propFieldName: "", + directInput: false, + inputFieldName: "Update row object", + }); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "No data found at this row index.", + ); + }); + }); + + it("6. Convert field to JS and verify", () => { + // Switch js on sheet name then run query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName, + spreadSheetName, + false, + ); + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + + //Enter a wrong sheet name then run query and verify + agHelper.EnterValue("Sheet 2", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Unable to parse range: 'Sheet 2'!1:1", + ); + }); + + //Covert sheet name field to dropdown then run query and verify + agHelper.HoverElement(dataSources._getJSONswitchLocator("Sheet name")); + agHelper.AssertTooltip("Clear the field to toggle back"); + agHelper.EnterValue("", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); //Clearing the sheet name field + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); // Converting the field to dropdown + dataSources.ValidateNSelectDropdown("Sheet name", "", "Sheet1"); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("7. Verify Delete query", function () { + // Delete spreadsheet and app + gsheetHelper.EnterBasicQueryValues( + "Delete One", + dataSourceName, + spreadSheetName, + ); + agHelper.EnterValue(GSHEET_DATA[0].rowIndex, { + propFieldName: "", + directInput: false, + inputFieldName: "Row Index", + }); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted row successfully!", + ); + }); + }); + + after("Delete spreadsheet and app", function () { + // Delete spreadsheet and app + gsheetHelper.DeleteSpreadsheetQuery(dataSourceName, spreadSheetName); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted spreadsheet successfully!", + ); + }); + homePage.NavigateToHome(); + homePage.DeleteApplication(appName); + }); +}); diff --git a/app/client/cypress/e2e/GSheet/ReadNWrite_Access_Spec.ts b/app/client/cypress/e2e/GSheet/ReadNWrite_Access_Spec.ts new file mode 100644 index 0000000000..a3743dea56 --- /dev/null +++ b/app/client/cypress/e2e/GSheet/ReadNWrite_Access_Spec.ts @@ -0,0 +1,314 @@ +/// +import { GSHEET_DATA } from "../../fixtures/test-data-gsheet"; +import { + homePage, + gsheetHelper, + dataSources, + agHelper, + entityExplorer, +} from "../../support/Objects/ObjectsCore"; + +describe("GSheet-Functional Tests With Read/Write Access", function () { + const workspaceName = "gsheet apps"; + const dataSourceName = { + allAccess: "gsheet", + readNWrite: "gsheet-read-write", + }; + let appName = "gsheet-app"; + let spreadSheetName = "test-sheet"; + + before("Setup app and spreadsheet", function () { + //Add a new app and an add new spreadsheet query + //Setting up the spreadsheet name + const uuid = Cypress._.random(0, 10000); + spreadSheetName = spreadSheetName + "_" + uuid; + appName = appName + "-" + uuid; + + //Adding query to insert a new spreadsheet + homePage.NavigateToHome(); + homePage.CreateAppInWorkspace(workspaceName); + homePage.RenameApplication(appName); + gsheetHelper.AddNewSpreadsheetQuery( + dataSourceName.readNWrite, + spreadSheetName, + JSON.stringify([GSHEET_DATA[0]]), + ); + cy.get("@postExecute").then((interception: any) => { + expect( + interception.response.body.data.body.properties.title, + ).to.deep.equal(spreadSheetName); + }); + }); + + it("1. Add and verify fetch details query", () => { + entityExplorer.CreateNewDsQuery(dataSourceName.readNWrite); + agHelper.RenameWithInPane("Fetch_Details"); + dataSources.ValidateNSelectDropdown( + "Operation", + "Fetch Many", + "Fetch Details", + ); + dataSources.ValidateNSelectDropdown("Entity", "Spreadsheet"); + agHelper.Sleep(500); + dataSources.ValidateNSelectDropdown("Spreadsheet", "", spreadSheetName); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.name).to.deep.equal( + spreadSheetName, + ); + }); + }); + + it("2. Verify Insert one and Insert many queries", () => { + // add insert one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert One", + dataSourceName.readNWrite, + spreadSheetName, + JSON.stringify(GSHEET_DATA[1]), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Inserted row successfully!", + ); + }); + // add insert many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert Many", + dataSourceName.readNWrite, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(2, 10)), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Inserted rows successfully!", + ); + }); + }); + + it("3. Verify Update one and Update many queries", () => { + // add update one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update One", + dataSourceName.readNWrite, + spreadSheetName, + JSON.stringify(GSHEET_DATA[1]), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Updated sheet successfully!", + ); + }); + // add update many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update Many", + dataSourceName.readNWrite, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(2, 4)), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Updated sheet successfully!", + ); + }); + }); + + it("4. Verify Fetch many query", () => { + // Add simple Fetch many query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName.readNWrite, + spreadSheetName, + ); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].uniq_id); + dataSources.AssertQueryTableResponse(1, "ホーンビィ 2014 カタログ"); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + // Update query to fetch only 1 column and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].product_name); + //Remove column filter and add Sort By Ascending and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); //unselect the Columns dd value + agHelper.EnterValue("price", { + propFieldName: "", + directInput: false, + inputFieldName: "Sort By", + }); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, "5afbaf65680c9f378af5b3a3ae22427e"); + dataSources.AssertQueryTableResponse( + 1, + "ラーニング カーブ チャギントン インタラクティブ チャッツワース", + ); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + // Sort by descending and verify + dataSources.ClearSortByOption(); //clearing previous sort option + dataSources.EnterSortByValues("price", "Descending"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse( + 1, + "ホーンビー ゲージ ウェスタン エクスプレス デジタル トレイン セット (eLink および TTS ロコ トレイン セット付き)", + ); // Asserting other language + dataSources.AssertQueryTableResponse( + 4, + "Hornby Gauge Western Express Digital Train Set with eLink and TTS Loco Train Set", + ); + // Filter by where clause and verify + agHelper.TypeDynamicInputValueNValidate( + "price", + dataSources._nestedWhereClauseKey(0), + ); + agHelper.TypeDynamicInputValueNValidate( + "100", + dataSources._nestedWhereClauseValue(0), + ); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(8); + dataSources.AssertQueryTableResponse(0, "87bbb472ef9d90dcef140a551665c929"); + // Currently commenting this until https://github.com/appsmithorg/appsmith/issues/25447 is fixed. + // Filter by cell range and verify + // dataSources.ValidateNSelectDropdown( + // "Filter Format", + // "Where Clause", + // "Cell range", + // ); + // agHelper.EnterValue("A2:A5", { + // propFieldName: "", + // directInput: false, + // inputFieldName: "Cell range", + // }); + // dataSources.RunQuery(); + // dataSources.RunQueryNVerifyResponseViews(8); + // dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("5. Update a record which is not present and verify the error", () => { + //preparing data + let data = GSHEET_DATA[1]; + data.rowIndex = "15"; + // add update one query and verify + gsheetHelper.EnterBasicQueryValues( + "Update One", + dataSourceName.readNWrite, + spreadSheetName, + false, + ); + agHelper.EnterValue(JSON.stringify(data), { + propFieldName: "", + directInput: false, + inputFieldName: "Update row object", + }); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "No data found at this row index.", + ); + }); + }); + + it("6. Convert field to JS and verify", () => { + // Switch js on sheet name then run query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName.readNWrite, + spreadSheetName, + false, + ); + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + //Enter a wrong sheet name then run query and verify + agHelper.EnterValue("Sheet 2", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Unable to parse range: 'Sheet 2'!1:1", + ); + }); + //Covert sheet name field to dropdown then run query and verify + agHelper.HoverElement(dataSources._getJSONswitchLocator("Sheet name")); + agHelper.AssertTooltip("Clear the field to toggle back"); + agHelper.EnterValue("", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); //Clearing the sheet name field + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); // Converting the field to dropdown + dataSources.ValidateNSelectDropdown("Sheet name", "", "Sheet1"); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("7. Delete row with Read/Write | All google sheets permission", () => { + gsheetHelper.EnterBasicQueryValues( + "Delete One", + dataSourceName.readNWrite, + spreadSheetName, + ); + agHelper.EnterValue(GSHEET_DATA[0].rowIndex, { + propFieldName: "", + directInput: false, + inputFieldName: "Row Index", + }); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted row successfully!", + ); + }); + }); + + it("8. Delete spreadsheet with Read/Write | All google sheets permission", () => { + gsheetHelper.EnterBasicQueryValues( + "Delete One", + dataSourceName.readNWrite, + spreadSheetName, + false, + "Spreadsheet", + ); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Request had insufficient authentication scopes.", + ); + }); + }); + + after("Delete spreadsheet and app", function () { + // Delete spreadsheet and app + gsheetHelper.DeleteSpreadsheetQuery( + dataSourceName.allAccess, + spreadSheetName, + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted spreadsheet successfully!", + ); + }); + homePage.NavigateToHome(); + homePage.DeleteApplication(appName); + }); +}); diff --git a/app/client/cypress/e2e/GSheet/ReadOnly_Access_Spec.ts b/app/client/cypress/e2e/GSheet/ReadOnly_Access_Spec.ts new file mode 100644 index 0000000000..37caa2df32 --- /dev/null +++ b/app/client/cypress/e2e/GSheet/ReadOnly_Access_Spec.ts @@ -0,0 +1,296 @@ +/// +import { GSHEET_DATA } from "../../fixtures/test-data-gsheet"; +import { + homePage, + gsheetHelper, + dataSources, + agHelper, + entityExplorer, +} from "../../support/Objects/ObjectsCore"; + +describe("GSheet-Functional Tests With Read Access", function () { + const workspaceName = "gsheet apps"; + const dataSourceName = { + allAccess: "gsheet", + readOnly: "gsheet-read", + }; + let appName = "gsheet-app"; + let spreadSheetName = "test-sheet"; + + before("Setup app and spreadsheet", function () { + //Add a new app and an add new spreadsheet query + //Setting up the spreadsheet name + const uuid = Cypress._.random(0, 10000); + spreadSheetName = spreadSheetName + "_" + uuid; + appName = appName + "-" + uuid; + + //Adding query to insert a new spreadsheet + homePage.NavigateToHome(); + homePage.CreateAppInWorkspace(workspaceName); + homePage.RenameApplication(appName); + gsheetHelper.AddNewSpreadsheetQuery( + dataSourceName.allAccess, + spreadSheetName, + JSON.stringify(GSHEET_DATA), + ); + cy.get("@postExecute").then((interception: any) => { + expect( + interception.response.body.data.body.properties.title, + ).to.deep.equal(spreadSheetName); + }); + }); + + it("1. Add and verify fetch details query", () => { + entityExplorer.CreateNewDsQuery(dataSourceName.readOnly); + agHelper.RenameWithInPane("Fetch_Details"); + dataSources.ValidateNSelectDropdown( + "Operation", + "Fetch Many", + "Fetch Details", + ); + dataSources.ValidateNSelectDropdown("Entity", "Spreadsheet"); + agHelper.Sleep(500); + dataSources.ValidateNSelectDropdown("Spreadsheet", "", spreadSheetName); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.name).to.deep.equal( + spreadSheetName, + ); + }); + }); + + it("2. Verify error responses for Insert one and Insert many queries for read only access", () => { + // add insert one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert One", + dataSourceName.readOnly, + spreadSheetName, + JSON.stringify(GSHEET_DATA[1]), + false, + ); + dataSources.RunQuery({ expectedStatus: false }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Request had insufficient authentication scopes.", + ); + }); + // add insert many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert Many", + dataSourceName.readOnly, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(2, 10)), + false, + ); + dataSources.RunQuery({ expectedStatus: false }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Request had insufficient authentication scopes.", + ); + }); + }); + + it("3. Verify error responses for Update one and Update many queries for Access only ", () => { + // add update one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update One", + dataSourceName.readOnly, + spreadSheetName, + JSON.stringify(GSHEET_DATA[1]), + false, + ); + dataSources.RunQuery({ expectedStatus: false }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Request had insufficient authentication scopes.", + ); + }); + // add update many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update Many", + dataSourceName.readOnly, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(2, 4)), + false, + ); + dataSources.RunQuery({ expectedStatus: false }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Request had insufficient authentication scopes.", + ); + }); + }); + + it("4. Verify Fetch many query", () => { + // Add simple Fetch many query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName.readOnly, + spreadSheetName, + ); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].uniq_id); + dataSources.AssertQueryTableResponse(1, "ホーンビィ 2014 カタログ"); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + // Update query to fetch only 1 column and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].product_name); + //Remove column filter and add Sort By Ascending and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); //unselect the Columns dd value + agHelper.EnterValue("price", { + propFieldName: "", + directInput: false, + inputFieldName: "Sort By", + }); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, "5afbaf65680c9f378af5b3a3ae22427e"); + dataSources.AssertQueryTableResponse( + 1, + "ラーニング カーブ チャギントン インタラクティブ チャッツワース", + ); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + // Sort by descending and verify + dataSources.ClearSortByOption(); //clearing previous sort option + dataSources.EnterSortByValues("price", "Descending"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse( + 1, + "ホーンビー ゲージ ウェスタン エクスプレス デジタル トレイン セット (eLink および TTS ロコ トレイン セット付き)", + ); // Asserting other language + dataSources.AssertQueryTableResponse( + 4, + "Hornby Gauge Western Express Digital Train Set with eLink and TTS Loco Train Set", + ); + // Filter by where clause and verify + agHelper.TypeDynamicInputValueNValidate( + "price", + dataSources._nestedWhereClauseKey(0), + ); + agHelper.TypeDynamicInputValueNValidate( + "100", + dataSources._nestedWhereClauseValue(0), + ); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(8); + dataSources.AssertQueryTableResponse(0, "87bbb472ef9d90dcef140a551665c929"); + // Currently commenting this until https://github.com/appsmithorg/appsmith/issues/25447 is fixed. + // Filter by cell range and verify + // dataSources.ValidateNSelectDropdown( + // "Filter Format", + // "Where Clause", + // "Cell range", + // ); + // agHelper.EnterValue("A2:A5", { + // propFieldName: "", + // directInput: false, + // inputFieldName: "Cell range", + // }); + // dataSources.RunQuery(); + // dataSources.RunQueryNVerifyResponseViews(8); + // dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("5. Convert field to JS and verify", () => { + // Switch js on sheet name then run query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName.readOnly, + spreadSheetName, + false, + ); + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + //Enter a wrong sheet name then run query and verify + agHelper.EnterValue("Sheet 2", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Unable to parse range: 'Sheet 2'!1:1", + ); + }); + //Covert sheet name field to dropdown then run query and verify + agHelper.HoverElement(dataSources._getJSONswitchLocator("Sheet name")); + agHelper.AssertTooltip("Clear the field to toggle back"); + agHelper.EnterValue("", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); //Clearing the sheet name field + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); // Converting the field to dropdown + dataSources.ValidateNSelectDropdown("Sheet name", "", "Sheet1"); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("6. Delete row with Read | All google sheets permission", () => { + gsheetHelper.EnterBasicQueryValues( + "Delete One", + dataSourceName.readOnly, + spreadSheetName, + ); + agHelper.EnterValue(GSHEET_DATA[0].rowIndex, { + propFieldName: "", + directInput: false, + inputFieldName: "Row Index", + }); + dataSources.RunQuery({ expectedStatus: false }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Request had insufficient authentication scopes.", + ); + }); + }); + + it("7. Delete spreadsheet with Read | All google sheets permission", () => { + gsheetHelper.EnterBasicQueryValues( + "Delete One", + dataSourceName.readOnly, + spreadSheetName, + false, + "Spreadsheet", + ); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Request had insufficient authentication scopes.", + ); + }); + }); + + after("Delete spreadsheet and app", function () { + // Delete spreadsheet and app + gsheetHelper.DeleteSpreadsheetQuery( + dataSourceName.allAccess, + spreadSheetName, + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted spreadsheet successfully!", + ); + }); + homePage.NavigateToHome(); + homePage.DeleteApplication(appName); + }); +}); diff --git a/app/client/cypress/e2e/GSheet/SelectedSheet_Access_Spec.ts b/app/client/cypress/e2e/GSheet/SelectedSheet_Access_Spec.ts new file mode 100644 index 0000000000..01f3705563 --- /dev/null +++ b/app/client/cypress/e2e/GSheet/SelectedSheet_Access_Spec.ts @@ -0,0 +1,299 @@ +/// +import { GSHEET_DATA } from "../../fixtures/test-data-gsheet"; +import { + homePage, + gsheetHelper, + dataSources, + agHelper, + entityExplorer, +} from "../../support/Objects/ObjectsCore"; + +const workspaceName = "gsheet apps"; +const dataSourceName = "gsheet-selected"; +let appName = "gsheet-app"; +let spreadSheetName = "test-sheet-automation-selected"; +describe("GSheet-Functional Tests With Selected Access", function () { + before("Setup app", function () { + //Setting up app name + const uuid = Cypress._.random(0, 10000); + appName = appName + "-" + uuid; + + //Adding app + homePage.NavigateToHome(); + homePage.CreateAppInWorkspace(workspaceName); + homePage.RenameApplication(appName); + }); + + it("1. Add and verify fetch details query", () => { + entityExplorer.CreateNewDsQuery(dataSourceName); + agHelper.RenameWithInPane("Fetch_Details"); + dataSources.ValidateNSelectDropdown( + "Operation", + "Fetch Many", + "Fetch Details", + ); + dataSources.ValidateNSelectDropdown("Entity", "Spreadsheet"); + agHelper.Sleep(500); + dataSources.ValidateNSelectDropdown("Spreadsheet", "", spreadSheetName); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.name).to.deep.equal( + spreadSheetName, + ); + }); + }); + + it("2. Verify Insert One and Insert Many queries", () => { + // add insert one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert One", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA[0]), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Inserted row successfully!", + ); + }); + + // add insert many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Insert Many", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(1, 10)), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Inserted rows successfully!", + ); + }); + }); + + it("3. Verify Update one and Update many queries", () => { + // add update one query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update One", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA[1]), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Updated sheet successfully!", + ); + }); + + // add update many query and verify + gsheetHelper.AddInsertOrUpdateQuery( + "Update Many", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA.slice(2, 4)), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Updated sheet successfully!", + ); + }); + }); + + it("4. Verify Fetch many query", () => { + // Add simple Fetch many query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName, + spreadSheetName, + ); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].uniq_id); + dataSources.AssertQueryTableResponse(1, "ホーンビィ 2014 カタログ"); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + + // Update query to fetch only 1 column and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, GSHEET_DATA[0].product_name); + + //Remove column filter and add Sort By Ascending and verify + gsheetHelper.SelectMultiDropDownValue("Columns", "product_name"); //unselect the Columns dd value + agHelper.EnterValue("price", { + propFieldName: "", + directInput: false, + inputFieldName: "Sort By", + }); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse(0, "5afbaf65680c9f378af5b3a3ae22427e"); + dataSources.AssertQueryTableResponse( + 1, + "ラーニング カーブ チャギントン インタラクティブ チャッツワース", + ); // Asserting other language + dataSources.AssertQueryTableResponse(2, "₹, $, €, ¥, £"); // Asserting different symbols + dataSources.AssertQueryTableResponse(3, "!@#$%^&*"); // Asserting special chars + + // Sort by descending and verify + dataSources.ClearSortByOption(); //clearing previous sort option + dataSources.EnterSortByValues("price", "Descending"); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(GSHEET_DATA.length); + dataSources.AssertQueryTableResponse( + 1, + "ホーンビー ゲージ ウェスタン エクスプレス デジタル トレイン セット (eLink および TTS ロコ トレイン セット付き)", + ); // Asserting other language + dataSources.AssertQueryTableResponse( + 4, + "Hornby Gauge Western Express Digital Train Set with eLink and TTS Loco Train Set", + ); + + // Filter by where clause and verify + agHelper.TypeDynamicInputValueNValidate( + "price", + dataSources._nestedWhereClauseKey(0), + ); + agHelper.TypeDynamicInputValueNValidate( + "100", + dataSources._nestedWhereClauseValue(0), + ); + dataSources.RunQuery(); + dataSources.RunQueryNVerifyResponseViews(8); + dataSources.AssertQueryTableResponse(0, "87bbb472ef9d90dcef140a551665c929"); + + // Currently commenting this until https://github.com/appsmithorg/appsmith/issues/25447 is fixed. + // Filter by cell range and verify + // dataSources.ValidateNSelectDropdown( + // "Filter Format", + // "Where Clause", + // "Cell range", + // ); + // agHelper.EnterValue("A2:A5", { + // propFieldName: "", + // directInput: false, + // inputFieldName: "Cell range", + // }); + // dataSources.RunQuery(); + // dataSources.RunQueryNVerifyResponseViews(8); + // dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("5. Update a record which is not present and verify the error", () => { + //preparing data + const data = GSHEET_DATA[1]; + data.rowIndex = "15"; + + // add update one query and verify + gsheetHelper.EnterBasicQueryValues( + "Update One", + dataSourceName, + spreadSheetName, + false, + ); + agHelper.EnterValue(JSON.stringify(data), { + propFieldName: "", + directInput: false, + inputFieldName: "Update row object", + }); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "No data found at this row index.", + ); + }); + + //reset the row index + data.rowIndex = "1"; + }); + + it("6. Convert field to JS and verify", () => { + // Switch js on sheet name then run query and verify + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName, + spreadSheetName, + false, + ); + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + + //Enter a wrong sheet name then run query and verify + agHelper.EnterValue("Sheet 2", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); + dataSources.RunQuery({ + expectedStatus: false, + }); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal( + "Unable to parse range: 'Sheet 2'!1:1", + ); + }); + + //Covert sheet name field to dropdown then run query and verify + agHelper.HoverElement(dataSources._getJSONswitchLocator("Sheet name")); + agHelper.AssertTooltip("Clear the field to toggle back"); + agHelper.EnterValue("", { + propFieldName: "", + directInput: false, + inputFieldName: "Sheet name", + }); //Clearing the sheet name field + agHelper.GetNClick( + dataSources._getJSONswitchLocator("Sheet name"), + 0, + true, + ); // Converting the field to dropdown + dataSources.ValidateNSelectDropdown("Sheet name", "", "Sheet1"); + dataSources.RunQueryNVerifyResponseViews(10); + dataSources.AssertQueryTableResponse(0, "eac7efa5dbd3d667f26eb3d3ab504464"); + }); + + it("7. Verify Delete query", function () { + // Delete spreadsheet and app + gsheetHelper.EnterBasicQueryValues( + "Delete One", + dataSourceName, + spreadSheetName, + ); + GSHEET_DATA.reverse().forEach((d) => { + agHelper.EnterValue(d.rowIndex, { + propFieldName: "", + directInput: false, + inputFieldName: "Row Index", + }); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted row successfully!", + ); + }); + agHelper.Sleep(500); + }); + // Fetch many to verify all the data is deleted + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName, + spreadSheetName, + false, + ); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body).to.deep.equal([]); + }); + }); + + after("Delete app", function () { + // Delete app + homePage.NavigateToHome(); + homePage.DeleteApplication(appName); + }); +}); diff --git a/app/client/cypress/e2e/GSheet/WidgetBinding_AllAccess_Spec.ts b/app/client/cypress/e2e/GSheet/WidgetBinding_AllAccess_Spec.ts new file mode 100644 index 0000000000..fe029d22eb --- /dev/null +++ b/app/client/cypress/e2e/GSheet/WidgetBinding_AllAccess_Spec.ts @@ -0,0 +1,87 @@ +/// +import { GSHEET_DATA } from "../../fixtures/test-data-gsheet"; +import { + homePage, + gsheetHelper, + dataSources, + agHelper, + entityExplorer, + propPane, + table, + draggableWidgets, +} from "../../support/Objects/ObjectsCore"; +import { Widgets } from "../../support/Pages/DataSources"; +import oneClickBindingLocator from "../../locators/OneClickBindingLocator"; + +const workspaceName = "gsheet apps"; +const dataSourceName = "gsheet"; +let appName = "gsheet-app"; +let spreadSheetName = "test-sheet"; +describe("GSheet-widget binding", function () { + before("Setup app and spreadsheet", function () { + //Setting up the app name + const uuid = Cypress._.random(0, 10000); + spreadSheetName = spreadSheetName + "_" + uuid; + appName = appName + "-" + uuid; + + //Adding app + homePage.NavigateToHome(); + homePage.CreateAppInWorkspace(workspaceName); + homePage.RenameApplication(appName); + gsheetHelper.AddNewSpreadsheetQuery( + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA), + ); + cy.get("@postExecute").then((interception: any) => { + expect( + interception.response.body.data.body.properties.title, + ).to.deep.equal(spreadSheetName); + }); + }); + + it("1. Verify 'Add to widget [Widget Suggestion]' functionality - GSheet", () => { + //Adding query + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName, + spreadSheetName, + ); + dataSources.RunQueryNVerifyResponseViews(10); + + // Adding suggested widgets and verify + dataSources.AddSuggesstedWidget(Widgets.Table); + table.ReadTableRowColumnData(0, 0, "v2").then((cellData) => { + expect(cellData).to.eq("eac7efa5dbd3d667f26eb3d3ab504464"); + }); + agHelper.GetNClick(propPane._deleteWidget); + }); + + it("2. One click binding to table widget functionality - GSheet", () => { + //Adding table widget + entityExplorer.DragDropWidgetNVerify(draggableWidgets.TABLE, 450, 200); + agHelper.GetNClick(oneClickBindingLocator.datasourceDropdownSelector); + agHelper.GetNClick( + oneClickBindingLocator.datasourceQuerySelector("fetch_many_query"), + ); + + // Assert table data + table.ReadTableRowColumnData(0, 0, "v2").then((cellData) => { + expect(cellData).to.eq("eac7efa5dbd3d667f26eb3d3ab504464"); + }); + agHelper.GetNClick(propPane._deleteWidget); + }); + + after("Delete app", function () { + // Delete spreadsheet and app + entityExplorer.NavigateToSwitcher("Explorer"); + gsheetHelper.DeleteSpreadsheetQuery(dataSourceName, spreadSheetName); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted spreadsheet successfully!", + ); + }); + homePage.NavigateToHome(); + homePage.DeleteApplication(appName); + }); +}); diff --git a/app/client/cypress/e2e/GSheet/WidgetBinding_SelectedAccess_Spec.ts b/app/client/cypress/e2e/GSheet/WidgetBinding_SelectedAccess_Spec.ts new file mode 100644 index 0000000000..002832c420 --- /dev/null +++ b/app/client/cypress/e2e/GSheet/WidgetBinding_SelectedAccess_Spec.ts @@ -0,0 +1,100 @@ +/// +import { GSHEET_DATA } from "../../fixtures/test-data-gsheet"; +import { + homePage, + gsheetHelper, + dataSources, + agHelper, + entityExplorer, + propPane, + table, + draggableWidgets, +} from "../../support/Objects/ObjectsCore"; +import { Widgets } from "../../support/Pages/DataSources"; +import oneClickBindingLocator from "../../locators/OneClickBindingLocator"; + +const workspaceName = "gsheet apps"; +const dataSourceName = "gsheet-selected"; +let appName = "gsheet-app"; +let spreadSheetName = "test-sheet-automation-selected"; +describe("GSheet-widget binding for selected sheet access", function () { + before("Setup app and spreadsheet", function () { + //Setting up the app name + const uuid = Cypress._.random(0, 10000); + appName = appName + "-" + uuid; + + //Adding app and data to the selected sheet + homePage.NavigateToHome(); + homePage.CreateAppInWorkspace(workspaceName); + homePage.RenameApplication(appName); + gsheetHelper.AddInsertOrUpdateQuery( + "Insert Many", + dataSourceName, + spreadSheetName, + JSON.stringify(GSHEET_DATA), + ); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Inserted rows successfully!", + ); + }); + }); + + it("1. Verify 'Add to widget [Widget Suggestion]' functionality for selected sheet access - GSheet", () => { + //Adding query + gsheetHelper.EnterBasicQueryValues( + "Fetch Many", + dataSourceName, + spreadSheetName, + ); + dataSources.RunQueryNVerifyResponseViews(10); + + // Adding suggested widgets and verify + dataSources.AddSuggesstedWidget(Widgets.Table); + table.ReadTableRowColumnData(0, 0, "v2").then((cellData) => { + expect(cellData).to.eq("eac7efa5dbd3d667f26eb3d3ab504464"); + }); + agHelper.GetNClick(propPane._deleteWidget); + }); + + it("2. One click binding to table widget functionality for selected sheet access - GSheet", () => { + //Adding table widget + entityExplorer.DragDropWidgetNVerify(draggableWidgets.TABLE, 450, 200); + agHelper.GetNClick(oneClickBindingLocator.datasourceDropdownSelector); + agHelper.GetNClick( + oneClickBindingLocator.datasourceQuerySelector("fetch_many_query"), + ); + + // Assert table data + table.ReadTableRowColumnData(0, 0, "v2").then((cellData) => { + expect(cellData).to.eq("eac7efa5dbd3d667f26eb3d3ab504464"); + }); + agHelper.GetNClick(propPane._deleteWidget); + }); + + after("Delete app", function () { + // Delete data in spreadsheet and app + entityExplorer.NavigateToSwitcher("Explorer"); + gsheetHelper.EnterBasicQueryValues( + "Delete One", + dataSourceName, + spreadSheetName, + ); + GSHEET_DATA.reverse().forEach((d) => { + agHelper.EnterValue(d.rowIndex, { + propFieldName: "", + directInput: false, + inputFieldName: "Row Index", + }); + dataSources.RunQuery(); + cy.get("@postExecute").then((interception: any) => { + expect(interception.response.body.data.body.message).to.deep.equal( + "Deleted row successfully!", + ); + }); + agHelper.Sleep(500); + }); + homePage.NavigateToHome(); + homePage.DeleteApplication(appName); + }); +}); diff --git a/app/client/cypress/e2e/Regression/Apps/CommunityIssues_Spec.ts b/app/client/cypress/e2e/Regression/Apps/CommunityIssues_Spec.ts index a97dcc9658..9e68d87949 100644 --- a/app/client/cypress/e2e/Regression/Apps/CommunityIssues_Spec.ts +++ b/app/client/cypress/e2e/Regression/Apps/CommunityIssues_Spec.ts @@ -146,7 +146,7 @@ describe("AForce - Community Issues page validations", function () { entityExplorer.SelectEntityByName("Table1", "Widgets"); //propPane.EnterJSContext("Default search text", "Question", false); - propPane.TypeTextIntoField("Default search text", "Quest"); + propPane.TypeTextIntoField("Default search text", "Quest", true, false); deployMode.DeployApp(); table.AssertSearchText("Quest", 2); diff --git a/app/client/cypress/e2e/Regression/Apps/EchoApiCMS_spec.js b/app/client/cypress/e2e/Regression/Apps/EchoApiCMS_spec.js index a9a04d449b..f8c1ab61bb 100644 --- a/app/client/cypress/e2e/Regression/Apps/EchoApiCMS_spec.js +++ b/app/client/cypress/e2e/Regression/Apps/EchoApiCMS_spec.js @@ -6,14 +6,14 @@ import { gitSync, apiPage, dataSources, + tedTestConfig, } from "../../../support/Objects/ObjectsCore"; describe("Content Management System App", function () { before(() => { - homePage.NavigateToHome(); agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { - homePage.CreateNewWorkspace("EchoApiCMS" + uid); + homePage.CreateNewWorkspace("EchoApiCMS" + uid, true); homePage.CreateAppInWorkspace("EchoApiCMS" + uid, "EchoApiCMSApp"); agHelper.AddDsl("CMSdsl"); }); @@ -21,55 +21,52 @@ describe("Content Management System App", function () { let repoName; it("1.Create Get echo Api call", function () { - cy.fixture("datasources").then((datasourceFormData) => { - apiPage.CreateAndFillApi(datasourceFormData["echoApiUrl"], "get_data"); - // creating get request using echo - apiPage.EnterHeader( - "info", - '[{"due":"2021-11-23","assignee":"Dan.Wyman@hotmail.com","title":"Recusan","description":"Ut quisquam eum beatae facere eos aliquam laborum ea.","id":"1"},{"due":"2021-11-23","assignee":"Dashawn_Maggio30@gmail.com","title":"Dignissimos eaque","description":"Consequatur corrupti et possimus en.","id":"2"},{"due":"2021-11-24","assignee":"Curt50@gmail.com","title":"Voluptas explicabo","description":"Quia ratione optio et maiores.","id":"3"},{"due":"2021-11-23","assignee":"Shanna63@hotmail.com","title":"Aut omnis.","description":"Neque rerum numquam veniam voluptatum id. Aut daut.","id":"4"}]', - ); - // entering the data in header - apiPage.RunAPI(); - apiPage.ResponseStatusCheck("200"); - }); + apiPage.CreateAndFillApi( + tedTestConfig.dsValues[tedTestConfig.defaultEnviorment].echoApiUrl, + "get_data", + ); + // creating get request using echo + apiPage.EnterHeader( + "info", + '[{"due":"2021-11-23","assignee":"Dan.Wyman@hotmail.com","title":"Recusan","description":"Ut quisquam eum beatae facere eos aliquam laborum ea.","id":"1"},{"due":"2021-11-23","assignee":"Dashawn_Maggio30@gmail.com","title":"Dignissimos eaque","description":"Consequatur corrupti et possimus en.","id":"2"},{"due":"2021-11-24","assignee":"Curt50@gmail.com","title":"Voluptas explicabo","description":"Quia ratione optio et maiores.","id":"3"},{"due":"2021-11-23","assignee":"Shanna63@hotmail.com","title":"Aut omnis.","description":"Neque rerum numquam veniam voluptatum id. Aut daut.","id":"4"}]', + ); + // entering the data in header + apiPage.RunAPI(); + apiPage.ResponseStatusCheck("200"); }); it("2. Create Post echo Api call", function () { - cy.fixture("datasources").then((datasourceFormData) => { - apiPage.CreateAndFillApi( - datasourceFormData["echoApiUrl"], - "send_mail", - 10000, - "POST", - ); - apiPage.SelectPaneTab("Body"); - apiPage.SelectSubTab("JSON"); - // creating post request using echo - dataSources.EnterQuery( - '{"to":"{{to_input.text}}","subject":"{{subject.text}}","content":"{{content.text}}"}', - ); - apiPage.RunAPI(); - apiPage.ResponseStatusCheck("200"); - }); + apiPage.CreateAndFillApi( + tedTestConfig.dsValues[tedTestConfig.defaultEnviorment].echoApiUrl, + "send_mail", + 10000, + "POST", + ); + apiPage.SelectPaneTab("Body"); + apiPage.SelectSubTab("JSON"); + // creating post request using echo + dataSources.EnterQuery( + '{"to":"{{to_input.text}}","subject":"{{subject.text}}","content":"{{content.text}}"}', + ); + apiPage.RunAPI(); + apiPage.ResponseStatusCheck("200"); }); it("3. Create Delete echo Api call", function () { - cy.fixture("datasources").then((datasourceFormData) => { - apiPage.CreateAndFillApi( - datasourceFormData["echoApiUrl"], - "delete_proposal", - 10000, - "DELETE", - ); - apiPage.SelectPaneTab("Body"); - apiPage.SelectSubTab("JSON"); - // creating post request using echo - dataSources.EnterQuery( - '{"title":"{{title.text}}","due":"{{due.text}}","assignee":"{{assignee.text}}"}', - ); - apiPage.RunAPI(); - apiPage.ResponseStatusCheck("200"); - }); + apiPage.CreateAndFillApi( + tedTestConfig.dsValues[tedTestConfig.defaultEnviorment].echoApiUrl, + "delete_proposal", + 10000, + "DELETE", + ); + apiPage.SelectPaneTab("Body"); + apiPage.SelectSubTab("JSON"); + // creating post request using echo + dataSources.EnterQuery( + '{"title":"{{title.text}}","due":"{{due.text}}","assignee":"{{assignee.text}}"}', + ); + apiPage.RunAPI(); + apiPage.ResponseStatusCheck("200"); }); it("4. Send mail and verify post request body", function () { diff --git a/app/client/cypress/e2e/Regression/Apps/MongoDBShoppingCart_spec.ts b/app/client/cypress/e2e/Regression/Apps/MongoDBShoppingCart_spec.ts index f196563fcd..77b7f8cf0d 100644 --- a/app/client/cypress/e2e/Regression/Apps/MongoDBShoppingCart_spec.ts +++ b/app/client/cypress/e2e/Regression/Apps/MongoDBShoppingCart_spec.ts @@ -12,10 +12,9 @@ describe("Shopping cart App", function () { let datasourceName: string, repoName: any; before(() => { - homePage.NavigateToHome(); agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { - homePage.CreateNewWorkspace("MongoDBShop" + uid); + homePage.CreateNewWorkspace("MongoDBShop" + uid, true); homePage.CreateAppInWorkspace("MongoDBShop" + uid, "MongoDBShopApp"); agHelper.AddDsl("mongoAppdsl"); }); @@ -28,7 +27,6 @@ describe("Shopping cart App", function () { it("1. Create MongoDB datasource and add Insert, Find, Update and Delete queries", function () { dataSources.CreateQueryAfterDSSaved("", "GetProduct"); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "Productnames", }); @@ -42,7 +40,6 @@ describe("Shopping cart App", function () { "Update document(s)", ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "Productnames", }); @@ -73,7 +70,6 @@ describe("Shopping cart App", function () { "Insert document(s)", ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "Productnames", }); @@ -101,7 +97,6 @@ describe("Shopping cart App", function () { "Delete document(s)", ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "Productnames", }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/ActionExecution/uiToCode/uiToCode_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/ActionExecution/uiToCode_spec.ts similarity index 94% rename from app/client/cypress/e2e/Regression/ClientSide/ActionExecution/uiToCode/uiToCode_spec.ts rename to app/client/cypress/e2e/Regression/ClientSide/ActionExecution/uiToCode_spec.ts index 215c4f6913..3ac7df80e8 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/ActionExecution/uiToCode/uiToCode_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/ActionExecution/uiToCode_spec.ts @@ -5,12 +5,14 @@ import { jsEditor, propPane, apiPage, -} from "../../../../../support/Objects/ObjectsCore"; + draggableWidgets, +} from "../../../../support/Objects/ObjectsCore"; describe("UI to Code", () => { before(() => { - agHelper.AddDsl("buttondsl"); - apiPage.CreateApi("Api1", "GET"); + entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON); + entityExplorer.NavigateToSwitcher("Explorer"); + apiPage.CreateApi(); apiPage.CreateApi("Api2", "POST"); }); @@ -372,18 +374,18 @@ describe("UI to Code", () => { // Edit the success callback of the nested Api2.run propPane.SelectActionByTitleAndValue("Execute a query", "Api2.run"); - cy.get( - jsEditor._lineinPropertyPaneJsEditor( - 2, - propPane._actionSelectorFieldContentByLabel("Params"), - ), - ).type("val: 1"); + agHelper.EnterActionValue( + "Params", + `{{{ + val: 1 + }}}`, + ); agHelper.GetNClick(propPane._actionSelectorPopupClose); propPane.ValidateJSFieldValue( "onClick", - `{{Api1.run().then(() => {  Api2.run({    val: 1    // "key": "value", }).then(() => {    showAlert("Hello"); }).catch(() => {    showAlert("World"); });});}}`, + `{{Api1.run().then(() => {  Api2.run({    val: 1 }).then(() => {    showAlert("Hello"); }).catch(() => {    showAlert("World"); });});}}`, ); }); @@ -414,13 +416,13 @@ describe("UI to Code", () => { it("9. correctly configures a setInterval action", () => { propPane.SelectPlatformFunction("onClick", "Set interval"); - - cy.get( - jsEditor._lineinPropertyPaneJsEditor( - 2, - propPane._actionSelectorFieldContentByLabel("Callback function"), - ), - ).type("{enter}showAlert('Hello'){enter}//"); + agHelper.EnterActionValue( + "Callback function", + `{{() => { + // add code here + showAlert('Hello') + }}}`, + ); agHelper.TypeText( propPane._actionSelectorFieldByLabel("Id"), @@ -430,7 +432,7 @@ describe("UI to Code", () => { propPane.ValidateJSFieldValue( "onClick", - `{{setInterval(() => {  // add c  showAlert(\'Hello\');  // ode here}, 5000, \'interval-id\');}}`, + `{{setInterval(() => {  // add code here  showAlert('Hello');}, 5000, 'interval-id');}}`, ); }); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Autocomplete/JS_AC1_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Autocomplete/JS_AC1_spec.ts index e4c72bea84..b633f5fd2e 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Autocomplete/JS_AC1_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Autocomplete/JS_AC1_spec.ts @@ -256,7 +256,8 @@ describe("Autocomplete tests", () => { }); }); - it("7. Autocompletion for bindings inside array and objects", () => { + //To fix soon + it.skip("7. Autocompletion for bindings inside array and objects", () => { dataSources.CreateDataSource("Mongo", true, false); dataSources.CreateQueryAfterDSSaved(); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js index 4510429211..5d7af7d023 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js @@ -33,11 +33,11 @@ describe("Text-Chart Binding Functionality", function () { this.dataSet.Chartval[1], this.dataSet.Chartval[2], ]; - [0, 1, 2].forEach((k) => { + [0, 2].forEach((k) => { cy.get(viewWidgetsPage.rectangleChart) - .eq(k) + .first() .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); + cy.get(viewWidgetsPage.Chartlabel).contains(labels[k]); }); deployMode.DeployApp(); }); @@ -51,8 +51,8 @@ describe("Text-Chart Binding Functionality", function () { this.dataSet.Chartval[2], ]; [0, 1, 2].forEach((k) => { - cy.get(publish.rectChart).eq(k).trigger("mousemove", { force: true }); - cy.get(publish.chartLab).eq(k).should("have.text", labels[k]); + cy.get(publish.rectChart).first().trigger("mousemove", { force: true }); + cy.get(publish.chartLab).contains(labels[k]); }); cy.get(commonlocators.TextInside).should( "have.text", diff --git a/app/client/cypress/e2e/Regression/ClientSide/Binding/SmartSubstitutionWidgets_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Binding/SmartSubstitutionWidgets_spec.js index 370874bba4..26100183c9 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Binding/SmartSubstitutionWidgets_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Binding/SmartSubstitutionWidgets_spec.js @@ -42,7 +42,7 @@ describe("Text-Table Binding Functionality", function () { cy.get(viewWidgetsPage.chartWidget) .find("svg") .find("text") - .should("contain.text", "Product2"); + .should("contain.text", "Product1"); cy.get(viewWidgetsPage.chartWidget) .find("svg") diff --git a/app/client/cypress/e2e/Regression/ClientSide/Binding/TableV2WithSnipingMode_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Binding/TableV2WithSnipingMode_spec.js deleted file mode 100644 index 82d91e5995..0000000000 --- a/app/client/cypress/e2e/Regression/ClientSide/Binding/TableV2WithSnipingMode_spec.js +++ /dev/null @@ -1,21 +0,0 @@ -import * as _ from "../../../../support/Objects/ObjectsCore"; - -describe("Test Create Api and Bind to Table widget V2", function () { - before(() => { - _.agHelper.AddDsl("tableV2WidgetDsl"); - }); - - it("1. Test_Add users api, execute it and go to sniping mode.", function () { - cy.createAndFillApi(this.dataSet.userApi, "/mock-api?records=10"); - cy.RunAPI(); - cy.get(".t--select-in-canvas").click(); - cy.get(".t--sniping-mode-banner").should("be.visible"); - //Click on table name controller to bind the data and exit sniping mode - cy.get(".t--draggable-tablewidgetv2").trigger("mouseover"); - cy.get(".t--settings-sniping-control").click(); - cy.get(".t--property-control-tabledata .CodeMirror").contains( - "{{Api1.data}}", - ); - cy.get(".t--sniping-mode-banner").should("not.exist"); - }); -}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Binding/TableV2WithSnipingMode_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Binding/TableV2WithSnipingMode_spec.ts new file mode 100644 index 0000000000..bf8cdf30b2 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/Binding/TableV2WithSnipingMode_spec.ts @@ -0,0 +1,32 @@ +import { + agHelper, + apiPage, + table, + tedTestConfig, +} from "../../../../support/Objects/ObjectsCore"; + +import OneClickBinding from "../../../../locators/OneClickBindingLocator"; +import FirstTimeUserOnboarding from "../../../../locators/FirstTimeUserOnboarding.json"; + +describe("Test Create Api and Bind to Table widget V2", function () { + before(() => { + agHelper.AddDsl("tableV2WidgetDsl"); + }); + + it("1. Test_Add users api, execute it and go to sniping mode.", function () { + apiPage.CreateAndFillApi( + tedTestConfig.dsValues[tedTestConfig.defaultEnviorment].mockApiUrl, + ); + apiPage.RunAPI(); + agHelper.GetNClick(FirstTimeUserOnboarding.selectWidgetBtn); + agHelper.AssertElementVisible(FirstTimeUserOnboarding.snipingBanner); + //Click on table name controller to bind the data and exit sniping mode + agHelper.GetNClick(table._tableV2Widget); + agHelper.AssertContains( + "Api1", + "exist", + OneClickBinding.datasourceDropdownSelector, + ); + agHelper.AssertElementAbsence(FirstTimeUserOnboarding.snipingBanner); + }); +}); 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 902a224b1b..fdf94c895d 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/BugTests/DatasourceSchema_spec.ts @@ -1,19 +1,26 @@ import { featureFlagIntercept } from "../../../../support/Objects/FeatureFlags"; -import { ObjectsRegistry } from "../../../../support/Objects/Registry"; - -const agHelper = ObjectsRegistry.AggregateHelper, - dataSources = ObjectsRegistry.DataSources, - ee = ObjectsRegistry.EntityExplorer; +import { + agHelper, + entityItems, + dataSources, + entityExplorer, + homePage, +} from "../../../../support/Objects/ObjectsCore"; let guid; let dataSourceName: string; describe("Datasource form related tests", function () { + before(() => { + homePage.CreateNewWorkspace("FetchSchemaOnce", true); + homePage.CreateAppInWorkspace("FetchSchemaOnce"); + }); + it("1. Bug - 17238 Verify datasource structure refresh on save - invalid datasource", () => { agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { guid = uid; dataSourceName = "Postgres " + guid; - ee.ExpandCollapseEntity("Datasources"); + entityExplorer.ExpandCollapseEntity("Datasources"); dataSources.NavigateToDSCreateNew(); dataSources.CreatePlugIn("PostgreSQL"); agHelper.RenameWithInPane(dataSourceName, false); @@ -36,14 +43,16 @@ describe("Datasource form related tests", function () { it("2. Verify if schema was fetched once #18448", () => { agHelper.RefreshPage(); - ee.ExpandCollapseEntity("Datasources"); - ee.ExpandCollapseEntity(dataSourceName, false); - cy.intercept("GET", dataSources._getStructureReq).as("getDSStructure"); - ee.ExpandCollapseEntity("Datasources"); - ee.ExpandCollapseEntity(dataSourceName); + entityExplorer.ExpandCollapseEntity("Datasources"); + entityExplorer.ExpandCollapseEntity(dataSourceName, false); + entityExplorer.ExpandCollapseEntity("Datasources"); + entityExplorer.ExpandCollapseEntity(dataSourceName); agHelper.Sleep(1500); agHelper.VerifyCallCount(`@getDatasourceStructure`, 1); - dataSources.DeleteQuery("Query1"); + agHelper.ActionContextMenuWithInPane({ + action: "Delete", + entityType: entityItems.Query, + }); dataSources.DeleteDatasouceFromWinthinDS(dataSourceName); }); @@ -61,7 +70,7 @@ describe("Datasource form related tests", function () { dataSources.CreateMockDB("Users"); dataSources.CreateQueryAfterDSSaved(); dataSources.VerifyTableSchemaOnQueryEditor("public.users"); - ee.ExpandCollapseEntity("public.users"); + entityExplorer.ExpandCollapseEntity("public.users"); dataSources.VerifyColumnSchemaOnQueryEditor("id"); dataSources.FilterAndVerifyDatasourceSchemaBySearch( "gender", diff --git a/app/client/cypress/e2e/Regression/ClientSide/BugTests/GitBugs_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/BugTests/GitBugs_Spec.ts index 0aeb22078a..f7132b4756 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/BugTests/GitBugs_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/BugTests/GitBugs_Spec.ts @@ -9,10 +9,9 @@ let tempBranch3: any; describe("Git Bugs", function () { before(() => { - _.homePage.NavigateToHome(); _.agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { - _.homePage.CreateNewWorkspace("GitBugs" + uid); + _.homePage.CreateNewWorkspace("GitBugs" + uid, true); _.homePage.CreateAppInWorkspace("GitBugs" + uid); }); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/DynamicHeight/TextWidget_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/DynamicHeight/TextWidget_Spec.ts index 2866518d4e..3cabf4ef83 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/DynamicHeight/TextWidget_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/DynamicHeight/TextWidget_Spec.ts @@ -1,43 +1,51 @@ -import * as _ from "../../../../support/Objects/ObjectsCore"; +import { + agHelper, + locators, + entityExplorer, + propPane, + deployMode, + draggableWidgets, + assertHelper, +} from "../../../../support/Objects/ObjectsCore"; describe("Dynamic Height Width validation for text widget", function () { before(() => { - _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.TEXT); + entityExplorer.DragDropWidgetNVerify(draggableWidgets.TEXT); }); it("1. Text widget validation of height with dynamic height feature", function () { const textMsg = "Dynamic height validation for text widget validation with respect to Auto height"; //changing the Text and verifying - _.propPane.AssertPropertiesDropDownCurrentValue("Height", "Auto Height"); + propPane.AssertPropertiesDropDownCurrentValue("Height", "Auto Height"); - _.agHelper.GetHeight(_.locators._widgetInDeployed(_.draggableWidgets.TEXT)); + propPane.AssertPropertiesDropDownValues("Height", [ + "Auto Height", + "Auto Height with limits", + "Fixed", + ]); + + agHelper.GetHeight(locators._widgetInDeployed(draggableWidgets.TEXT)); cy.get("@eleHeight").then(($initalHeight) => { - _.propPane.UpdatePropertyFieldValue("Text", textMsg); - _.propPane.MoveToTab("Style"); - _.propPane.SelectPropertiesDropDown("Font size", "L"); - _.assertHelper.AssertNetworkStatus("@updateLayout", 200); //for textMsg update - _.agHelper.GetHeight( - _.locators._widgetInDeployed(_.draggableWidgets.TEXT), - ); + propPane.UpdatePropertyFieldValue("Text", textMsg); + propPane.MoveToTab("Style"); + propPane.SelectPropertiesDropDown("Font size", "L"); + assertHelper.AssertNetworkStatus("@updateLayout", 200); //for textMsg update + agHelper.GetHeight(locators._widgetInDeployed(draggableWidgets.TEXT)); cy.get("@eleHeight").then(($addedtextHeight) => { expect($addedtextHeight).to.not.equal($initalHeight); - _.deployMode.DeployApp(_.locators._textWidgetInDeployed); - _.agHelper - .GetText(_.locators._textWidgetInDeployed) - .then(($text: any) => { - expect($text).to.eq(textMsg); - }); + deployMode.DeployApp(locators._textWidgetInDeployed); + agHelper.GetText(locators._textWidgetInDeployed).then(($text: any) => { + expect($text).to.eq(textMsg); + }); - _.agHelper.AssertAttribute( - _.locators._textWidgetStyleInDeployed, + agHelper.AssertAttribute( + locators._textWidgetStyleInDeployed, "font-size", "1.25rem", //for Font size 'L' ); - _.agHelper.GetHeight( - _.locators._widgetInDeployed(_.draggableWidgets.TEXT), - ); + agHelper.GetHeight(locators._widgetInDeployed(draggableWidgets.TEXT)); cy.get("@eleHeight").then(($deployedAutoHeight) => { expect($deployedAutoHeight).not.eq($initalHeight); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/ExplorerTests/API_Pane_spec.js b/app/client/cypress/e2e/Regression/ClientSide/ExplorerTests/API_Pane_spec.js index beac47b703..b3a2d19580 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/ExplorerTests/API_Pane_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/ExplorerTests/API_Pane_spec.js @@ -11,8 +11,7 @@ let ee = ObjectsRegistry.EntityExplorer, describe("Entity explorer API pane related testcases", function () { it("1. Empty Message validation for Widgets/API/Queries", function () { - homePage.NavigateToHome(); - homePage.CreateNewWorkspace("EmptyMsgCheck"); + homePage.CreateNewWorkspace("EmptyMsgCheck", true); homePage.CreateAppInWorkspace("EmptyMsgCheck"); ee.ExpandCollapseEntity("Widgets"); agHelper.AssertElementVisible( diff --git a/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkAppWithMultipleDS_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkAppWithMultipleDS_Spec.ts index 59e554bcc6..62a72547ce 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkAppWithMultipleDS_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkAppWithMultipleDS_Spec.ts @@ -32,11 +32,10 @@ describe("Fork application with multiple datasources", function () { it("1. Bug Id: 24708 - fork and test the forked application", function () { // Create a new workspace and fork application const appname: string = localStorage.getItem("AppName") || "randomApp"; - homePage.NavigateToHome(); agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { workspaceId = "forkApp" + uid; - homePage.CreateNewWorkspace(workspaceId); + homePage.CreateNewWorkspace(workspaceId, true); agHelper.PressEscape(); cy.log("------------------" + workspaceId); homePage.ForkApplication(appname, workspaceId); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkApplicationReconnectModal_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkApplicationReconnectModal_spec.ts index 68191c848f..2216aac1d6 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkApplicationReconnectModal_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Fork/ForkApplicationReconnectModal_spec.ts @@ -8,13 +8,12 @@ let currentWorkspace: string, currentAppName: string, forkWorkspaceName: string; describe("Fork application across workspaces", function () { it("Bug 24702: Signed user should be able to fork a public forkable app & Check if the forked application has the same dsl as the original", function () { - homePage.NavigateToHome(); // Create new workspace to create App in agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { currentWorkspace = "CurrentWorkspace " + uid; currentAppName = "MongoQueryApp " + uid; - homePage.CreateNewWorkspace(currentWorkspace); + homePage.CreateNewWorkspace(currentWorkspace, true); homePage.CreateAppInWorkspace(currentWorkspace, currentAppName); // Create datasource and query @@ -23,12 +22,11 @@ describe("Fork application across workspaces", function () { // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(2000); - homePage.NavigateToHome(); agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { forkWorkspaceName = "ForkApplication" + uid; - homePage.CreateNewWorkspace(forkWorkspaceName); + homePage.CreateNewWorkspace(forkWorkspaceName, true); homePage.FilterApplication(currentAppName); agHelper.Sleep(500); diff --git a/app/client/cypress/e2e/Regression/ClientSide/FormNativeToRawTests/MongoConversion_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/FormNativeToRawTests/MongoConversion_spec.ts index ba3ff3d40a..1bd79224a7 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/FormNativeToRawTests/MongoConversion_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/FormNativeToRawTests/MongoConversion_spec.ts @@ -9,7 +9,6 @@ describe("Mongo Form to Native conversion works", () => { _.dataSources.CreateQueryAfterDSSaved(); _.assertHelper.AssertNetworkStatus("@trigger"); _.dataSources.EnterJSContext({ - fieldProperty: _.dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "listingAndReviews", }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Git/ExistingApps/v1.9.24/DSCrudAndBindings_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Git/ExistingApps/v1.9.24/DSCrudAndBindings_Spec.ts index 8edd00b84a..fa6b11e304 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Git/ExistingApps/v1.9.24/DSCrudAndBindings_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Git/ExistingApps/v1.9.24/DSCrudAndBindings_Spec.ts @@ -19,11 +19,10 @@ describe("Import and validate older app (app created in older versions of Appsmi keyId: any, workspaceName: any; before(() => { - homePage.NavigateToHome(); agHelper.GenerateUUID(); cy.get("@guid").then((uid) => { workspaceName = "GitImport_" + uid; - homePage.CreateNewWorkspace(workspaceName); + homePage.CreateNewWorkspace(workspaceName, true); }); //Import App From Gitea gitSync.ImportAppFromGit(workspaceName, appRepoName, true); diff --git a/app/client/cypress/e2e/Regression/ClientSide/IDE/MaintainContext&Focus_spec.js b/app/client/cypress/e2e/Regression/ClientSide/IDE/MaintainContext&Focus_spec.js index 3a985d8eec..2eb884c215 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/IDE/MaintainContext&Focus_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/IDE/MaintainContext&Focus_spec.js @@ -79,7 +79,6 @@ describe("MaintainContext&Focus", function () { cy.wait(1000); _.dataSources.EnterJSContext({ - fieldProperty: _.dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "TestCollection", }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/AppPageLayout_spec.js b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/AppPageLayout_spec.js index 4bca57f843..654f64911c 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/AppPageLayout_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/AppPageLayout_spec.js @@ -1,7 +1,7 @@ import homePage from "../../../../locators/HomePage"; import * as _ from "../../../../support/Objects/ObjectsCore"; -describe.skip("Visual regression tests", () => { +describe("Visual regression tests", () => { // for any changes in UI, update the screenshot in snapshot folder, to do so: // 1. Delete the required screenshot which you want to update. // 2. Run test in headless mode with any browser 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 d8f1aa6006..af4b55b064 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/DatasourcePageLayout_spec.js @@ -1,6 +1,6 @@ import * as _ from "../../../../support/Objects/ObjectsCore"; -describe.skip("Visual tests for datasources", () => { +describe("Visual tests for datasources", () => { // for any changes in UI, update the screenshot in snapshot folder, to do so: // 1. Delete the required screenshot which you want to update. // 2. Run test in headless mode with any browser diff --git a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorComment_spec.js b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorComment_spec.js index 9a450fafa1..292e091c92 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorComment_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorComment_spec.js @@ -3,7 +3,7 @@ import { ObjectsRegistry } from "../../../../support/Objects/Registry"; let jsEditor = ObjectsRegistry.JSEditor, agHelper = ObjectsRegistry.AggregateHelper; -describe.skip("JSEditor Comment - Visual tests", () => { +describe("JSEditor Comment - Visual tests", () => { it("1. comments code on the editor", () => { jsEditor.CreateJSObject( `export default { 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 1a49a7dd2f..a95ee658fe 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorIndent_spec.js @@ -6,7 +6,7 @@ import { jsEditor, } from "../../../../support/Objects/ObjectsCore"; -describe.skip("JSEditor Indendation - Visual tests", () => { +describe("JSEditor Indendation - Visual tests", () => { it("6. TC 1933 - jSEditor prettify verification on cloned application", () => { const appname = localStorage.getItem("AppName"); jsEditor.CreateJSObject( 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 b18471b0a9..6b7c757986 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/JSEditorSaveAndAutoIndent_spec.js @@ -1,6 +1,6 @@ import * as _ from "../../../../support/Objects/ObjectsCore"; -describe.skip("JS Editor Save and Auto-indent: Visual tests", () => { +describe("JS Editor Save and Auto-indent: Visual tests", () => { it("1. Auto indents and saves the code when Ctrl/Cmd+s is pressed", () => { _.jsEditor.CreateJSObject( `export default { 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 b9d25e41f4..19a9ebafde 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/VisualTests/WidgetsLayout_spec.js @@ -1,4 +1,4 @@ -describe.skip("Visual regression tests", () => { +describe("Visual regression tests", () => { // for any changes in UI, update the screenshot in snapshot folder, to do so: // 1. Delete the required screenshot which you want to update // 2. Run test in headless mode with chrome (to maintain same resolution in CI) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/ChartDataPoint_Spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/ChartDataPoint_Spec.ts index 7d3d964774..be81cb4f69 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/ChartDataPoint_Spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/ChartDataPoint_Spec.ts @@ -7,6 +7,8 @@ import { entityExplorer, } from "../../../../../support/Objects/ObjectsCore"; +const widgetLocators = require("../../../../../locators/Widgets.json"); + let dataSet: any, dsl: any; describe("Input widget test with default value from chart datapoint", () => { @@ -38,7 +40,7 @@ describe("Input widget test with default value from chart datapoint", () => { ); deployMode.DeployApp(); agHelper.Sleep(1500); //waiting for chart to load! - agHelper.GetNClick("//*[local-name()='rect']", 13); + agHelper.GetNClick(widgetLocators.chartDataPoint); cy.get(locators._widgetInputSelector("inputwidgetv2")) .first() .invoke("val") diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/ChartWidgetErrors_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/ChartWidgetErrors_spec.ts new file mode 100644 index 0000000000..7c70b8a53b --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/ChartWidgetErrors_spec.ts @@ -0,0 +1,46 @@ +import { + agHelper, + locators, + entityExplorer, + draggableWidgets, +} from "../../../../../support/Objects/ObjectsCore"; + +describe("Chart renders widget errors", () => { + it("1. If there are syntax errors, the errors are displayed inside the chart widget", function () { + entityExplorer.DragDropWidgetNVerify(draggableWidgets.CHART); + + agHelper.AssertContains( + "Sales Report", + "exist", + locators._widgetInDeployed(draggableWidgets.CHART), + ); + agHelper.AssertContains( + "Error in Chart Data/Configuration", + "not.exist", + locators._widgetInDeployed(draggableWidgets.CHART), + ); + + agHelper.EnterActionValue("Series data", "{{Button1.text}}"); + + agHelper.AssertContains( + "Error in Chart Data/Configuration", + "exist", + locators._widgetInDeployed(draggableWidgets.CHART), + ); + agHelper.AssertContains( + "Sales Report", + "not.exist", + locators._widgetInDeployed(draggableWidgets.CHART), + ); + }); + + it("2. shows no chart data available is series data is missing", function () { + agHelper.EnterActionValue("Series data", ""); + + agHelper.AssertContains( + "No chart data to display", + "exist", + locators._widgetInDeployed(draggableWidgets.CHART), + ); + }); +}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_1_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_1_spec.js deleted file mode 100644 index 302b9f45f7..0000000000 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_1_spec.js +++ /dev/null @@ -1,283 +0,0 @@ -const viewWidgetsPage = require("../../../../../locators/ViewWidgets.json"); -const widgetsPage = require("../../../../../locators/Widgets.json"); -import * as _ from "../../../../../support/Objects/ObjectsCore"; - -describe("Chart Widget Functionality", function () { - before(() => { - _.agHelper.AddDsl("chartUpdatedDsl"); - }); - - beforeEach(() => { - cy.openPropertyPane("chartwidget"); - }); - - it("1. Fill the Chart Widget Properties.", function () { - //changing the Chart Name - /** - * @param{Text} Random Text - * @param{ChartWidget}Mouseover - * @param{ChartPre Css} Assertion - */ - cy.widgetText( - "Test", - viewWidgetsPage.chartWidget, - widgetsPage.widgetNameSpan, - ); - cy.EnableAllCodeEditors(); - //changing the Chart Title - /** - * @param{Text} Random Input Value - */ - cy.testJsontext("title", this.dataSet.chartIndata); - cy.get(viewWidgetsPage.chartInnerText) - .click() - .contains("App Sign Up") - .should("have.text", "App Sign Up"); - - //Entering the Chart data - cy.testJsontext( - "chart-series-data-control", - JSON.stringify(this.dataSet.chartInput), - ); - cy.get(".t--propertypane").click("right"); - - // Asserting Chart Height - cy.get(viewWidgetsPage.chartWidget) - .should("be.visible") - .and((chart) => { - expect(chart.height()).to.be.greaterThan(200); - }); - - //Entring the label of x-axis - cy.get(viewWidgetsPage.xlabel) - .click({ force: true }) - .type(this.dataSet.command) - .type(this.dataSet.plan); - //Entring the label of y-axis - cy.get(viewWidgetsPage.ylabel) - .click({ force: true }) - .type(this.dataSet.command) - .click({ force: true }) - .type(this.dataSet.ylabel); - - _.deployMode.DeployApp(); - }); - - it("2. Pie Chart Widget Functionality", function () { - //changing the Chart type - cy.UpdateChartType("Pie chart"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .last() - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.PieChartLabel) - .eq(k) - .should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("3. Line Chart Widget Functionality", function () { - //changing the Chart type - cy.UpdateChartType("Line chart"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .last() - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("4. Bar Chart Widget Functionality", function () { - //changing the Chart type - cy.UpdateChartType("Bar chart"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .eq(k) - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("5. Area Chart Widget Functionality", function () { - //changing the Chart type - cy.UpdateChartType("Area chart"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .last() - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("6. Column Chart Widget Functionality", function () { - //changing the Chart type - cy.UpdateChartType("Column chart"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .eq(k) - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("7. Toggle JS - Pie Chart Widget Functionality", function () { - //changing the Chart type - cy.get(widgetsPage.toggleChartType).click({ force: true }); - cy.testJsontext("charttype", "PIE_CHART"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .last() - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.PieChartLabel) - .eq(k) - .should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("8. Toggle JS - Line Chart Widget Functionality", function () { - //changing the Chart type - cy.testJsontext("charttype", "LINE_CHART"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .last() - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("9. Toggle JS - Bar Chart Widget Functionality", function () { - //changing the Chart type - cy.testJsontext("charttype", "BAR_CHART"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .eq(k) - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("10. Toggle JS - Area Chart Widget Functionality", function () { - //changing the Chart type - cy.testJsontext("charttype", "AREA_CHART"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .last() - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("11. Toggle JS - Column Chart Widget Functionality", function () { - //changing the Chart type - cy.testJsontext("charttype", "COLUMN_CHART"); - - //Verifying X-axis labels - cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); - const labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) - .eq(k) - .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); - }); - _.deployMode.DeployApp(); - }); - - it("12. Check Chart widget reskinning config", function () { - cy.get(widgetsPage.toggleChartType).click({ force: true }); - cy.UpdateChartType("Column chart"); - - // Check plot fill color - cy.get("g[class*='plot-group'] rect").should( - "have.css", - "fill", - "rgb(85, 61, 233)", - ); - - // Check axis name font size - cy.get("g[class*='dataset-axis-name'] text").should( - "have.css", - "font-size", - "14px", - ); - - // Check axis value font size and fill color - cy.get("g[class$='dataset-axis'] text") - .should("have.css", "font-size", "12px") - .should("have.css", "fill", "rgb(113, 110, 110)"); - - // Check axis caption's fontSize, and fill color - cy.get("g[class$='caption'] text") - .should("have.css", "font-size", "24px") - .should("have.css", "fill", "rgb(35, 31, 32)"); - - // Check base font family - cy.get(".fusioncharts-container").should( - "have.css", - "font-family", - '"Nunito Sans", sans-serif', - ); - - cy.UpdateChartType("Pie chart"); - cy.get("g[class$='item'] text").should( - "have.css", - "font-family", - '"Nunito Sans"', - ); - cy.get("g[class$='labels'] text").should( - "have.css", - "font-family", - '"Nunito Sans"', - ); - _.deployMode.DeployApp(); - }); - - afterEach(() => { - _.deployMode.NavigateBacktoEditor(); - }); -}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_2_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_2_spec.js deleted file mode 100644 index 03f7ce99d8..0000000000 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Chart_2_spec.js +++ /dev/null @@ -1,124 +0,0 @@ -const commonlocators = require("../../../../../locators/commonlocators.json"); -const viewWidgetsPage = require("../../../../../locators/ViewWidgets.json"); -const publish = require("../../../../../locators/publishWidgetspage.json"); -const modalWidgetPage = require("../../../../../locators/ModalWidget.json"); -const widgetsPage = require("../../../../../locators/Widgets.json"); -import * as _ from "../../../../../support/Objects/ObjectsCore"; - -describe("Chart Widget Functionality", function () { - before(() => { - _.agHelper.AddDsl("chartUpdatedDsl"); - }); - - beforeEach(() => { - cy.openPropertyPane("chartwidget"); - }); - - it("1. Fill the Chart Widget Properties.", function () { - //changing the Chart Name - /** - * @param{Text} Random Text - * @param{ChartWidget}Mouseover - * @param{ChartPre Css} Assertion - */ - cy.widgetText( - "Test", - viewWidgetsPage.chartWidget, - widgetsPage.widgetNameSpan, - ); - cy.EnableAllCodeEditors(); - //changing the Chart Title - /** - * @param{Text} Random Input Value - */ - cy.testJsontext("title", this.dataSet.chartIndata); - cy.get(viewWidgetsPage.chartInnerText) - .click() - .contains("App Sign Up") - .should("have.text", "App Sign Up"); - - //Entering the Chart data - cy.testJsontext( - "chart-series-data-control", - JSON.stringify(this.dataSet.chartInput), - ); - cy.get(".t--propertypane").click("right"); - - // Asserting Chart Height - cy.get(viewWidgetsPage.chartWidget) - .should("be.visible") - .and((chart) => { - expect(chart.height()).to.be.greaterThan(200); - }); - - //Entring the label of x-axis - cy.get(viewWidgetsPage.xlabel) - .click({ force: true }) - .type(this.dataSet.command) - .type(this.dataSet.plan); - //Entring the label of y-axis - cy.get(viewWidgetsPage.ylabel) - .click({ force: true }) - .type(this.dataSet.command) - .click({ force: true }) - .type(this.dataSet.ylabel); - - _.deployMode.DeployApp(); - }); - - it("2. Chart - Modal", function () { - //creating the Modal and verify Modal name - cy.createModal(this.dataSet.ModalName, "onDataPointClick"); - _.deployMode.DeployApp(); - cy.get(widgetsPage.chartPlotGroup).children().first().click(); - cy.get(modalWidgetPage.modelTextField).should( - "have.text", - this.dataSet.ModalName, - ); - }); - - it("3. Chart-Unckeck Visible field Validation", function () { - // Making the widget invisible - cy.togglebarDisable(commonlocators.visibleCheckbox); - _.deployMode.DeployApp(); - cy.get(publish.chartWidget).should("not.exist"); - }); - - it("4. Chart-Check Visible field Validation", function () { - // Making the widget visible - cy.togglebar(commonlocators.visibleCheckbox); - _.deployMode.DeployApp(); - cy.get(publish.chartWidget).should("be.visible"); - }); - - it("5. Toggle JS - Chart-Unckeck Visible field Validation", function () { - //Uncheck the disabled checkbox using JS and validate - cy.get(widgetsPage.toggleVisible).click({ force: true }); - cy.testJsontext("visible", "false"); - _.deployMode.DeployApp(); - cy.get(publish.chartWidget).should("not.exist"); - }); - - it("6. Toggle JS - Chart-Check Visible field Validation", function () { - //Check the disabled checkbox using JS and Validate - cy.testJsontext("visible", "true"); - _.deployMode.DeployApp(); - cy.get(publish.chartWidget).should("be.visible"); - }); - - it("7. Chart Widget Functionality To Uncheck Horizontal Scroll Visible", function () { - cy.togglebarDisable(commonlocators.allowScroll); - _.deployMode.DeployApp(); - cy.get(publish.horizontalTab).should("not.exist"); - }); - - it("8. Chart Widget Functionality To Check Horizontal Scroll Visible", function () { - cy.togglebar(commonlocators.allowScroll); - _.deployMode.DeployApp(); - cy.get(publish.horizontalTab).eq(1).should("exist"); - }); - - afterEach(() => { - _.deployMode.NavigateBacktoEditor(); - }); -}); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom_Chart_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom_Chart_spec.js index f41cb4a1d7..f40c9811f2 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom_Chart_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Chart/Custom_Chart_spec.js @@ -77,10 +77,12 @@ describe("Chart Widget Functionality around custom chart feature", function () { cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); const labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]; [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) + cy.get(viewWidgetsPage.fusionRectangleChart) .eq(k) .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); + cy.get(viewWidgetsPage.FusionChartlabel) + .eq(k) + .should("have.text", labels[k]); }); _.deployMode.DeployApp(); }); @@ -94,17 +96,19 @@ describe("Chart Widget Functionality around custom chart feature", function () { "response.body.responseMeta.status", 200, ); - cy.get(viewWidgetsPage.Chartlabel + ":first-child", { + cy.get(viewWidgetsPage.FusionChartlabel + ":first-child", { timeout: 10000, }).should("have.css", "opacity", "1"); //Verifying X-axis labels cy.get(viewWidgetsPage.chartWidget).should("have.css", "opacity", "1"); const labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]; [0, 1, 2, 3, 4, 5, 6].forEach((k) => { - cy.get(viewWidgetsPage.rectangleChart) + cy.get(viewWidgetsPage.fusionRectangleChart) .eq(k) .trigger("mousemove", { force: true }); - cy.get(viewWidgetsPage.Chartlabel).eq(k).should("have.text", labels[k]); + cy.get(viewWidgetsPage.FusionChartlabel) + .eq(k) + .should("have.text", labels[k]); }); //Close edit prop diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_onOptionChange_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_onOptionChange_spec.js index ff6bb0277a..f06d14b406 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_onOptionChange_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Dropdown/Dropdown_onOptionChange_spec.js @@ -18,9 +18,10 @@ describe("Dropdown Widget", function () { it("1. Dropdown-Modal Validation", function () { entityExplorer.ExpandCollapseEntity("Container3", "Widgets"); entityExplorer.SelectEntityByName("Dropdown1", "Widgets"); - - cy.EnableAllCodeEditors(); - cy.testJsontext("sourcedata", JSON.stringify(this.dataSet.input)); + propPane.UpdatePropertyFieldValue( + "Source Data", + JSON.stringify(this.dataSet.input), + ); //creating the Modal and verify Modal name //to fix below // cy.createModal("Modal1", false); // deployMode.DeployApp(); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_FilePicker_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_FilePicker_spec.js index 1a9772fea5..74ff4254fd 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_FilePicker_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_FilePicker_spec.js @@ -57,13 +57,15 @@ describe(" File Picker Widget", function () { // Test for isValid === True cy.dragAndDropToWidget("textwidget", "listwidgetv2", { x: 550, - y: 50, + y: 100, }); - cy.RenameWidgetFromPropertyPane("textwidget", "Text1", "FilePicker_Widget"); + propPane.RenameWidget("Text1", "FilePicker_Widget"); + propPane.UpdatePropertyFieldValue( "Text", "{{currentView.FilePicker1.isDirty}}_{{currentView.FilePicker1.isValid}}_{{currentView.FilePicker1.files[0]?.name}}", + false, ); cy.get( `${widgetSelector("FilePicker_Widget")} ${commonlocators.bodyTextStyle}`, diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Inputs_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Inputs_spec.js index da8667a8a9..584ada7cd1 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Inputs_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Childwigets/List_Inputs_spec.js @@ -77,7 +77,7 @@ describe("Input Widgets", function () { it("2. Input Widgets isValid", function () { // Test for isValid === True _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.TEXT, 600, 300); - cy.RenameWidgetFromPropertyPane("textwidget", "Text1", "Input_Widget"); + _.propPane.RenameWidget("Text1", "Input_Widget"); cy.wait(1000); _.propPane.UpdatePropertyFieldValue( "Text", @@ -87,8 +87,9 @@ describe("Input Widgets", function () { .first() .should("have.text", "true"); - _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.TEXT, 600, 100); - cy.RenameWidgetFromPropertyPane("textwidget", "Text1", "Currency_Widget"); + _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.TEXT, 700, 100); + _.propPane.RenameWidget("Text1", "Currency_Widget"); + cy.wait(1000); _.propPane.UpdatePropertyFieldValue( "Text", @@ -100,9 +101,8 @@ describe("Input Widgets", function () { .first() .should("have.text", "true"); - _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.TEXT, 600, 200); - - cy.RenameWidgetFromPropertyPane("textwidget", "Text1", "PhoneInput_Widget"); + _.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.TEXT, 500, 400); + _.propPane.RenameWidget("Text1", "PhoneInput_Widget"); cy.wait(1000); _.propPane.UpdatePropertyFieldValue( "Text", diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_SerververSide_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_SerververSide_spec.js index 0103dd23fb..b02ea8c99f 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_SerververSide_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_SerververSide_spec.js @@ -3,6 +3,7 @@ import { deployMode, entityExplorer, jsEditor, + locators, } from "../../../../../support/Objects/ObjectsCore"; const commonlocators = require("../../../../../locators/commonlocators.json"); @@ -78,10 +79,9 @@ describe("List widget V2 Serverside Pagination", () => { cy.wrap(data).should("deep.equal", {}); }); - // Select First Row - cy.get(`${widgetSelector("List1")} ${containerWidgetSelector}`) - .eq(0) - .click(); + // Select First Row in List + agHelper.GetNClick(locators._imgWidgetInsideList, 0, true); + cy.wait(200); cy.get( diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_nested_List_widget_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_nested_List_widget_spec.js index 7b0bc9ac71..c1bb60260f 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_nested_List_widget_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_nested_List_widget_spec.js @@ -85,25 +85,12 @@ describe(" Nested List Widgets ", function () { y: 100, }, ); - propPane.RemoveText("Text"); + propPane.TypeTextIntoField("Text", "{{level_1.currentView."); - cy.get(".t--property-control-text .CodeMirror textarea").type( - "{{level_1.currentView.", - { - force: true, - }, - ); checkAutosuggestion("Text1", "Object"); checkAutosuggestion("List1Copy", "Object"); - propPane.RemoveText("Text", false); - - cy.get(".t--property-control-text .CodeMirror textarea").type( - "{{level_1.currentView.List1Copy.", - { - force: true, - }, - ); + propPane.TypeTextIntoField("Text", "{{level_1.currentView.List1Copy."); checkAutosuggestion("backgroundColor", "String"); checkAutosuggestion("itemSpacing", "Number"); checkAutosuggestion("isVisible", "Boolean"); @@ -123,10 +110,7 @@ describe(" Nested List Widgets ", function () { cy.wrap($el).should("not.have.text", "triggeredItemView"); }); - cy.get(".CodeMirror-hints") - .contains("pageNo") - .first() - .click({ force: true }); + agHelper.GetNClickByContains(".CodeMirror-hints", "pageNo", 0, true); cy.get(`${widgetSelector("Text2")} .bp3-ui-text span`).should( "have.text", diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_onItemClick_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_onItemClick_spec.js index f41cca7ec3..4cd81f10c6 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_onItemClick_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_onItemClick_spec.js @@ -4,6 +4,8 @@ import { agHelper, draggableWidgets, entityExplorer, + locators, + propPane, } from "../../../../../support/Objects/ObjectsCore"; const toggleJSButton = (name) => `.t--property-control-${name} .t--js-toggle`; const widgetSelector = (name) => `[data-widgetname-cy="${name}"]`; @@ -69,10 +71,11 @@ describe("List widget v2 onItemClick", () => { }); it("2. List widget V2 with onItemClick should be triggered when child widget without event is clicked", () => { - cy.get(widgetSelector("Image1")).first().click({ force: true }); + //Select first row Image within list + agHelper.GetNClick(locators._imgWidgetInsideList, 0, true); agHelper.WaitUntilToastDisappear("ListWidget_Blue_0"); - cy.get(widgetSelector("Text1")).first().click({ force: true }); + agHelper.GetNClickByContains(locators._textWidget, "Blue", 0, true); agHelper.WaitUntilToastDisappear("ListWidget_Blue_0"); deleteAllWidgetsInContainer(); @@ -84,10 +87,8 @@ describe("List widget v2 onItemClick", () => { draggableWidgets.CONTAINER, ); - cy.get(`${widgetSelector("Input1")} input`) - .first() - .click({ force: true }); - validateToastDoestExist(); + agHelper.GetNClick(`${locators._widgetByName("Input1")} input`, 0, true); + agHelper.AssertElementAbsence(locators._toastMsg); deleteAllWidgetsInContainer(); @@ -98,10 +99,9 @@ describe("List widget v2 onItemClick", () => { draggableWidgets.CONTAINER, ); - cy.get(`${widgetSelector("Select1")} button`) - .first() - .click({ force: true }); - validateToastDoestExist(); + //This is clicking Select Widget + agHelper.ClickButton("Green", 0); + agHelper.AssertElementAbsence(locators._toastMsg); deleteAllWidgetsInContainer(); @@ -112,20 +112,13 @@ describe("List widget v2 onItemClick", () => { draggableWidgets.CONTAINER, ); - cy.get(`${widgetSelector("Button1")} button`) - .first() - .click({ force: true }); + agHelper.ClickButton("Submit", 0); agHelper.WaitUntilToastDisappear("ListWidget_Blue_0"); - cy.get(widgetsPage.toggleOnClick).click({ force: true }); - cy.get(".t--property-control-onclick").then(($el) => { - cy.updateCodeInput($el, "{{clearStore()}}"); - }); - cy.wait(1000); + propPane.EnterJSContext("onClick", "{{clearStore()}}"); + agHelper.Sleep(1000); - cy.get(`${widgetSelector("Button1")} button`) - .first() - .click({ force: true }); - validateToastDoestExist(); + agHelper.ClickButton("Submit", 0); + agHelper.AssertElementAbsence(locators._toastMsg); }); }); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/Video_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/Video_spec.js index 472472f7cf..30bc871637 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/Video_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Others/Video_spec.js @@ -4,6 +4,7 @@ import { agHelper, entityExplorer, draggableWidgets, + propPane, } from "../../../../../support/Objects/ObjectsCore"; describe("Video Widget Functionality", function () { @@ -70,27 +71,32 @@ describe("Video Widget Functionality", function () { }); it("4. Checks if video widget is reset on button click", function () { - cy.testCodeMirror(testdata.videoUrl2); + propPane.UpdatePropertyFieldValue("URL", testdata.videoUrl2); entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 200, 200); cy.selectResetWidget("onClick"); cy.selectWidgetForReset("Video1"); entityExplorer.DragDropWidgetNVerify(draggableWidgets.TEXT, 300, 300); - - cy.updateCodeInput(".t--property-control-text", `{{Video1.playState}}`); + propPane.UpdatePropertyFieldValue("Text", "{{Video1.playState}}"); + agHelper.Sleep(1500); // Wait time added for the widget to load current video state cy.openPropertyPane("videowidget"); - cy.get(widgetsPage.autoPlay).click({ force: true }); - // Wait time added, allowing a second to pass between playing and pausing the widget, before it is reset to zero - cy.wait(1000); - cy.get(widgetsPage.autoPlay).click({ force: true }); - cy.get(widgetsPage.widgetBtn).click({ force: true }); + propPane.TogglePropertyState("Autoplay", "On"); + agHelper.Sleep(1500); // Wait time added for the widget to load current video state + cy.get(".t--widget-textwidget").should("contain", "ENDED"); + + propPane.TogglePropertyState("Autoplay", "Off"); + agHelper.Sleep(1500); // Wait time added, allowing a second to pass between playing and pausing the widget, before it is reset to zero + cy.get(".t--widget-textwidget").should("contain", "PAUSED"); + + agHelper.ClickButton("Submit"); cy.wait(1000); cy.get(`${widgetsPage.videoWidget} video`).then(($video) => { const video = $video.get(0); expect(video.currentTime).to.equal(0); }); + agHelper.Sleep(1500); // Wait time added for the widget to load current video state cy.get(".t--widget-textwidget").should("contain", "NOT_STARTED"); }); diff --git a/app/client/cypress/e2e/Regression/Enterprise/AdminSettings/Admin_settings_spec.js b/app/client/cypress/e2e/Regression/Enterprise/AdminSettings/Admin_settings_spec.js index 4c85d7febf..5f1eb0dce7 100644 --- a/app/client/cypress/e2e/Regression/Enterprise/AdminSettings/Admin_settings_spec.js +++ b/app/client/cypress/e2e/Regression/Enterprise/AdminSettings/Admin_settings_spec.js @@ -59,9 +59,15 @@ describe("Admin settings page", function () { cy.go(-1); } }); + it("3. should test that Business features shows upgrade button and direct to pricing page", () => { cy.visit("/settings/general", { timeout: 60000 }); if (CURRENT_REPO === REPO.CE) { + cy.get(adminsSettings.accessControl).within(() => { + cy.get(adminsSettings.businessTag) + .should("exist") + .should("contain", "Business"); + }); cy.get(adminsSettings.accessControl).click(); cy.url().should("contain", "/settings/access-control"); stubPricingPage(); @@ -69,6 +75,11 @@ describe("Admin settings page", function () { cy.get("@pricingPage").should("be.called"); cy.wait(2000); cy.go(-1); + cy.get(adminsSettings.auditLogs).within(() => { + cy.get(adminsSettings.businessTag) + .should("exist") + .should("contain", "Business"); + }); cy.get(adminsSettings.auditLogs).click(); cy.url().should("contain", "/settings/audit-logs"); stubPricingPage(); @@ -76,6 +87,18 @@ describe("Admin settings page", function () { cy.get("@pricingPage").should("be.called"); cy.wait(2000); cy.go(-1); + cy.get(adminsSettings.provisioning).within(() => { + cy.get(adminsSettings.businessTag) + .should("exist") + .should("contain", "Enterprise"); + }); + cy.get(adminsSettings.provisioning).click(); + cy.url().should("contain", "/settings/provisioning"); + stubPricingPage(); + cy.xpath(adminsSettings.upgrade).click(); + cy.get("@pricingPage").should("be.called"); + cy.wait(2000); + cy.go(-1); } }); }); diff --git a/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/MongoURI_Spec.ts b/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/MongoURI_Spec.ts new file mode 100644 index 0000000000..7a0c492edb --- /dev/null +++ b/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/MongoURI_Spec.ts @@ -0,0 +1,232 @@ +import { + agHelper, + entityExplorer, + deployMode, + appSettings, + dataSources, + table, + locators, + assertHelper, + draggableWidgets, +} from "../../../../support/Objects/ObjectsCore"; +import { Widgets } from "../../../../support/Pages/DataSources"; + +describe("Validate Mongo URI CRUD with JSON Form", () => { + let dsName: any; + + it("1. Create DS & Generate CRUD template", () => { + dataSources.NavigateToDSCreateNew(); + agHelper.GenerateUUID(); + cy.get("@guid").then((uid) => { + dataSources.CreatePlugIn("MongoDB"); + dsName = "Mongo" + uid; + agHelper.RenameWithInPane(dsName, false); + dataSources.FillMongoDatasourceFormWithURI(); + dataSources.TestSaveDatasource(); + entityExplorer.AddNewPage("Generate page with data"); + agHelper.GetNClick(dataSources._selectDatasourceDropdown); + agHelper.GetNClickByContains(dataSources._dropdownOption, dsName); + + assertHelper.AssertNetworkStatus("@getDatasourceStructure"); //Making sure table dropdown is populated + agHelper.GetNClick(dataSources._selectTableDropdown, 0, true); + agHelper.GetNClickByContains(dataSources._dropdownOption, "mongomart"); + GenerateCRUDNValidateDeployPage( + "/img/products/mug.jpg", + "Coffee Mug", + `Kitchen`, + 4, + ); + + deployMode.NavigateBacktoEditor(); + table.WaitUntilTableLoad(); + //Should not be able to delete ds until app is published again + //coz if app is published & shared then deleting ds may cause issue, So! + dataSources.DeleteDatasouceFromActiveTab(dsName as string, 409); + }); + }); + + it("2. Verify Update data from Deploy page - on mongomart - existing record", () => { + //Update documents query to handle the int _id data + entityExplorer.NavigateToSwitcher("Explorer", 0, true); + entityExplorer.SelectEntityByName("UpdateQuery"); + agHelper.EnterValue(`{ _id: {{data_table.selectedRow._id}}}`, { + propFieldName: "", + directInput: false, + inputFieldName: "Query", + }); + deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE_V1)); + agHelper.GetNAssertElementText( + locators._textWidgetInDeployed, + "mongomart Data", + ); + //Validating loaded table + table.SelectTableRow(2); + agHelper.AssertElementExist(dataSources._selectedRow); + table.ReadTableRowColumnData(2, 0, "v1", 200).then(($cellData) => { + expect($cellData).to.be.empty; + }); + table.ReadTableRowColumnData(2, 6, "v1", 2000).then(($cellData) => { + expect($cellData).to.eq("WiredTiger T-shirt"); + }); + table.ReadTableRowColumnData(2, 7, "v1", 200).then(($cellData) => { + expect($cellData).to.eq("Apparel"); + }); + + table.SelectTableRow(8); + deployMode.ClearJSONFieldValue("Slogan"); + deployMode.ClearJSONFieldValue("Category"); + + agHelper.ClickButton("Update"); + agHelper.AssertElementAbsence(locators._toastMsg); //Validating fix for Bug 14063 + for (let i = 7; i <= 8; i++) { + table.ReadTableRowColumnData(8, i, "v1").then(($cellData) => { + expect($cellData).to.be.empty; + }); + } + deployMode.EnterJSONInputValue( + "Slogan", + "Write Your Story with Elegance: The Pen of Choice!", + ); + agHelper.GetNClick(deployMode._jsonFormNumberFieldByName("Stars", "up")); //1 + agHelper.GetNClick(deployMode._jsonFormNumberFieldByName("Stars", "up")); //2 + agHelper.GetNClick(deployMode._jsonFormNumberFieldByName("Stars", "up")); //3 + + agHelper.ClickButton("Update"); + agHelper.AssertElementAbsence(locators._toastMsg); //Validating fix for Bug 14063 + table.ReadTableRowColumnData(8, 8, "v1", 200).then(($cellData) => { + expect($cellData).to.eq( + "Write Your Story with Elegance: The Pen of Choice!", + ); + }); + table.ReadTableRowColumnData(8, 5, "v1", 200).then(($cellData) => { + expect($cellData).to.eq("3"); + }); + }); + + it("3. Verify Add/Insert from Deploy page - on MongoMart - new record - few validations", () => { + agHelper.GetNClick(dataSources._addIcon); + agHelper.Sleep(); + //agHelper.AssertElementVisible(locators._jsonFormWidget, 1); //Insert Modal + agHelper.AssertElementVisible(locators._visibleTextDiv("Insert Document")); + + agHelper.AssertElementEnabledDisabled( + locators._spanButton("Submit") + "/parent::div", + 0, + false, + ); + agHelper.ClickButton("Submit"); + for (let i = 0; i <= 1; i++) { + table.ReadTableRowColumnData(i, 6, "v1").then(($cellData) => { + expect($cellData).contains("Coffee Mug"); + }); + } + }); + + it("4. Verify Delete from Deploy page - on MongoMart - newly added record", () => { + agHelper.ClickButton("Delete", 0); + agHelper.AssertElementVisible(locators._modal); + agHelper.AssertElementVisible( + dataSources._visibleTextSpan( + "Are you sure you want to delete this document?", + ), + ); + agHelper.ClickButton("Confirm"); + assertHelper.AssertNetworkStatus("@postExecute", 200); + assertHelper.AssertNetworkStatus("@postExecute", 200); + table.ReadTableRowColumnData(0, 6, "v1", 200).then(($cellData) => { + expect($cellData).to.eq("Coffee Mug"); + }); + table.ReadTableRowColumnData(1, 6, "v1", 200).then(($cellData) => { + expect($cellData).to.eq("Track Jacket"); + }); + }); + + it("5 Verify Filter & Search & Download from Deploy page - on MongoMart - existing record", () => { + table.SearchTable("Swag"); + agHelper.Sleep(2500); //for search to load + for (let i = 0; i <= 1; i++) { + table.ReadTableRowColumnData(i, 6, "v1").then(($cellData) => { + expect($cellData).to.eq("Swag"); + }); + } + table.ResetSearch(); + + table.OpenNFilterTable("title", "contains", "USB"); + for (let i = 0; i < 3; i++) { + table.ReadTableRowColumnData(i, 5, "v1").then(($cellData) => { + expect($cellData).contains("USB"); + }); + } + table.CloseFilter(); + + table.DownloadFromTable("Download as CSV"); + table.ValidateDownloadNVerify("data_table.csv", "USB Stick (Green)"); + + table.DownloadFromTable("Download as Excel"); + table.ValidateDownloadNVerify("data_table.xlsx", "USB Stick (Leaf)"); + table.OpenFilter(); + table.RemoveFilter(); + agHelper + .GetText(table._filtersCount) + .then(($filters) => expect($filters).to.eq("Filters")); + }); + + it("6. Suggested Widget - Table", () => { + table.SelectTableRow(8); + agHelper.GetNClick(deployMode._jsonFormNumberFieldByName("Stars", "down")); //2 + agHelper.GetNClick(deployMode._jsonFormNumberFieldByName("Stars", "down")); //1 + agHelper.GetNClick(deployMode._jsonFormNumberFieldByName("Stars", "down")); //0 + agHelper.ClickButton("Update"); + + deployMode.NavigateBacktoEditor(); + table.WaitUntilTableLoad(); + entityExplorer.AddNewPage(); + dataSources.NavigateFromActiveDS(dsName, true); + dataSources.ValidateNSelectDropdown("Collection", "", "mongomart"); + dataSources.RunQuery({ toValidateResponse: false }); + dataSources.AddSuggesstedWidget(Widgets.Table); + table.ReadTableRowColumnData(0, 3, "v2").then((cellData) => { + expect(cellData).to.eq("1"); + }); + }); +}); + +function GenerateCRUDNValidateDeployPage( + col1Text: string, + col6Text: string, + col7Text: string, + idIndex: number, +) { + agHelper.GetNClick(dataSources._generatePageBtn); + assertHelper.AssertNetworkStatus("@replaceLayoutWithCRUDPage", 201); + agHelper.AssertContains("Successfully generated a page"); // Commenting this since FindQuery failure appears sometimes + assertHelper.AssertNetworkStatus("@getActions", 200); + assertHelper.AssertNetworkStatus("@postExecute", 200); + agHelper.GetNClick(dataSources._visibleTextSpan("Got it")); + assertHelper.AssertNetworkStatus("@updateLayout", 200); + appSettings.OpenPaneAndChangeTheme("Pacific"); + deployMode.DeployApp(locators._widgetInDeployed("tablewidget")); + + //Validating loaded table + agHelper.AssertElementExist(dataSources._selectedRow); + table.ReadTableRowColumnData(0, 1, "v1", 2000).then(($cellData) => { + expect($cellData).to.eq(col1Text); + }); + table.ReadTableRowColumnData(0, 6, "v1", 200).then(($cellData) => { + expect($cellData).to.eq(col6Text); + }); + table.ReadTableRowColumnData(0, 7, "v1", 200).then(($cellData) => { + expect($cellData).to.eq(col7Text); + }); + + //Validating loaded JSON form + cy.xpath(locators._spanButton("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); +} diff --git a/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/S3_Spec.js b/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/S3_Spec.js index 1826ecf906..080aa82560 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/S3_Spec.js +++ b/app/client/cypress/e2e/Regression/ServerSide/GenerateCRUD/S3_Spec.js @@ -3,6 +3,8 @@ const datasourceEditor = require("../../../../locators/DatasourcesEditor.json"); const commonlocators = require("../../../../locators/commonlocators.json"); import { + agHelper, + dataSources, entityExplorer, deployMode, homePage, @@ -34,13 +36,8 @@ describe("Generate New CRUD Page Inside from entity explorer", function () { cy.wrap(datasourceName).as("dSName"); }); - //TestData source - cy.get(".t--test-datasource").click(); - cy.wait("@testDatasource"); - - //Save source - cy.get(".t--save-datasource").click(); - + //TestData & save datasource + dataSources.TestSaveDatasource(); // fetch bucket cy.wait("@getDatasourceStructure").should( "have.nested.property", @@ -48,13 +45,13 @@ describe("Generate New CRUD Page Inside from entity explorer", function () { 200, ); - cy.get(generatePage.selectTableDropdown).click(); - cy.get(generatePage.dropdownOption) - .contains("assets-test.appsmith.com") - .scrollIntoView() - .should("be.visible") - .click(); - cy.get(generatePage.generatePageFormSubmitBtn).click(); + agHelper.AssertContains("Generate from data"); + agHelper.GetNClick(generatePage.selectTableDropdown); + agHelper.GetNClickByContains( + generatePage.dropdownOption, + "assets-test.appsmith.com", + ); + agHelper.GetNClick(generatePage.generatePageFormSubmitBtn); cy.wait("@put_replaceLayoutCRUD").should( "have.nested.property", diff --git a/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.js b/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.js index 55df36dc9c..75dadb15ce 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.js +++ b/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.js @@ -83,7 +83,6 @@ describe("Validate Mongo query commands", function () { ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "listingAndReviews", }); @@ -153,7 +152,6 @@ describe("Validate Mongo query commands", function () { "Count", ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "listingAndReviews", }); @@ -182,7 +180,6 @@ describe("Validate Mongo query commands", function () { "Distinct", ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "listingAndReviews", }); @@ -215,7 +212,6 @@ describe("Validate Mongo query commands", function () { "Aggregate", ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "listingAndReviews", }); @@ -411,7 +407,6 @@ describe("Validate Mongo query commands", function () { {"_id":3, "Från" :"Olivia" , "Frõ" :"Active", "Leverantör":"De Bolster", "Frö":"Sallad - Oakleaf 'Red Salad Bowl'"}]`; dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "NonAsciiTest", }); diff --git a/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.ts b/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.ts index bb6c4aeece..bd53cb2ddb 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.ts +++ b/app/client/cypress/e2e/Regression/ServerSide/QueryPane/Mongo_Spec.ts @@ -287,7 +287,6 @@ describe("Validate Mongo Query Pane Validations", () => { ); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "AuthorNAwards", }); @@ -777,7 +776,6 @@ describe("Validate Mongo Query Pane Validations", () => { agHelper.RenameWithInPane("InsertBirthNDeath"); dataSources.EnterJSContext({ - fieldProperty: dataSources._mongoCollectionPath, fieldLabel: "Collection", fieldValue: "BirthNDeath", }); diff --git a/app/client/cypress/e2e/Sanity/Datasources/Airtable_Basic_Spec.ts b/app/client/cypress/e2e/Sanity/Datasources/Airtable_Basic_Spec.ts index 9d13200d5a..bd3de7ce4f 100644 --- a/app/client/cypress/e2e/Sanity/Datasources/Airtable_Basic_Spec.ts +++ b/app/client/cypress/e2e/Sanity/Datasources/Airtable_Basic_Spec.ts @@ -8,7 +8,7 @@ import { } from "../../../support/Objects/ObjectsCore"; let dsName: any, jsonSpecies: any, offset: any, insertedRecordId: any; -describe.skip("excludeForAirgap", "Validate Airtable Ds", () => { +describe("excludeForAirgap", "Validate Airtable Ds", () => { before("Create a new Airtable DS", () => { dataSources.CreateDataSource("Airtable", true, false); cy.get("@dsName").then(($dsName) => { @@ -259,7 +259,8 @@ describe.skip("excludeForAirgap", "Validate Airtable Ds", () => { }); }); - it("2. Create/Retrieve/Update/Delete records", () => { + //Skipping since Create records sometimes not giving results + it.skip("2. Create/Retrieve/Update/Delete records", () => { let createReq = `[{"fields": { "Species_ID": "SF", "Genus": "Sigmodon", @@ -379,6 +380,6 @@ describe.skip("excludeForAirgap", "Validate Airtable Ds", () => { action: "Delete", entityType: entityItems.Datasource, }); - assertHelper.AssertNetworkStatus("@deleteDatasource", 200); + //assertHelper.AssertNetworkStatus("@deleteDatasource", 200); //to uncomment after 2nd case is fixed }); }); diff --git a/app/client/cypress/e2e/Sanity/Datasources/AuthenticatedApiDatasource_spec.js b/app/client/cypress/e2e/Sanity/Datasources/AuthenticatedApiDatasource_spec.js index 2563184729..65e21acb99 100644 --- a/app/client/cypress/e2e/Sanity/Datasources/AuthenticatedApiDatasource_spec.js +++ b/app/client/cypress/e2e/Sanity/Datasources/AuthenticatedApiDatasource_spec.js @@ -41,7 +41,8 @@ describe("Authenticated API Datasource", function () { dataSources.DeleteDatasouceFromActiveTab(dsName); }); - it("4. Bug: 18051 - Save and Authorise should return to datasource page in view mode and not new datasource page", () => { + //skipping this test as it is failing in pipeline - "authorizationURL": "https://oauth.mocklab.io/oauth/authorize", + it.skip("4. Bug: 18051 - Save and Authorise should return to datasource page in view mode and not new datasource page", () => { cy.NavigateToAPI_Panel(); cy.get(apiwidget.createAuthApiDatasource).click(); cy.generateUUID().then((uuid) => { diff --git a/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts b/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts index a6d10560f4..92ef443468 100644 --- a/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts +++ b/app/client/cypress/e2e/Sanity/Datasources/MsSQL_Basic_Spec.ts @@ -241,12 +241,8 @@ describe("Validate MsSQL connection & basic querying with UI flows", () => { }); after("Verify Deletion of the datasource", () => { - entityExplorer.SelectEntityByName(dsName, "Datasources"); - entityExplorer.ActionContextMenuByEntityName({ - entityNameinLeftSidebar: dsName, - action: "Delete", - entityType: entityItems.Datasource, - }); + cy.intercept("DELETE", "/api/v1/datasources/*").as("deleteDatasource"); //Since intercept from before is not working + dataSources.DeleteDatasouceFromWinthinDS(dsName); //dataSources.StopNDeleteContainer(containerName); //commenting to check if MsSQL specific container deletion is causing issues }); diff --git a/app/client/cypress/e2e/Sanity/Datasources/RestApiOAuth2Validation_spec.js b/app/client/cypress/e2e/Sanity/Datasources/RestApiOAuth2Validation_spec.js index 9f96ed652c..80b7a7fe0f 100644 --- a/app/client/cypress/e2e/Sanity/Datasources/RestApiOAuth2Validation_spec.js +++ b/app/client/cypress/e2e/Sanity/Datasources/RestApiOAuth2Validation_spec.js @@ -12,10 +12,8 @@ describe("Datasource form OAuth2 client credentials related tests", function () it("1. Create an API with app url and save as Datasource for Client Credentials test", function () { apiPage.CreateAndFillApi(testdata.appUrl, "TestOAuth"); agHelper.GetNClick(apiPage._saveAsDS); - // agHelper.ValidateToastMessage("datasource created"); //verifying there is no error toast, Bug 14566 - }); - it("2. Add Oauth details to datasource and save", function () { + // Add Oauth details to datasource and save cy.get(datasource.saveBtn).should("not.be.disabled"); dataSources.AddOAuth2AuthorizationCodeDetails( testdata.accessTokenUrl, @@ -27,7 +25,7 @@ describe("Datasource form OAuth2 client credentials related tests", function () // since we are moving to different, it will show unsaved changes dialog // save datasource and then proceed dataSources.SaveDatasource(); - + agHelper.ValidateToastMessage("datasource created"); //verifying there is no error toast, Bug 14566 entityExplorer.SelectEntityByName("TestOAuth", "Queries/JS"); agHelper.ActionContextMenuWithInPane({ action: "Delete", @@ -35,13 +33,10 @@ describe("Datasource form OAuth2 client credentials related tests", function () }); }); - it("3. Create an API with app url and save as Datasource for Authorization code details test", function () { + it("2. Create an API with app url and save as Datasource for Authorization code details test", function () { apiPage.CreateAndFillApi(testdata.appUrl, "TestOAuth"); agHelper.GetNClick(apiPage._saveAsDS); - // agHelper.ValidateToastMessage("datasource created"); //verifying there is no error toast, Bug 14566 - }); - - it("4. Add Oauth details to datasource and save", function () { + //Add Oauth details to datasource and save cy.get(datasource.saveBtn).should("not.be.disabled"); dataSources.AddOAuth2AuthorizationCodeDetails( testdata.accessTokenUrl, @@ -51,7 +46,8 @@ describe("Datasource form OAuth2 client credentials related tests", function () ); }); - it("5. Validate save and Authorise", function () { + //skipping this test as it is failing in pipeline - "authorizationURL": "https://oauth.mocklab.io/oauth/authorize", + it.skip("3. Validate save and Authorise", function () { cy.get(datasource.saveAndAuthorize).click(); cy.contains("#login-submit", "Login"); cy.url().should("include", "oauth.mocklab.io/oauth/authorize"); diff --git a/app/client/cypress/fixtures/test-data-gsheet.ts b/app/client/cypress/fixtures/test-data-gsheet.ts new file mode 100644 index 0000000000..05d45543c0 --- /dev/null +++ b/app/client/cypress/fixtures/test-data-gsheet.ts @@ -0,0 +1,192 @@ +export const GSHEET_DATA = [ + { + rowIndex: "0", + uniq_id: "eac7efa5dbd3d667f26eb3d3ab504464", + japanese_name: "ホーンビィ 2014 カタログ", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: "Hornby 2014 Catalogue", + manufacturer: "Hornby", + price: "3.42", + number_available_in_stock: "5 new", + number_of_reviews: "15", + number_of_answered_questions: "1", + average_review_rating: "4.9 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Hornby-R8150-Catalogue-2015/dp/B00S9SUUBE | http://www.amazon.co.uk/Hornby-Book-Model-Railways-Edition/dp/1844860957 | http://www.amazon.co.uk/Hornby-Book-Scenic-Railway-Modelling/dp/1844861120 | http://www.amazon.co.uk/Peco-60-Plans-Book/dp/B002QVL16I | http://www.amazon.co.uk/Hornby-Gloucester | http://www.amazon.co.uk/Airfix-5014429781902", + }, + { + rowIndex: "1", + uniq_id: "b17540ef7e86e461d37f3ae58b7b72ac", + japanese_name: + "FunkyBuys® ラージ クリスマス ホリデー エクスプレス フェスティバル トレイン セット (SI-TY1017) おもちゃ ライト / サウンド / 電池式 & 煙", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: + "FunkyBuys® Large Christmas Holiday Express Festive Train Set (SI-TY1017) Toy Light / Sounds / Battery Operated & Smoke", + manufacturer: "FunkyBuys", + price: "16.99", + number_available_in_stock: "null", + number_of_reviews: "2", + number_of_answered_questions: "1", + average_review_rating: "4.5 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Christmas-Holiday-Express-Festive-Train-Set-Toy/dp/B009R8S8AA | http://www.amazon.co.uk/Goldlok-Holiday-Express-Operated-Multi-Colour/dp/B009R8PAO2 | http://www.amazon.co.uk/FunkyBuys%C2%AE-Christmas-SI-TY1017-Ornaments-Operated/dp/B01437QMHA | http://www.amazon.co.uk/Holiday-Express-Christmas-Ornament-Decoration | http://www.amazon.co.uk/Seasonal-Vision-Christmas-Tree-Train/dp/B0044ZC1W2 | http://www.amazon.co.uk/Coca-Cola-Santa-Express-Train-Set/dp/B004BYSNU0", + }, + { + rowIndex: "2", + uniq_id: "348f344247b0c1a935b1223072ef9d8a", + japanese_name: + "クラシックなおもちゃの電車セット トラック車両 ライトエンジン 箱入り男の子 子供用バッテリー", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: + "CLASSIC TOY TRAIN SET TRACK CARRIAGES LIGHT ENGINE BOXED BOYS KIDS BATTERY", + manufacturer: "ccf", + price: "9.99", + number_available_in_stock: "2 new", + number_of_reviews: "17", + number_of_answered_questions: "2", + average_review_rating: "3.9 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Classic-Train-Lights-Battery-Operated/dp/B0041L9OHE | http://www.amazon.co.uk/Train-With-Tracks-Battery-Operated-x/dp/B009P540O8 | http://www.amazon.co.uk/13-Piece-Train-Set-Ideal/dp/B0173N6E4W | http://www.amazon.co.uk/Train-Flash-Electric-Sound-Europe/dp/B008D7CEH4 | http://www.amazon.co.uk/Train-Ultimate-Sticker-Book-Stickers/dp/1405314516 | http://www.amazon.co.uk/Train-Stickers-Dover-Little-Activity/dp/0486403106", + }, + { + rowIndex: "3", + uniq_id: "e12b92dbb8eaee78b22965d2a9bbbd9f", + japanese_name: "ホーンビー コーチ R4410A BR ホークスワース コリドー 3", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: "HORNBY Coach R4410A BR Hawksworth Corridor 3rd", + manufacturer: "Hornby", + price: "39.99", + number_available_in_stock: "null", + number_of_reviews: "1", + number_of_answered_questions: "2", + average_review_rating: "5.0 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: "null", + }, + { + rowIndex: "4", + uniq_id: "e33a9adeed5f36840ccc227db4682a36", + japanese_name: + "ホーンビー 00 ゲージ 0-4-0 ギルデンロー塩社 蒸気機関車モデル", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: + "Hornby 00 Gauge 0-4-0 Gildenlow Salt Co. Steam Locomotive Model", + manufacturer: "Hornby", + price: "32.19", + number_available_in_stock: "null", + number_of_reviews: "3", + number_of_answered_questions: "2", + average_review_rating: "4.7 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Hornby-R6367-RailRoad-Gauge-Rolling/dp/B000WDWSD2 | http://www.amazon.co.uk/Hornby-R3064-RailRoad-Smokey-Locomotive | http://www.amazon.co.uk/Hornby-R8222-Gauge-Track-Extension/dp/B000RK3FZK | http://www.amazon.co.uk/Hornby-R6371-RailRoad-Petrol-Tanker/dp/B000WDS002 | http://www.amazon.co.uk/Hornby-R076-00-Gauge-Footbridge | http://www.amazon.co.uk/Hornby-R6368-RailRoad-Gauge-Brake/dp/B000WDWT22", + }, + { + rowIndex: "5", + uniq_id: "cb34f0a84102c1ebc3ef6892d7444d36", + japanese_name: "20 個モデルガーデンライトダブルヘッド街灯スケール 1:100", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: "20pcs Model Garden Light Double Heads Lamppost Scale 1:100", + manufacturer: "Generic", + price: "6.99", + number_available_in_stock: "null", + number_of_reviews: "2", + number_of_answered_questions: "1", + average_review_rating: "5.0 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Lighting & Signal Engineering > Lamps & Lighting", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Single-Head-Garden-Lights-Lamppost-Layout/dp/B008XCSHCA | http://www.amazon.co.uk/douself-100Pcs-OO-Scale-Passenger/dp/B00GRUD8W4 | http://www.amazon.co.uk/Hornby-Digital-Electric-Point-Track/dp/B00105UJ14 | http://www.amazon.co.uk/20Pcs-Scenery-Landscape-Train-Flowers/dp/B00C1843MA | http://www.amazon.co.uk/Scenery-Landscape-100-Made-Plastic-Cement/dp/B007UYIJ48", + }, + { + rowIndex: "6", + uniq_id: "f74b562470571dfb689324adf236f82c", + japanese_name: + "Hornby 00 ゲージ 230mm BR ボギー 旅客ブレーキ コーチ モデル (レッド)", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: + "Hornby 00 Gauge 230mm BR Bogie Passenger Brake Coach Model (Red)", + manufacturer: "Hornby", + price: "24.99", + number_available_in_stock: "null", + number_of_reviews: "2", + number_of_answered_questions: "1", + average_review_rating: "4.5 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Hornby-R4388-RailRoad-Composite-Gauge/dp/B00260GEXO | http://www.amazon.co.uk/Hornby-R1138-Passenger-Freight-Electric/dp/B006ZL6976", + }, + { + rowIndex: "7", + uniq_id: "87bbb472ef9d90dcef140a551665c929", + japanese_name: "ホーンビー サンタの特急列車セット", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: "Hornby Santa's Express Train Set", + manufacturer: "Hornby", + price: "69.93", + number_available_in_stock: "3 new", + number_of_reviews: "36", + number_of_answered_questions: "7", + average_review_rating: "4.3 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Hornby-R8221-Gauge-Track-Extension/dp/B000PVFYZ0 | http://www.amazon.co.uk/Hornby-R8222-Gauge-Track-Extension/dp/B000RK3FZK | http://www.amazon.co.uk/Hornby-R6368-RailRoad-Gauge-Brake/dp/B000WDWT22 | http://www.amazon.co.uk/Hornby-R6370-RailRoad-Tredegar-Gauge/dp/B000WDZH58 | http://www.amazon.co.uk/Hornby-R044-Passing-Contact-Switch/dp/B000H5V0RK | http://www.amazon.co.uk/Hornby-Gauge-Logan-Plank-Wagon/dp/B00SWV6RAG", + }, + { + rowIndex: "8", + uniq_id: "7e2aa2b4596a39ba852449718413d7cc", + japanese_name: + "ホーンビー ゲージ ウェスタン エクスプレス デジタル トレイン セット (eLink および TTS ロコ トレイン セット付き)", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: + "Hornby Gauge Western Express Digital Train Set with eLink and TTS Loco Train Set", + manufacturer: "Hornby", + price: "235.58", + number_available_in_stock: "4 new", + number_of_reviews: "1", + number_of_answered_questions: "1", + average_review_rating: "5.0 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Hornby-Western-Master-E-Link-Electric/dp/B00BUKPXS8 | http://www.amazon.co.uk/Hornby-Gloucester | http://www.amazon.co.uk/Hornby-Majestic-E-Link-Gauge-Electric/dp/B00BUKPXU6 | http://www.amazon.co.uk/Hornby-Gauge-Master-Glens/dp/B00TQNJIIW | http://www.amazon.co.uk/Hornby-Gauge-Eurostar-2014-Train/dp/B00TQNJIIC | http://www.amazon.co.uk/HORNBY-Digital-Train-Layout-Track/dp/B006BRH55Y", + }, + { + rowIndex: "9", + uniq_id: "5afbaf65680c9f378af5b3a3ae22427e", + japanese_name: + "ラーニング カーブ チャギントン インタラクティブ チャッツワース", + currencies: "₹, $, €, ¥, £", + specialChars: "!@#$%^&*", + product_name: "Learning Curve Chuggington Interactive Chatsworth", + manufacturer: "Chuggington", + price: "null", + number_available_in_stock: "1 new", + number_of_reviews: "8", + number_of_answered_questions: "1", + average_review_rating: "4.8 out of 5 stars", + amazon_category_and_sub_category: + "Hobbies > Model Trains & Railway Sets > Rail Vehicles > Trains", + customers_who_bought_this_item_also_bought: + "http://www.amazon.co.uk/Learning-Curve-Chuggington | http://www.amazon.co.uk/Chuggington | http://www.amazon.co.uk/Learning-Curve-Chuggington | http://www.amazon.co.uk/Learning-Chuggington", + }, +]; diff --git a/app/client/cypress/locators/AdminsSettings.js b/app/client/cypress/locators/AdminsSettings.js index 22516a2cfa..a4ded79085 100644 --- a/app/client/cypress/locators/AdminsSettings.js +++ b/app/client/cypress/locators/AdminsSettings.js @@ -29,5 +29,7 @@ export default { upgrade: "//button//span[text()='Upgrade']", accessControl: ".t--settings-category-access-control", auditLogs: ".t--settings-category-audit-logs", + provisioning: ".t--settings-category-provisioning", upgrageLeftPane: "[data-testid='t--enterprise-settings-category-item-be']", + businessTag: "[data-testid='t--business-tag']", }; diff --git a/app/client/cypress/locators/FirstTimeUserOnboarding.json b/app/client/cypress/locators/FirstTimeUserOnboarding.json index 707cc1c4e7..1f840b515a 100644 --- a/app/client/cypress/locators/FirstTimeUserOnboarding.json +++ b/app/client/cypress/locators/FirstTimeUserOnboarding.json @@ -19,5 +19,6 @@ "textWidgetName": ".t--widget-textwidget", "welcomeTourBtn": ".t--start-building", "editorWelcomeTourBtn": "[data-testid='editor-welcome-tour']", - "checklistCompletionBanner": "[data-testid='checklist-completion-banner']" + "checklistCompletionBanner": "[data-testid='checklist-completion-banner']", + "selectWidgetBtn": ".t--select-in-canvas" } diff --git a/app/client/cypress/locators/ViewWidgets.json b/app/client/cypress/locators/ViewWidgets.json index c2ddc3f1ef..d369cc307c 100644 --- a/app/client/cypress/locators/ViewWidgets.json +++ b/app/client/cypress/locators/ViewWidgets.json @@ -19,7 +19,8 @@ "chartInnerText": ".t--property-control-title", "inputChartValue": ".t--property-control-chartseries .CodeMirror textarea", "chartButton": ".t--property-control-chartseries button", - "rectangleChart": ".t--draggable-chartwidget g rect", + "rectangleChart": ".t--draggable-chartwidget g", + "fusionRectangleChart": ".t--draggable-chartwidget g rect", "xlabel": ".t--property-control-x-axislabel .CodeMirror-code", "ylabel": ".t--property-control-y-axislabel .CodeMirror-code", "mapInner": ".t--draggable-mapwidget span.t--widget-name", @@ -30,8 +31,8 @@ "zoomLevel": ".t--property-control-zoomlevel svg", "sourceImage": ".t--property-control-image .CodeMirror-code", "defaultImage": ".t--property-control-defaultimage .CodeMirror textarea", - "Chartlabel": ".t--draggable-chartwidget g:nth-child(5) text", - "PieChartLabel": ".t--draggable-chartwidget g g:nth-child(1) g text", + "Chartlabel": ".t--draggable-chartwidget g text", + "FusionChartlabel": ".t--draggable-chartwidget g:nth-child(5) text", "pickMyLocation": ".t--draggable-mapwidget div[title='Pick My Location']", "mapChartEntityLabels": ".t--draggable-mapchartwidget g[class*='-entityLabels'] text", "listWidget": ".t--draggable-listwidget" diff --git a/app/client/cypress/locators/Widgets.json b/app/client/cypress/locators/Widgets.json index ca4e28fb22..4fef88acfc 100644 --- a/app/client/cypress/locators/Widgets.json +++ b/app/client/cypress/locators/Widgets.json @@ -156,7 +156,7 @@ "toggleBackground": ".t--property-control-background .t--js-toggle", "toggleItemBackground": ".t--property-control-itembackground .t--js-toggle", "toggleShowStepArrows": ".t--property-control-showsteparrows .t--js-toggle", - "chartPlotGroup": "g.raphael-group-63-plot-group", + "chartDataPoint": "g path[d^='M100 205.51']", "toggleEnableMultirowselection": ".t--property-control-enablemulti-rowselection input", "toggleEnableMultirowselection_tablev1": ".t--property-control-enablemultirowselection input", "formWidget": ".t--draggable-formwidget", diff --git a/app/client/cypress/locators/publishWidgetspage.json b/app/client/cypress/locators/publishWidgetspage.json index 0c346bc7b1..43f8c1d17f 100644 --- a/app/client/cypress/locators/publishWidgetspage.json +++ b/app/client/cypress/locators/publishWidgetspage.json @@ -21,16 +21,15 @@ "tabWidget": ".t--widget-tabswidget", "jsonFormWidget": ".t--widget-jsonformwidget", "chartWidget": ".t--widget-chartwidget", - "horizontalTab": ".t--widget-chartwidget g[class*='-scrollContainer'] rect", "tableWidget": ".t--widget-tablewidget", - "chartCanvasVal": ".t--widget-chartwidget g[class*='-canvas'] rect ", + "chartCanvasVal": ".t--widget-chartwidget svg rect", "mapWidget": ".t--widget-mapwidget", "tableLength": ".t--widget-tablewidget .tbody", "tableV2Length": ".t--widget-tablewidgetv2 .tbody", "mapSearch": ".t--widget-mapwidget input", "pickMyLocation": ".t--widget-mapwidget div[title='Pick My Location']", - "rectChart": ".t--widget-chartwidget g rect", - "chartLab": ".t--widget-chartwidget g:nth-child(5) text", + "rectChart": ".t--widget-chartwidget svg rect", + "chartLab": ".t--widget-chartwidget svg g text", "searchInput": ".t--search-input", "downloadBtn": ".t--table-download-btn", "filterBtn": ".t--table-filter-toggle-btn", diff --git a/app/client/cypress/package.json b/app/client/cypress/package.json index be50161464..6b825c9887 100644 --- a/app/client/cypress/package.json +++ b/app/client/cypress/package.json @@ -26,7 +26,7 @@ "@typescript-eslint/parser": "^5.25.0", "chalk": "^4.1.1", "cy-verify-downloads": "^0.0.5", - "cypress": "^12.16.0", + "cypress": "^12.17.0", "cypress-file-upload": "^4.1.1", "cypress-image-snapshot": "^4.0.1", "cypress-log-to-output": "^1.1.2", diff --git a/app/client/cypress/support/ApiCommands.js b/app/client/cypress/support/ApiCommands.js index f7ccf3623d..fc80531f21 100644 --- a/app/client/cypress/support/ApiCommands.js +++ b/app/client/cypress/support/ApiCommands.js @@ -9,6 +9,7 @@ const apiwidget = require("../locators/apiWidgetslocator.json"); const explorer = require("../locators/explorerlocators.json"); import { ObjectsRegistry } from "./Objects/Registry"; +let agHelper = ObjectsRegistry.AggregateHelper; let dataSources = ObjectsRegistry.DataSources; let apiPage = ObjectsRegistry.ApiPage; @@ -109,6 +110,7 @@ Cypress.Commands.add( (apiName, baseurl, path, verb, error = false) => { cy.get(".ads-v2-tabs__list").contains("Logs").click(); cy.get("[data-testid=t--debugger-search]").clear().type(apiName); + agHelper.PressEnter(); if (!error) { cy.get(".object-key").last().contains("request").click(); diff --git a/app/client/cypress/support/Objects/CommonLocators.ts b/app/client/cypress/support/Objects/CommonLocators.ts index 6b0f70e545..64c567dd56 100644 --- a/app/client/cypress/support/Objects/CommonLocators.ts +++ b/app/client/cypress/support/Objects/CommonLocators.ts @@ -3,7 +3,8 @@ export class CommonLocators { _inputField = "input"; _canvasViewport = "#canvas-viewport"; _emptyPageTxt = ".bp3-heading"; - _chevronUp = ".bp3-icon-chevron-up"; + _chevronUp = "span[contains(@class, 'bp3-icon-chevron-up')]"; + _chevronDown = "span[contains(@class, 'bp3-icon-chevron-down')]"; _loading = "#loading"; _animationSpnner = ".bp3-spinner-animation"; _btnSpinner = ".ads-v2-spinner"; @@ -263,6 +264,7 @@ export class CommonLocators { _adsV2CollapsibleHeader = ".ads-v2-collapsible__header"; _adsV2Text = ".ads-v2-text"; _svg = "svg"; + _imgWidgetInsideList = `//div[@data-testid='styledImage']//img`; public ds_editor_env_filter = (envName: string) => `[data-testid="t--ds-data-filter-${envName}"]`; diff --git a/app/client/cypress/support/Objects/ObjectsCore.ts b/app/client/cypress/support/Objects/ObjectsCore.ts index f6ee30202c..963dda4329 100644 --- a/app/client/cypress/support/Objects/ObjectsCore.ts +++ b/app/client/cypress/support/Objects/ObjectsCore.ts @@ -32,3 +32,4 @@ export const fakerHelper = ObjectsRegistry.FakerHelper; export const tedTestConfig = ObjectsRegistry.TEDTestConfigs; export const entityItems = EntityItems; export const tabs = ObjectsRegistry.Tabs; +export const gsheetHelper = ObjectsRegistry.GSheetHelper; diff --git a/app/client/cypress/support/Objects/Registry.ts b/app/client/cypress/support/Objects/Registry.ts index 0ca9792811..716ca762c7 100644 --- a/app/client/cypress/support/Objects/Registry.ts +++ b/app/client/cypress/support/Objects/Registry.ts @@ -27,6 +27,7 @@ import { TEDTestConfigs } from "./TestConfigs"; import { AssertHelper } from "../Pages/AssertHelper"; import { ReusableHelper } from "./ReusableHelper"; import { Tabs } from "../Pages/Tabs"; +import { GsheetHelper } from "../Pages/GSheetHelper"; export class ObjectsRegistry { private static aggregateHelper__: AggregateHelper; @@ -260,6 +261,14 @@ export class ObjectsRegistry { } return ObjectsRegistry.tedTestConfigs__; } + + private static gsheetHelper__: GsheetHelper; + static get GSheetHelper(): GsheetHelper { + if (ObjectsRegistry.gsheetHelper__ === undefined) { + ObjectsRegistry.gsheetHelper__ = new GsheetHelper(); + } + return ObjectsRegistry.gsheetHelper__; + } } export const initLocalstorageRegistry = () => { diff --git a/app/client/cypress/support/Objects/TestConfigs.ts b/app/client/cypress/support/Objects/TestConfigs.ts index bb3c9cf780..9185c2108b 100644 --- a/app/client/cypress/support/Objects/TestConfigs.ts +++ b/app/client/cypress/support/Objects/TestConfigs.ts @@ -77,6 +77,7 @@ export class TEDTestConfigs { mockHttpCodeUrl: "http://host.docker.internal:5001/v1/mock-http-codes/", AirtableBaseForME: "appubHrVbovcudwN6", AirtableTableForME: "tblsFCQSskVFf7xNd", + ApiUrlME: "http://host.docker.internal:5001/v1/production", firestore_database_url: "https://appsmith-22e8b.firebaseio.com", firestore_projectID: "appsmith-22e8b", @@ -98,7 +99,7 @@ export class TEDTestConfigs { mongo_authenticationAuthtype: "SCRAM-SHA-1", mongo_host: "host.docker.internal", mongo_port: 28017, - mongo_databaseName: "mongo_samples", + mongo_databaseName: "mongo_samples2", postgres_host: "host.docker.internal", postgres_port: 5432, @@ -165,6 +166,7 @@ export class TEDTestConfigs { mockHttpCodeUrl: "http://host.docker.internal:5001/v1/mock-http-codes/", AirtableBaseForME: "appubHrVbovcudwN6", AirtableTableForME: "tblsFCQSskVFf7xNd", + ApiUrlME: "http://host.docker.internal:5001/v1/staging", firestore_database_url: "https://appsmith-22e8b.firebaseio.com", firestore_projectID: "appsmith-22e8b", diff --git a/app/client/cypress/support/Pages/AdminSettings.ts b/app/client/cypress/support/Pages/AdminSettings.ts index cbb74e2f62..83a5080393 100644 --- a/app/client/cypress/support/Pages/AdminSettings.ts +++ b/app/client/cypress/support/Pages/AdminSettings.ts @@ -5,7 +5,7 @@ export class AdminSettings { public locator = ObjectsRegistry.CommonLocators; public homePage = ObjectsRegistry.HomePage; - private _adminSettingsBtn = '[data-testid="t--admin-settings-menu-option"]'; + public _adminSettingsBtn = '[data-testid="t--admin-settings-menu-option"]'; private _settingsList = ".t--settings-category-list"; public _usersTab = ".t--settings-category-users"; public _roles = (user: string) => diff --git a/app/client/cypress/support/Pages/AggregateHelper.ts b/app/client/cypress/support/Pages/AggregateHelper.ts index 85e9694df5..cd4dafe966 100644 --- a/app/client/cypress/support/Pages/AggregateHelper.ts +++ b/app/client/cypress/support/Pages/AggregateHelper.ts @@ -674,11 +674,20 @@ export class AggregateHelper extends ReusableHelper { .wait(waitTimeInterval); } - public HoverElement(selector: string, index = 0, waitTimeInterval = 100) { - return ( - this.ScrollIntoView(selector, index) + public HoverElement( + selector: string, + index = 0, + realTouch = true, + waitTimeInterval = 100, + ) { + let chain = this.ScrollIntoView(selector, index); + if (realTouch) { + chain = chain .realTouch({ position: "center" }) - .realHover({ pointer: "mouse" }) + .realHover({ pointer: "mouse" }); + } + return ( + chain //.trigger("mousemove", { eventConstructor: "MouseEvent" }) .wait(waitTimeInterval) ); @@ -1055,6 +1064,7 @@ export class AggregateHelper extends ReusableHelper { input.focus(); this.Sleep(200); input.setValue(value); + input.execCommand("goLineEnd"); this.Sleep(200); }); this.Sleep(500); //for value set to settle @@ -1524,4 +1534,10 @@ export class AggregateHelper extends ReusableHelper { // } // return items; // }, { timeout: 5000 }); + + public AssertTooltip(tooltipText: string) { + cy.get(".rc-tooltip-inner").should(($x) => { + expect($x).contain(tooltipText); + }); + } } diff --git a/app/client/cypress/support/Pages/ApiPage.ts b/app/client/cypress/support/Pages/ApiPage.ts index 49eb9546da..dc156e0c35 100644 --- a/app/client/cypress/support/Pages/ApiPage.ts +++ b/app/client/cypress/support/Pages/ApiPage.ts @@ -75,6 +75,7 @@ export class ApiPage { public _autoGeneratedHeaderInfoIcon = (key: string) => `.t--auto-generated-${key}-info`; private _createQuery = ".t--create-query"; + public _editorDS = ".t--datasource-editor"; CreateApi( apiName = "", @@ -115,7 +116,7 @@ export class ApiPage { ) { this.CreateApi(apiName, apiVerb, aftDSSaved); this.EnterURL(url); - //this.agHelper.Sleep(2000);// Added because api name edit takes some time to reflect in api sidebar after the call passes. + this.agHelper.Sleep(2000); // Added because api name edit takes some time to reflect in api sidebar after the call passes. this.AssertRunButtonDisability(); if (queryTimeout != 10000) this.SetAPITimeout(queryTimeout); } @@ -130,8 +131,8 @@ export class ApiPage { directInput: true, inputFieldName: "", }); - this.agHelper.AssertAutoSave(); - + //this.agHelper.GetNClick(this._resourceUrl); + this.agHelper.Sleep(); if (evaluatedValue) { this.agHelper.VerifyEvaluatedValue(evaluatedValue); } diff --git a/app/client/cypress/support/Pages/DataSources.ts b/app/client/cypress/support/Pages/DataSources.ts index b13dd4299c..d46a258231 100644 --- a/app/client/cypress/support/Pages/DataSources.ts +++ b/app/client/cypress/support/Pages/DataSources.ts @@ -47,6 +47,7 @@ export class DataSources { }; //Container KeyValuePair private _dsCreateNewTab = "[data-testid=t--tab-CREATE_NEW]"; + private _dsReviewSection = "[data-testid='t--ds-review-section']"; private _addNewDataSource = ".t--entity-add-btn.datasources button"; private _createNewPlgin = (pluginName: string) => ".t--plugin-name:contains('" + pluginName + "')"; @@ -91,6 +92,7 @@ export class DataSources { ddTitle + "']/following-sibling::span//button"; _reconnectModal = "[data-testid='reconnect-datasource-modal']"; + _reconnect = ".t--reconnect-btn"; _dropdown = (ddTitle: string) => "//span[contains(@title, '" + ddTitle + @@ -180,7 +182,6 @@ export class DataSources { _gsScopeOptions = ".ads-v2-select__dropdown .rc-select-item-option"; private _queryTimeout = "//input[@name='actionConfiguration.timeoutInMillisecond']"; - _getStructureReq = "/api/v1/datasources/*/structure?ignoreCache=true"; _editDatasourceFromActiveTab = (dsName: string) => ".t--datasource-name:contains('" + dsName + "')"; private _suggestedWidget = (widgetType: string) => @@ -193,7 +194,7 @@ export class DataSources { dbName + "']/ancestor::div[contains(@class, 't--entity-item')]/following-sibling::div//p[text()='Schema not available']"; // Authenticated API locators - private _authApiDatasource = ".t--createAuthApiDatasource"; + public _authApiDatasource = ".t--createAuthApiDatasource"; private _authType = "[data-testid=authType]"; private _oauth2 = ".rc-select-item-option:contains('OAuth 2.0')"; private _accessTokenUrl = @@ -215,8 +216,10 @@ export class DataSources { public _cancelEditDatasourceButton = ".t--cancel-edit-datasource"; public _urlInputControl = "input[name='url']"; public _mongoCollectionPath = "t--actionConfiguration.formData.collection"; - private _getJSONswitchLocator = (fieldLocator: string) => - `[data-testid='${fieldLocator}.data-JS']`; + _getJSONswitchLocator = (fieldName: string) => + "//p[contains(text(),'" + + fieldName + + "')]/ancestor::div[@class='form-config-top']//button"; _nestedWhereClauseKey = (index: number) => ".t--actionConfiguration\\.formData\\.where\\.data\\.children\\[" + index + @@ -231,12 +234,17 @@ export class DataSources { _bodyCodeMirror = "//div[contains(@class, 't--actionConfiguration.body')]"; private _reconnectModalDSToolTip = ".t--ds-list .t--ds-list-title"; private _reconnectModalDSToopTipIcon = ".t--ds-list .ads-v2-icon"; + _multiSelectDropdown = (ddName: string) => + "//p[contains(text(),'" + + ddName + + "')]/ancestor::div[@class='form-config-top']/following-sibling::div//div[contains(@class, 'rc-select-multiple')]"; private _datasourceTableSchemaInQueryEditor = ".datasourceStructure-query-editor"; private _datasourceSchemaRefreshBtn = ".datasourceStructure-refresh"; private _datasourceStructureHeader = ".datasourceStructure-header"; private _datasourceColumnSchemaInQueryEditor = ".t--datasource-column"; private _datasourceStructureSearchInput = ".datasourceStructure-search input"; + _jsModeSortingControl = ".t--actionConfiguration\\.formData\\.sortBy\\.data"; public _queryEditorCollapsibleIcon = ".collapsible-icon"; public AssertDSEditViewMode(mode: "Edit" | "View") { @@ -436,6 +444,20 @@ export class DataSources { this.ValidateNSelectDropdown("SSL mode", "Default"); } + public ValidatePostgresDSForm( + environment = this.tedTestConfig.defaultEnviorment, + ) { + const databaseName = + this.tedTestConfig.dsValues[environment].postgres_databaseName; + this.agHelper.AssertContains(databaseName, "exist", this._dsReviewSection); + } + + public ValidateMongoForm(environment = this.tedTestConfig.defaultEnviorment) { + const databaseName = + this.tedTestConfig.dsValues[environment].mongo_databaseName; + this.agHelper.AssertContains(this._dsReviewSection, databaseName); + } + public FillOracleDSForm( environment = this.tedTestConfig.defaultEnviorment, shouldAddTrailingSpaces = false, @@ -902,6 +924,18 @@ export class DataSources { } } + public CreateQueryForDS(datasourceName: string, query = "", queryName = "") { + this.NavigateToActiveTab(); + cy.get(this._datasourceCard) + .contains(datasourceName) + .scrollIntoView() + .should("be.visible") + .click(); + this.agHelper.Sleep(); //for the Datasource page to open + this.agHelper.GetNClick(this._cancelEditDatasourceButton, 0, true, 200); + this.CreateQueryAfterDSSaved(query, queryName); + } + DeleteQuery(queryName: string) { this.ee.ExpandCollapseEntity("Queries/JS"); this.ee.ActionContextMenuByEntityName({ @@ -929,6 +963,17 @@ export class DataSources { } } + public ValidateReviewModeConfig( + dsName: "PostgreSQL" | "MongoDB", + environment = this.tedTestConfig.defaultEnviorment, + ) { + if (dsName === "PostgreSQL") { + this.ValidatePostgresDSForm(environment); + } else if (dsName === "MongoDB") { + this.ValidateMongoForm(environment); + } + } + public ReconnectSingleDSNAssert( dbName: string, dsName: "PostgreSQL" | "MySQL" | "MongoDB", @@ -943,6 +988,18 @@ export class DataSources { this.assertHelper.AssertNetworkStatus("getWorkspace"); } + public AssertReconnectDS(datasourceName: string) { + cy.get(this._datasourceCard, { withinSubject: null }) + .find(this._activeDS) + .contains(datasourceName) + .scrollIntoView() + .should("be.visible") + .closest(this._datasourceCard) + .scrollIntoView() + .within(() => { + this.agHelper.AssertElementVisible(this._reconnect, 0, 20000); + }); + } public ReconnectModalValidation( dbName: string, dsName: "PostgreSQL" | "MySQL" | "MongoDB", @@ -1265,7 +1322,6 @@ export class DataSources { schema: string, isUpdate = false, ) { - cy.intercept("GET", this._getStructureReq).as("getDSStructure"); if (isUpdate) { this.UpdateDatasource(); } else { @@ -1275,7 +1331,7 @@ export class DataSources { entityNameinLeftSidebar: dataSourceName, action: "Refresh", }); - cy.wait("@getDSStructure").then(() => { + cy.wait("@getDatasourceStructure").then(() => { cy.get(".bp3-collapse-body").contains(schema); }); } @@ -1572,21 +1628,19 @@ export class DataSources { public EnterJSContext({ fieldLabel, - fieldProperty, fieldValue, }: { - fieldProperty: string; fieldValue: string; fieldLabel: string; }) { this.agHelper.Sleep(); this.agHelper - .GetElement(this._getJSONswitchLocator(fieldProperty)) + .GetElement(this._getJSONswitchLocator(fieldLabel)) .invoke("attr", "data-selected") .then(($state: any) => { if (!$state.includes("true")) this.agHelper.GetNClick( - this._getJSONswitchLocator(fieldProperty), + this._getJSONswitchLocator(fieldLabel), 0, true, ); @@ -1658,4 +1712,40 @@ export class DataSources { }); }); } + + public EnterSortByValues(sortBy: string, option: string, index = 0) { + this.agHelper + .GetElement(this._jsModeSortingControl) + .eq(0) + .children() + .eq(index) + .then((ele) => { + cy.wrap(ele) + .children() + .eq(0) + .find("textarea") + .type(sortBy, { force: true }); + cy.wrap(ele).children().eq(1).find("input").click(); + }); + this.agHelper.GetNClickByContains(this._dropdownOption, option); + } + + public ClearSortByOption(index = 0) { + this.agHelper.Sleep(500); + this.agHelper + .GetElement(this._jsModeSortingControl) + .eq(0) + .children() + .eq(index) + .find(`button[data-testid='t--sorting-delete-[${index}]']`) + .click({ force: true }); + this.agHelper.Sleep(500); + } + + public AddNewSortByParameter() { + this.agHelper + .GetElement(this._jsModeSortingControl) + .find("button[data-testid='t--sorting-add-field']") + .click({ force: true }); + } } diff --git a/app/client/cypress/support/Pages/DeployModeHelper.ts b/app/client/cypress/support/Pages/DeployModeHelper.ts index 2ddaf654e0..6b2718556c 100644 --- a/app/client/cypress/support/Pages/DeployModeHelper.ts +++ b/app/client/cypress/support/Pages/DeployModeHelper.ts @@ -15,6 +15,13 @@ export class DeployMode { `//p[text()='${fieldName}']/ancestor::div[@direction='column']//div[@data-testid='radiogroup-container']//input`; _jsonFormDatepickerFieldByName = (fieldName: string) => `//p[text()='${fieldName}']/ancestor::div[@direction='column']//div[@data-testid='datepicker-container']//input`; + _jsonFormNumberFieldByName = ( + fieldName: string, + direction: "up" | "down" = "up", + ) => + `//p[text()='${fieldName}']/ancestor::div[@direction='column']//div[@data-testid='input-container']// ${ + direction == "up" ? this.locator._chevronUp : this.locator._chevronDown + }`; _jsonSelectDropdown = "button.select-button"; private _jsonFormMultiSelectByName = (fieldName: string) => `//p[text()='${fieldName}']/ancestor::div[@direction='column']//div[@data-testid='multiselect-container']//div[contains(@class, 'rc-select-show-arrow')]`; diff --git a/app/client/cypress/support/Pages/EntityExplorer.ts b/app/client/cypress/support/Pages/EntityExplorer.ts index 2e27701909..0cb72f6947 100644 --- a/app/client/cypress/support/Pages/EntityExplorer.ts +++ b/app/client/cypress/support/Pages/EntityExplorer.ts @@ -28,7 +28,8 @@ interface EntityActionParams { | "Copy to page" | "Move to page" | "Hide" - | "Refresh"; + | "Refresh" + | "Set as home page"; subAction?: string; entityType?: EntityItems; toAssertAction?: boolean; @@ -270,9 +271,7 @@ export class EntityExplorer { } public ValidateDuplicateMessageToolTip(tooltipText: string) { - cy.get(".rc-tooltip-inner").should(($x) => { - expect($x).contain(tooltipText.concat(" is already being used.")); - }); + this.agHelper.AssertTooltip(tooltipText.concat(" is already being used.")); } public DeleteAllQueriesForDB(dsName: string) { @@ -407,16 +406,20 @@ export class EntityExplorer { } public PinUnpinEntityExplorer(pin = true) { - this.agHelper - .GetElement(this._entityExplorer) - .invoke("attr", "class") - .then(($classes) => { - if (pin && !$classes?.includes("fixed")) - this.agHelper.GetNClick(this._pinEntityExplorer, 0, false, 1000); - else if (!pin && $classes?.includes("fixed")) - this.agHelper.GetNClick(this._pinEntityExplorer, 0, false, 1000); - else this.agHelper.Sleep(200); //do nothing - }); + cy.get("body").then(($ele) => { + if ($ele.find(this._pinEntityExplorer).length) { + this.agHelper + .GetElement(this._entityExplorer) + .invoke("attr", "class") + .then(($classes) => { + if (pin && !$classes?.includes("fixed")) + this.agHelper.GetNClick(this._pinEntityExplorer, 0, false, 1000); + else if (!pin && $classes?.includes("fixed")) + this.agHelper.GetNClick(this._pinEntityExplorer, 0, false, 1000); + else this.agHelper.Sleep(200); //do nothing + }); + } + }); } public RenameEntityFromExplorer( diff --git a/app/client/cypress/support/Pages/GSheetHelper.ts b/app/client/cypress/support/Pages/GSheetHelper.ts new file mode 100644 index 0000000000..d355dd1f89 --- /dev/null +++ b/app/client/cypress/support/Pages/GSheetHelper.ts @@ -0,0 +1,138 @@ +import { ObjectsRegistry } from "../Objects/Registry"; + +type operation = + | "Insert One" + | "Insert Many" + | "Update One" + | "Update Many" + | "Fetch Details" + | "Fetch Many" + | "Delete One"; + +export class GsheetHelper { + public agHelper = ObjectsRegistry.AggregateHelper; + public locator = ObjectsRegistry.CommonLocators; + private dataSources = ObjectsRegistry.DataSources; + private entityExplorer = ObjectsRegistry.EntityExplorer; + + public AddNewSpreadsheetQuery( + dataSourceName: string, + spreadsheet: string, + rowData: string, + ) { + this.entityExplorer.CreateNewDsQuery(dataSourceName); + this.dataSources.ValidateNSelectDropdown( + "Operation", + "Fetch Many", + "Insert One", + ); + this.dataSources.ValidateNSelectDropdown( + "Entity", + "Sheet Row(s)", + "Spreadsheet", + ); + this.agHelper.EnterValue(spreadsheet, { + propFieldName: "", + directInput: false, + inputFieldName: "Spreadsheet Name", + }); + this.agHelper.RenameWithInPane("insert_spreadsheet"); + this.agHelper.EnterValue(rowData, { + propFieldName: "", + directInput: false, + inputFieldName: "Row object(s)", + }); + this.dataSources.RunQuery(); + } + + public DeleteSpreadsheetQuery(dataSourceName: string, spreadsheet: string) { + this.entityExplorer.CreateNewDsQuery(dataSourceName); + this.dataSources.ValidateNSelectDropdown( + "Operation", + "Fetch Many", + "Delete One", + ); + this.dataSources.ValidateNSelectDropdown( + "Entity", + "Sheet Row(s)", + "Spreadsheet", + ); + this.dataSources.ValidateNSelectDropdown("Spreadsheet", "", spreadsheet); + this.agHelper.RenameWithInPane("delete_spreadsheet"); + this.dataSources.RunQuery(); + } + + public AddInsertOrUpdateQuery( + operation: operation, + dataSourceName: string, + spreadSheet: string, + rowData: string, + executeQuery = true, + sheetName = "Sheet1", + headRowIndex = "1", + ) { + this.EnterBasicQueryValues( + operation, + dataSourceName, + spreadSheet, + true, + "Sheet Row(s)", + sheetName, + headRowIndex, + ); + let inputField = ""; + if (operation.includes("Insert")) { + inputField = operation == "Insert One" ? "Row object" : "Row object(s)"; + } else if (operation.includes("Update")) { + inputField = + operation == "Update One" + ? "Update row object" + : "Update row object(s)"; + } + + this.agHelper.EnterValue(rowData, { + propFieldName: "", + directInput: false, + inputFieldName: inputField, + }); + if (executeQuery) this.dataSources.RunQuery(); + } + + public EnterBasicQueryValues( + operation: operation, + dataSourceName: string, + spreadSheet: string, + renameQuery = true, + entity = "Sheet Row(s)", + sheetName = "Sheet1", + headRowIndex = "1", + ) { + this.entityExplorer.CreateNewDsQuery(dataSourceName); + this.dataSources.ValidateNSelectDropdown( + "Operation", + "Fetch Many", + operation, + ); + this.dataSources.ValidateNSelectDropdown("Entity", "Sheet Row(s)", entity); + this.agHelper.Sleep(500); + this.dataSources.ValidateNSelectDropdown("Spreadsheet", "", spreadSheet); + if (!entity.includes("Spreadsheet")) { + this.dataSources.ValidateNSelectDropdown("Sheet name", "", sheetName); + this.agHelper.EnterValue(headRowIndex, { + propFieldName: "", + directInput: false, + inputFieldName: "Table heading row index", + }); + } + if (renameQuery) { + this.agHelper.RenameWithInPane( + operation.toLowerCase().replace(" ", "_") + "_query", + ); + } + } + + public SelectMultiDropDownValue(ddName: string, option: string) { + this.agHelper.GetNClick(this.dataSources._multiSelectDropdown(ddName)); + this.agHelper.GetNClickByContains(this.dataSources._dropdownOption, option); + } +} diff --git a/app/client/cypress/support/Pages/HomePage.ts b/app/client/cypress/support/Pages/HomePage.ts index 8c52d7e668..2d136ccf39 100644 --- a/app/client/cypress/support/Pages/HomePage.ts +++ b/app/client/cypress/support/Pages/HomePage.ts @@ -124,7 +124,11 @@ export class HomePage { this.agHelper.GetNClick(this._homeTab); } - public CreateNewWorkspace(workspaceNewName: string) { + public CreateNewWorkspace( + workspaceNewName: string, + toNavigateToHome = false, + ) { + if (toNavigateToHome) this.NavigateToHome(); let oldName = ""; this.agHelper.GetNClick(this._newWorkSpaceLink); this.assertHelper.AssertNetworkStatus("createWorkspace", 201); @@ -255,6 +259,7 @@ export class HomePage { //Maps to CreateAppForWorkspace in command.js public CreateAppInWorkspace(workspaceName: string, appname = "") { cy.xpath(this._existingWorkspaceCreateNewApp(workspaceName)) + .last() .scrollIntoView() .should("be.visible") .click({ force: true }); diff --git a/app/client/cypress/support/Pages/PropertyPane.ts b/app/client/cypress/support/Pages/PropertyPane.ts index ae622c0374..a89d65b5f1 100644 --- a/app/client/cypress/support/Pages/PropertyPane.ts +++ b/app/client/cypress/support/Pages/PropertyPane.ts @@ -88,8 +88,10 @@ export class PropertyPane { _selectorViewLabel = '[data-testId="selector-view-label"]'; _textView = ".text-view"; _selectorView = ".selector-view"; + _dropdownOptions = + "//div[@class='rc-virtual-list']//div[contains(@class, 'rc-select-item-option')]"; _dropDownValue = (dropdownOption: string) => - `//div[@class='rc-virtual-list']//div[contains(@class, 'rc-select-item-option')]//span[text()='${dropdownOption}']`; + `${this._dropdownOptions}//span[text()='${dropdownOption}']`; _selectPropDropdown = (ddName: string) => "//div[contains(@class, 't--property-control-" + ddName.replace(/ +/g, "").toLowerCase() + @@ -259,6 +261,33 @@ export class PropertyPane { }); } + public AssertPropertiesDropDownValues( + endpoint: string, + dropdownExpectedValues: string[], + ) { + this.agHelper.GetNClick(this._selectPropDropdown(endpoint)); + this.agHelper + .GetElement(this._dropdownOptions) + .then(($ddVisibleTexts: any) => { + let foundAll = true; // Flag to track if all expected selections are found + const foundSelections: string[] = []; // Array to track found selections + $ddVisibleTexts.each((index: any, element: any) => { + const spanText = Cypress.$(element).text().trim(); + foundSelections.push(spanText); + }); + // Check if all expected selections are found in the dropdown + dropdownExpectedValues.forEach((expectedSelection) => { + if (!foundSelections.includes(expectedSelection)) { + foundAll = false; + cy.log("Expected dropdown text not found: " + expectedSelection); + } + }); + expect(foundAll).to.be.true; + cy.log("All dropdown values are present"); + }); + this.agHelper.GetNClick(this._selectPropDropdown(endpoint)); //Closing dropdown + } + public SelectJSFunctionToExecuteInExistingActionBlock( jsName: string, funcName: string, @@ -383,9 +412,14 @@ export class PropertyPane { toVerifySave && this.agHelper.AssertAutoSave(); } - public TypeTextIntoField(endp: string, value: string, removeText = true) { + public TypeTextIntoField( + endp: string, + value: string, + removeText = true, + toVerifySave = true, + ) { if (removeText) { - this.RemoveText(endp); + this.RemoveText(endp, toVerifySave); } this.agHelper .GetElement(this.locator._propertyInputField(endp)) diff --git a/app/client/cypress/support/Pages/Table.ts b/app/client/cypress/support/Pages/Table.ts index c4051fab4e..cb07a01260 100644 --- a/app/client/cypress/support/Pages/Table.ts +++ b/app/client/cypress/support/Pages/Table.ts @@ -160,6 +160,7 @@ export class Table { _columnCheckbox = (columnName: string) => "[data-rbd-draggable-id='" + columnName + "']" + " .t--card-checkbox input"; _dateInputPopover = ".bp3-dateinput-popover"; + _tableV2Widget = ".t--draggable-tablewidgetv2"; _tableV2Row = ".t--draggable-tablewidgetv2 .tbody"; _weekdayRowDayPicker = ".bp3-datepicker .DayPicker .DayPicker-Months .DayPicker-WeekdaysRow"; diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 3570a24235..6d06215d54 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -864,7 +864,8 @@ Cypress.Commands.add( (forSuccess, forFailure, actionType, actionValue, idx = 0) => { propPane.SelectActionByTitleAndValue(actionType, actionValue); - cy.get(propPane._actionCallbacks).last().click(); + agHelper.Sleep(); + agHelper.GetNClick(propPane._actionCallbacks, 0, true); // add a success callback cy.get(propPane._actionAddCallback("success")).click().wait(500); diff --git a/app/client/cypress_ci.config.ts b/app/client/cypress_ci.config.ts index 1b35d4596d..9c752cacee 100644 --- a/app/client/cypress_ci.config.ts +++ b/app/client/cypress_ci.config.ts @@ -30,6 +30,9 @@ export default defineConfig({ }, specPattern: "cypress/e2e/**/*.{js,ts}", testIsolation: false, - excludeSpecPattern: "cypress/e2e/**/spec_utility.ts", + excludeSpecPattern: [ + "cypress/e2e/**/spec_utility.ts", + "cypress/e2e/GSheet/**/**/*", + ], }, }); \ No newline at end of file diff --git a/app/client/cypress_ci_hosted.config.ts b/app/client/cypress_ci_hosted.config.ts new file mode 100644 index 0000000000..e5491dc9fa --- /dev/null +++ b/app/client/cypress_ci_hosted.config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from "cypress"; + +export default defineConfig({ + defaultCommandTimeout: 30000, + requestTimeout: 60000, + responseTimeout: 60000, + pageLoadTimeout: 60000, + videoUploadOnPasses: false, + videoCompression: false, + numTestsKeptInMemory: 5, + experimentalMemoryManagement: true, + reporterOptions: { + reportDir: "results", + overwrite: false, + html: true, + json: false, + }, + chromeWebSecurity: false, + viewportHeight: 1100, + viewportWidth: 1400, + scrollBehavior: "center", + retries: { + runMode: 1, + openMode: 0, + }, + e2e: { + baseUrl: "https://regression.test.appsmith.com", + setupNodeEvents(on, config) { + return require("./cypress/plugins/index.js")(on, config); + }, + specPattern: "cypress/e2e/**/*.{js,ts}", + testIsolation: false, + excludeSpecPattern: [ + "cypress/e2e/**/spec_utility.ts", + "cypress/e2e/Regression/**/**/*", + "cypress/e2e/Sanity/**/**/*", + "cypress/e2e/Smoke/**/**/*", + ], + }, +}); diff --git a/app/client/jest.config.js b/app/client/jest.config.js index a3a4bef0d9..3fd4b33709 100644 --- a/app/client/jest.config.js +++ b/app/client/jest.config.js @@ -31,6 +31,9 @@ module.exports = { "design-system-old": "/node_modules/design-system-old/build", "@design-system/widgets-old": "/node_modules/@design-system/widgets-old", + "@design-system/widgets": "/node_modules/@design-system/widgets", + "@design-system/headless": "/node_modules/@design-system/headless", + "@design-system/theming": "/node_modules/@design-system/theming", "design-system": "/node_modules/design-system/build", "^proxy-memoize$": "/node_modules/proxy-memoize/dist/wrapper.cjs", // @blueprintjs packages need to be resolved to the `esnext` directory. The default `esm` directory diff --git a/app/client/package.json b/app/client/package.json index f8c534063e..f438408125 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -96,6 +96,7 @@ "design-system": "npm:@appsmithorg/design-system@2.1.17", "design-system-old": "npm:@appsmithorg/design-system-old@1.1.11", "downloadjs": "^1.4.7", + "echarts": "^5.4.2", "fast-deep-equal": "^3.1.3", "fast-xml-parser": "^3.17.5", "fastdom": "^1.0.11", @@ -278,7 +279,7 @@ "compression-webpack-plugin": "^10.0.0", "cra-bundle-analyzer": "^0.1.0", "cy-verify-downloads": "^0.0.5", - "cypress": "^12.16.0", + "cypress": "^12.17.0", "cypress-file-upload": "^4.1.1", "cypress-image-snapshot": "^4.0.1", "cypress-mochawesome-reporter": "^3.5.1", @@ -353,6 +354,7 @@ "@blueprintjs/core@^3.43.0": "patch:@blueprintjs/core@npm%3A3.47.0#./.yarn/patches/@blueprintjs-core-npm-3.47.0-a5bc1ea927.patch", "@blueprintjs/core@^3.33.0": "patch:@blueprintjs/core@npm%3A3.47.0#./.yarn/patches/@blueprintjs-core-npm-3.47.0-a5bc1ea927.patch", "@blueprintjs/core@^3.47.0": "patch:@blueprintjs/core@npm%3A3.47.0#./.yarn/patches/@blueprintjs-core-npm-3.47.0-a5bc1ea927.patch", - "@blueprintjs/icons": "3.22.0" + "@blueprintjs/icons": "3.22.0", + "@types/react": "^17.0.2" } } diff --git a/app/client/packages/design-system/headless/package.json b/app/client/packages/design-system/headless/package.json index 22ea2551a4..e1db29e74b 100644 --- a/app/client/packages/design-system/headless/package.json +++ b/app/client/packages/design-system/headless/package.json @@ -15,6 +15,7 @@ "@react-aria/focus": "^3.11.0", "@react-aria/interactions": "^3.14.0", "@react-aria/radio": "^3.6.1", + "@react-aria/switch": "^3.5.2", "@react-aria/utils": "^3.16.0", "@react-aria/visually-hidden": "^3.8.0", "@react-spectrum/utils": "^3.9.0", diff --git a/app/client/packages/design-system/headless/src/components/Switch/Switch.tsx b/app/client/packages/design-system/headless/src/components/Switch/Switch.tsx new file mode 100644 index 0000000000..b7549fec7d --- /dev/null +++ b/app/client/packages/design-system/headless/src/components/Switch/Switch.tsx @@ -0,0 +1,90 @@ +import { mergeProps } from "@react-aria/utils"; +import { useSwitch } from "@react-aria/switch"; +import { useFocusRing } from "@react-aria/focus"; +import { useHover } from "@react-aria/interactions"; +import { useToggleState } from "@react-stately/toggle"; +import { useFocusableRef } from "@react-spectrum/utils"; +import { useCheckboxGroupItem } from "@react-aria/checkbox"; +import React, { forwardRef, useContext, useRef } from "react"; +import { useVisuallyHidden } from "@react-aria/visually-hidden"; +import type { SpectrumSwitchProps } from "@react-types/switch"; +import type { FocusableRef, StyleProps, Validation } from "@react-types/shared"; + +import type { InlineLabelProps } from "../Checkbox"; +import { CheckboxGroupContext } from "../Checkbox/context"; +import type { CheckboxGroupContextType } from "../Checkbox/context"; + +export interface SwitchProps + extends Omit, + Validation, + InlineLabelProps { + icon?: React.ReactNode; + className?: string; +} + +export type SwitchRef = FocusableRef; + +export const Switch = forwardRef((props: SwitchProps, ref: SwitchRef) => { + const { + autoFocus, + children, + className, + isDisabled: isDisabledProp = false, + validationState, + } = props; + const state = useToggleState(props); + const inputRef = useRef(null); + const domRef = useFocusableRef(ref, inputRef); + const { visuallyHiddenProps } = useVisuallyHidden(); + const { focusProps, isFocusVisible } = useFocusRing({ autoFocus }); + + // The hooks will be swapped based on whether the switch is a part of a CheckboxGroup. + // Although this approach is not conventional since hooks cannot usually be called conditionally, + // it should be safe in this case since the switch is not expected to be added or removed from the group. + const context = useContext(CheckboxGroupContext) as CheckboxGroupContextType; + const isDisabled = isDisabledProp || context?.isDisabled; + const { hoverProps, isHovered } = useHover({ isDisabled }); + const { inputProps } = context?.state + ? // eslint-disable-next-line react-hooks/rules-of-hooks + useCheckboxGroupItem( + { + ...props, + // Value is optional for standalone switch, but required for CheckboxGroup items; + // it's passed explicitly here to avoid typescript error (requires ignore). + // @ts-expect-error value is required in switch group items + value: props.value, + // Only pass isRequired and validationState to react-aria if they came from + // the props for this individual switch, and not from the group via context. + isRequired: props.isRequired, + validationState: props.validationState, + isDisabled: isDisabled, + }, + context?.state, + inputRef, + ) + : // eslint-disable-next-line react-hooks/rules-of-hooks + useSwitch(props, state, inputRef); + + const dataState = inputProps.checked ? "checked" : "unchecked"; + + return ( + + ); +}); diff --git a/app/client/packages/design-system/headless/src/components/Switch/index.tsx b/app/client/packages/design-system/headless/src/components/Switch/index.tsx new file mode 100644 index 0000000000..b1fbed9cb2 --- /dev/null +++ b/app/client/packages/design-system/headless/src/components/Switch/index.tsx @@ -0,0 +1,7 @@ +export { Switch } from "./Switch"; +export type { + CheckboxGroupProps as SwitchGroupProps, + CheckboxGroupRef as SwitchGroupRef, +} from "../Checkbox/CheckboxGroup"; +export type { SwitchProps, SwitchRef } from "./Switch"; +export { CheckboxGroup as SwitchGroup } from "../Checkbox/CheckboxGroup"; diff --git a/app/client/packages/design-system/headless/src/components/Tooltip/Tooltip.tsx b/app/client/packages/design-system/headless/src/components/Tooltip/TooltipRoot.tsx similarity index 72% rename from app/client/packages/design-system/headless/src/components/Tooltip/Tooltip.tsx rename to app/client/packages/design-system/headless/src/components/Tooltip/TooltipRoot.tsx index 2f60e59b15..8f91843382 100644 --- a/app/client/packages/design-system/headless/src/components/Tooltip/Tooltip.tsx +++ b/app/client/packages/design-system/headless/src/components/Tooltip/TooltipRoot.tsx @@ -5,9 +5,9 @@ import { useTooltip } from "./useTooltip"; import { TooltipContext } from "./TooltipContext"; import type { TooltipOptions } from "./useTooltip"; -type TooltipProps = { children: ReactNode } & TooltipOptions; +type TooltipRootProps = { children: ReactNode } & TooltipOptions; -export function Tooltip({ children, ...options }: TooltipProps) { +export function TooltipRoot({ children, ...options }: TooltipRootProps) { const tooltip = useTooltip(options); return ( diff --git a/app/client/packages/design-system/headless/src/components/Tooltip/index.tsx b/app/client/packages/design-system/headless/src/components/Tooltip/index.tsx index a5fbc67a04..bc7a77fab9 100644 --- a/app/client/packages/design-system/headless/src/components/Tooltip/index.tsx +++ b/app/client/packages/design-system/headless/src/components/Tooltip/index.tsx @@ -1,4 +1,4 @@ -export { Tooltip } from "./Tooltip"; +export { TooltipRoot } from "./TooltipRoot"; export { TooltipTrigger } from "./TooltipTrigger"; export { TooltipContent } from "./TooltipContent"; diff --git a/app/client/packages/design-system/headless/src/index.ts b/app/client/packages/design-system/headless/src/index.ts index c0da25f17f..553938f288 100644 --- a/app/client/packages/design-system/headless/src/index.ts +++ b/app/client/packages/design-system/headless/src/index.ts @@ -5,3 +5,4 @@ export * from "./components/Field"; export * from "./components/Icon"; export * from "./components/Tooltip"; export * from "./components/Radio"; +export * from "./components/Switch"; diff --git a/app/client/packages/design-system/theming/src/color/DarkModeTheme.ts b/app/client/packages/design-system/theming/src/color/DarkModeTheme.ts index 60288588ae..c6516b666c 100644 --- a/app/client/packages/design-system/theming/src/color/DarkModeTheme.ts +++ b/app/client/packages/design-system/theming/src/color/DarkModeTheme.ts @@ -1,6 +1,6 @@ +import Color from "colorjs.io"; import { ColorsAccessor } from "./ColorsAccessor"; -import Color from "colorjs.io"; import type { ColorTypes } from "colorjs.io/types/src/color"; import type { ColorModeTheme } from "./types"; @@ -87,15 +87,20 @@ export class DarkModeTheme implements ColorModeTheme { fgOnAssistive: this.fgOnAssistive.to("sRGB").toString(), // bd bdAccent: this.bdAccent.toString(), + bdOnAccent: this.bdOnAccent.toString(), bdFocus: this.bdFocus.toString(), bdNegative: this.bdNegative.to("sRGB").toString(), bdNegativeHover: this.bdNegativeHover.to("sRGB").toString(), + bdOnNegative: this.bdOnNegative.to("sRGB").toString(), bdNeutral: this.bdNeutral.toString(), bdNeutralHover: this.bdNeutralHover.toString(), + bdOnNeutral: this.bdOnNeutral.to("sRGB").toString(), bdPositive: this.bdPositive.to("sRGB").toString(), bdPositiveHover: this.bdPositiveHover.to("sRGB").toString(), + bdOnPositive: this.bdOnPositive.to("sRGB").toString(), bdWarning: this.bdWarning.to("sRGB").toString(), bdWarningHover: this.bdWarningHover.to("sRGB").toString(), + bdOnWarning: this.bdOnWarning.to("sRGB").toString(), }; }; @@ -803,17 +808,50 @@ export class DarkModeTheme implements ColorModeTheme { return color; } - // Keyboard focus outline. Opposite complimentary hue to the seed. + private get bdOnAccent() { + // Separator on bgAccent, low contrast to not pull attention from actual separated content elements + const color = this.bgAccent.clone(); + + if (this.bgAccent.oklch.l >= 0.7) { + color.oklch.l = this.bgAccent.oklch.l - 0.22; + } + + if (this.bgAccent.oklch.l < 0.7 && this.bgAccent.oklch.l >= 0.4) { + color.oklch.l = this.bgAccent.oklch.l - 0.29; + } + + if (this.bgAccent.oklch.l < 0.4) { + color.oklch.l = this.bgAccent.oklch.l - 0.36; + } + + return color; + } + private get bdFocus() { + // Keyboard focus outline. Doesn't match the seed to increase contrast const color = this.seedColor.clone(); - color.oklch.h = this.seedHue - 180; - - // Set minimal lightness if (this.seedLightness < 0.4) { color.oklch.l = 0.4; } + if (this.seedLightness > 0.65) { + color.oklch.l = 0.65; + } + + // Achromatic seeds still produce colorful focus; this is good for accessibility even though it affects visual style + if (this.seedChroma < 0.12) { + color.oklch.c = 0.12; + } + + // Green-red color blindness is among the most prevalent, so instead of 180 we're rotating hue by additional 60° + color.oklch.h = this.seedHue - 240; + + // Additional adjustments for red, pinks, magentas + if ((this.seedHue >= 0 && this.seedHue <= 55) || this.seedHue >= 340) { + color.oklch.h = color.oklch.h + 160; + } + return color; } @@ -857,6 +895,16 @@ export class DarkModeTheme implements ColorModeTheme { return color; } + private get bdOnNegative() { + // Separator on bgNegative, low contrast to not pull attention from actual separated content elements + const color = this.bgNegative.clone(); + + // Lightness of bgNegative is known, no additional checks like in bdOnAccent / bdOnNeutral + color.oklch.l = this.bgNegative.oklch.l - 0.25; + + return color; + } + // Desatured version of the seed for harmonious combination with backgrounds and accents. private get bdNeutral() { const color = this.bdAccent.clone(); @@ -892,6 +940,25 @@ export class DarkModeTheme implements ColorModeTheme { return color; } + private get bdOnNeutral() { + // Separator on bgNeutral, low contrast to not pull attention from actual separated content elements + const color = this.bgNeutral.clone(); + + if (this.bgNeutral.oklch.l >= 0.7) { + color.oklch.l = this.bgNeutral.oklch.l - 0.22; + } + + if (this.bgNeutral.oklch.l < 0.7 && this.bgNeutral.oklch.l >= 0.4) { + color.oklch.l = this.bgNeutral.oklch.l - 0.29; + } + + if (this.bgNeutral.oklch.l < 0.4) { + color.oklch.l = this.bgNeutral.oklch.l - 0.36; + } + + return color; + } + private get bdPositive() { const color = this.bgPositive.clone(); @@ -901,6 +968,36 @@ export class DarkModeTheme implements ColorModeTheme { return color; } + private get bdOnWarning() { + // Separator on bgWarning, low contrast to not pull attention from actual separated content elements + const color = this.bgWarning.clone(); + + // Lightness of bgWarning is known, no additional checks like in bdOnAccent / bdOnNeutral + color.oklch.l = this.bgWarning.oklch.l - 0.25; + + return color; + } + + private get bdPositiveHover() { + const color = this.bdPositive.clone(); + + // Lightness of bdPositive is known, no additional checks like in bdNeutralHover + + color.oklch.l = color.oklch.l + 0.12; + + return color; + } + + private get bdOnPositive() { + // Separator on bgPositive, low contrast to not pull attention from actual separated content elements + const color = this.bgPositive.clone(); + + // Lightness of bgPositive is known, no additional checks like in bdOnAccent / bdOnNeutral + color.oklch.l = this.bgPositive.oklch.l - 0.2; + + return color; + } + private get bdWarning() { const color = this.bgWarning.clone(); @@ -945,14 +1042,4 @@ export class DarkModeTheme implements ColorModeTheme { return color; } - - private get bdPositiveHover() { - const color = this.bdPositive.clone(); - - // Lightness of bdPositive is known, no additional checks like in bdNeutralHover - - color.oklch.l = color.oklch.l + 0.12; - - return color; - } } diff --git a/app/client/packages/design-system/theming/src/color/LightModeTheme.ts b/app/client/packages/design-system/theming/src/color/LightModeTheme.ts index 20a26f6166..26ab4d261b 100644 --- a/app/client/packages/design-system/theming/src/color/LightModeTheme.ts +++ b/app/client/packages/design-system/theming/src/color/LightModeTheme.ts @@ -1,6 +1,6 @@ +import Color from "colorjs.io"; import { ColorsAccessor } from "./ColorsAccessor"; -import Color from "colorjs.io"; import type { ColorTypes } from "colorjs.io/types/src/color"; import type { ColorModeTheme } from "./types"; @@ -87,15 +87,20 @@ export class LightModeTheme implements ColorModeTheme { fgOnAssistive: this.fgOnAssistive.to("sRGB").toString(), // bd bdAccent: this.bdAccent.toString(), + bdOnAccent: this.bdOnAccent.toString(), bdFocus: this.bdFocus.toString(), bdNegative: this.bdNegative.to("sRGB").toString(), bdNegativeHover: this.bdNegativeHover.to("sRGB").toString(), + bdOnNegative: this.bdOnNegative.to("sRGB").toString(), bdNeutral: this.bdNeutral.toString(), bdNeutralHover: this.bdNeutralHover.toString(), + bdOnNeutral: this.bdOnNeutral.to("sRGB").toString(), bdPositive: this.bdPositive.to("sRGB").toString(), bdPositiveHover: this.bdPositiveHover.to("sRGB").toString(), + bdOnPositive: this.bdOnPositive.to("sRGB").toString(), bdWarning: this.bdWarning.to("sRGB").toString(), bdWarningHover: this.bdWarningHover.to("sRGB").toString(), + bdOnWarning: this.bdOnWarning.to("sRGB").toString(), }; }; @@ -839,14 +844,52 @@ export class LightModeTheme implements ColorModeTheme { return color; } - // Keyboard focus outline. Opposite complimentary hue to the seed. + private get bdOnAccent() { + // Separator on bgAccent, low contrast to not pull attention from actual separated content elements + const color = this.bgAccent.clone(); + + if (this.bgAccent.oklch.l >= 0.7) { + color.oklch.l = this.bgAccent.oklch.l - 0.25; + } + + if (this.bgAccent.oklch.l < 0.7 && this.bgAccent.oklch.l >= 0.4) { + color.oklch.l = this.bgAccent.oklch.l - 0.33; + } + + if (this.bgAccent.oklch.l < 0.4 && this.bgAccent.oklch.l >= 0.15) { + color.oklch.l = this.bgAccent.oklch.l + 0.2; + } + + if (this.bgAccent.oklch.l < 0.15) { + color.oklch.l = this.bgAccent.oklch.l + 0.46; + } + + return color; + } + private get bdFocus() { + // Keyboard focus outline. Doesn't match the seed to increase contrast const color = this.seedColor.clone(); - color.oklch.h = this.seedHue - 180; + if (this.seedLightness < 0.6) { + color.oklch.l = 0.6; + } - if (this.seedLightness > 0.7) { - color.oklch.l = 0.7; + if (this.seedLightness > 0.8) { + color.oklch.l = 0.8; + } + + // Achromatic seeds still produce colorful focus; this is good for accessibility even though it affects visual style + if (this.seedChroma < 0.15) { + color.oklch.c = 0.15; + } + + // Green-red color blindness is among the most prevalent, so instead of 180 we're rotating hue by additional 60° + color.oklch.h = this.seedHue - 240; + + // Additional adjustments for red, pinks, magentas + if ((this.seedHue >= 0 && this.seedHue <= 55) || this.seedHue >= 340) { + color.oklch.h = color.oklch.h + 160; } return color; @@ -889,6 +932,16 @@ export class LightModeTheme implements ColorModeTheme { return color; } + private get bdOnNegative() { + // Separator on bgNegative, low contrast to not pull attention from actual separated content elements + const color = this.bgNegative.clone(); + + // Lightness of bgNegative is known, no additional checks like in bdOnAccent / bdOnNeutral + color.oklch.l = this.bgNegative.oklch.l - 0.33; + + return color; + } + // Desatured version of the seed for harmonious combination with backgrounds and accents. private get bdNeutral() { const color = this.bdAccent.clone(); @@ -928,6 +981,29 @@ export class LightModeTheme implements ColorModeTheme { return color; } + private get bdOnNeutral() { + // Separator on bgNeutral, low contrast to not pull attention from actual separated content elements + const color = this.bgNeutral.clone(); + + if (this.bgNeutral.oklch.l >= 0.7) { + color.oklch.l = this.bgNeutral.oklch.l - 0.28; + } + + if (this.bgNeutral.oklch.l < 0.7 && this.bgNeutral.oklch.l >= 0.4) { + color.oklch.l = this.bgNeutral.oklch.l - 0.35; + } + + if (this.bgNeutral.oklch.l < 0.4 && this.bgNeutral.oklch.l >= 0.15) { + color.oklch.l = this.bgNeutral.oklch.l + 0.22; + } + + if (this.bgNeutral.oklch.l < 0.15) { + color.oklch.l = this.bgNeutral.oklch.l + 0.47; + } + + return color; + } + // Positive (green) border. Additional compensations are applied if seed is withing green range. private get bdPositive() { const color = this.bgPositive.clone(); @@ -965,6 +1041,16 @@ export class LightModeTheme implements ColorModeTheme { return color; } + private get bdOnPositive() { + // Separator on bgPositive, low contrast to not pull attention from actual separated content elements + const color = this.bgPositive.clone(); + + // Lightness of bgPositive is known, no additional checks like in bdOnAccent / bdOnNeutral + color.oklch.l = this.bgPositive.oklch.l - 0.33; + + return color; + } + // Warning (yellow) border. Produced out of bgNegative. Additional compensations are applied if seed is within yellow range. private get bdWarning() { const color = this.bgWarning.clone(); @@ -1001,4 +1087,14 @@ export class LightModeTheme implements ColorModeTheme { return color; } + + private get bdOnWarning() { + // Separator on bgWarning, low contrast to not pull attention from actual separated content elements + const color = this.bgWarning.clone(); + + // Lightness of bgWarning is known, no additional checks like in bdOnAccent / bdOnNeutral + color.oklch.l = this.bgWarning.oklch.l - 0.33; + + return color; + } } diff --git a/app/client/packages/design-system/theming/src/theme/Theme.stories.mdx b/app/client/packages/design-system/theming/src/theme/Theme.stories.mdx deleted file mode 100644 index e74e4ef72c..0000000000 --- a/app/client/packages/design-system/theming/src/theme/Theme.stories.mdx +++ /dev/null @@ -1,122 +0,0 @@ -import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; -import { ThemeProvider } from "./ThemeProvider"; -import styled from "styled-components"; - - - -# Theme - -The theme package substitutes hooks and components for working with theming. - -## ThemeProvider - -export const Template = () => ; -; - -export const StyledWrapper = styled.div` - display: flex; - flex-direction: column; - width: 100%; - align-self: stretch; -`; - - - - -

ThemeProvider

-

- This page describes how to use ThemeProvider. How to access tokens, what - input parameters are needed and how to change the color mode. -

-

- The ThemeProvider is React component in that allows for the easy - implementation of themes within an app. With ThemeProvider, you can - define a set of design tokens that will be applied to specific - components in your application, allowing for consistent styling across - your entire application. -

-

useFluidTokens

-

- A hook that creates typography, rootUnit, spacing, sizing fluid tokens - based on the passed parameters. To create tokens, we use a calculation - values based on a musical scale. This allows us to create a harmonious - set of tokens. Tokens also depend on user's viewport. -

- Related materials - -

useTheme [WIP]

-

- A hook that helps dynamically update tokens depending on incoming - parameters. -

-

tokensAccessor

-

- Creates an object containing tokens based on the passed parameters (see - the defaultToken structure) for subsequent conversion to - CSS variables. -

-

defaultTokens

-

Basic token configuration file.

-
-
-
- -## Usage - -```javascript -import React from "react"; -import { useEffect, useState } from "react"; -import { - ThemeProvider, - TokensAccessor, - defaultTokens, - useFluidTokens, -} from "@design-system/theming"; - -export const theming = (Story, args) => { - const { fluid, ...restDefaultTokens } = defaultTokens; - const { typography, rootUnit, spacing, sizing } = useFluidTokens(fluid); - const tokensAccessor = new TokensAccessor({ - ...restDefaultTokens, - rootUnit, - spacing, - sizing, - typography, - }); - const [theme, setTheme] = useState(tokensAccessor.getAllTokens()); - - useEffect(() => { - if (args.globals.colorMode) { - tokensAccessor.updateColorMode(args.globals.colorMode); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getColors(), - }; - }); - } - }, [args.globals.colorMode]); - - return {children}; -}; -``` diff --git a/app/client/packages/design-system/theming/src/theme/ThemeProvider.tsx b/app/client/packages/design-system/theming/src/theme/ThemeProvider.tsx index 902b9defae..04cbddcd4f 100644 --- a/app/client/packages/design-system/theming/src/theme/ThemeProvider.tsx +++ b/app/client/packages/design-system/theming/src/theme/ThemeProvider.tsx @@ -11,7 +11,7 @@ const GlobalStyles = createGlobalStyle`${fontFaces}`; export const ThemeProvider = (props: ThemeProviderProps) => { const { children, className, theme } = props; - const { typography, ...rest } = theme; + const { fontFamily, typography, ...rest } = theme; return ( { > ; export const StyledProvider = styled.div` - ${({ $typography, theme }) => { + ${({ $fontFamily, $typography, theme }) => { return css` + font-family: ${$fontFamily}; ${$typography} ${Object.keys(theme).map((key) => { if (typeof theme[key] === "object") { diff --git a/app/client/packages/design-system/theming/src/theme/index.ts b/app/client/packages/design-system/theming/src/theme/index.ts index 9d681df8bc..594fd26808 100644 --- a/app/client/packages/design-system/theming/src/theme/index.ts +++ b/app/client/packages/design-system/theming/src/theme/index.ts @@ -1,3 +1,4 @@ export * from "./ThemeContext"; export * from "./ThemeProvider"; export * from "./types"; +export * from "./useTheme"; diff --git a/app/client/packages/design-system/theming/src/theme/types.ts b/app/client/packages/design-system/theming/src/theme/types.ts index 5854763026..ebe53004f2 100644 --- a/app/client/packages/design-system/theming/src/theme/types.ts +++ b/app/client/packages/design-system/theming/src/theme/types.ts @@ -1,8 +1,12 @@ import type { ReactNode } from "react"; + +import type { ColorMode } from "../color"; +import type { FontFamily } from "../typography"; import type { RootUnit, ThemeToken } from "../token"; export type Theme = ThemeToken & { typography?: string; + fontFamily?: string; rootUnit?: RootUnit; }; @@ -15,3 +19,11 @@ export interface ThemeProviderProps { children: ReactNode; className?: string; } + +export type UseThemeProps = { + seedColor?: string; + colorMode?: ColorMode; + borderRadius?: string; + fontFamily?: FontFamily; + rootUnitRatio?: number; +}; diff --git a/app/client/packages/design-system/theming/src/theme/useTheme.tsx b/app/client/packages/design-system/theming/src/theme/useTheme.tsx new file mode 100644 index 0000000000..bc0da040aa --- /dev/null +++ b/app/client/packages/design-system/theming/src/theme/useTheme.tsx @@ -0,0 +1,142 @@ +import Color from "colorjs.io"; +import { useEffect, useState } from "react"; +import type { TokenSource } from "@design-system/theming"; +import { + TokensAccessor, + defaultTokens, + useFluidTokens, +} from "@design-system/theming"; + +import type { UseThemeProps } from "./types"; + +const { fluid, ...restDefaultTokens } = defaultTokens; + +const tokensAccessor = new TokensAccessor({ + ...(restDefaultTokens as TokenSource), +}); + +export function useTheme(props: UseThemeProps = {}) { + const { + borderRadius, + colorMode = "light", + fontFamily, + rootUnitRatio: rootUnitRatioProp, + seedColor, + } = props; + + const [rootUnitRatio, setRootUnitRatio] = useState(1); + + const { rootUnit, sizing, spacing, typography } = useFluidTokens( + fluid, + rootUnitRatio, + ); + + const [theme, setTheme] = useState(tokensAccessor.getAllTokens()); + + useEffect(() => { + tokensAccessor.updateRootUnit(rootUnit); + tokensAccessor.updateSpacing(spacing); + tokensAccessor.updateSizing(sizing); + tokensAccessor.updateTypography(typography); + + setTheme(tokensAccessor.getAllTokens()); + }, []); + + useEffect(() => { + if (colorMode) { + tokensAccessor.updateColorMode(colorMode); + + setTheme((prevState) => { + return { + ...prevState, + ...tokensAccessor.getColors(), + }; + }); + } + }, [colorMode]); + + useEffect(() => { + if (borderRadius) { + tokensAccessor.updateBorderRadius({ + 1: borderRadius, + }); + + setTheme((prevState) => { + return { + ...prevState, + ...tokensAccessor.getBorderRadius(), + }; + }); + } + }, [borderRadius]); + + useEffect(() => { + if (seedColor) { + let color; + + try { + color = Color.parse(seedColor); + } catch (error) { + // eslint-disable-next-line no-console + console.error(error); + } + + if (color) { + tokensAccessor.updateSeedColor(seedColor); + + setTheme((prevState) => { + return { + ...prevState, + ...tokensAccessor.getColors(), + }; + }); + } + } + }, [seedColor]); + + useEffect(() => { + if (fontFamily) { + tokensAccessor.updateFontFamily(fontFamily); + + setTheme((prevState) => { + return { + ...prevState, + typography: tokensAccessor.getTypography(), + fontFamily: tokensAccessor.getFontFamily(), + }; + }); + } + }, [fontFamily]); + + useEffect(() => { + if (rootUnitRatioProp) { + setRootUnitRatio(rootUnitRatioProp); + } + }, [rootUnitRatioProp]); + + useEffect(() => { + tokensAccessor.updateRootUnit(rootUnit); + tokensAccessor.updateSpacing(spacing); + + setTheme((prevState) => { + return { + ...prevState, + rootUnit: tokensAccessor.getRootUnit(), + ...tokensAccessor.getSpacing(), + }; + }); + }, [rootUnit, spacing]); + + useEffect(() => { + tokensAccessor.updateTypography(typography); + + setTheme((prevState) => { + return { + ...prevState, + typography: tokensAccessor.getTypography(), + }; + }); + }, [typography]); + + return { theme, setTheme }; +} diff --git a/app/client/packages/design-system/theming/src/token/Tokens.stories.mdx b/app/client/packages/design-system/theming/src/token/Tokens.stories.mdx deleted file mode 100644 index bc3066a64a..0000000000 --- a/app/client/packages/design-system/theming/src/token/Tokens.stories.mdx +++ /dev/null @@ -1,419 +0,0 @@ -import { Canvas, Meta, Story } from "@storybook/addon-docs"; -import { - TokenTable, - StyledLinePreview, - StyledSquarePreview, - StyledTable, -} from "./TokenTable"; -import { useThemeContext } from "../theme"; -import styled from "styled-components"; - - - -export const StyledWrapper = styled.div` - display: flex; - flex-direction: column; - width: 100%; - align-self: stretch; -`; - -# Tokens - -A **design token** is a single source of truth for visual and -functional design decisions. It is an abstract way to represent design -decisions and is used to maintain consistency across a project. - -export const RootUnit = () => { - const { rootUnit } = useThemeContext(); - return ( - -

Root Unit

-

What is it?

-

- We use a fluid root unit to create baseline grid for our design to - ensure visual consistency and rhythm. The baseline grid is one of the - most essential layout structures in product design. It makes interfaces - more consistent, balanced, and easier to scan by users, as it - establishes a repetitive pattern in visual recognition for your users. -

-

How to use it?

-

- To establish a grid system, ensure all sizes, spacing (margins, padding) - and typography in your designs are multiples of root Unit. As simple as - that. -

-

Why fluid?

-

- We use fluid root unit since the smaller the size of the user viewport, - the higher the interface density should be, so we change the value of - the root unit depending on viewport. -

-

Important

-

- We do not use root unit value directly for creating components, but only - derived values are based on it such as spacing, sizing and typography. -

-

Value

-

{rootUnit}

-
- ); -}; - -## Root Unit - - - - - - - -export const Sizing = () => { - const { sizing } = useThemeContext(); - return ( - -

Sizing

-

- Sizing is a fundamental aspect of design systems that determines the - measurements of various elements in a user interface. It refers to the - process of defining consistent measurements for different components - such as buttons, icons, typography, and spacing to ensure that they are - visually balanced and harmonious. -

-

- We use root unit to calculate values of all sizes since this is a - fundamental element and used to define the size of all the other - elements in the system. -

-

Tokens Table

- - {(cssVar) => ( - - )} - -
- ); -}; - -## Sizing - - - - - - - -export const Spacing = () => { - const { spacing } = useThemeContext(); - return ( - -

Spacing

-

- Spacing is a crucial aspect of design that can make or break the user - experience. It helps to create a visual hierarchy, improve readability, - and make elements of a design easier to understand. A well-thought-out - spacing system can add clarity and consistency to a design. -

-

Types of Spacing

-

- There are two types of spacing in design systems: inner spacing and - outer spacing. -

-

Inner Spacing

-

- Inner spacing, also known as padding, is the space between an - element's content and its border. It creates room for the content to - breathe and makes the element more visually appealing. -

-

Outer Spacing

-

- Outer spacing, also known as margin and gap, is the space - between elements. It creates a visual separation between elements and - contributes to the overall balance of a design. -

-

Tokens Table

- - {(cssVar) => ( - - )} - -
- ); -}; - -## Spacing - - - - - - - -export const Color = () => { - const { color } = useThemeContext(); - return ( - -

Color

-

- Color is a crucial element in any design system. It communicates - information, creates hierarchy, and evokes emotions. Therefore, it is - essential to establish a consistent and meaningful color palette for - your design system. -

-

Semantic Color Naming Strategy

-

- This naming schema is for the most part inspired by the one shown in The - hardest part about building dark mode is that people think it’s easy - talk by - - Hassan and Jacob Miller at Figma Config 2022 - . This enables flexibility and focuses on deriving these tokens from - a starting seed rather than assuming those can be hand-picked by a designer. -

- - - - type - role (optional) - prominence (optional) - state (optional) - - - - - bg - accent - regular (default) - resting (default) - - - fg - neutral - strong - hover - - - bd - content - subtle - active - - - - assistive - - disabled - - - - negative - - focus - - - - positive - - - - - - warning - - - - - - on* - - - - - -

Background Tokens Table

- - {(cssVar) => ( - - )} - -

Foreground Tokens Table

- - {(cssVar) => ( - - )} - -

Border Tokens Table

- - {(cssVar) => ( - - )} - -
- ); -}; - -## Color - - - - - - - -export const BorderRadius = () => { - const { borderRadius } = useThemeContext(); - return ( - -

Border Radius

-

- Border radius is a commonly used design element in user interfaces that - can add visual interest and depth to a application. By incorporating - standardized border radius values into our design system, we can create - a more cohesive and professional look for our products. -

-

Tokens Table

- - {(cssVar) => ( - - )} - -
- ); -}; - -## Border Radius - - - - - - - -## Box Shadow - -export const BoxShadow = () => { - const { boxShadow } = useThemeContext(); - return ( - -

Box Shadow

-

- Box shadow is a visual effect that creates a three-dimensional look on a - two-dimensional element. It is used in web design to add depth and - texture to user interfaces. In a design system, box shadow is an - important element that helps to maintain consistency across all - components. -

-

Tokens Table

- - {(cssVar) => ( - - )} - -
- ); -}; - -## Box Shadow - - - - - - - -## Opacity - -export const Opacity = () => { - const { opacity } = useThemeContext(); - return ( - -

Opacity

-

- Opacity is an important aspect of design system that determines the - transparency of an element. It is measured in percentage, where 0% is - completely transparent and 100% is completely opaque. In design system, - opacity is used to create visual hierarchy, depth, and contrast. By - adjusting the opacity of an element, designers can create subtle or - dramatic effects that enhance the user experience. -

- - {(cssVar) => ( - - )} - -
- ); -}; - - - - - - - -## Typography - - - - -

Typography

-

- To work with typography, we offer a{" "} - - Text component - - . This component provides a variant prop for semantic options. - You can use the `type` prop to control the component's color in accordance - with the theme. -

-

- To control the font size and line height, we use the{" "} - capHeight and - lineGap parameter supplied by the - capsize - library. -

-

- For font sizes, we also use a approach based on the root unit and - viewport calculation. -

-
-
-
diff --git a/app/client/packages/design-system/theming/src/token/TokensAccessor.ts b/app/client/packages/design-system/theming/src/token/TokensAccessor.ts index 1877acf615..538e2bbd92 100644 --- a/app/client/packages/design-system/theming/src/token/TokensAccessor.ts +++ b/app/client/packages/design-system/theming/src/token/TokensAccessor.ts @@ -24,6 +24,7 @@ export class TokensAccessor { private fontFamily?: FontFamily; private spacing?: TokenObj; private sizing?: TokenObj; + private zIndex?: TokenObj; constructor({ borderRadius, @@ -37,6 +38,7 @@ export class TokensAccessor { sizing, spacing, typography, + zIndex, }: TokenSource) { this.seedColor = seedColor; this.colorMode = colorMode; @@ -49,6 +51,7 @@ export class TokensAccessor { this.sizing = sizing; this.spacing = spacing; this.typography = typography; + this.zIndex = zIndex; } updateRootUnit = (rootUnit: RootUnit) => { @@ -87,6 +90,10 @@ export class TokensAccessor { this.opacity = opacity; }; + updateZIndex = (zIndex: TokenObj) => { + this.zIndex = zIndex; + }; + updateSpacing = (spacing: TokenObj) => { this.spacing = spacing; }; @@ -99,6 +106,7 @@ export class TokensAccessor { return { rootUnit: this.getRootUnit(), typography: this.getTypography(), + fontFamily: this.getFontFamily(), ...this.getSpacing(), ...this.getSizing(), ...this.getSizing(), @@ -107,6 +115,7 @@ export class TokensAccessor { ...this.getBoxShadow(), ...this.getBorderWidth(), ...this.getOpacity(), + ...this.getZIndex(), }; }; @@ -116,10 +125,14 @@ export class TokensAccessor { getTypography = (): string | undefined => { if (this.typography) { - return createTypographyStringMap(this.typography); + return createTypographyStringMap(this.typography, this.fontFamily); } }; + getFontFamily = () => { + return this.fontFamily; + }; + getColors = () => { if (this.seedColor == null) return {} as ThemeToken; @@ -178,6 +191,12 @@ export class TokensAccessor { return this.createTokenObject(this.opacity, "opacity"); }; + getZIndex = () => { + if (this.zIndex == null) return {} as ThemeToken; + + return this.createTokenObject(this.zIndex, "zIndex"); + }; + private get isLightMode() { return this.colorMode === "light"; } diff --git a/app/client/packages/design-system/theming/src/token/defaultTokens.json b/app/client/packages/design-system/theming/src/token/defaultTokens.json index 271a0c0a37..8c5300e140 100644 --- a/app/client/packages/design-system/theming/src/token/defaultTokens.json +++ b/app/client/packages/design-system/theming/src/token/defaultTokens.json @@ -47,5 +47,11 @@ }, "opacity": { "disabled": 0.3 + }, + "zIndex": { + "1": 3, + "2": 4, + "3": 10, + "99": 9999 } } diff --git a/app/client/packages/design-system/theming/src/token/types.ts b/app/client/packages/design-system/theming/src/token/types.ts index 4cf8812682..59878c60e1 100644 --- a/app/client/packages/design-system/theming/src/token/types.ts +++ b/app/client/packages/design-system/theming/src/token/types.ts @@ -12,7 +12,8 @@ export type TokenType = | "borderRadius" | "boxShadow" | "borderWidth" - | "opacity"; + | "opacity" + | "zIndex"; export interface Token { value: string | number; @@ -31,6 +32,7 @@ export interface TokenSource { borderWidth?: TokenObj; opacity?: TokenObj; fontFamily?: FontFamily; + zIndex?: TokenObj; sizing?: TokenObj; spacing?: TokenObj; } diff --git a/app/client/packages/design-system/theming/src/typography/typography.ts b/app/client/packages/design-system/theming/src/typography/typography.ts index 2833f92ff1..7893158928 100644 --- a/app/client/packages/design-system/theming/src/typography/typography.ts +++ b/app/client/packages/design-system/theming/src/typography/typography.ts @@ -37,10 +37,12 @@ export const getTypographyClassName = (key: keyof typeof TypographyVariant) => { return `wds-${TypographyVariant[key]}-text`; }; -export const createTypographyStringMap = (typography: Typography) => { +export const createTypographyStringMap = ( + typography: Typography, + fontFamily?: FontFamily, +) => { return Object.keys(typography).reduce((prev, current) => { - const { capHeight, fontFamily, lineGap } = - typography[current as keyof Typography]; + const { capHeight, lineGap } = typography[current as keyof Typography]; return ( prev + `${createTypographyString( @@ -68,7 +70,7 @@ export const createTypographyString = ( }); } - return createStyleString(`wds-${typographyVariant}-text`, { + return createStyleString(getTypographyClassName(typographyVariant), { capHeight, lineGap, fontMetrics: fontMetrics[fontFamily], diff --git a/app/client/packages/design-system/widgets-old/src/MenuDivider/MenuDivider.stories.tsx b/app/client/packages/design-system/widgets-old/src/MenuDivider/MenuDivider.stories.tsx deleted file mode 100644 index cbe13bca59..0000000000 --- a/app/client/packages/design-system/widgets-old/src/MenuDivider/MenuDivider.stories.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; -import type { ComponentMeta } from "@storybook/react"; - -import MenuDivider from "./index"; - -export default { - title: "Design System/widgets-old/Menu Divider", - component: MenuDivider, -} as ComponentMeta; - -export const MenuDividerExample = ( -
- -
-); diff --git a/app/client/packages/design-system/widgets-old/src/ScrollIndicator/ScrollIndicator.stories.tsx b/app/client/packages/design-system/widgets-old/src/ScrollIndicator/ScrollIndicator.stories.tsx deleted file mode 100644 index 0c5f1928a4..0000000000 --- a/app/client/packages/design-system/widgets-old/src/ScrollIndicator/ScrollIndicator.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useRef } from "react"; -import type { ComponentMeta } from "@storybook/react"; - -import ScrollIndicatorComponent from "./index"; - -export default { - title: "Design System/widgets-old/ScrollIndicator", - component: ScrollIndicatorComponent, -} as ComponentMeta; - -// eslint-disable-next-line react/function-component-definition -export const ScrollIndicator = () => { - const containerRef = useRef(null); - return ( -
-
- -
- ); -}; diff --git a/app/client/packages/design-system/widgets/src/components/Button/Button.stories.mdx b/app/client/packages/design-system/widgets/src/components/Button/Button.stories.mdx deleted file mode 100644 index e917a2882c..0000000000 --- a/app/client/packages/design-system/widgets/src/components/Button/Button.stories.mdx +++ /dev/null @@ -1,152 +0,0 @@ -import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; - -import { Button } from "./"; -import { Icon } from "@design-system/headless"; -import EmotionHappyLineIcon from "remixicon-react/EmotionHappyLineIcon"; - - - -export const Template = (args) =>
- ), - ), - )} - - - - -# States - - - - {Template.bind({})} - - alert("on pressed"), - }} - > - {Template.bind({})} - - - -# With Icon - - - - - - ), - }} - > - {Template.bind({})} - - - -# Icon Position - - - - - - ), - }} - > - {Template.bind({})} - - - - - ), - iconPosition: "end", - }} - > - {Template.bind({})} - - diff --git a/app/client/packages/design-system/widgets/src/components/Button/Button.tsx b/app/client/packages/design-system/widgets/src/components/Button/Button.tsx index 78b2a0f3e0..6e7e9faf96 100644 --- a/app/client/packages/design-system/widgets/src/components/Button/Button.tsx +++ b/app/client/packages/design-system/widgets/src/components/Button/Button.tsx @@ -5,28 +5,33 @@ import type { import React, { forwardRef } from "react"; import { Icon as HeadlessIcon } from "@design-system/headless"; import { useVisuallyHidden } from "@react-aria/visually-hidden"; - import { Text } from "../Text"; import { Spinner } from "../Spinner"; +import type { + BUTTON_COLORS, + BUTTON_VARIANTS, + BUTTON_ICON_POSITIONS, +} from "./types"; import { DragContainer, StyledButton } from "./index.styled"; export interface ButtonProps extends Omit { /** variant of the button - * - * @default "filled" + * @default filled */ - variant?: "filled" | "outlined" | "ghost"; - /** Color tone of the button */ - color?: "accent" | "neutral" | "positive" | "negative" | "warning"; - /** When true, makes the button occupy all the space available */ - isFitContainer?: boolean; + variant?: (typeof BUTTON_VARIANTS)[keyof typeof BUTTON_VARIANTS]; + /** Color tone of the button + * @default accent + */ + color?: (typeof BUTTON_COLORS)[keyof typeof BUTTON_COLORS]; /** Indicates the loading state of the button */ isLoading?: boolean; /** Icon to be used in the button of the button */ icon?: React.ReactNode; - /** Indicates the position of icon of the button */ - iconPosition?: "start" | "end"; - /** Makes the button visually and functionally disabled but focusable */ + /** Indicates the position of icon of the button + * @default accent + */ + iconPosition?: (typeof BUTTON_ICON_POSITIONS)[keyof typeof BUTTON_ICON_POSITIONS]; + /** Makes the button visually and functionaly disabled but focusable */ visuallyDisabled?: boolean; } @@ -38,7 +43,6 @@ export const Button = forwardRef( color = "accent", icon, iconPosition = "start", - isFitContainer = false, isLoading, // eslint-disable-next-line -- TODO add onKeyUp when the bug is fixed https://github.com/adobe/react-spectrum/issues/4350 onKeyUp, @@ -64,7 +68,9 @@ export const Button = forwardRef( return ( <> {icon} - {children} + + {children} + ); }; @@ -78,8 +84,8 @@ export const Button = forwardRef( visuallyDisabled || isLoading || props.isDisabled ? true : undefined } data-button="" - data-fit-container={isFitContainer ? "" : undefined} - data-icon-position={iconPosition === "start" ? undefined : "end"} + data-color={color} + data-icon-position={iconPosition === "start" ? "start" : "end"} data-loading={isLoading ? "" : undefined} data-variant={variant} draggable diff --git a/app/client/packages/design-system/widgets/src/components/Button/index.styled.tsx b/app/client/packages/design-system/widgets/src/components/Button/index.styled.tsx index 0ea2c7d251..acf1829728 100644 --- a/app/client/packages/design-system/widgets/src/components/Button/index.styled.tsx +++ b/app/client/packages/design-system/widgets/src/components/Button/index.styled.tsx @@ -1,8 +1,8 @@ import styled, { css } from "styled-components"; import { Button as HeadlessButton } from "@design-system/headless"; -import type { PickRename } from "../../utils"; import type { ButtonProps } from "./Button"; +import type { PickRename } from "../../utils"; type StyledButtonProps = PickRename< ButtonProps, @@ -73,16 +73,22 @@ export const StyledButton = styled(HeadlessButton)` cursor: pointer; outline: 0; padding: var(--spacing-2) var(--spacing-4); + block-size: var(--sizing-8); border-radius: var(--border-radius-1); user-select: none; - height: var(--sizing-8); - min-width: var(--sizing-8); - text-align: center; + min-inline-size: var(--sizing-8); position: relative; font-weight: 600; + border-width: 0; + border-style: solid; + font-family: inherit; - & *:not([data-hidden]) + *:not([data-hidden]) { - margin: 0 var(--spacing-1); + &[data-icon-position="start"] *:not([data-hidden]) + *:not([data-hidden]) { + margin-inline-start: var(--spacing-1); + } + + &[data-icon-position="end"] *:not([data-hidden]) + *:not([data-hidden]) { + margin-inline-end: var(--spacing-1); } ${buttonStyles} @@ -96,8 +102,14 @@ export const StyledButton = styled(HeadlessButton)` display: flex; justify-content: center; align-items: center; - height: var(--sizing-5); - width: var(--sizing-5); + height: var(--sizing-4); + width: var(--sizing-4); + } + + // Note: adding important here as ADS is overriding the color of blueprint icon globally + // TODO(pawan): Remove this once ADS team removes the global override + &[data-button] .bp3-icon { + color: currentColor !important; } /** diff --git a/app/client/packages/design-system/widgets/src/components/Button/index.tsx b/app/client/packages/design-system/widgets/src/components/Button/index.tsx index 1c3bdccf40..7a23efc0f3 100644 --- a/app/client/packages/design-system/widgets/src/components/Button/index.tsx +++ b/app/client/packages/design-system/widgets/src/components/Button/index.tsx @@ -1,2 +1,3 @@ export { Button } from "./Button"; export type { ButtonProps } from "./Button"; +export * from "./types"; diff --git a/app/client/packages/design-system/widgets/src/components/Button/types.ts b/app/client/packages/design-system/widgets/src/components/Button/types.ts new file mode 100644 index 0000000000..224364655d --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/Button/types.ts @@ -0,0 +1,18 @@ +export const BUTTON_VARIANTS = { + FILLED: "filled", + OUTLINED: "outlined", + GHOST: "ghost", +} as const; + +export const BUTTON_ICON_POSITIONS = { + START: "start", + END: "end", +} as const; + +export const BUTTON_COLORS = { + ACCENT: "accent", + NEUTRAL: "neutral", + POSITIVE: "positive", + NEGATIVE: "negative", + WARNING: "warning", +} as const; diff --git a/app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.stories.mdx b/app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.stories.mdx deleted file mode 100644 index 59c137b299..0000000000 --- a/app/client/packages/design-system/widgets/src/components/ButtonGroup/ButtonGroup.stories.mdx +++ /dev/null @@ -1,192 +0,0 @@ -import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; - -import { Button } from "../Button"; -import { ButtonGroup } from "./"; - - - - - - - ), - }} -/> - -export const Template = (args) => ; - -## Button Group - -A button group is a group of buttons that are visually connected together. - - - {Template.bind({})} - - - - -# Variants - - - - - - - - ), - }} - > - {Template.bind({})} - - - - - - - ), - }} - > - {Template.bind({})} - - - - - - - ), - }} - > - {Template.bind({})} - - - -# Orientation - - - - - - - - ), - }} - > - {Template.bind({})} - - - - - - - ), - }} - > - {Template.bind({})} - - - - - - - ), - }} - > - {Template.bind({})} - - - -# Disabled - - - - - - - - ), - }} - > - {Template.bind({})} - - - - - - - ), - }} - > - {Template.bind({})} - - - - - - - ), - }} - > - {Template.bind({})} - - diff --git a/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx b/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx index b5fe780214..1b05ac56a9 100644 --- a/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx +++ b/app/client/packages/design-system/widgets/src/components/ButtonGroup/index.styled.tsx @@ -51,10 +51,6 @@ export const StyledContainer = styled.div` & + [data-button] { margin-left: calc(var(--border-width-1) * -1); - - @media (min-resolution: 192dpi) { - margin-left: 0px; - } } } @@ -76,10 +72,56 @@ export const StyledContainer = styled.div` & + [data-button] { margin-top: calc(var(--border-width-1) * -1); - - @media (min-resolution: 192dpi) { - margin-top: 0px; - } } } + + /** + * ---------------------------------------------------------------------------- + * Filled variant + *----------------------------------------------------------------------------- + */ + & [data-variant="filled"][data-color="accent"] { + border-color: var(--color-bd-on-accent); + } + + & [data-variant="filled"][data-color="neutral"] { + border-color: var(--color-bd-on-neutral); + } + + & [data-variant="filled"][data-color="positive"] { + border-color: var(--color-bd-on-positive); + } + + & [data-variant="filled"][data-color="negative"] { + border-color: var(--color-bd-on-negative); + } + + & [data-variant="filled"][data-color="warning"] { + border-color: var(--color-bd-on-warning); + } + + /** + * ---------------------------------------------------------------------------- + * Outlined variant + *----------------------------------------------------------------------------- + */ + & [data-variant="outlined"][data-color="accent"] { + border-color: var(--color-bd-accent); + } + + & [data-variant="outlined"][data-color="neutral"] { + border-color: var(--color-bd-neutral); + } + + & [data-variant="outlined"][data-color="positive"] { + border-color: var(--color-bd-positive); + } + + & [data-variant="outlined"][data-color="negative"] { + border-color: var(--color-bd-negative); + } + + & [data-variant="outlined"][data-color="warning"] { + border-color: var(--color-bd-warning); + } `; diff --git a/app/client/packages/design-system/widgets/src/components/RadioGroup/RadioGroup.stories.mdx b/app/client/packages/design-system/widgets/src/components/RadioGroup/RadioGroup.stories.mdx deleted file mode 100644 index 8ccec559c8..0000000000 --- a/app/client/packages/design-system/widgets/src/components/RadioGroup/RadioGroup.stories.mdx +++ /dev/null @@ -1,120 +0,0 @@ -import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; - -import { RadioGroup } from "./"; -import { Radio } from "../Radio"; - - - Value 1 - Value 2 - - ), - }} -/> - -export const Template = (args) => ; - -# Radio Group - -Radio group is a component that allows users to select one option from a set of options. - - - {Template.bind({})} - - - - -# Orientation - - - - {Template.bind({})} - - - {Template.bind({})} - - - -# Emphasized - - - - {Template.bind({})} - - - -# Label Position and Alignment - - - - {Template.bind({})} - - - -# Is Disabled - - - - {Template.bind({})} - - - -# Is Required - - - - {Template.bind({})} - - - -# Invalid State - - - - {Template.bind({})} - - diff --git a/app/client/packages/design-system/widgets/src/components/Checkbox/Checkbox.stories.mdx b/app/client/packages/design-system/widgets/src/components/Switch/Switch.stories.mdx similarity index 54% rename from app/client/packages/design-system/widgets/src/components/Checkbox/Checkbox.stories.mdx rename to app/client/packages/design-system/widgets/src/components/Switch/Switch.stories.mdx index 7b5d9663f7..c8c76328c5 100644 --- a/app/client/packages/design-system/widgets/src/components/Checkbox/Checkbox.stories.mdx +++ b/app/client/packages/design-system/widgets/src/components/Switch/Switch.stories.mdx @@ -1,24 +1,24 @@ import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; import EmotionHappyLineIcon from "remixicon-react/EmotionHappyLineIcon"; -import { Checkbox } from "./"; +import { Switch } from "./"; -export const Template = (args) => ; +export const Template = (args) => ; -# Checkbox +# Switch -Checkbox is a component that allows the user to select one or more options from a set. +Switch is a component that allows the user to select one or more options from a set. - {Template.bind({})} + {Template.bind({})} ### States @@ -60,36 +60,6 @@ Checkbox is a component that allows the user to select one or more options from > {Template.bind({})} - - {Template.bind({})} - - - {Template.bind({})} - - - {Template.bind({})} - ### Label Position @@ -120,17 +90,3 @@ Checkbox is a component that allows the user to select one or more options from {Template.bind({})} - -### Custom Icon - - - , - }} - > - {Template.bind({})} - - diff --git a/app/client/packages/design-system/widgets/src/components/Switch/Switch.tsx b/app/client/packages/design-system/widgets/src/components/Switch/Switch.tsx new file mode 100644 index 0000000000..331509dc01 --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/Switch/Switch.tsx @@ -0,0 +1,28 @@ +import React, { forwardRef } from "react"; + +import type { + SwitchRef as HeadlessSwitchRef, + SwitchProps as HeadlessSwitchProps, +} from "@design-system/headless"; + +import { Text } from "../Text"; +import { StyledSwitch } from "./index.styled"; + +export type SwitchProps = Omit; + +export const Switch = forwardRef( + (props: SwitchProps, ref: HeadlessSwitchRef) => { + const { children, labelPosition = "right", ...rest } = props; + + return ( + + {children && {children}} + + ); + }, +); diff --git a/app/client/packages/design-system/widgets/src/components/Switch/index.styled.tsx b/app/client/packages/design-system/widgets/src/components/Switch/index.styled.tsx new file mode 100644 index 0000000000..b0623239e0 --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/Switch/index.styled.tsx @@ -0,0 +1,69 @@ +import styled from "styled-components"; +import { Switch as HeadlessSwitch } from "@design-system/headless"; + +import type { SwitchProps } from "."; +import { inlineLabelStyles } from "../../styles/inlineLabelStyles"; + +export const StyledSwitch = styled(HeadlessSwitch)` + ${inlineLabelStyles} + + [data-icon] { + --gutter: 2px; + --knob-size: var(--sizing-3); + + position: relative; + width: var(--sizing-8); + height: var(--sizing-4); + background-color: var(--color-bg-neutral); + border-radius: var(--knob-size); + color: var(--color-bg); + display: inline-flex; + align-items: center; + justify-content: center; + user-select: none; + flex-shrink: 0; + } + + [data-icon]::after { + content: ""; + height: var(--knob-size); + width: var(--knob-size); + transition: all 0.2s ease; + position: absolute; + left: var(--gutter); + border-radius: var(--knob-size); + background-color: currentColor; + } + + &[data-hovered]:not([data-disabled]) [data-icon] { + --checkbox-border-color: var(--color-bd-neutral-hover); + } + + /** + * ---------------------------------------------------------------------------- + * CHECKED - BUT NOT DISABLED + *----------------------------------------------------------------------------- + */ + &[data-state="checked"] [data-icon] { + background-color: var(--color-bg-accent); + color: var(--color-bg); + } + + &[data-hovered][data-state="checked"]:not([data-disabled]) [data-icon] { + background-color: var(--color-bg-accent-hover); + color: var(--color-bg); + } + + &[data-state="checked"] [data-icon]::after { + left: calc(100% - var(--knob-size) - var(--gutter)); + } + + /** + * ---------------------------------------------------------------------------- + * FOCUS + *----------------------------------------------------------------------------- + */ + &[data-focused] [data-icon] { + box-shadow: 0 0 0 2px var(--color-bg), 0 0 0 4px var(--color-bd-focus); + } +`; diff --git a/app/client/packages/design-system/widgets/src/components/Switch/index.tsx b/app/client/packages/design-system/widgets/src/components/Switch/index.tsx new file mode 100644 index 0000000000..ffb3ce2374 --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/Switch/index.tsx @@ -0,0 +1,2 @@ +export { Switch } from "./Switch"; +export type { SwitchProps } from "./Switch"; diff --git a/app/client/packages/design-system/widgets/src/components/CheckboxGroup/CheckboxGroup.stories.mdx b/app/client/packages/design-system/widgets/src/components/SwitchGroup/SwitchGroup.stories.mdx similarity index 71% rename from app/client/packages/design-system/widgets/src/components/CheckboxGroup/CheckboxGroup.stories.mdx rename to app/client/packages/design-system/widgets/src/components/SwitchGroup/SwitchGroup.stories.mdx index bd2e6f5f6c..c210c53235 100644 --- a/app/client/packages/design-system/widgets/src/components/CheckboxGroup/CheckboxGroup.stories.mdx +++ b/app/client/packages/design-system/widgets/src/components/SwitchGroup/SwitchGroup.stories.mdx @@ -1,34 +1,34 @@ import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; -import { CheckboxGroup } from "./"; -import { Checkbox } from "../Checkbox"; +import { SwitchGroup } from "./"; +import { Switch } from "../Switch"; - Value 1 - Value 2 + Value 1 + Value 2 ), }} /> -export const Template = (args) => ; +export const Template = (args) => ; -# Checkbox Group +# Switch Group -Checkbox Group is a group of checkboxes that can be selected together. +Switch Group is a group of checkboxes that can be selected together. - {Template.bind({})} + {Template.bind({})} - + # Orientation diff --git a/app/client/packages/design-system/widgets/src/components/SwitchGroup/index.tsx b/app/client/packages/design-system/widgets/src/components/SwitchGroup/index.tsx new file mode 100644 index 0000000000..bf13531db1 --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/SwitchGroup/index.tsx @@ -0,0 +1,2 @@ +export { CheckboxGroup as SwitchGroup } from "../CheckboxGroup"; +export type { CheckboxGroupProps as SwitchGroupProps } from "../CheckboxGroup"; diff --git a/app/client/packages/design-system/widgets/src/components/Text/Text.stories.mdx b/app/client/packages/design-system/widgets/src/components/Text/Text.stories.mdx deleted file mode 100644 index 31ca689dc1..0000000000 --- a/app/client/packages/design-system/widgets/src/components/Text/Text.stories.mdx +++ /dev/null @@ -1,79 +0,0 @@ -import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; -import { Text } from "./"; -import { Flex } from "../Flex"; -import { TypographyVariant, TypographyColor } from "@design-system/theming"; - - - -export const Template = (args) => ; - -# Text - -Text is a component that renders a capsized text. - - - {Template.bind({})} - - - - -## Line clamp - - - - {Template.bind({})} - - - -## Variant - - - - - {Object.keys(TypographyVariant).map((variant) => ( - aA - ))} - - - - -## Color - - - - - {Object.keys(TypographyColor).map((color) => ( - - aA - - ))} - - - diff --git a/app/client/packages/design-system/widgets/src/components/Text/Text.tsx b/app/client/packages/design-system/widgets/src/components/Text/Text.tsx index a30baf6e4e..d4c7576537 100644 --- a/app/client/packages/design-system/widgets/src/components/Text/Text.tsx +++ b/app/client/packages/design-system/widgets/src/components/Text/Text.tsx @@ -10,10 +10,25 @@ import type { } from "@design-system/theming"; export interface TextProps { + /** variant of the text + * @default body + */ variant?: keyof typeof TypographyVariant; + /** color of the text + * @default default — sets inherit via CSS; + */ color?: keyof typeof TypographyColor; + /** sets the weight (or boldness) of the font + * @default false + */ isBold?: boolean; + /** sets the weight (or boldness) of the font + * @default false + */ isItalic?: boolean; + /** Sets a font that is classified as italic. + * @default false + */ textAlign?: "left" | "center" | "right"; lineClamp?: number; className?: string; diff --git a/app/client/packages/design-system/widgets/src/components/Text/index.styled.tsx b/app/client/packages/design-system/widgets/src/components/Text/index.styled.tsx index 2342d03e16..995f1a277f 100644 --- a/app/client/packages/design-system/widgets/src/components/Text/index.styled.tsx +++ b/app/client/packages/design-system/widgets/src/components/Text/index.styled.tsx @@ -33,7 +33,7 @@ export const StyledText = styled.div` font-weight: ${({ $isBold }) => ($isBold ? "bold" : "normal")}; font-style: ${({ $isItalic }) => ($isItalic ? "italic" : "normal")}; text-align: ${({ $textAlign }) => $textAlign}; - max-width: 100%; + width: 100%; color: ${({ color }) => { switch (true) { diff --git a/app/client/packages/design-system/widgets/src/components/Tooltip/Tooltip.stories.mdx b/app/client/packages/design-system/widgets/src/components/Tooltip/Tooltip.stories.mdx deleted file mode 100644 index 4d01f2d448..0000000000 --- a/app/client/packages/design-system/widgets/src/components/Tooltip/Tooltip.stories.mdx +++ /dev/null @@ -1,92 +0,0 @@ -import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; - -import { Button } from "../Button"; -import { ButtonGroup } from "../ButtonGroup"; -import { Tooltip, TooltipTrigger, TooltipContent } from "./"; - - - -export const Template = (args) => { - return ( - - - - - My tooltip - - ); -}; - -# Tooltip - -A tooltip is a small pop-up that appears when a user places their cursor over an element such as a link or button. Tooltips can be used to provide users with additional information about an element without having to clutter up the UI with additional text. - - - {Template.bind({})} - - - - -# Placement - -The placement of the tooltip can be changed by passing the `placement` prop. - - - - - - - - - My tooltip - - - - - - My tooltip - - - - - - My tooltip - - - - - - My tooltip - - - - - -# Disabled - -If the trigger is disabled, the tooltip will still be displayed. - - - - - - - - My tooltip - - - diff --git a/app/client/packages/design-system/widgets/src/components/Tooltip/Tooltip.tsx b/app/client/packages/design-system/widgets/src/components/Tooltip/Tooltip.tsx new file mode 100644 index 0000000000..599050b918 --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/Tooltip/Tooltip.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +import { TooltipRoot, TooltipContent, TooltipTrigger } from "./"; + +export type TooltipProps = { + tooltip?: React.ReactNode; + children: React.ReactElement; +}; + +export function Tooltip(props: TooltipProps) { + const { children, tooltip } = props; + + if (!tooltip) return children; + + return ( + + {children} + {tooltip} + + ); +} diff --git a/app/client/packages/design-system/widgets/src/components/Tooltip/index.styled.tsx b/app/client/packages/design-system/widgets/src/components/Tooltip/index.styled.tsx index 70780dac6c..07083630d6 100644 --- a/app/client/packages/design-system/widgets/src/components/Tooltip/index.styled.tsx +++ b/app/client/packages/design-system/widgets/src/components/Tooltip/index.styled.tsx @@ -15,6 +15,7 @@ export const StyledTooltipContent = styled( color: var(--color-fg-on-assistive); padding: var(--spacing-2) var(--spacing-3); border-radius: var(--border-radius-1); + z-index: var(--z-index-99); [data-tooltip-trigger-arrow] { fill: var(--color-bg-assistive); diff --git a/app/client/packages/design-system/widgets/src/components/Tooltip/index.tsx b/app/client/packages/design-system/widgets/src/components/Tooltip/index.tsx index dd99c34245..dacc28afd3 100644 --- a/app/client/packages/design-system/widgets/src/components/Tooltip/index.tsx +++ b/app/client/packages/design-system/widgets/src/components/Tooltip/index.tsx @@ -1,3 +1,4 @@ -export { Tooltip } from "@design-system/headless"; +export { Tooltip } from "./Tooltip"; +export { TooltipRoot } from "@design-system/headless"; export { TooltipTrigger } from "./TooltipTrigger"; export { TooltipContent } from "./TooltipContent"; diff --git a/app/client/packages/design-system/widgets/src/index.ts b/app/client/packages/design-system/widgets/src/index.ts index cc5101a387..84d36bdd31 100644 --- a/app/client/packages/design-system/widgets/src/index.ts +++ b/app/client/packages/design-system/widgets/src/index.ts @@ -1,7 +1,13 @@ // components +export { Icon } from "@design-system/headless"; + export * from "./components/Button"; +export * from "./components/ButtonGroup"; export * from "./components/Checkbox"; export * from "./components/Text"; export * from "./components/CheckboxGroup"; export * from "./components/Tooltip"; +export * from "./components/Flex"; +export * from "./components/Radio"; +export * from "./components/RadioGroup"; export * from "./utils"; diff --git a/app/client/packages/design-system/widgets/src/styles/fieldStyles.ts b/app/client/packages/design-system/widgets/src/styles/fieldStyles.ts index a333f59c38..57c608611c 100644 --- a/app/client/packages/design-system/widgets/src/styles/fieldStyles.ts +++ b/app/client/packages/design-system/widgets/src/styles/fieldStyles.ts @@ -73,6 +73,7 @@ export const fieldStyles = css` flex-direction: column; &[data-orientation="horizontal"] { + gap: var(--spacing-4); flex-direction: row; } diff --git a/app/client/packages/design-system/widgets/src/utils/OmitRename.ts b/app/client/packages/design-system/widgets/src/utils/OmitRename.ts index 1448af6789..95dd166032 100644 --- a/app/client/packages/design-system/widgets/src/utils/OmitRename.ts +++ b/app/client/packages/design-system/widgets/src/utils/OmitRename.ts @@ -3,7 +3,5 @@ export type OmitRename< TOmitKeys extends keyof TObj, TSymbol extends string = "$", > = { - [K in keyof TObj as K extends TOmitKeys - ? never - : `${TSymbol}${string & K}`]: TObj[K]; -} & Omit; + [K in keyof Omit as `${TSymbol}${string & K}`]: TObj[K]; +} & Pick; diff --git a/app/client/packages/storybook/.storybook/addons/theming/ThemingPanel.tsx b/app/client/packages/storybook/.storybook/addons/theming/ThemingPanel.tsx new file mode 100644 index 0000000000..c4005eda42 --- /dev/null +++ b/app/client/packages/storybook/.storybook/addons/theming/ThemingPanel.tsx @@ -0,0 +1,130 @@ +import * as React from "react"; +import { useCallback, useState } from "react"; +import { FORCE_RE_RENDER } from "@storybook/core-events"; +import { useGlobals, addons } from "@storybook/manager-api"; +import { AddonPanel, H6, Form } from "@storybook/components"; +import { ColorControl, BooleanControl, NumberControl } from "@storybook/blocks"; +import { fontMetrics } from "@design-system/theming"; +import { debounce } from "lodash"; +import styled from "styled-components"; + +interface PanelProps { + active: boolean; +} + +const StyledSelect = styled(Form.Select)` + appearance: none; + padding-right: 30px; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23696969%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"); + background-repeat: no-repeat, repeat; + background-position: right 0.8em top 50%, 0 0; + background-size: 0.65em auto, 100%; +`; + +const Wrapper = styled.div` + padding: 10px; + display: flex; + flex-direction: column; + gap: 10px; +`; + +export const ThemingPanel: React.FC = (props) => { + const [globals, updateGlobals] = useGlobals(); + const [isDarkMode, setDarkMode] = useState(false); + + const updateGlobal = (key, value) => { + updateGlobals({ + [key]: value, + }), + // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh + addons.getChannel().emit(FORCE_RE_RENDER); + }; + + const colorChange = (value) => updateGlobal("accentColor", value); + const debouncedColorChange = useCallback(debounce(colorChange, 300), []); + return ( + + +
+
Dark mode
+ { + setDarkMode(checked); + updateGlobal("colorMode", checked ? "dark" : "light"); + }} + /> +
+ +
+
Border Radius
+ updateGlobal("borderRadius", e.target.value)} + > + + + + +
+ +
+
Accent Color
+ +
+ +
+
Font Family
+ updateGlobal("fontFamily", e.target.value)} + > + + {Object.keys(fontMetrics) + .filter((item) => { + return ( + ["-apple-system", "BlinkMacSystemFont", "Segoe UI"].includes( + item, + ) === false + ); + }) + .map((font) => ( + + ))} + +
+ +
+
Root Unit Ratio
+ updateGlobal("rootUnitRatio", value)} + /> +
+
+
+ ); +}; diff --git a/app/client/packages/storybook/.storybook/addons/theming/manager.ts b/app/client/packages/storybook/.storybook/addons/theming/manager.ts new file mode 100644 index 0000000000..72b5435a5f --- /dev/null +++ b/app/client/packages/storybook/.storybook/addons/theming/manager.ts @@ -0,0 +1,23 @@ +import { addons, types } from "@storybook/manager-api"; +import { ThemingPanel } from "./ThemingPanel"; + +// Register the addon +addons.register("widgets/theming", () => { + // Register the tool + addons.add("widgets-addon/panel", { + type: types.PANEL, + title: "Theming", + match: (args) => { + const { viewMode, storyId } = args; + + // show the addon only on wds + return !!( + storyId && + storyId?.includes("widgets") && + !storyId?.includes("widgets-old") && + !!(viewMode && viewMode.match(/^(story|docs)$/)) + ); + }, + render: ThemingPanel, + }); +}); diff --git a/app/client/packages/storybook/.storybook/addons/theming/register.js b/app/client/packages/storybook/.storybook/addons/theming/register.js deleted file mode 100644 index 819f0f503a..0000000000 --- a/app/client/packages/storybook/.storybook/addons/theming/register.js +++ /dev/null @@ -1,152 +0,0 @@ -import styled from "styled-components"; -import React, { useCallback, useState } from "react"; -import { addons, types } from "@storybook/addons"; -import { - Form, - H6, - ColorControl, - AddonPanel, - BooleanControl, - NumberControl, -} from "@storybook/components"; -import { useGlobals } from "@storybook/api"; -import { fontMetrics } from "@design-system/theming"; -import debounce from "lodash/debounce"; - -const { Select } = Form; - -const Wrapper = styled.div` - padding: 10px; - display: flex; - flex-direction: column; - gap: 10px; -`; - -const StyledSelect = styled(Select)` - appearance: none; - padding-right: 30px; - -moz-appearance: none; - -webkit-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23696969%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"); - background-repeat: no-repeat, repeat; - background-position: right 0.8em top 50%, 0 0; - background-size: 0.65em auto, 100%; -`; - -addons.register("widgets/theming", () => { - addons.add("widgets-addon/panel", { - id: "widgets-addon/toolbar", - title: "Theming", - type: types.PANEL, - match: (args) => { - const { viewMode, storyId } = args; - - // show the addon only on wds - return !!( - storyId && - storyId?.includes("widgets") && - !!(viewMode && viewMode.match(/^(story|docs)$/)) - ); - }, - render: ({ active, key }) => { - const [globals, updateGlobals] = useGlobals(); - const [isDarkMode, setDarkMode] = useState(false); - - const updateGlobal = (key, value) => { - updateGlobals({ - [key]: value, - }); - }; - - const colorChange = (value) => updateGlobal("accentColor", value); - const debouncedColorChange = useCallback(debounce(colorChange, 300), []); - - return ( - - -
-
Dark mode
- { - setDarkMode(checked); - updateGlobal("colorMode", checked ? "dark" : "light"); - }} - /> -
- -
-
Border Radius
- updateGlobal("borderRadius", e.target.value)} - > - - - - -
- -
-
Accent Color
- -
- -
-
Font Family
- updateGlobal("fontFamily", e.target.value)} - > - - {Object.keys(fontMetrics) - .filter((item) => { - return ( - [ - "-apple-system", - "BlinkMacSystemFont", - "Segoe UI", - ].includes(item) === false - ); - }) - .map((font) => ( - - ))} - -
- -
-
Root Unit Ratio
- updateGlobal("rootUnitRatio", value)} - /> -
-
-
- ); - }, - }); -}); diff --git a/app/client/packages/storybook/.storybook/appsmith-theme.js b/app/client/packages/storybook/.storybook/appsmith-theme.ts similarity index 100% rename from app/client/packages/storybook/.storybook/appsmith-theme.js rename to app/client/packages/storybook/.storybook/appsmith-theme.ts diff --git a/app/client/packages/storybook/.storybook/decorators/theming.tsx b/app/client/packages/storybook/.storybook/decorators/theming.tsx index 498cd84aa6..d90169b004 100644 --- a/app/client/packages/storybook/.storybook/decorators/theming.tsx +++ b/app/client/packages/storybook/.storybook/decorators/theming.tsx @@ -1,14 +1,6 @@ import * as React from "react"; -import { useEffect, useState } from "react"; -import * as webfontloader from "webfontloader"; import styled from "styled-components"; -import { - ThemeProvider, - TokensAccessor, - defaultTokens, - useFluidTokens, -} from "@design-system/theming"; -import Color from "colorjs.io"; +import { ThemeProvider, useTheme } from "@design-system/theming"; const StyledThemeProvider = styled(ThemeProvider)` display: inline-flex; @@ -22,132 +14,14 @@ const StyledThemeProvider = styled(ThemeProvider)` `; export const theming = (Story, args) => { - const [rootUnitRatio, setRootUnitRatio] = useState(1); - const { fluid, ...restDefaultTokens } = defaultTokens; - - const { typography, rootUnit, spacing, sizing } = useFluidTokens( - fluid, - rootUnitRatio, - ); - - const tokensAccessor = new TokensAccessor({ - ...restDefaultTokens, - rootUnit, - spacing, - sizing, - typography, + const { theme } = useTheme({ + seedColor: args.globals.accentColor, + colorMode: args.globals.colorMode, + borderRadius: args.globals.borderRadius, + fontFamily: args.globals.fontFamily, + rootUnitRatio: args.globals.rootUnitRatio, }); - const [theme, setTheme] = useState(tokensAccessor.getAllTokens()); - - const updateFontFamily = (fontFamily) => { - tokensAccessor.updateFontFamily(fontFamily); - - setTheme((prevState) => { - return { - ...prevState, - typography: tokensAccessor.getTypography(), - }; - }); - }; - - useEffect(() => { - if (args.globals.colorMode) { - tokensAccessor.updateColorMode(args.globals.colorMode); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getColors(), - }; - }); - } - }, [args.globals.colorMode]); - - useEffect(() => { - if (args.globals.borderRadius) { - tokensAccessor.updateBorderRadius({ - 1: args.globals.borderRadius, - }); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getBorderRadius(), - }; - }); - } - }, [args.globals.borderRadius]); - - useEffect(() => { - if (args.globals.accentColor) { - let color; - - try { - color = Color.parse(args.globals.accentColor); - } catch (error) { - console.error(error); - } - - if (color) { - tokensAccessor.updateSeedColor(args.globals.accentColor); - - setTheme((prevState) => { - return { - ...prevState, - ...tokensAccessor.getColors(), - }; - }); - } - } - }, [args.globals.accentColor]); - - useEffect(() => { - if ( - args.globals.fontFamily && - args.globals.fontFamily !== "Arial" && - args.globals.fontFamily !== "System Default" - ) { - webfontloader.load({ - google: { - families: [`${args.globals.fontFamily}:300,400,500,700`], - }, - active: () => { - updateFontFamily(args.globals.fontFamily); - }, - }); - } else { - updateFontFamily(args.globals.fontFamily); - } - }, [args.globals.fontFamily]); - - useEffect(() => { - if (args.globals.rootUnitRatio) { - setRootUnitRatio(args.globals.rootUnitRatio); - tokensAccessor.updateRootUnit(rootUnit); - tokensAccessor.updateSpacing(spacing); - - setTheme((prevState) => { - return { - ...prevState, - rootUnit: tokensAccessor.getRootUnit(), - ...tokensAccessor.getSpacing(), - }; - }); - } - }, [args.globals.rootUnitRatio]); - - useEffect(() => { - tokensAccessor.updateTypography(typography); - - setTheme((prevState) => { - return { - ...prevState, - typography: tokensAccessor.getTypography(), - }; - }); - }, [typography]); - return ( diff --git a/app/client/packages/storybook/.storybook/main.js b/app/client/packages/storybook/.storybook/main.js deleted file mode 100644 index b6613be687..0000000000 --- a/app/client/packages/storybook/.storybook/main.js +++ /dev/null @@ -1,50 +0,0 @@ -const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); - -async function webpackConfig(config) { - config.module.rules.push({ - test: /\.(js|jsx|ts|tsx)$/, - use: { - loader: "babel-loader", - options: { - presets: [ - "@babel/preset-env", - "@babel/preset-react", - "@babel/preset-typescript", - ], - }, - }, - }); - - config.resolve.plugins.push(new TsconfigPathsPlugin()); - - return config; -} - -module.exports = { - stories: [ - "../../design-system/**/*.stories.mdx", - "../../design-system/**/*.stories.@(js|jsx|ts|tsx)", - ], - addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@storybook/addon-interactions", - "@storybook/preset-create-react-app", - "storybook-addon-pseudo-states", - "./addons/theming/register.js", - ], - framework: "@storybook/react", - webpackFinal: webpackConfig, - core: { - builder: "@storybook/builder-webpack5", - }, - typescript: { - reactDocgen: "react-docgen-typescript", - reactDocgenTypescriptOptions: { - compilerOptions: { - allowSyntheticDefaultImports: false, - esModuleInterop: false, - }, - }, - }, -}; diff --git a/app/client/packages/storybook/.storybook/main.ts b/app/client/packages/storybook/.storybook/main.ts new file mode 100644 index 0000000000..1e5c2fc5ba --- /dev/null +++ b/app/client/packages/storybook/.storybook/main.ts @@ -0,0 +1,60 @@ +import { dirname, join } from "path"; +const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); +async function webpackConfig(config) { + config.module.rules.push({ + test: /\.(js|jsx|ts|tsx)$/, + use: { + loader: "babel-loader", + options: { + presets: [ + "@babel/preset-env", + "@babel/preset-react", + "@babel/preset-typescript", + ], + }, + }, + }); + config.resolve.plugins.push(new TsconfigPathsPlugin()); + return config; +} +module.exports = { + stories: [ + "../stories/**/*.stories.mdx", + "../stories/**/*.stories.@(js|jsx|ts|tsx)", + ], + addons: [ + getAbsolutePath("@storybook/addon-viewport"), + getAbsolutePath("@storybook/addon-docs"), + getAbsolutePath("@storybook/addon-actions"), + getAbsolutePath("@storybook/addon-controls"), + getAbsolutePath("@storybook/addon-toolbars"), + getAbsolutePath("@storybook/addon-measure"), + getAbsolutePath("@storybook/addon-outline"), + getAbsolutePath("@storybook/preset-create-react-app"), + "./addons/theming/manager.ts", + ], + framework: { + name: getAbsolutePath("@storybook/react-webpack5"), + options: {}, + }, + webpackFinal: webpackConfig, + typescript: { + reactDocgen: "react-docgen-typescript", + reactDocgenTypescriptOptions: { + compilerOptions: { + allowSyntheticDefaultImports: false, + esModuleInterop: false, + }, + }, + }, + core: { + disableTelemetry: true, + }, +}; +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ +function getAbsolutePath(value) { + return dirname(require.resolve(join(value, "package.json"))); +} diff --git a/app/client/packages/storybook/.storybook/manager-head.html b/app/client/packages/storybook/.storybook/manager-head.html index 79b867f5fa..a879905e6e 100644 --- a/app/client/packages/storybook/.storybook/manager-head.html +++ b/app/client/packages/storybook/.storybook/manager-head.html @@ -1,74 +1,8 @@ diff --git a/app/client/packages/storybook/.storybook/manager.js b/app/client/packages/storybook/.storybook/manager.ts similarity index 100% rename from app/client/packages/storybook/.storybook/manager.js rename to app/client/packages/storybook/.storybook/manager.ts diff --git a/app/client/packages/storybook/.storybook/preview.js b/app/client/packages/storybook/.storybook/preview.js deleted file mode 100644 index 0a1a4dcee4..0000000000 --- a/app/client/packages/storybook/.storybook/preview.js +++ /dev/null @@ -1,20 +0,0 @@ -import { theming } from "./decorators/theming"; -import "@blueprintjs/icons/lib/css/blueprint-icons.css"; -import "@blueprintjs/core/lib/css/blueprint.css"; -import "./styles.css"; - -export const parameters = { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, - backgrounds: { - disable: true, - }, - layout: "centered", -}; - -export const decorators = [theming]; diff --git a/app/client/packages/storybook/.storybook/preview.ts b/app/client/packages/storybook/.storybook/preview.ts new file mode 100644 index 0000000000..2d0574ae81 --- /dev/null +++ b/app/client/packages/storybook/.storybook/preview.ts @@ -0,0 +1,67 @@ +import { theming } from "./decorators/theming"; +import "@blueprintjs/icons/lib/css/blueprint-icons.css"; +import "@blueprintjs/core/lib/css/blueprint.css"; +import "./styles.css"; + +export const decorators = [theming]; + +const customViewports = { + HighResLaptop: { + name: "High-res laptop or desktop", + styles: { + width: "1920px", + height: "1080px", + }, + }, + Laptop: { + name: "Laptop", + styles: { + width: "1366px", + height: "768px", + }, + }, + Tablet: { + name: "Tablet", + styles: { + width: "768px", + height: "1024px", + }, + }, + Pixel2: { + name: "Pixel2", + styles: { + width: "411px", + height: "731px", + }, + }, + iPhoneX: { + name: "iPhoneX", + styles: { + width: "375px", + height: "812px", + }, + }, + Mobile: { + name: "Mobile", + styles: { + width: "360px", + height: "720px", + }, + }, +}; + +const preview = { + globalTypes: { + colorMode: {}, + borderRadius: {}, + accentColor: {}, + fontFamily: {}, + rootUnitRatio: {}, + }, + parameters: { + viewport: { viewports: customViewports }, + actions: { argTypesRegex: "^on[A-Z].*" }, + }, +}; + +export default preview; diff --git a/app/client/packages/storybook/.storybook/styles.css b/app/client/packages/storybook/.storybook/styles.css index 7633354920..fbe7c6ae71 100644 --- a/app/client/packages/storybook/.storybook/styles.css +++ b/app/client/packages/storybook/.storybook/styles.css @@ -1,17 +1,17 @@ html, body, -#root { +#storybook-root { height: 100%; width: 100%; } -*, -:after, -:before { - border: 0 solid #e4e4e7; - box-sizing: border-box; -} - -.innerZoomElementWrapper > * { - overflow: hidden; -} +/* fonts */ +@import url("https://fonts.googleapis.com/css2?family=Nunito+Sans:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); diff --git a/app/client/packages/storybook/package.json b/app/client/packages/storybook/package.json index 6042432e64..5454fc8de4 100644 --- a/app/client/packages/storybook/package.json +++ b/app/client/packages/storybook/package.json @@ -5,8 +5,8 @@ "author": "Valera Melnikov , Pawan Kumar ", "license": "MIT", "scripts": { - "storybook": "start-storybook -p 6006", - "build": "build-storybook", + "storybook": "storybook dev -p 6006", + "build": "storybook build", "chromatic": "chromatic --project-token CHROMATIC_PROJECT_TOKEN" }, "devDependencies": { @@ -14,29 +14,31 @@ "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", - "@storybook/addon-actions": "^6.5.16", - "@storybook/addon-essentials": "^6.5.16", - "@storybook/addon-interactions": "^6.5.16", - "@storybook/addon-links": "^6.5.16", - "@storybook/addon-postcss": "^2.0.0", - "@storybook/builder-webpack5": "^6.5.16", - "@storybook/manager-webpack5": "^6.5.16", - "@storybook/node-logger": "^6.5.16", - "@storybook/preset-create-react-app": "^4.1.2", - "@storybook/react": "^6.5.16", - "@storybook/testing-library": "^0.0.13", - "@types/react": "^17.0.2", - "@types/react-dom": "^17.0.2", - "autoprefixer": "^9.0.0", + "@storybook/addon-actions": "^7.1.1", + "@storybook/addon-controls": "^7.1.1", + "@storybook/addon-docs": "^7.1.1", + "@storybook/addon-measure": "^7.1.1", + "@storybook/addon-outline": "^7.1.1", + "@storybook/addon-toolbars": "^7.1.1", + "@storybook/addon-viewport": "^7.1.1", + "@storybook/blocks": "^7.1.1", + "@storybook/components": "^7.1.1", + "@storybook/manager-api": "^7.1.1", + "@storybook/preset-create-react-app": "^7.1.1", + "@storybook/react": "^7.1.1", + "@storybook/react-webpack5": "^7.1.1", + "@storybook/theming": "^7.1.1", "babel-loader": "9.1.2", - "chromatic": "^6.19.8", - "postcss": "^8.4.23", - "storybook-addon-pseudo-states": "^1.15.2", - "storybook-color-picker": "^3.1.0", + "chromatic": "^6.20.0", + "react-docgen-typescript": "^2.2.2", + "storybook": "^7.1.1", "tsconfig-paths-webpack-plugin": "^4.0.1" }, "dependencies": { - "colorjs.io": "^0.4.3", - "react-docgen-typescript": "^2.2.2" + "@design-system/headless": "workspace:^", + "@design-system/theming": "workspace:^", + "@design-system/widgets": "workspace:^", + "@design-system/widgets-old": "workspace:^", + "colorjs.io": "^0.4.3" } } diff --git a/app/client/packages/design-system/headless/src/components/Button/Button.stories.mdx b/app/client/packages/storybook/stories/design-system/headless/Button.stories.mdx similarity index 81% rename from app/client/packages/design-system/headless/src/components/Button/Button.stories.mdx rename to app/client/packages/storybook/stories/design-system/headless/Button.stories.mdx index 90d9263ad7..96696daaad 100644 --- a/app/client/packages/design-system/headless/src/components/Button/Button.stories.mdx +++ b/app/client/packages/storybook/stories/design-system/headless/Button.stories.mdx @@ -1,9 +1,9 @@ import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; -import { Button } from "./"; +import { Button } from "@design-system/headless"; { return ( - + - + My tooltip - + ); }; @@ -31,36 +35,38 @@ A tooltip is a small pop-up that appears when a user places their cursor over an {Template.bind({})} + + # Placement The placement of the tooltip can be changed by passing the `placement` prop. - + - + My tooltip - - + + - + My tooltip - - + + - + My tooltip - - + + - + My tooltip - + @@ -70,13 +76,11 @@ If the trigger is disabled, the tooltip will not be displayed. - + My tooltip - + - - diff --git a/app/client/packages/storybook/stories/design-system/theming/BorderRadius.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/BorderRadius.stories.mdx new file mode 100644 index 0000000000..42fa5f18c1 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/BorderRadius.stories.mdx @@ -0,0 +1,34 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme, ThemeProvider } from "@design-system/theming"; +import { TokenTable, StyledSquarePreview } from "./components"; + + + +# BorderRadius + +Border radius is a commonly used design element in user interfaces that +can add visual interest and depth to an application. By incorporating +standardized border radius values into our design system, we can create +a more cohesive and professional look for our products. + +## Tokens Table + +export const BorderRadius = () => { + const { theme } = useTheme(); + const { borderRadius } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + diff --git a/app/client/packages/storybook/stories/design-system/theming/BoxShadow.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/BoxShadow.stories.mdx new file mode 100644 index 0000000000..f0fc5e24cc --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/BoxShadow.stories.mdx @@ -0,0 +1,35 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme, ThemeProvider } from "@design-system/theming"; +import { TokenTable, StyledSquarePreview } from "./components"; + + + +# BoxShadow + +Box shadow is a visual effect that creates a three-dimensional look on a +two-dimensional element. It is used in web design to add depth and +texture to user interfaces. In a design system, box shadow is an +important element that helps to maintain consistency across all +components. + +## Tokens Table + +export const BoxShadow = () => { + const { theme } = useTheme(); + const { boxShadow } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + diff --git a/app/client/packages/storybook/stories/design-system/theming/Color.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/Color.stories.mdx new file mode 100644 index 0000000000..d3c90fb094 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/Color.stories.mdx @@ -0,0 +1,148 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme, ThemeProvider } from "@design-system/theming"; +import { TokenTable, StyledTable, StyledSquarePreview } from "./components"; + + + +# Color + +Color is a crucial element in any design system. It communicates +information, creates hierarchy, and evokes emotions. Therefore, it is +essential to establish a consistent and meaningful color palette for +your design system. + +## Semantic Color Naming Strategy + +This naming schema is for the most part inspired by the one shown in The +hardest part about building dark mode is that people think it’s easy +talk by [Hassan and Jacob Miller at Figma Config 2022](https://www.youtube.com/watch?v=1DTnojio89Y&t=454s). +This enables flexibility and focuses on deriving these tokens from a +starting seed rather than assuming those can be hand-picked by a +designer. + + + + + type + role (optional) + prominence (optional) + state (optional) + + + + + bg + accent + regular (default) + resting (default) + + + fg + neutral + strong + hover + + + bd + content + subtle + active + + + + assistive + + disabled + + + + negative + + focus + + + + positive + + + + + + warning + + + + + + on* + + + + + + +## Background Tokens Table + +export const Background = () => { + const { theme } = useTheme(); + const { color } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + + +## Foreground Tokens Table + +export const Foreground = () => { + const { theme } = useTheme(); + const { color } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + + +### Border Tokens Table + +export const Border = () => { + const { theme } = useTheme(); + const { color } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + diff --git a/app/client/packages/storybook/stories/design-system/theming/Opacity.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/Opacity.stories.mdx new file mode 100644 index 0000000000..207d0c6421 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/Opacity.stories.mdx @@ -0,0 +1,34 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme, ThemeProvider } from "@design-system/theming"; +import { TokenTable, StyledSquarePreview } from "./components"; + + + +# Opacity + +Opacity is an important aspect of design system that determines the +transparency of an element. It is measured in percentage, where 0% is +completely transparent and 100% is completely opaque. In design system, +opacity is used to create visual hierarchy, depth, and contrast. By +adjusting the opacity of an element, designers can create subtle or +dramatic effects that enhance the user experience. + +export const Opacity = () => { + const { theme } = useTheme(); + const { opacity } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + diff --git a/app/client/packages/storybook/stories/design-system/theming/RootUnit.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/RootUnit.stories.mdx new file mode 100644 index 0000000000..187246e765 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/RootUnit.stories.mdx @@ -0,0 +1,40 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme } from "@design-system/theming"; + + + +# Root Unit + +## What is it? + +We use a fluid root unit to create baseline grid for our design to +ensure visual consistency and rhythm. The baseline grid is one of the +most essential layout structures in product design. It makes interfaces +more consistent, balanced, and easier to scan by users, as it +establishes a repetitive pattern in visual recognition for your users. + +## How to use it? + +To establish a grid system, ensure all sizes, spacing (margins, padding) +and typography in your designs are multiples of root Unit. As simple as +that. + +## Why fluid? + +We use fluid root unit since the smaller the size of the user viewport, +the higher the interface density should be, so we change the value of +the root unit depending on viewport. + +**Important** +We do not use root unit value directly for creating components, but only +derived values are based on it such as spacing, sizing and typography. + +## Value + +export const RootUnit = () => { + const { theme } = useTheme(); + const { rootUnit } = theme; + return

{rootUnit}

; +}; + + diff --git a/app/client/packages/storybook/stories/design-system/theming/Sizing.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/Sizing.stories.mdx new file mode 100644 index 0000000000..4a4256aa76 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/Sizing.stories.mdx @@ -0,0 +1,39 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme, ThemeProvider } from "@design-system/theming"; +import { TokenTable, StyledLinePreview } from "./components"; + + + +# Sizing + +Sizing is a fundamental aspect of design systems that determines the +measurements of various elements in a user interface. It refers to the +process of defining consistent measurements for different components +such as buttons, icons, typography, and spacing to ensure that they are +visually balanced and harmonious. + +We use root unit to calculate values of all sizes since this is a +fundamental element and used to define the size of all the other +elements in the system. + +## Tokens Table + +export const Sizing = () => { + const { theme } = useTheme(); + const { sizing } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + diff --git a/app/client/packages/storybook/stories/design-system/theming/Spacing.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/Spacing.stories.mdx new file mode 100644 index 0000000000..57dc0f06c1 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/Spacing.stories.mdx @@ -0,0 +1,51 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme, ThemeProvider } from "@design-system/theming"; +import { TokenTable, StyledLinePreview } from "./components"; + + + +# Spacing + +Spacing is a crucial aspect of design that can make or break the user +experience. It helps to create a visual hierarchy, improve readability, +and make elements of a design easier to understand. A well-thought-out +spacing system can add clarity and consistency to a design. + +## Types of Spacing + +There are two types of spacing in design systems: inner spacing and +outer spacing. + +### Inner Spacing + +Inner spacing, also known as **padding**, is the space between an +element's content and its border. It creates room for the content to +breathe and makes the element more visually appealing. + +### Outer Spacing + +Outer spacing, also known as **margin** and **gap**, is the space +between elements. It creates a visual separation between elements and +contributes to the overall balance of a design. + +## Tokens Table + +export const Spacing = () => { + const { theme } = useTheme(); + const { spacing } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + diff --git a/app/client/packages/storybook/stories/design-system/theming/Theme.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/Theme.stories.mdx new file mode 100644 index 0000000000..abda91ce67 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/Theme.stories.mdx @@ -0,0 +1,101 @@ +import { Meta, ArgsTable } from "@storybook/addon-docs"; +import { ThemeProvider } from "@design-system/theming"; + + + +# Theme + +The theme package substitutes hooks and components for working with theming. + +## ThemeProvider + +This page describes how to use ThemeProvider. How to access tokens, what input parameters are needed and how to change the color mode. + +The ThemeProvider is React component in that allows for the easy +implementation of themes within an app. With ThemeProvider, you can define a +set of design tokens that will be applied to specific components in your +application, allowing for consistent styling across your entire application. + +export const Template = () => ; + + + +## useFluidTokens + +A hook that creates typography, rootUnit, spacing, sizing fluid tokens based +on the passed parameters. To create tokens, we use a calculation values +based on a musical scale. This allows us to create a harmonious set of +tokens. Tokens also depend on user's viewport. + +**Related materials** + +- [Fluid Design with Tokens](https://www.youtube.com/watch?v=EbykWCBeqBg) +- [Fluid Typescale Tool.](https://fluid-tokenization.vercel.app/) +- [Spencer Mortensen. The typographic scale.](https://spencermortensen.com/articles/typographic-scale/) + +## useTheme + +A hook that helps dynamically update tokens depending on incoming parameters. + +```javascript +import { ThemeProvider, useTheme } from "@design-system/theming"; + +const { theme } = useTheme({ + seedColor, + colorMode, + borderRadius, + fontFamily, + rootUnitRatio, +}); + +return ...; +``` + +## tokensAccessor + +Creates an object containing tokens based on the passed parameters (see the `defaultToken` structure) for subsequent conversion to CSS variables. + +## defaultTokens + +Basic token configuration file. + +## Usage + +```javascript +import React from "react"; +import { useEffect, useState } from "react"; +import { + ThemeProvider, + TokensAccessor, + defaultTokens, + useFluidTokens, +} from "@design-system/theming"; + +export const theming = (Story, args) => { + const { fluid, ...restDefaultTokens } = defaultTokens; + const { typography, rootUnit, spacing, sizing } = useFluidTokens(fluid); + const tokensAccessor = new TokensAccessor({ + ...restDefaultTokens, + rootUnit, + spacing, + sizing, + typography, + }); + const [theme, setTheme] = useState(tokensAccessor.getAllTokens()); + + useEffect(() => { + if (args.globals.colorMode) { + tokensAccessor.updateColorMode(args.globals.colorMode); + + setTheme((prevState) => { + return { + ...prevState, + ...tokensAccessor.getColors(), + }; + }); + } + }, [args.globals.colorMode]); + + return {children}; +}; +``` diff --git a/app/client/packages/storybook/stories/design-system/theming/Typography.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/Typography.stories.mdx new file mode 100644 index 0000000000..ba8f10bd9b --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/Typography.stories.mdx @@ -0,0 +1,13 @@ +import { Meta } from "@storybook/addon-docs"; + + + +# Typography + +To work with typography, we offer a [Text component](/?path=/docs/design-system-widgets-text--text). +This component provides a variant prop for semantic options. +You can use the `type` prop to control the component's color in accordance with the theme. + +To control the font size and line height, we use the `capHeight`and `lineGap` parameter supplied by the [capsize](https://seek-oss.github.io/capsize/) library. + +For font sizes, we also use a approach based on the root unit and viewport calculation. diff --git a/app/client/packages/storybook/stories/design-system/theming/ZIndex.stories.mdx b/app/client/packages/storybook/stories/design-system/theming/ZIndex.stories.mdx new file mode 100644 index 0000000000..6ad130dbbb --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/ZIndex.stories.mdx @@ -0,0 +1,35 @@ +import { Meta } from "@storybook/addon-docs"; +import { useTheme, ThemeProvider } from "@design-system/theming"; +import { TokenTable, StyledSquarePreview } from "./components"; + + + +# ZIndex + +Z-index design token is a numerical value used to determine the layering +of elements in a UI. By assigning different z-index values to elements, +developers can control which elements appear on top of others. This can +be useful in creating visual hierarchies, such as ensuring that +navigation menus appear above other content on a page. + +## Tokens Table + +export const ZIndex = () => { + const { theme } = useTheme(); + const { zIndex } = theme; + return ( + + + {(cssVar) => ( + + )} + + + ); +}; + + diff --git a/app/client/packages/design-system/theming/src/token/CopyLink.tsx b/app/client/packages/storybook/stories/design-system/theming/components/CopyLink.tsx similarity index 92% rename from app/client/packages/design-system/theming/src/token/CopyLink.tsx rename to app/client/packages/storybook/stories/design-system/theming/components/CopyLink.tsx index a6a8ebf356..5fe84f19f5 100644 --- a/app/client/packages/design-system/theming/src/token/CopyLink.tsx +++ b/app/client/packages/storybook/stories/design-system/theming/components/CopyLink.tsx @@ -1,4 +1,5 @@ -import React, { useState } from "react"; +import * as React from "react"; +import { useState } from "react"; import styled from "styled-components"; export const StyledCopyLink = styled.a` diff --git a/app/client/packages/design-system/theming/src/token/TokenTable.tsx b/app/client/packages/storybook/stories/design-system/theming/components/TokenTable.tsx similarity index 94% rename from app/client/packages/design-system/theming/src/token/TokenTable.tsx rename to app/client/packages/storybook/stories/design-system/theming/components/TokenTable.tsx index 54e46090b4..a426d11654 100644 --- a/app/client/packages/design-system/theming/src/token/TokenTable.tsx +++ b/app/client/packages/storybook/stories/design-system/theming/components/TokenTable.tsx @@ -1,8 +1,8 @@ -import React from "react"; +import * as React from "react"; import styled from "styled-components"; import { CopyLink } from "./CopyLink"; -import type { Token } from "./types"; +import type { Token } from "@design-system/theming"; import type { ReactNode } from "react"; export const StyledLinePreview = styled.div` diff --git a/app/client/packages/storybook/stories/design-system/theming/components/index.ts b/app/client/packages/storybook/stories/design-system/theming/components/index.ts new file mode 100644 index 0000000000..aedc68c278 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/theming/components/index.ts @@ -0,0 +1 @@ +export * from "./TokenTable"; diff --git a/app/client/packages/design-system/widgets-old/src/Button/Button.stories.tsx b/app/client/packages/storybook/stories/design-system/widgets-old/Button.stories.tsx similarity index 58% rename from app/client/packages/design-system/widgets-old/src/Button/Button.stories.tsx rename to app/client/packages/storybook/stories/design-system/widgets-old/Button.stories.tsx index 69c1b8329a..1ed6e7cd64 100644 --- a/app/client/packages/design-system/widgets-old/src/Button/Button.stories.tsx +++ b/app/client/packages/storybook/stories/design-system/widgets-old/Button.stories.tsx @@ -1,11 +1,10 @@ -import React from "react"; +import * as React from "react"; import type { ComponentMeta, ComponentStory } from "@storybook/react"; - -import ButtonComponent, { Size } from "./index"; +import { Button, Category, Size } from "@design-system/widgets-old"; export default { - title: "Design System/widgets-old/Button", - component: ButtonComponent, + title: "Design System/Widgets-old/Button", + component: Button, args: { fill: true, onClick: () => { @@ -16,24 +15,24 @@ export default { tag: "button", text: "Button", }, -} as ComponentMeta; +} as ComponentMeta; // eslint-disable-next-line react/function-component-definition -const Template: ComponentStory = (args: any) => { - return ; +const Template: ComponentStory = (args) => { + return + + +
+ + + + + +## Semantic + +`Button` component has 3 visual style variants and 5 semantic color options + +### Filled variant + + + + {["accent", "neutral", "positive", "negative", "warning"].map((color) => ( + + + + + + + + + + + + + + + + + + + + + +## Disabled + + + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + + + + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + + + + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + {/* prettier-ignore */} + + + diff --git a/app/client/packages/storybook/stories/design-system/widgets/Checkbox.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/Checkbox.stories.mdx new file mode 100644 index 0000000000..9263282831 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/widgets/Checkbox.stories.mdx @@ -0,0 +1,131 @@ +import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; +import EmotionHappyLineIcon from "remixicon-react/EmotionHappyLineIcon"; +import { Checkbox } from "@design-system/widgets"; + + + +export const Template = (args) => ; + +# Checkbox + +Checkbox is a component that allows the user to select one or more options from a set. + + + {Template.bind({})} + + + + +## States + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + + {Template.bind({})} + + +## Label Position + + + {Template.bind({})} + + + {Template.bind({})} + + +## Custom Icon + +, + }} +> + {Template.bind({})} + diff --git a/app/client/packages/storybook/stories/design-system/widgets/CheckboxGroup.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/CheckboxGroup.stories.mdx new file mode 100644 index 0000000000..c501663f32 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/widgets/CheckboxGroup.stories.mdx @@ -0,0 +1,106 @@ +import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; +import { CheckboxGroup, Checkbox } from "@design-system/widgets"; + + + Value 1 + Value 2 + + ), + }} +/> + +export const Template = (args) => ; + +# Checkbox Group + +Checkbox Group is a group of checkboxes that can be selected together. + + + {Template.bind({})} + + + + +## Orientation + + + {Template.bind({})} + + + {Template.bind({})} + + +## Emphasized + + + {Template.bind({})} + + +## Label Position and Alignment + + + {Template.bind({})} + + +## Disabled + + + {Template.bind({})} + + +## Required + + + {Template.bind({})} + + +## Invalid State + + + {Template.bind({})} + diff --git a/app/client/packages/design-system/widgets/src/components/Flex/Flex.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/Flex.stories.mdx similarity index 52% rename from app/client/packages/design-system/widgets/src/components/Flex/Flex.stories.mdx rename to app/client/packages/storybook/stories/design-system/widgets/Flex.stories.mdx index 4eb500f0b7..c03f05c778 100644 --- a/app/client/packages/design-system/widgets/src/components/Flex/Flex.stories.mdx +++ b/app/client/packages/storybook/stories/design-system/widgets/Flex.stories.mdx @@ -1,13 +1,10 @@ import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; import { useState } from "react"; -import { Flex } from "./Flex"; -import { Text } from "../Text"; -import { RadioGroup } from "../RadioGroup"; -import { Radio } from "../Radio"; +import { Flex, Text, RadioGroup, Radio } from "@design-system/widgets"; import styled from "styled-components"; ( ## Vertical stack with gap - - - - - - - - - + + + + + + + ## Horizontal stack with gap - - - - - - - - - + + + + + + + ## Nesting - - - - - - - - - - + + + + + + + - - + + + ## Responsive @@ -120,76 +111,53 @@ To make everything work, we just need to add `isContainer` prop to the parent FL ## Responsive cards -export const WidthControl = ({ children }) => { - let [width, setWidth] = useState("100%"); - const widthOptions = ["300px", "480px", "680px", "926px", "100%"]; - return ( - - - {widthOptions.map((width) => ( - {width} - ))} - -
{children}
-
- ); -}; - - - - - - {[...Array(12)].map(() => ( - - - - ))} + + + {[...Array(12)].map(() => ( + + - - - + ))} + + ## Responsive list - - - + + + {[...Array(4)].map(() => ( - {[...Array(4)].map(() => ( - - - - - - Title - - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Autem - consequuntur explicabo quia veniam? Aliquid amet cum delectus - deleniti eligendi eum facilis, fugit in iusto nemo, porro quod - reiciendis sint velit? - - - - ))} + + + + + Title + + Lorem ipsum dolor sit amet, consectetur adipisicing elit. Autem + consequuntur explicabo quia veniam? Aliquid amet cum delectus + deleniti eligendi eum facilis, fugit in iusto nemo, porro quod + reiciendis sint velit? + + - - - + ))} + + diff --git a/app/client/packages/storybook/stories/design-system/widgets/RadioGroup.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/RadioGroup.stories.mdx new file mode 100644 index 0000000000..b0fcb854e0 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/widgets/RadioGroup.stories.mdx @@ -0,0 +1,106 @@ +import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; +import { RadioGroup, Radio } from "@design-system/widgets"; + + + Value 1 + Value 2 + + ), + }} +/> + +export const Template = (args) => ; + +# Radio Group + +Radio group is a component that allows users to select one option from a set of options. + + + {Template.bind({})} + + + + +# Orientation + + + {Template.bind({})} + + + {Template.bind({})} + + +# Emphasized + + + {Template.bind({})} + + +# Label Position and Alignment + + + {Template.bind({})} + + +# Is Disabled + + + {Template.bind({})} + + +# Is Required + + + {Template.bind({})} + + +# Invalid State + + + {Template.bind({})} + diff --git a/app/client/packages/storybook/stories/design-system/widgets/Text.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/Text.stories.mdx new file mode 100644 index 0000000000..7f4f75f9e6 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/widgets/Text.stories.mdx @@ -0,0 +1,72 @@ +import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; +import { Text, Flex } from "@design-system/widgets"; +import { TypographyVariant, TypographyColor } from "@design-system/theming"; + + + +export const Template = (args) => ; + +# Text + +Text is a component that renders a capsized text. + + + {Template.bind({})} + + + + +## Line clamp + + + {Template.bind({})} + + +## Variant + + + + {Object.keys(TypographyVariant).map((variant) => ( + aA + ))} + + + +## Color + + + + {Object.keys(TypographyColor).map((color) => ( + + aA + + ))} + + diff --git a/app/client/packages/storybook/stories/design-system/widgets/Tooltip.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/Tooltip.stories.mdx new file mode 100644 index 0000000000..e96da7d824 --- /dev/null +++ b/app/client/packages/storybook/stories/design-system/widgets/Tooltip.stories.mdx @@ -0,0 +1,93 @@ +import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs"; +import { + Button, + ButtonGroup, + TooltipRoot, + TooltipTrigger, + TooltipContent, + Tooltip, +} from "@design-system/widgets"; + + + +export const Template = (args) => { + return ( + + + + + My tooltip + + ); +}; + +# Tooltip + +A tooltip is a small pop-up that appears when a user places their cursor over an element such as a link or button. Tooltips can be used to provide users with additional information about an element without having to clutter up the UI with additional text. + + + {Template.bind({})} + + + + +# Placement + +The placement of the tooltip can be changed by passing the `placement` prop. + + + + + + + + My tooltip + + + + + + My tooltip + + + + + + My tooltip + + + + + + My tooltip + + + + +# Disabled + +If the trigger is disabled, the tooltip will still be displayed. + + + + + + + My tooltip + + + +# Tooltip Component + + + + + + diff --git a/app/client/packages/design-system/widgets/src/testComponents/ColorGrid.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.stories.mdx similarity index 89% rename from app/client/packages/design-system/widgets/src/testComponents/ColorGrid.stories.mdx rename to app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.stories.mdx index 46f579f12d..4d17305289 100644 --- a/app/client/packages/design-system/widgets/src/testComponents/ColorGrid.stories.mdx +++ b/app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.stories.mdx @@ -1,7 +1,7 @@ -import { Canvas, Meta, Story } from "@storybook/addon-docs"; +import { Meta, Canvas, Story } from "@storybook/addon-docs"; import { ColorGrid } from "./ColorGrid"; - + export const Template = (args, { globals: { colorMode } }) => ( @@ -21,7 +21,7 @@ export const Template = (args, { globals: { colorMode } }) => ( args={{ source: "oklch", size: "small", - steps: 11, + steps: 8, colorSpace: "oklch", variant: "primary", isHovered: false, diff --git a/app/client/packages/design-system/widgets/src/testComponents/ColorGrid.styled.tsx b/app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.styled.tsx similarity index 100% rename from app/client/packages/design-system/widgets/src/testComponents/ColorGrid.styled.tsx rename to app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.styled.tsx diff --git a/app/client/packages/design-system/widgets/src/testComponents/ColorGrid.tsx b/app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.tsx similarity index 98% rename from app/client/packages/design-system/widgets/src/testComponents/ColorGrid.tsx rename to app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.tsx index 92b6ad1f35..0c2d42c54d 100644 --- a/app/client/packages/design-system/widgets/src/testComponents/ColorGrid.tsx +++ b/app/client/packages/storybook/stories/design-system/widgets/testing/ColorGrid.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import * as React from "react"; import { ThemeProvider, TokensAccessor, @@ -6,7 +6,7 @@ import { DarkModeTheme, } from "@design-system/theming"; import Color from "colorjs.io"; -import { Text } from "../"; +import { Text } from "@design-system/widgets"; import { StyledColorGridButton } from "./ColorGrid.styled"; import { COLORS as appsmithColors } from "./colors"; @@ -119,7 +119,7 @@ export const ColorGrid = (props: any) => { const tokensAccessor = new TokensAccessor({ seedColor, - colorMode: colorMode, + colorMode, }); const tokens = diff --git a/app/client/packages/design-system/widgets/src/testComponents/CompareTokens.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/testing/CompareTokens.stories.mdx similarity index 78% rename from app/client/packages/design-system/widgets/src/testComponents/CompareTokens.stories.mdx rename to app/client/packages/storybook/stories/design-system/widgets/testing/CompareTokens.stories.mdx index f56a864297..52b3a65a9b 100644 --- a/app/client/packages/design-system/widgets/src/testComponents/CompareTokens.stories.mdx +++ b/app/client/packages/storybook/stories/design-system/widgets/testing/CompareTokens.stories.mdx @@ -1,7 +1,7 @@ import { Canvas, Meta, Story } from "@storybook/addon-docs"; import { CompareTokens } from "./CompareTokens"; - + export const Template = () => ; diff --git a/app/client/packages/design-system/widgets/src/testComponents/CompareTokens.tsx b/app/client/packages/storybook/stories/design-system/widgets/testing/CompareTokens.tsx similarity index 98% rename from app/client/packages/design-system/widgets/src/testComponents/CompareTokens.tsx rename to app/client/packages/storybook/stories/design-system/widgets/testing/CompareTokens.tsx index da56253bfe..2b76c196d3 100644 --- a/app/client/packages/design-system/widgets/src/testComponents/CompareTokens.tsx +++ b/app/client/packages/storybook/stories/design-system/widgets/testing/CompareTokens.tsx @@ -1,4 +1,5 @@ -import React, { useState } from "react"; +import * as React from "react"; +import { useState } from "react"; import { useThemeContext } from "@design-system/theming"; export const CompareTokens = () => { diff --git a/app/client/packages/design-system/widgets/src/testComponents/ComplexForm.stories.mdx b/app/client/packages/storybook/stories/design-system/widgets/testing/ComplexForm.stories.mdx similarity index 79% rename from app/client/packages/design-system/widgets/src/testComponents/ComplexForm.stories.mdx rename to app/client/packages/storybook/stories/design-system/widgets/testing/ComplexForm.stories.mdx index 5fb87ce2a1..d255b07c78 100644 --- a/app/client/packages/design-system/widgets/src/testComponents/ComplexForm.stories.mdx +++ b/app/client/packages/storybook/stories/design-system/widgets/testing/ComplexForm.stories.mdx @@ -1,7 +1,7 @@ import { Canvas, Meta, Story } from "@storybook/addon-docs"; import { ComplexForm } from "./ComplexForm"; - + export const Template = (args) => ; diff --git a/app/client/packages/design-system/widgets/src/testComponents/ComplexForm.tsx b/app/client/packages/storybook/stories/design-system/widgets/testing/ComplexForm.tsx similarity index 89% rename from app/client/packages/design-system/widgets/src/testComponents/ComplexForm.tsx rename to app/client/packages/storybook/stories/design-system/widgets/testing/ComplexForm.tsx index 6361a5c544..28ffcbe748 100644 --- a/app/client/packages/design-system/widgets/src/testComponents/ComplexForm.tsx +++ b/app/client/packages/storybook/stories/design-system/widgets/testing/ComplexForm.tsx @@ -1,13 +1,13 @@ -import React from "react"; +import * as React from "react"; import { Button, Text, CheckboxGroup, Checkbox, - Tooltip, + TooltipRoot, TooltipTrigger, TooltipContent, -} from "../"; +} from "@design-system/widgets"; export const ComplexForm = () => { return ( @@ -34,14 +34,14 @@ export const ComplexForm = () => { gap: "var(--spacing-2)", }} > - + If you cancel, you will lose your order - + diff --git a/app/client/packages/design-system/widgets/src/testComponents/colors.ts b/app/client/packages/storybook/stories/design-system/widgets/testing/colors.ts similarity index 100% rename from app/client/packages/design-system/widgets/src/testComponents/colors.ts rename to app/client/packages/storybook/stories/design-system/widgets/testing/colors.ts diff --git a/app/client/packages/storybook/tsconfig.json b/app/client/packages/storybook/tsconfig.json index 752e48c03e..4082f16a5d 100644 --- a/app/client/packages/storybook/tsconfig.json +++ b/app/client/packages/storybook/tsconfig.json @@ -1,4 +1,3 @@ { - "extends": "../../tsconfig.json", - "include": ["./src/**/*"] + "extends": "../../tsconfig.json" } diff --git a/app/client/src/actions/controlActions.tsx b/app/client/src/actions/controlActions.tsx index d3bc46f1ab..77f8295114 100644 --- a/app/client/src/actions/controlActions.tsx +++ b/app/client/src/actions/controlActions.tsx @@ -40,6 +40,17 @@ export const batchUpdateWidgetProperty = ( shouldReplay, }, }); + +export const batchUpdateWidgetDynamicProperty = ( + widgetId: string, + updates: BatchUpdateDynamicPropertyUpdates[], +): ReduxAction => ({ + type: ReduxActionTypes.BATCH_SET_WIDGET_DYNAMIC_PROPERTY, + payload: { + widgetId, + updates, + }, +}); export const batchUpdateMultipleWidgetProperties = ( updatesArray: UpdateWidgetPropertyPayload[], ): ReduxAction<{ updatesArray: UpdateWidgetPropertyPayload[] }> => ({ @@ -129,6 +140,16 @@ export interface SetWidgetDynamicPropertyPayload { skipValidation?: boolean; } +export type BatchUpdateDynamicPropertyUpdates = Omit< + SetWidgetDynamicPropertyPayload, + "widgetId" +>; + +export interface BatchUpdateWidgetDynamicPropertyPayload { + widgetId: string; + updates: BatchUpdateDynamicPropertyUpdates[]; +} + export interface DeleteWidgetPropertyPayload { widgetId: string; propertyPaths: string[]; diff --git a/app/client/src/api/ApiResponses.tsx b/app/client/src/api/ApiResponses.tsx index eee6c06f47..65a85ea29c 100644 --- a/app/client/src/api/ApiResponses.tsx +++ b/app/client/src/api/ApiResponses.tsx @@ -14,14 +14,3 @@ export type ApiResponse = { data: T; code?: string; }; - -// NO_DATASOURCES_FOUND, 1000, "Unable to find {0} with id {1}" -// INVALID_PARAMTER, 4000, "Invalid parameter {0} provided in the input" -// PLUGIN_NOT_INSTALLED, 4001, "Plugin {0} not installed" -// MISSING_PLUGIN_ID, 4002, "Missing plugin id. Please input correct plugin id" -// MISSING_DATASOURCES_ID, 4003, "Missing datasource id. Please input correct datasource id" -// MISSING_PAGE_ID, 4004, "Missing page id. Pleaes input correct page id" -// PAGE_DOES_NOT_EXIST_IN_WORKSPACE, 4006, "Page {0} does not belong to the current user {1} workspace." -// UNAUTHORIZED_DOMAIN, 4001, "Invalid email domain provided. Please sign in with a valid work email ID" -// INTERNAL_SERVER_ERROR, 5000, "Internal server error while processing request" -// REPOSITORY_SAVE_FAILED, 5001, "Repository save failed." diff --git a/app/client/src/ce/api/ApiUtils.ts b/app/client/src/ce/api/ApiUtils.ts index e0cb46fecb..ffd0dc16c5 100644 --- a/app/client/src/ce/api/ApiUtils.ts +++ b/app/client/src/ce/api/ApiUtils.ts @@ -26,7 +26,7 @@ import { getAppsmithConfigs } from "@appsmith/configs"; import * as Sentry from "@sentry/react"; import { CONTENT_TYPE_HEADER_KEY } from "constants/ApiEditorConstants/CommonApiConstants"; import { isAirgapped } from "@appsmith/utils/airgapHelpers"; -import { getEnvironmentIdForHeader } from "@appsmith/api/ApiUtils"; +import { getCurrentEnvironment } from "@appsmith/utils/Environments"; const executeActionRegex = /actions\/execute/; const timeoutErrorRegex = /timeout of (\d+)ms exceeded/; @@ -93,7 +93,7 @@ export const apiRequestInterceptor = (config: AxiosRequestConfig) => { } // Add header for environment name - const activeEnv = getEnvironmentIdForHeader(); + const activeEnv = getCurrentEnvironment(); if (activeEnv && config.headers) { config.headers.environmentId = activeEnv; diff --git a/app/client/src/ce/constants/ReduxActionConstants.tsx b/app/client/src/ce/constants/ReduxActionConstants.tsx index 8a2cb1ea9e..920f9420ff 100644 --- a/app/client/src/ce/constants/ReduxActionConstants.tsx +++ b/app/client/src/ce/constants/ReduxActionConstants.tsx @@ -432,6 +432,7 @@ const ActionTypes = { SUBMIT_CURL_FORM_INIT: "SUBMIT_CURL_FORM_INIT", SUBMIT_CURL_FORM_SUCCESS: "SUBMIT_CURL_FORM_SUCCESS", SET_WIDGET_DYNAMIC_PROPERTY: "SET_WIDGET_DYNAMIC_PROPERTY", + BATCH_SET_WIDGET_DYNAMIC_PROPERTY: "BATCH_SET_WIDGET_DYNAMIC_PROPERTY", FETCH_PROVIDER_TEMPLATES_INIT: "FETCH_PROVIDER_TEMPLATES_INIT", FETCH_PROVIDER_TEMPLATES_SUCCESS: "FETCH_PROVIDER_TEMPLATES_SUCCESS", ADD_API_TO_PAGE_INIT: "ADD_API_TO_PAGE_INIT", diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index 99156677d5..fba2fee0c9 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -169,7 +169,6 @@ export const INVITE_USER_RAMP_TEXT = () => "Users will have access to all applications in the workspace. For application-level access, try out our "; export const CUSTOM_ROLES_RAMP_TEXT = () => "To build and assign custom roles, try out our "; -export const BUSINESS_TEXT = () => "Business"; export const CUSTOM_ROLE_TEXT = () => "Custom role"; export const CUSTOM_ROLE_DISABLED_OPTION_TEXT = () => "Can access specific applications or only certain pages and queries within an application"; @@ -1339,6 +1338,9 @@ export const PROPERTY_PANE_EMPTY_SEARCH_RESULT_MESSAGE = export const PROPERTY_SEARCH_INPUT_PLACEHOLDER = "Search for controls, labels etc"; export const EXPLORER_BETA_ENTITY = () => "BETA"; +export const BINDING_WIDGET_WALKTHROUGH_TITLE = () => "Widget properties"; +export const BINDING_WIDGET_WALKTHROUGH_DESC = () => + `We’ve set the table data property for you. You can change it at anytime. The properties pane is a central hub for configuring widgets, allowing you to easily modify settings.`; // API Pane export const API_PANE_NO_BODY = () => "This request does not have a body"; diff --git a/app/client/src/ce/entities/FeatureFlag.ts b/app/client/src/ce/entities/FeatureFlag.ts index f42f174173..02db16ed69 100644 --- a/app/client/src/ce/entities/FeatureFlag.ts +++ b/app/client/src/ce/entities/FeatureFlag.ts @@ -12,7 +12,7 @@ export const FEATURE_FLAG = { "release_embed_hide_share_settings_enabled", ab_ds_schema_enabled: "ab_ds_schema_enabled", ab_ds_binding_enabled: "ab_ds_binding_enabled", - release_scim_provisioning_enabled: "release_scim_provisioning_enabled", + ab_wds_enabled: "ab_wds_enabled", release_widgetdiscovery_enabled: "release_widgetdiscovery_enabled", } as const; @@ -30,7 +30,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = { release_embed_hide_share_settings_enabled: false, ab_ds_schema_enabled: false, ab_ds_binding_enabled: false, - release_scim_provisioning_enabled: false, + ab_wds_enabled: false, release_widgetdiscovery_enabled: false, }; diff --git a/app/client/src/ce/pages/AdminSettings/LeftPane.tsx b/app/client/src/ce/pages/AdminSettings/LeftPane.tsx index 679261226d..57916852eb 100644 --- a/app/client/src/ce/pages/AdminSettings/LeftPane.tsx +++ b/app/client/src/ce/pages/AdminSettings/LeftPane.tsx @@ -13,7 +13,6 @@ import { Icon, Tag, Text } from "design-system"; import { useDispatch, useSelector } from "react-redux"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import { getCurrentUser } from "selectors/usersSelectors"; -import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors"; import { BUSINESS_TAG, ENTERPRISE_TAG, @@ -161,7 +160,7 @@ export function Categories({ )} {config.title} {config?.needsUpgrade && ( - + {createMessage( config?.isEnterprise ? ENTERPRISE_TAG : BUSINESS_TAG, )} @@ -190,16 +189,9 @@ export default function LeftPane() { const { category, selected: subCategory } = useParams() as any; const user = useSelector(getCurrentUser); const isSuperUser = user?.isSuperUser; - const featureFlags = useSelector(selectFeatureFlags); const filteredAclCategories = aclCategories ?.map((category) => { - if ( - category.slug === "provisioning" && - !featureFlags.release_scim_provisioning_enabled - ) { - return null; - } return category; }) .filter(Boolean) as Category[]; diff --git a/app/client/src/ce/pages/AdminSettings/Main.tsx b/app/client/src/ce/pages/AdminSettings/Main.tsx index ff247d4cfa..6ef23f29bf 100644 --- a/app/client/src/ce/pages/AdminSettings/Main.tsx +++ b/app/client/src/ce/pages/AdminSettings/Main.tsx @@ -7,7 +7,6 @@ import { getDefaultAdminSettingsPath } from "@appsmith/utils/adminSettingsHelper import { useSelector } from "react-redux"; import { getCurrentUser } from "selectors/usersSelectors"; import { getTenantPermissions } from "@appsmith/selectors/tenantSelectors"; -import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors"; const Main = () => { const params = useParams() as any; @@ -17,18 +16,6 @@ const Main = () => { const isSuperUser = user?.isSuperUser || false; const wrapperCategory = AdminConfig.wrapperCategories[subCategory ?? category]; - const featureFlags = useSelector(selectFeatureFlags); - - if ( - category === "provisioning" && - !featureFlags.release_scim_provisioning_enabled - ) { - return ( - - ); - } if (!!wrapperCategory?.component) { const { component: WrapperCategoryComponent } = wrapperCategory; diff --git a/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx b/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx index 5b19547cc9..a6ba1cf8e4 100644 --- a/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx +++ b/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx @@ -24,9 +24,9 @@ import { BUSINESS_EDITION_TEXT, INVITE_USER_RAMP_TEXT, CUSTOM_ROLES_RAMP_TEXT, - BUSINESS_TEXT, CUSTOM_ROLE_DISABLED_OPTION_TEXT, CUSTOM_ROLE_TEXT, + BUSINESS_TAG, } from "@appsmith/constants/messages"; import { isEmail } from "utils/formhelpers"; import { @@ -309,7 +309,7 @@ export function CustomRolesRamp() { {createMessage(CUSTOM_ROLE_TEXT)} - {createMessage(BUSINESS_TEXT)} + {createMessage(BUSINESS_TAG)} diff --git a/app/client/src/ce/sagas/JSFunctionExecutionSaga.ts b/app/client/src/ce/sagas/JSFunctionExecutionSaga.ts index e1a3d1f139..0f2fb86747 100644 --- a/app/client/src/ce/sagas/JSFunctionExecutionSaga.ts +++ b/app/client/src/ce/sagas/JSFunctionExecutionSaga.ts @@ -1,3 +1,30 @@ -export function* logJSFunctionExecution(data: any) { - return data; +import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants"; +import type { TriggerSource } from "constants/AppsmithActionConstants/ActionConstants"; +import { call } from "redux-saga/effects"; +import type { TMessage } from "utils/MessageUtil"; +import { logJSActionExecution } from "./analyticsSaga"; + +export function* logJSFunctionExecution( + data: TMessage<{ + data: { + jsFnFullName: string; + isSuccess: boolean; + triggerMeta: { + source: TriggerSource; + triggerPropertyName: string | undefined; + triggerKind: TriggerKind | undefined; + }; + }[]; + }>, +) { + const { + body: { data: executionData }, + } = data; + + // We only care about EVENT_EXECUTION + const triggerExecutionData = executionData.filter( + (execData) => + execData.triggerMeta.triggerKind === TriggerKind.EVENT_EXECUTION, + ); + yield call(logJSActionExecution, triggerExecutionData); } diff --git a/app/client/src/ce/sagas/analyticsSaga.ts b/app/client/src/ce/sagas/analyticsSaga.ts new file mode 100644 index 0000000000..2b7fcb94fb --- /dev/null +++ b/app/client/src/ce/sagas/analyticsSaga.ts @@ -0,0 +1,228 @@ +import { getCurrentUser } from "selectors/usersSelectors"; +import { getInstanceId } from "@appsmith/selectors/tenantSelectors"; +import { getAppsmithConfigs } from "@appsmith/configs"; +import { call, select } from "redux-saga/effects"; +import type { APP_MODE } from "entities/App"; +import { + getCurrentApplication, + getCurrentPageId, +} from "selectors/editorSelectors"; +import type { TriggerMeta } from "@appsmith/sagas/ActionExecution/ActionExecutionSagas"; +import type { TriggerSource } from "constants/AppsmithActionConstants/ActionConstants"; +import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants"; +import { isArray } from "lodash"; +import AnalyticsUtil from "utils/AnalyticsUtil"; +import { getEntityNameAndPropertyPath } from "@appsmith/workers/Evaluation/evaluationUtils"; +import { getAppMode, getJSActionFromName } from "selectors/entitiesSelector"; +import type { AppState } from "@appsmith/reducers"; +import { getWidget } from "sagas/selectors"; + +export function getUserSource() { + const { cloudHosting } = getAppsmithConfigs(); + const source = cloudHosting ? "cloud" : "ce"; + return source; +} + +export interface UserAndAppDetails { + pageId: string; + appId: string; + appMode: APP_MODE | undefined; + appName: string; + isExampleApp: boolean; + userId: string; + email: string; + source: string; + instanceId: string; +} + +export function* getUserAndAppDetails() { + const appMode: ReturnType = yield select(getAppMode); + const currentApp: ReturnType = yield select( + getCurrentApplication, + ); + const user: ReturnType = yield select(getCurrentUser); + const instanceId: ReturnType = yield select( + getInstanceId, + ); + const pageId: ReturnType = yield select( + getCurrentPageId, + ); + const userAndAppDetails: UserAndAppDetails = { + pageId, + appId: currentApp?.id || "", + appMode, + appName: currentApp?.name || "", + isExampleApp: currentApp?.appIsExample || false, + userId: user?.username || "", + email: user?.email || "", + source: getUserSource(), + instanceId: instanceId, + }; + + return userAndAppDetails; +} +export function* logDynamicTriggerExecution({ + dynamicTrigger, + errors, + triggerMeta, +}: { + dynamicTrigger: string; + errors: unknown; + triggerMeta: TriggerMeta; +}) { + if (triggerMeta.triggerKind !== TriggerKind.EVENT_EXECUTION) return; + const isUnsuccessfulExecution = isArray(errors) && errors.length > 0; + const { + appId, + appMode, + appName, + email, + instanceId, + isExampleApp, + pageId, + source, + userId, + }: UserAndAppDetails = yield call(getUserAndAppDetails); + const widget: ReturnType | undefined = yield select( + (state: AppState) => getWidget(state, triggerMeta.source?.id || ""), + ); + + const dynamicPropertyPathList = widget?.dynamicPropertyPathList; + const isJSToggled = !!dynamicPropertyPathList?.find( + (property) => property.key === triggerMeta.triggerPropertyName, + ); + AnalyticsUtil.logEvent("EXECUTE_ACTION", { + type: "JS_EXPRESSION", + unevalValue: dynamicTrigger, + pageId, + appId, + appMode, + appName, + isExampleApp, + userData: { + userId, + email, + appId, + source, + }, + widgetName: widget?.widgetName, + widgetType: widget?.type, + propertyName: triggerMeta.triggerPropertyName, + instanceId, + isJSToggled, + }); + + AnalyticsUtil.logEvent( + isUnsuccessfulExecution + ? "EXECUTE_ACTION_FAILURE" + : "EXECUTE_ACTION_SUCCESS", + { + type: "JS_EXPRESSION", + unevalValue: dynamicTrigger, + pageId, + appId, + appMode, + appName, + isExampleApp, + userData: { + userId, + email, + appId, + source, + }, + widgetName: widget?.widgetName, + widgetType: widget?.type, + propertyName: triggerMeta.triggerPropertyName, + instanceId, + isJSToggled, + }, + ); +} + +export function* logJSActionExecution( + executionData: { + jsFnFullName: string; + isSuccess: boolean; + triggerMeta: { + source: TriggerSource; + triggerPropertyName: string | undefined; + triggerKind: TriggerKind | undefined; + }; + }[], +) { + const { + appId, + appMode, + appName, + email, + instanceId, + isExampleApp, + pageId, + source, + userId, + }: UserAndAppDetails = yield call(getUserAndAppDetails); + for (const { isSuccess, jsFnFullName, triggerMeta } of executionData) { + const { entityName: JSObjectName, propertyPath: functionName } = + getEntityNameAndPropertyPath(jsFnFullName); + const jsAction: ReturnType = yield select( + (state: AppState) => + getJSActionFromName(state, JSObjectName, functionName), + ); + const triggeredWidget: ReturnType | undefined = + yield select((state: AppState) => + getWidget(state, triggerMeta.source?.id || ""), + ); + const dynamicPropertyPathList = triggeredWidget?.dynamicPropertyPathList; + const isJSToggled = !!dynamicPropertyPathList?.find( + (property) => property.key === triggerMeta.triggerPropertyName, + ); + AnalyticsUtil.logEvent("EXECUTE_ACTION", { + type: "JS", + name: functionName, + JSObjectName, + pageId, + appId, + appMode, + appName, + isExampleApp, + actionId: jsAction?.id, + userData: { + userId, + email, + appId, + source, + }, + widgetName: triggeredWidget?.widgetName, + widgetType: triggeredWidget?.type, + propertyName: triggerMeta.triggerPropertyName, + isJSToggled, + instanceId, + }); + + AnalyticsUtil.logEvent( + isSuccess ? "EXECUTE_ACTION_SUCCESS" : "EXECUTE_ACTION_FAILURE", + { + type: "JS", + name: functionName, + JSObjectName, + pageId, + appId, + appMode, + appName, + isExampleApp, + actionId: jsAction?.id, + userData: { + userId, + email, + appId, + source, + }, + widgetName: triggeredWidget?.widgetName, + widgetType: triggeredWidget?.type, + propertyName: triggerMeta.triggerPropertyName, + isJSToggled, + instanceId, + }, + ); + } +} diff --git a/app/client/src/ce/selectors/featureFlagsSelectors.ts b/app/client/src/ce/selectors/featureFlagsSelectors.ts index e534163711..a9eaf123ab 100644 --- a/app/client/src/ce/selectors/featureFlagsSelectors.ts +++ b/app/client/src/ce/selectors/featureFlagsSelectors.ts @@ -1,6 +1,6 @@ +import { createSelector } from "reselect"; import type { AppState } from "@appsmith/reducers"; import type { FeatureFlag } from "@appsmith/entities/FeatureFlag"; -import { createSelector } from "reselect"; export const selectFeatureFlags = (state: AppState) => state.ui.users.featureFlag.data; diff --git a/app/client/src/ce/utils/licenseHelpers.ts b/app/client/src/ce/utils/licenseHelpers.ts index c48fe56460..15adb34bc1 100644 --- a/app/client/src/ce/utils/licenseHelpers.ts +++ b/app/client/src/ce/utils/licenseHelpers.ts @@ -1 +1,3 @@ export const getLicenseKey = () => ""; + +export const pricingPageUrlSource = "CE"; diff --git a/app/client/src/ce/workers/Evaluation/JSObject/postJSFunctionExecution.ts b/app/client/src/ce/workers/Evaluation/JSObject/postJSFunctionExecution.ts index e1b7b61105..62af8de5f9 100644 --- a/app/client/src/ce/workers/Evaluation/JSObject/postJSFunctionExecution.ts +++ b/app/client/src/ce/workers/Evaluation/JSObject/postJSFunctionExecution.ts @@ -1,4 +1,16 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export function postJSFunctionExecutionLog(fullName: string) { - // +import TriggerEmitter, { + BatchKey, +} from "workers/Evaluation/fns/utils/TriggerEmitter"; +import type { PostProcessorArg } from "workers/Evaluation/fns/utils/jsObjectFnFactory"; + +export function postJSFunctionExecutionLog({ + executionMetaData, + isSuccess, + jsFnFullName, +}: PostProcessorArg) { + TriggerEmitter.emit(BatchKey.process_batched_fn_invoke_log, { + jsFnFullName, + isSuccess, + triggerMeta: executionMetaData.triggerMeta, + }); } diff --git a/app/client/src/components/designSystems/appsmith/SignPostingBanner.tsx b/app/client/src/components/designSystems/appsmith/SignPostingBanner.tsx index ad85380950..3bb836c4ba 100644 --- a/app/client/src/components/designSystems/appsmith/SignPostingBanner.tsx +++ b/app/client/src/components/designSystems/appsmith/SignPostingBanner.tsx @@ -19,7 +19,7 @@ function SignPostingBanner(props: SignPostingBannerProps) {
))}
diff --git a/app/client/src/components/editorComponents/ActionCreator/types.ts b/app/client/src/components/editorComponents/ActionCreator/types.ts index 236cbc0576..6ba49fac98 100644 --- a/app/client/src/components/editorComponents/ActionCreator/types.ts +++ b/app/client/src/components/editorComponents/ActionCreator/types.ts @@ -74,6 +74,9 @@ export type ActionCreatorProps = { onValueChange: (newValue: string, isUpdatedViaKeyboard: boolean) => void; additionalAutoComplete?: AdditionalDynamicDataTree; additionalControlData: Record; + propertyName: string; + widgetType: string; + widgetName: string; }; export type Field = { diff --git a/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.test.tsx b/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.test.tsx index e5d55bdd4f..e875ad49ac 100644 --- a/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.test.tsx +++ b/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.test.tsx @@ -31,6 +31,9 @@ describe("tests for Action Tree in Action Selector", () => { onChange={() => { return; }} + propertyName="" + widgetName="" + widgetType="" />
, @@ -61,6 +64,9 @@ describe("tests for Action Tree in Action Selector", () => { onChange={() => { return; }} + propertyName="" + widgetName="" + widgetType="" /> , diff --git a/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.tsx b/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.tsx index f054a00498..f5eb2abb2f 100644 --- a/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.tsx +++ b/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/ActionTree.tsx @@ -49,6 +49,9 @@ export default function ActionTree(props: { level: number; isLastBlock?: boolean; variant?: VariantType; + widgetName: string; + propertyName: string; + widgetType: string; }) { const { id } = props; const [actionBlock, setActionBlock] = React.useState(props.actionBlock); @@ -255,6 +258,9 @@ export default function ActionTree(props: { ), code: deletedBlock.code, callback: blockType, + widgetName: props.widgetName, + propertyName: props.propertyName, + widgetType: props.widgetType, }); } else { const prevActionType = blocks[index].actionType; @@ -271,12 +277,18 @@ export default function ActionTree(props: { actionType: actionTypeLabel, code: newActionCode, callback: blockType, + widgetName: props.widgetName, + propertyName: props.propertyName, + widgetType: props.widgetType, }); } else { AnalyticsUtil.logEvent("ACTION_MODIFIED", { actionType: actionTypeLabel, code: newActionCode, callback: blockType, + widgetName: props.widgetName, + propertyName: props.propertyName, + widgetType: props.widgetType, }); } } @@ -286,7 +298,10 @@ export default function ActionTree(props: { props.onChange(newActionBlock); } }} + propertyName={props.propertyName} variant="callbackBlock" + widgetName={props.widgetName} + widgetType={props.widgetType} /> ))} diff --git a/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/index.tsx b/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/index.tsx index 2b07a46b52..93734f6c52 100644 --- a/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/index.tsx +++ b/app/client/src/components/editorComponents/ActionCreator/viewComponents/Action/index.tsx @@ -9,6 +9,9 @@ type TRootActionProps = { id: string; onChange: (code: string) => void; index: number; + propertyName: string; + widgetName: string; + widgetType: string; }; export default function Action(props: TRootActionProps) { @@ -41,6 +44,9 @@ export default function Action(props: TRootActionProps) { id={id} level={0} onChange={handleChange} + propertyName={props.propertyName} + widgetName={props.widgetName} + widgetType={props.widgetType} /> ); } diff --git a/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx b/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx index 809bd2d55e..1c7ba41894 100644 --- a/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx +++ b/app/client/src/components/editorComponents/ActionRightPane/SuggestedWidgets.tsx @@ -47,11 +47,14 @@ import textWidgetIconSvg from "../../../widgets/TextWidget/icon.svg"; import listWidgetIconSvg from "../../../widgets/ListWidget/icon.svg"; import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; import { - getFeatureFlagShownStatus, + getFeatureWalkthroughShown, isUserSignedUpFlagSet, - setFeatureFlagShownStatus, + setFeatureWalkthroughShown, } from "utils/storage"; import { getCurrentUser } from "selectors/usersSelectors"; +import localStorage from "utils/localStorage"; +import { WIDGET_ID_SHOW_WALKTHROUGH } from "constants/WidgetConstants"; +import { FEATURE_WALKTHROUGH_KEYS } from "constants/WalkthroughConstants"; const BINDING_GUIDE_GIF = `${ASSETS_CDN_URL}/binding.gif`; @@ -362,14 +365,15 @@ function SuggestedWidgets(props: SuggestedWidgetProps) { queryId?: string; }>(); - const closeWalkthrough = async () => { - if (isWalkthroughOpened) { - popFeature && popFeature(); - await setFeatureFlagShownStatus(FEATURE_FLAG.ab_ds_binding_enabled, true); - } + const closeWalkthrough = () => { + popFeature && popFeature("BINDING_WIDGET"); + setFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_binding_enabled, + true, + ); }; - const addWidget = ( + const addWidget = async ( suggestedWidget: SuggestedWidget, widgetInfo: WidgetBindingInfo, ) => { @@ -388,16 +392,25 @@ function SuggestedWidgets(props: SuggestedWidgetProps) { AnalyticsUtil.logEvent("SUGGESTED_WIDGET_CLICK", { widget: suggestedWidget.type, [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: - FEATURE_FLAG.ab_ds_binding_enabled, + FEATURE_WALKTHROUGH_KEYS.ab_ds_binding_enabled, [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: isEnabledForQueryBinding, isWalkthroughOpened, }); - closeWalkthrough(); + const showStatus = await getFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.binding_widget, + ); + // To enable setting the widget id for showing walkthrough once the widget is created in WidgetOperationSagas.tsx -> addSuggestedWidget function + if (!showStatus && isEnabledForQueryBinding) { + (payload.props as any).setWidgetIdForWalkthrough = "true"; + } + if (isWalkthroughOpened) { + closeWalkthrough(); + } dispatch(addSuggestedWidget(payload)); }; - const handleBindData = (widgetId: string) => { + const handleBindData = async (widgetId: string) => { dispatch( bindDataOnCanvas({ queryId: (params.apiId || params.queryId) as string, @@ -406,12 +419,24 @@ function SuggestedWidgets(props: SuggestedWidgetProps) { }), ); - closeWalkthrough(); + if (isEnabledForQueryBinding) { + const value = await getFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.binding_widget, + ); + if (!value) { + localStorage.setItem(WIDGET_ID_SHOW_WALKTHROUGH, widgetId); + } + } + dispatch( bindDataToWidget({ widgetId: widgetId, }), ); + + if (isWalkthroughOpened) { + closeWalkthrough(); + } }; const isTableWidgetPresentOnCanvas = () => { @@ -443,8 +468,8 @@ function SuggestedWidgets(props: SuggestedWidgetProps) { const isWidgetsPresentOnCanvas = Object.keys(canvasWidgets).length > 0; const checkAndShowWalkthrough = async () => { - const isFeatureWalkthroughShown = await getFeatureFlagShownStatus( - FEATURE_FLAG.ab_ds_binding_enabled, + const isFeatureWalkthroughShown = await getFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_binding_enabled, ); const isNewUser = user && (await isUserSignedUpFlagSet(user.email)); @@ -455,14 +480,8 @@ function SuggestedWidgets(props: SuggestedWidgetProps) { pushFeature({ targetId: BINDING_SECTION_ID, onDismiss: async () => { - AnalyticsUtil.logEvent("WALKTHROUGH_DISMISSED", { - [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: - FEATURE_FLAG.ab_ds_binding_enabled, - [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: - isEnabledForQueryBinding, - }); - await setFeatureFlagShownStatus( - FEATURE_FLAG.ab_ds_binding_enabled, + await setFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_binding_enabled, true, ); }, @@ -479,9 +498,10 @@ function SuggestedWidgets(props: SuggestedWidgetProps) { }, eventParams: { [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: - FEATURE_FLAG.ab_ds_binding_enabled, + FEATURE_WALKTHROUGH_KEYS.ab_ds_binding_enabled, [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: isEnabledForQueryBinding, }, + delay: 5000, }); }; diff --git a/app/client/src/components/editorComponents/ActionRightPane/index.tsx b/app/client/src/components/editorComponents/ActionRightPane/index.tsx index 316f89ab4c..acadfb4ea6 100644 --- a/app/client/src/components/editorComponents/ActionRightPane/index.tsx +++ b/app/client/src/components/editorComponents/ActionRightPane/index.tsx @@ -55,18 +55,18 @@ import { DatasourceComponentTypes } from "api/PluginApi"; import { fetchDatasourceStructure } from "actions/datasourceActions"; import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; import { - getFeatureFlagShownStatus, + getFeatureWalkthroughShown, isUserSignedUpFlagSet, - setFeatureFlagShownStatus, + setFeatureWalkthroughShown, } from "utils/storage"; +import { SCHEMA_SECTION_ID } from "entities/Action"; import { getCurrentUser } from "selectors/usersSelectors"; import { Tooltip } from "design-system"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; +import { FEATURE_WALKTHROUGH_KEYS } from "constants/WalkthroughConstants"; const SCHEMA_GUIDE_GIF = `${ASSETS_CDN_URL}/schema.gif`; -const SCHEMA_SECTION_ID = "t--api-right-pane-schema"; - const SideBar = styled.div` height: 100%; width: 100%; @@ -378,8 +378,8 @@ function ActionSidebar({ }, []); const checkAndShowWalkthrough = async () => { - const isFeatureWalkthroughShown = await getFeatureFlagShownStatus( - FEATURE_FLAG.ab_ds_schema_enabled, + const isFeatureWalkthroughShown = await getFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_schema_enabled, ); const isNewUser = user && (await isUserSignedUpFlagSet(user.email)); @@ -390,13 +390,8 @@ function ActionSidebar({ pushFeature({ targetId: SCHEMA_SECTION_ID, onDismiss: async () => { - AnalyticsUtil.logEvent("WALKTHROUGH_DISMISSED", { - [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: - FEATURE_FLAG.ab_ds_schema_enabled, - [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: isEnabledForDSSchema, - }); - await setFeatureFlagShownStatus( - FEATURE_FLAG.ab_ds_schema_enabled, + await setFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_schema_enabled, true, ); }, @@ -416,9 +411,10 @@ function ActionSidebar({ }, eventParams: { [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: - FEATURE_FLAG.ab_ds_schema_enabled, + FEATURE_WALKTHROUGH_KEYS.ab_ds_schema_enabled, [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: isEnabledForDSSchema, }, + delay: 5000, }); }; diff --git a/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx b/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx index d9d9be70dc..f116acacac 100644 --- a/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx @@ -43,11 +43,7 @@ function BindingPrompt(props: { ref={promptRef} visible={props.isOpen} > - {props.isAIEnabled ? ( - <> - Use /ai to generate JS expressions - - ) : props.promptMessage ? ( + {props.promptMessage ? ( props.promptMessage ) : ( <> diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index 016d0f4783..8d67870a34 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -160,6 +160,7 @@ import type { MultiplexingModeConfig } from "components/editorComponents/CodeEdi import { MULTIPLEXING_MODE_CONFIGS } from "components/editorComponents/CodeEditor/modes"; import { getDeleteLineShortcut } from "./utils/deleteLine"; import { CodeEditorSignPosting } from "@appsmith/components/editorComponents/CodeEditorSignPosting"; +import { getFocusablePropertyPaneField } from "selectors/propertyPaneSelectors"; type ReduxStateProps = ReturnType; type ReduxDispatchProps = ReturnType; @@ -541,10 +542,24 @@ class CodeEditor extends Component { //Refresh editor when the container height is increased. this.debounceEditorRefresh(); } + + const entityInformation = this.getEntityInformation(); + const isWidgetType = entityInformation.entityType === ENTITY_TYPE.WIDGET; + + const hasFocusedValueChanged = + getEditorIdentifier(this.props) !== this.props.focusedProperty; + + if (hasFocusedValueChanged && isWidgetType) { + if (this.state.showAIWindow) { + this.setState({ showAIWindow: false }); + } + } + if (identifierHasChanged) { if (this.state.showAIWindow) { this.setState({ showAIWindow: false }); } + if (shouldFocusOnPropertyControl()) { setTimeout(() => { if (this.props.editorIsFocused) { @@ -553,6 +568,7 @@ class CodeEditor extends Component { }, 200); } } + this.editor.operation(() => { if (prevProps.lintErrors !== this.props.lintErrors) { this.lintCode(this.editor); @@ -1664,6 +1680,7 @@ const mapStateToProps = (state: AppState, props: EditorProps) => ({ featureFlags: selectFeatureFlags(state), datasourceTableKeys: getAllDatasourceTableKeys(state, props.dataTreePath), installedLibraries: selectInstalledLibraries(state), + focusedProperty: getFocusablePropertyPaneField(state), }); const mapDispatchToProps = (dispatch: any) => ({ diff --git a/app/client/src/components/editorComponents/PropertyPaneSidebar.tsx b/app/client/src/components/editorComponents/PropertyPaneSidebar.tsx index e4d086810b..2f5bc16434 100644 --- a/app/client/src/components/editorComponents/PropertyPaneSidebar.tsx +++ b/app/client/src/components/editorComponents/PropertyPaneSidebar.tsx @@ -1,7 +1,7 @@ import classNames from "classnames"; import * as Sentry from "@sentry/react"; import { useSelector } from "react-redux"; -import React, { memo, useEffect, useMemo, useRef } from "react"; +import React, { memo, useContext, useEffect, useMemo, useRef } from "react"; import PerformanceTracker, { PerformanceTransactionName, @@ -21,6 +21,9 @@ import { getIsAppSettingsPaneOpen } from "selectors/appSettingsPaneSelectors"; import AppSettingsPane from "pages/Editor/AppSettingsPane"; import { APP_SETTINGS_PANE_WIDTH } from "constants/AppConstants"; import styled from "styled-components"; +import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; + +export const PROPERTY_PANE_ID = "t--property-pane-sidebar"; const StyledResizer = styled.div<{ resizing: boolean }>` ${(props) => @@ -54,6 +57,8 @@ export const PropertyPaneSidebar = memo((props: Props) => { const selectedWidgetIds = useSelector(getSelectedWidgets); const isDraggingOrResizing = useSelector(getIsDraggingOrResizing); const isAppSettingsPaneOpen = useSelector(getIsAppSettingsPaneOpen); + const { isOpened: isWalkthroughOpened, popFeature } = + useContext(WalkthroughContext) || {}; //while dragging or resizing and //the current selected WidgetId is not equal to previous widget id, @@ -109,6 +114,21 @@ export const PropertyPaneSidebar = memo((props: Props) => { keepThemeWhileDragging, ]); + const closeWalkthrough = () => { + if (popFeature) { + popFeature("PROPERTY_PANE"); + sidebarRef.current?.removeEventListener("click", closeWalkthrough); + } + }; + + useEffect(() => { + if (isWalkthroughOpened) + sidebarRef.current?.addEventListener("click", closeWalkthrough); + return () => { + sidebarRef.current?.removeEventListener("click", closeWalkthrough); + }; + }, [isWalkthroughOpened]); + return (
{/* PROPERTY PANE */} @@ -119,6 +139,7 @@ export const PropertyPaneSidebar = memo((props: Props) => { "relative ": !isPreviewMode, "fixed translate-x-full right-0": isPreviewMode, })} + id={PROPERTY_PANE_ID} ref={sidebarRef} > {/* RESIZER */} diff --git a/app/client/src/components/editorComponents/WidgetComponentBoundary.tsx b/app/client/src/components/editorComponents/WidgetComponentBoundary.tsx index 922e01e079..6c5ee8271b 100644 --- a/app/client/src/components/editorComponents/WidgetComponentBoundary.tsx +++ b/app/client/src/components/editorComponents/WidgetComponentBoundary.tsx @@ -1,8 +1,10 @@ -import { WIDGET_COMPONENT_BOUNDARY_CLASS } from "constants/componentClassNameConstants"; import type { ReactNode } from "react"; -import React from "react"; +import React, { useContext } from "react"; import styled from "styled-components"; +import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; +import { WIDGET_COMPONENT_BOUNDARY_CLASS } from "constants/componentClassNameConstants"; + type Props = { children: ReactNode; widgetType: string }; const WidgetComponentBoundaryWrapper = styled.div` @@ -11,8 +13,24 @@ const WidgetComponentBoundaryWrapper = styled.div` `; function WidgetComponentBoundary(props: Props) { + const { isOpened: isWalkthroughOpened, popFeature } = + useContext(WalkthroughContext) || {}; + + const closeWalkthrough = () => { + if (isWalkthroughOpened && popFeature) { + popFeature("WIDGET_CONTAINER"); + } + }; + + const onClickHandler = () => { + closeWalkthrough(); + }; + return ( - + {props.children} ); diff --git a/app/client/src/components/featureWalkthrough/index.tsx b/app/client/src/components/featureWalkthrough/index.tsx index eedbbd6195..71f26aef4b 100644 --- a/app/client/src/components/featureWalkthrough/index.tsx +++ b/app/client/src/components/featureWalkthrough/index.tsx @@ -1,10 +1,12 @@ import React, { lazy, useEffect, useState, Suspense } from "react"; import type { FeatureParams } from "./walkthroughContext"; +import { DEFAULT_DELAY } from "./walkthroughContext"; import WalkthroughContext from "./walkthroughContext"; import { createPortal } from "react-dom"; import { hideIndicator } from "pages/Editor/GuidedTour/utils"; import { retryPromise } from "utils/AppsmithUtils"; import { useLocation } from "react-router-dom"; +import AnalyticsUtil from "utils/AnalyticsUtil"; const WalkthroughRenderer = lazy(() => { return retryPromise( @@ -35,8 +37,16 @@ export default function Walkthrough({ children }: any) { updateActiveWalkthrough(); }; - const popFeature = () => { + const popFeature = (triggeredFrom?: string) => { hideIndicator(); + const eventParams = activeWalkthrough?.eventParams || {}; + if (triggeredFrom) { + eventParams.from = triggeredFrom; + } + AnalyticsUtil.logEvent("WALKTHROUGH_DISMISSED", eventParams); + if (activeWalkthrough && activeWalkthrough.onDismiss) { + activeWalkthrough.onDismiss(); + } setFeature((e) => { e.shift(); return [...e]; @@ -45,11 +55,12 @@ export default function Walkthrough({ children }: any) { const updateActiveWalkthrough = () => { if (feature.length > 0) { - const highlightArea = document.querySelector(`#${feature[0].targetId}`); + const highlightArea = document.getElementById(feature[0].targetId); + setActiveWalkthrough(null); if (highlightArea) { - setActiveWalkthrough(feature[0]); - } else { - setActiveWalkthrough(null); + setTimeout(() => { + setActiveWalkthrough(feature[0]); + }, feature[0].delay || DEFAULT_DELAY); } } else { setActiveWalkthrough(null); diff --git a/app/client/src/components/featureWalkthrough/walkthroughContext.tsx b/app/client/src/components/featureWalkthrough/walkthroughContext.tsx index 9d31d38eef..2035132006 100644 --- a/app/client/src/components/featureWalkthrough/walkthroughContext.tsx +++ b/app/client/src/components/featureWalkthrough/walkthroughContext.tsx @@ -2,6 +2,8 @@ import React from "react"; export type PositionType = "top" | "bottom" | "left" | "right"; +export const DEFAULT_DELAY = 0; + export type OffsetType = { // Position for the instructions and indicator position?: PositionType; @@ -38,11 +40,15 @@ export type FeatureParams = { offset?: OffsetType; // Event params eventParams?: Record; + // Walkthrough delay in ms + delay?: number; + // Multiple Highlights -> multiple ids for highlighter, if not present considers targetId as the only highlighting div. + multipleHighlights?: string[]; }; type WalkthroughContextType = { pushFeature: (feature: FeatureParams) => void; - popFeature: () => void; + popFeature: (triggeredFrom?: string) => void; feature: FeatureParams[]; isOpened: boolean; }; diff --git a/app/client/src/components/featureWalkthrough/walkthroughRenderer.tsx b/app/client/src/components/featureWalkthrough/walkthroughRenderer.tsx index 97f52dfec2..bc5360c049 100644 --- a/app/client/src/components/featureWalkthrough/walkthroughRenderer.tsx +++ b/app/client/src/components/featureWalkthrough/walkthroughRenderer.tsx @@ -82,7 +82,7 @@ type RefRectParams = { }; /* - * Clip Path Polygon : + * Clip Path Polygon for single target with bounding rect : * 1) 0 0 ----> (body start) (body start) * 2) 0 ${boundingRect.bh} ----> (body start) (body end) * 3) ${boundingRect.tx} ${boundingRect.bh} ----> (target start) (body end) @@ -108,6 +108,9 @@ type RefRectParams = { * ↓ ↑↓ ↑ * ↓ ↑↓ ↑ * 2 → → → → 3,8 → → → → → → → → → → → 9 + * + * Repeat steps 3 to 8 for each element if there are multiple highlighting elements. + * */ /** @@ -115,47 +118,66 @@ type RefRectParams = { * @param targetId Id for the target container to show highlighting around it */ +type BoundingRectTargets = Record; + const WalkthroughRenderer = ({ details, offset, - onDismiss, targetId, eventParams = {}, + multipleHighlights, }: FeatureParams) => { - const [boundingRect, setBoundingRect] = useState(null); + const [boundingRects, setBoundingRects] = + useState(null); const { popFeature } = useContext(WalkthroughContext) || {}; + + const multipleHighlightsIds = multipleHighlights?.length + ? multipleHighlights + : [targetId]; + if (multipleHighlightsIds.indexOf(targetId) === -1) + multipleHighlightsIds.push(targetId); const updateBoundingRect = () => { - const highlightArea = document.querySelector(`#${targetId}`); - if (highlightArea) { - const boundingRect = highlightArea.getBoundingClientRect(); - const bodyRect = document.body.getBoundingClientRect(); - const offsetHighlightPad = - typeof offset?.highlightPad === "number" - ? offset?.highlightPad - : PADDING_HIGHLIGHT; - setBoundingRect({ - bw: bodyRect.width, - bh: bodyRect.height, - tw: boundingRect.width + 2 * offsetHighlightPad, - th: boundingRect.height + 2 * offsetHighlightPad, - tx: boundingRect.x - offsetHighlightPad, - ty: boundingRect.y - offsetHighlightPad, - }); - showIndicator(`#${targetId}`, offset?.position, { - top: offset?.indicatorTop || 0, - left: offset?.indicatorLeft || 0, - zIndex: Z_INDEX + 1, + const mainTarget = document.getElementById(targetId); + if (mainTarget) { + const data: BoundingRectTargets = {}; + multipleHighlightsIds.forEach((id) => { + const highlightArea = document.getElementById(id); + if (highlightArea) { + const boundingRect = highlightArea.getBoundingClientRect(); + const bodyRect = document.body.getBoundingClientRect(); + const offsetHighlightPad = + typeof offset?.highlightPad === "number" + ? offset?.highlightPad + : PADDING_HIGHLIGHT; + data[id] = { + bw: bodyRect.width, + bh: bodyRect.height, + tw: boundingRect.width + 2 * offsetHighlightPad, + th: boundingRect.height + 2 * offsetHighlightPad, + tx: boundingRect.x - offsetHighlightPad, + ty: boundingRect.y - offsetHighlightPad, + }; + } }); + + if (Object.keys(data).length > 0) { + setBoundingRects(data); + showIndicator(`#${targetId}`, offset?.position, { + top: offset?.indicatorTop || 0, + left: offset?.indicatorLeft || 0, + zIndex: Z_INDEX + 1, + }); + } } }; useEffect(() => { updateBoundingRect(); - const highlightArea = document.querySelector(`#${targetId}`); - AnalyticsUtil.logEvent("WALKTHROUGH_SHOWN", eventParams); + const highlightArea = document.getElementById(targetId); window.addEventListener("resize", updateBoundingRect); const resizeObserver = new ResizeObserver(updateBoundingRect); if (highlightArea) { + AnalyticsUtil.logEvent("WALKTHROUGH_SHOWN", eventParams); resizeObserver.observe(highlightArea); } return () => { @@ -165,37 +187,42 @@ const WalkthroughRenderer = ({ }, [targetId]); const onDismissWalkthrough = () => { - onDismiss && onDismiss(); - popFeature && popFeature(); + popFeature && popFeature("WALKTHROUGH_CROSS_ICON"); }; - if (!boundingRect) return null; + if (!boundingRects || Object.keys(boundingRects).length === 0) return null; + const targetBounds = boundingRects[targetId]; + + if (!targetBounds) return null; return ( { + const boundingRect = boundingRects[id]; + acc = `${acc} ${boundingRect.tx} ${boundingRect.bh}, + ${boundingRect.tx} ${boundingRect.ty}, + ${boundingRect.tx + boundingRect.tw} ${boundingRect.ty}, + ${boundingRect.tx + boundingRect.tw} ${ + boundingRect.ty + boundingRect.th + }, + ${boundingRect.tx} ${boundingRect.ty + boundingRect.th}, + ${boundingRect.tx} ${boundingRect.bh},`; + return acc; + }, "")} + ${targetBounds.bw} ${targetBounds.bh}, + ${targetBounds.bw} 0 + `} /> @@ -203,9 +230,9 @@ const WalkthroughRenderer = ({ style={{ clipPath: 'url("#' + CLIPID + '")', fill: "currentcolor", - height: boundingRect.bh, + height: targetBounds.bh, pointerEvents: "auto", - width: boundingRect.bw, + width: targetBounds.bw, }} /> diff --git a/app/client/src/components/propertyControls/ActionSelectorControl.tsx b/app/client/src/components/propertyControls/ActionSelectorControl.tsx index 29e3a9d888..36dcf4d0fa 100644 --- a/app/client/src/components/propertyControls/ActionSelectorControl.tsx +++ b/app/client/src/components/propertyControls/ActionSelectorControl.tsx @@ -61,7 +61,7 @@ class ActionSelectorControl extends BaseControl { }; render() { - const { label, propertyValue } = this.props; + const { label, propertyName, propertyValue, widgetProperties } = this.props; return ( { this.props.additionalControlData as Record } onValueChange={this.handleValueUpdate} + propertyName={propertyName} ref={this.componentRef} value={propertyValue} + widgetName={widgetProperties.widgetName} + widgetType={widgetProperties.type} /> ); } diff --git a/app/client/src/components/propertyControls/ColumnActionSelectorControl.tsx b/app/client/src/components/propertyControls/ColumnActionSelectorControl.tsx index 10d19a6bc1..e909236f82 100644 --- a/app/client/src/components/propertyControls/ColumnActionSelectorControl.tsx +++ b/app/client/src/components/propertyControls/ColumnActionSelectorControl.tsx @@ -32,6 +32,7 @@ const Wrapper = styled.div` class ColumnActionSelectorControl extends BaseControl { render() { + const { propertyName, widgetProperties } = this.props; return ( <> {this.props.propertyValue && @@ -63,7 +64,10 @@ class ColumnActionSelectorControl extends BaseControl Array | undefined; + ) => Array | undefined; }; export type PropertyPaneControlConfig = { @@ -71,7 +65,7 @@ export type PropertyPaneControlConfig = { props: any, propertyName: string, propertyValue: any, - ) => Array | undefined; + ) => Array | undefined; hidden?: (props: any, propertyPath: string) => boolean; invisible?: boolean; isBindProperty: boolean; diff --git a/app/client/src/constants/ThirdPartyConstants.tsx b/app/client/src/constants/ThirdPartyConstants.tsx index 8eed58b655..2590ab3a90 100644 --- a/app/client/src/constants/ThirdPartyConstants.tsx +++ b/app/client/src/constants/ThirdPartyConstants.tsx @@ -23,6 +23,8 @@ export const SIGNUP_RESTRICTION_DOC = "https://docs.appsmith.com/getting-started/setup/instance-configuration/disable-user-signup#disable-sign-up"; export const EMBED_PRIVATE_APPS_DOC = "https://docs.appsmith.com/advanced-concepts/embed-appsmith-into-existing-application#embedding-private-apps"; +export const PROVISIONING_SETUP_DOC = + "http://docs.appsmith.com/advanced-concepts/user-provisioning-group-sync"; export const PRICING_PAGE_URL = ( URL: string, source: string, diff --git a/app/client/src/constants/WalkthroughConstants.ts b/app/client/src/constants/WalkthroughConstants.ts new file mode 100644 index 0000000000..1b0fbec3ec --- /dev/null +++ b/app/client/src/constants/WalkthroughConstants.ts @@ -0,0 +1,7 @@ +import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; + +export const FEATURE_WALKTHROUGH_KEYS = { + [FEATURE_FLAG.ab_ds_binding_enabled]: FEATURE_FLAG.ab_ds_binding_enabled, + [FEATURE_FLAG.ab_ds_schema_enabled]: FEATURE_FLAG.ab_ds_schema_enabled, + binding_widget: "binding_widget", +}; diff --git a/app/client/src/constants/WidgetConstants.tsx b/app/client/src/constants/WidgetConstants.tsx index 9b8e4a9709..a04a5a52c3 100644 --- a/app/client/src/constants/WidgetConstants.tsx +++ b/app/client/src/constants/WidgetConstants.tsx @@ -71,7 +71,7 @@ export const layoutConfigurations: LayoutConfigurations = { FLUID: { minWidth: -1, maxWidth: -1 }, }; -export const LATEST_PAGE_VERSION = 82; +export const LATEST_PAGE_VERSION = 83; export const GridDefaults = { DEFAULT_CELL_SIZE: 1, @@ -252,3 +252,6 @@ export const SUGGESTED_WIDGETS_ORDER: Record = { SELECT_WIDGET: 5, LIST_WIDGET_V2: 6, }; + +// Constant key to show walkthrough for a widget -> stores widget id +export const WIDGET_ID_SHOW_WALKTHROUGH = "WIDGET_ID_SHOW_WALKTHROUGH"; diff --git a/app/client/src/ee/sagas/analyticsSaga.ts b/app/client/src/ee/sagas/analyticsSaga.ts new file mode 100644 index 0000000000..b03dbf7e6b --- /dev/null +++ b/app/client/src/ee/sagas/analyticsSaga.ts @@ -0,0 +1 @@ +export * from "../../ce/sagas/analyticsSaga"; diff --git a/app/client/src/entities/Action/index.ts b/app/client/src/entities/Action/index.ts index 18ea8f72bb..f27eed1f2f 100644 --- a/app/client/src/entities/Action/index.ts +++ b/app/client/src/entities/Action/index.ts @@ -239,3 +239,5 @@ export function getGraphQLPlugin(plugins: Plugin[]): Plugin | undefined { export function isGraphqlPlugin(plugin: Plugin | undefined) { return plugin?.packageName === PluginPackageName.GRAPHQL; } + +export const SCHEMA_SECTION_ID = "t--api-right-pane-schema"; diff --git a/app/client/src/pages/AppViewer/index.tsx b/app/client/src/pages/AppViewer/index.tsx index 25d7d66101..24f98b6174 100644 --- a/app/client/src/pages/AppViewer/index.tsx +++ b/app/client/src/pages/AppViewer/index.tsx @@ -37,13 +37,18 @@ import { WidgetGlobaStyles } from "globalStyles/WidgetGlobalStyles"; import { getAppsmithConfigs } from "@appsmith/configs"; import useWidgetFocus from "utils/hooks/useWidgetFocus/useWidgetFocus"; import HtmlTitle from "./AppViewerHtmlTitle"; +import BottomBar from "components/BottomBar"; import type { ApplicationPayload } from "@appsmith/constants/ReduxActionConstants"; import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; import { editorInitializer } from "../../utils/editor/EditorUtils"; import { widgetInitialisationSuccess } from "../../actions/widgetActions"; -import BottomBar from "components/BottomBar"; import { areEnvironmentsFetched } from "@appsmith/selectors/environmentSelectors"; import { datasourceEnvEnabled } from "@appsmith/selectors/featureFlagsSelectors"; +import { + ThemeProvider as WDSThemeProvider, + useTheme, +} from "@design-system/theming"; +import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; const AppViewerBody = styled.section<{ hasPages: boolean; @@ -98,7 +103,10 @@ function AppViewer(props: Props) { const currentApplicationDetails: ApplicationPayload | undefined = useSelector( getCurrentApplication, ); - + const { theme } = useTheme({ + borderRadius: selectedTheme.properties.borderRadius.appBorderRadius, + seedColor: selectedTheme.properties.colors.primaryColor, + }); const focusRef = useWidgetFocus(); const workspaceId = currentApplicationDetails?.workspaceId || ""; @@ -176,46 +184,53 @@ function AppViewer(props: Props) { }; }, [selectedTheme.properties.fontFamily.appFont]); + const isWDSV2Enabled = useFeatureFlag("ab_wds_enabled"); + const backgroundForBody = isWDSV2Enabled + ? "var(--color-bg)" + : selectedTheme.properties.colors.backgroundColor; + return ( - - - - - - 1} - headerHeight={headerHeight} - ref={focusRef} - showBottomBar={showBottomBar} - showGuidedTourMessage={showGuidedTourMessage} - > - {isInitialized && } - - {showBottomBar && } - {!hideWatermark && ( - + + + + {!isWDSV2Enabled && ( + )} - - - + + + 1} + headerHeight={headerHeight} + ref={focusRef} + showBottomBar={showBottomBar} + showGuidedTourMessage={showGuidedTourMessage} + > + {isInitialized && } + + {showBottomBar && } + {!hideWatermark && ( + + )} + + + + ); } diff --git a/app/client/src/pages/Applications/EmbedSnippet/PrivateEmbeddingContent.tsx b/app/client/src/pages/Applications/EmbedSnippet/PrivateEmbeddingContent.tsx index a703e87251..d1e7b7adb4 100644 --- a/app/client/src/pages/Applications/EmbedSnippet/PrivateEmbeddingContent.tsx +++ b/app/client/src/pages/Applications/EmbedSnippet/PrivateEmbeddingContent.tsx @@ -1,7 +1,7 @@ import React from "react"; import { Text, Link, Button, Icon, Tag } from "design-system"; import { - BUSINESS_TEXT, + BUSINESS_TAG, createMessage, IN_APP_EMBED_SETTING, } from "@appsmith/constants/messages"; @@ -60,7 +60,7 @@ export function PrivateEmbedRampModal() { {createMessage(IN_APP_EMBED_SETTING.privateAppsText)} - {createMessage(BUSINESS_TEXT)} + {createMessage(BUSINESS_TAG)}
{ getIsAppSettingsPaneWithNavigationTabOpen, ); const selectedTheme = useSelector(getSelectedAppTheme); + const isWDSV2Enabled = useFeatureFlag("ab_wds_enabled"); + const { theme } = useTheme({ + borderRadius: selectedTheme.properties.borderRadius.appBorderRadius, + seedColor: selectedTheme.properties.colors.primaryColor, + }); /** * background for canvas @@ -43,9 +53,17 @@ const Canvas = (props: CanvasProps) => { let backgroundForCanvas; if (isPreviewMode || isAppSettingsPaneWithNavigationTabOpen) { - backgroundForCanvas = "initial"; + if (isWDSV2Enabled) { + backgroundForCanvas = "var(--color-bg)"; + } else { + backgroundForCanvas = "initial"; + } } else { - backgroundForCanvas = selectedTheme.properties.colors.backgroundColor; + if (isWDSV2Enabled) { + backgroundForCanvas = "var(--color-bg)"; + } else { + backgroundForCanvas = selectedTheme.properties.colors.backgroundColor; + } } const focusRef = useWidgetFocus(); @@ -54,23 +72,25 @@ const Canvas = (props: CanvasProps) => { const paddingBottomClass = props.isAutoLayout ? "" : "pb-52"; try { return ( - - {props.widgetsStructure.widgetId && - WidgetFactory.createWidget( - props.widgetsStructure, - RenderModes.CANVAS, - )} - + + + {props.widgetsStructure.widgetId && + WidgetFactory.createWidget( + props.widgetsStructure, + RenderModes.CANVAS, + )} + + ); } catch (error) { log.error("Error rendering DSL", error); diff --git a/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx b/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx index 63672c39e6..63e0d677e9 100644 --- a/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx +++ b/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx @@ -131,7 +131,7 @@ class DatasourceDBEditor extends JSONtoForm { )} {viewMode && ( - + {!_.isNil(formConfig) && !_.isNil(datasource) ? ( ` + width: 30vw; + margin-top: 24px; + margin-left ${(props) => (props.isSideBarPresent ? "24px" : "0px")} +`; + export type DatasourceFilterState = { id: string; name: string; @@ -243,13 +251,11 @@ class DatasourceEditorRouter extends React.Component { this.props.switchDatasource(this.props.datasourceId); } - const urlObject = new URL(window.location.href); - const pluginId = urlObject?.searchParams.get("pluginId"); // update block state when form becomes dirty/view mode is switched on if ( prevProps.viewMode !== this.props.viewMode && !this.props.viewMode && - !!pluginId + !!this.props.pluginId ) { this.blockRoutes(); } @@ -304,7 +310,7 @@ class DatasourceEditorRouter extends React.Component { pluginId, }); } - if (!this.props.viewMode && !!pluginId) { + if (!this.props.viewMode && !!this.props.pluginId) { this.blockRoutes(); } @@ -440,7 +446,7 @@ class DatasourceEditorRouter extends React.Component { } closeDialog() { - this.setState({ showDialog: false }); + this.setState({ showDialog: false, switchFilterBlocked: false }); } onSave() { @@ -461,7 +467,7 @@ class DatasourceEditorRouter extends React.Component { this.state.navigation(); this.props.datasourceDiscardAction(this.props?.pluginId); - if (!this.props.viewMode) { + if (!this.props.viewMode && !this.state.switchFilterBlocked) { this.props.setDatasourceViewMode({ datasourceId: this.props.datasourceId, viewMode: true, @@ -667,7 +673,7 @@ class DatasourceEditorRouter extends React.Component { ); if (toastMessage.message) return ( -
+ { > {toastMessage.message} -
+ ); return null; } diff --git a/app/client/src/pages/Editor/EditorAppName/index.tsx b/app/client/src/pages/Editor/EditorAppName/index.tsx index 4271f44ff7..2307fe14f6 100644 --- a/app/client/src/pages/Editor/EditorAppName/index.tsx +++ b/app/client/src/pages/Editor/EditorAppName/index.tsx @@ -52,6 +52,7 @@ const Container = styled.div` ${getTypographyByKey("h5")}; line-height: ${(props) => props.theme.smallHeaderHeight} !important; padding: 0 ${(props) => props.theme.spaces[2]}px; + height: ${(props) => props.theme.smallHeaderHeight} !important; } &&&& .${Classes.EDITABLE_TEXT_INPUT} { margin-right: 20px; diff --git a/app/client/src/pages/Editor/EditorHeader.tsx b/app/client/src/pages/Editor/EditorHeader.tsx index a45e06e5e8..1a6d189f33 100644 --- a/app/client/src/pages/Editor/EditorHeader.tsx +++ b/app/client/src/pages/Editor/EditorHeader.tsx @@ -1,13 +1,11 @@ import React, { useCallback, useEffect, useState, lazy, Suspense } from "react"; import styled, { ThemeProvider } from "styled-components"; import classNames from "classnames"; -import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import { APPLICATIONS_URL } from "constants/routes"; import AppInviteUsersForm from "pages/workspace/AppInviteUsersForm"; import AnalyticsUtil from "utils/AnalyticsUtil"; import AppsmithLogo from "assets/images/appsmith_logo_square.png"; import { Link } from "react-router-dom"; -import type { AppState } from "@appsmith/reducers"; import { getCurrentApplicationId, getCurrentPageId, @@ -18,14 +16,17 @@ import { getAllUsers, getCurrentWorkspaceId, } from "@appsmith/selectors/workspaceSelectors"; -import type { ConnectedProps } from "react-redux"; -import { connect, useDispatch, useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import DeployLinkButtonDialog from "components/designSystems/appsmith/header/DeployLinkButton"; -import { updateApplication } from "@appsmith/actions/applicationActions"; +import { + publishApplication, + updateApplication, +} from "@appsmith/actions/applicationActions"; import { getApplicationList, getIsSavingAppName, getIsErroredSavingAppName, + getCurrentApplication, } from "@appsmith/selectors/applicationSelectors"; import EditorAppName from "./EditorAppName"; import { getCurrentUser } from "selectors/usersSelectors"; @@ -207,18 +208,7 @@ const GlobalSearch = lazy(() => { const theme = getTheme(ThemeMode.LIGHT); -// Seperating redux props types from props being passed to the component from a parent -type PropsFromRedux = ConnectedProps; - -export function EditorHeader(props: PropsFromRedux) { - const { - applicationId, - currentApplication, - isPublishing, - pageId, - publishApplication, - workspaceId, - } = props; +export function EditorHeader() { const [activeTab, setActiveTab] = useState("invite"); const dispatch = useDispatch(); const isSnipingMode = useSelector(snipingModeSelector); @@ -229,6 +219,14 @@ export function EditorHeader(props: PropsFromRedux) { const applicationList = useSelector(getApplicationList); const isPreviewMode = useSelector(previewModeSelector); const signpostingEnabled = useSelector(getIsFirstTimeUserOnboardingEnabled); + const workspaceId = useSelector(getCurrentWorkspaceId); + const applicationId = useSelector(getCurrentApplicationId); + const currentApplication = useSelector(getCurrentApplication); + const isPublishing = useSelector(getIsPublishingApplication); + const pageId = useSelector(getCurrentPageId) as string; + const sharedUserList = useSelector(getAllUsers); + const currentUser = useSelector(getCurrentUser); + const deployLink = useHref(viewerURL, { pageId }); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, @@ -242,7 +240,7 @@ export function EditorHeader(props: PropsFromRedux) { const handlePublish = () => { if (applicationId) { - publishApplication(applicationId); + dispatch(publishApplication(applicationId)); const appName = currentApplication ? currentApplication.name : ""; const pageCount = currentApplication?.pages?.length; @@ -323,8 +321,8 @@ export function EditorHeader(props: PropsFromRedux) { dispatch(fetchUsersForWorkspace(workspaceId)); } }, [workspaceId]); - const filteredSharedUserList = props.sharedUserList.filter( - (user) => user.username !== props.currentUser?.username, + const filteredSharedUserList = sharedUserList.filter( + (user) => user.username !== currentUser?.username, ); return ( @@ -551,31 +549,4 @@ export function EditorHeader(props: PropsFromRedux) { ); } -const mapStateToProps = (state: AppState) => ({ - pageName: state.ui.editor.currentPageName, - workspaceId: getCurrentWorkspaceId(state), - applicationId: getCurrentApplicationId(state), - currentApplication: state.ui.applications.currentApplication, - isPublishing: getIsPublishingApplication(state), - pageId: getCurrentPageId(state) as string, - sharedUserList: getAllUsers(state), - currentUser: getCurrentUser(state), -}); - -const mapDispatchToProps = (dispatch: any) => ({ - publishApplication: (applicationId: string) => { - dispatch({ - type: ReduxActionTypes.PUBLISH_APPLICATION_INIT, - payload: { - applicationId, - }, - }); - }, -}); - -EditorHeader.whyDidYouRender = { - logOnDifferentValues: false, -}; - -const connector = connect(mapStateToProps, mapDispatchToProps); -export default connector(EditorHeader); +export default EditorHeader; diff --git a/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructure.tsx b/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructure.tsx index 13a5123b12..e1c2c6a446 100644 --- a/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructure.tsx +++ b/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructure.tsx @@ -1,4 +1,4 @@ -import React, { useState, useContext } from "react"; +import React, { useState } from "react"; import Entity, { EntityClassNames } from "../Entity"; import { datasourceTableIcon } from "../ExplorerIcons"; import QueryTemplates from "./QueryTemplates"; @@ -17,9 +17,6 @@ import styled from "styled-components"; import { DatasourceStructureContext } from "./DatasourceStructureContainer"; import AnalyticsUtil from "utils/AnalyticsUtil"; import type { Plugin } from "api/PluginApi"; -import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; -import { setFeatureFlagShownStatus } from "utils/storage"; -import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; type DatasourceStructureProps = { dbStructure: DatasourceTable; @@ -42,9 +39,6 @@ export function DatasourceStructure(props: DatasourceStructureProps) { const [active, setActive] = useState(false); useCloseMenuOnScroll(SIDEBAR_ID, active, () => setActive(false)); - const { isOpened: isWalkthroughOpened, popFeature } = - useContext(WalkthroughContext) || {}; - const datasource = useSelector((state: AppState) => getDatasource(state, props.datasourceId), ); @@ -72,15 +66,6 @@ export function DatasourceStructure(props: DatasourceStructureProps) { }); canCreateDatasourceActions && setActive(!active); - - dbStructure.templates.length === 0 && - isWalkthroughOpened && - closeWalkthrough(); - }; - - const closeWalkthrough = () => { - popFeature && popFeature(); - setFeatureFlagShownStatus(FEATURE_FLAG.ab_ds_schema_enabled, true); }; const lightningMenu = diff --git a/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructureContainer.tsx b/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructureContainer.tsx index a31d194317..411881bd29 100644 --- a/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructureContainer.tsx +++ b/app/client/src/pages/Editor/Explorer/Datasources/DatasourceStructureContainer.tsx @@ -9,6 +9,7 @@ import type { DatasourceTable, } from "entities/Datasource"; import type { ReactElement } from "react"; +import { useContext } from "react"; import React, { memo, useEffect, useMemo, useState } from "react"; import EntityPlaceholder from "../Entity/Placeholder"; import DatasourceStructure from "./DatasourceStructure"; @@ -21,6 +22,10 @@ import DatasourceStructureLoadingContainer from "./DatasourceStructureLoadingCon import DatasourceStructureNotFound from "./DatasourceStructureNotFound"; import AnalyticsUtil from "utils/AnalyticsUtil"; import { PluginName } from "entities/Action"; +import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; +import { setFeatureWalkthroughShown } from "utils/storage"; +import { FEATURE_WALKTHROUGH_KEYS } from "constants/WalkthroughConstants"; +import { SCHEMA_SECTION_ID } from "entities/Action"; type Props = { datasourceId: string; @@ -71,6 +76,35 @@ const Container = (props: Props) => { >(props.datasourceStructure); const [hasSearchedOccured, setHasSearchedOccured] = useState(false); + const { isOpened: isWalkthroughOpened, popFeature } = + useContext(WalkthroughContext) || {}; + + const attachCloseWalkthrough = + props.context !== DatasourceStructureContext.EXPLORER && + isWalkthroughOpened && + !isLoading && + !props.datasourceStructure?.tables?.length; + + const closeWalkthrough = () => { + popFeature && popFeature("DATASOURCE_SCHEMA_CONTAINER"); + setFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_schema_enabled, + true, + ); + }; + + useEffect(() => { + const schemaContainer = document.querySelector(`#${SCHEMA_SECTION_ID}`); + if (schemaContainer && attachCloseWalkthrough) { + schemaContainer.addEventListener("click", closeWalkthrough); + } + return () => { + if (schemaContainer && attachCloseWalkthrough) { + schemaContainer.removeEventListener("click", closeWalkthrough); + } + }; + }, [attachCloseWalkthrough]); + useEffect(() => { if (datasourceStructure !== props.datasourceStructure) { setDatasourceStructure(props.datasourceStructure); diff --git a/app/client/src/pages/Editor/Explorer/Datasources/QueryTemplates.tsx b/app/client/src/pages/Editor/Explorer/Datasources/QueryTemplates.tsx index 1450313194..a8d742ec40 100644 --- a/app/client/src/pages/Editor/Explorer/Datasources/QueryTemplates.tsx +++ b/app/client/src/pages/Editor/Explorer/Datasources/QueryTemplates.tsx @@ -21,14 +21,14 @@ import { MenuItem } from "design-system"; import type { Plugin } from "api/PluginApi"; import { DatasourceStructureContext } from "./DatasourceStructureContainer"; import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; -import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; -import { setFeatureFlagShownStatus } from "utils/storage"; +import { setFeatureWalkthroughShown } from "utils/storage"; import styled from "styled-components"; import { change, getFormValues } from "redux-form"; import { QUERY_EDITOR_FORM_NAME } from "@appsmith/constants/forms"; import { diff } from "deep-diff"; import { UndoRedoToastContext, showUndoRedoToast } from "utils/replayHelpers"; import AnalyticsUtil from "utils/AnalyticsUtil"; +import { FEATURE_WALKTHROUGH_KEYS } from "constants/WalkthroughConstants"; type QueryTemplatesProps = { templates: QueryTemplate[]; @@ -110,8 +110,11 @@ export function QueryTemplates(props: QueryTemplatesProps) { ); if (isWalkthroughOpened) { - popFeature && popFeature(); - setFeatureFlagShownStatus(FEATURE_FLAG.ab_ds_schema_enabled, true); + popFeature && popFeature("SCHEMA_QUERY_CREATE"); + setFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_schema_enabled, + true, + ); } history.push( @@ -170,8 +173,11 @@ export function QueryTemplates(props: QueryTemplatesProps) { }); if (isWalkthroughOpened) { - popFeature && popFeature(); - setFeatureFlagShownStatus(FEATURE_FLAG.ab_ds_schema_enabled, true); + popFeature && popFeature("SCHEMA_QUERY_UPDATE"); + setFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.ab_ds_schema_enabled, + true, + ); } showUndoRedoToast( diff --git a/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts b/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts index 22c1f646a7..6b207add11 100644 --- a/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts +++ b/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts @@ -1,6 +1,16 @@ +import { SIGNPOSTING_STEP } from "./Utils"; + //Hide Anonymous Data Popup after 15 seconds export const ANONYMOUS_DATA_POPOP_TIMEOUT = 15000; //Telemetry Docs Page export const TELEMETRY_DOCS_PAGE_URL = "https://docs.appsmith.com/product/telemetry"; + +export const SIGNPOSTING_ANALYTICS_STEP_NAME = { + [SIGNPOSTING_STEP.CONNECT_A_DATASOURCE]: "Connect to datasource", + [SIGNPOSTING_STEP.CREATE_A_QUERY]: "Created query", + [SIGNPOSTING_STEP.ADD_WIDGETS]: "Created Widget", + [SIGNPOSTING_STEP.CONNECT_DATA_TO_WIDGET]: "Binding success", + [SIGNPOSTING_STEP.DEPLOY_APPLICATIONS]: "Deployed app", +}; diff --git a/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx b/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx index 430f1f743d..e9bef3fd10 100644 --- a/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx +++ b/app/client/src/pages/Editor/PropertyPane/PropertyControl.tsx @@ -16,10 +16,7 @@ import { deleteWidgetProperty, setWidgetDynamicProperty, } from "actions/controlActions"; -import type { - PropertyHookUpdates, - PropertyPaneControlConfig, -} from "constants/PropertyControlConstants"; +import type { PropertyPaneControlConfig } from "constants/PropertyControlConstants"; import type { IPanelProps } from "@blueprintjs/core"; import PanelPropertiesEditor from "./PanelPropertiesEditor"; import type { DynamicPath } from "utils/DynamicBindingUtils"; @@ -55,6 +52,7 @@ import clsx from "clsx"; import styled from "styled-components"; import { importSvg } from "design-system-old"; import classNames from "classnames"; +import type { PropertyUpdates } from "widgets/constants"; import { getIsOneClickBindingOptionsVisibility } from "selectors/oneClickBindingSelectors"; const ResetIcon = importSvg(() => import("assets/icons/control/undo_2.svg")); @@ -265,7 +263,7 @@ const PropertyControl = memo((props: Props) => { propertyName: string, propertyValue: any, ): UpdateWidgetPropertyPayload | undefined => { - let propertiesToUpdate: Array | undefined; + let propertiesToUpdate: Array | undefined; // To support updating multiple properties of same widget. if (updateHook) { propertiesToUpdate = updateHook( diff --git a/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx b/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx index 5441a70c3a..d5b0c92dff 100644 --- a/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx +++ b/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx @@ -1,4 +1,5 @@ import type { ReactElement } from "react"; +import { useContext } from "react"; import React, { useCallback, useEffect, useMemo, useRef } from "react"; import equal from "fast-deep-equal/es6"; import { useDispatch, useSelector } from "react-redux"; @@ -12,6 +13,7 @@ import { deleteSelectedWidget, copyWidget } from "actions/widgetActions"; import ConnectDataCTA, { actionsExist } from "./ConnectDataCTA"; import PropertyPaneConnections from "./PropertyPaneConnections"; import type { WidgetType } from "constants/WidgetConstants"; +import { WIDGET_ID_SHOW_WALKTHROUGH } from "constants/WidgetConstants"; import type { InteractionAnalyticsEventDetail } from "utils/AppsmithUtils"; import { INTERACTION_ANALYTICS_EVENT } from "utils/AppsmithUtils"; import { emitInteractionAnalyticsEvent } from "utils/AppsmithUtils"; @@ -23,6 +25,18 @@ import { PropertyPaneTab } from "./PropertyPaneTab"; import { useSearchText } from "./helpers"; import { PropertyPaneSearchInput } from "./PropertyPaneSearchInput"; import { sendPropertyPaneSearchAnalytics } from "./propertyPaneSearch"; +import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; +import { AB_TESTING_EVENT_KEYS } from "@appsmith/entities/FeatureFlag"; +import localStorage from "utils/localStorage"; +import { FEATURE_WALKTHROUGH_KEYS } from "constants/WalkthroughConstants"; +import { PROPERTY_PANE_ID } from "components/editorComponents/PropertyPaneSidebar"; +import { setFeatureWalkthroughShown } from "utils/storage"; +import { + BINDING_WIDGET_WALKTHROUGH_DESC, + BINDING_WIDGET_WALKTHROUGH_TITLE, + createMessage, +} from "@appsmith/constants/messages"; +import { getWidgets } from "sagas/selectors"; // TODO(abhinav): The widget should add a flag in their configuration if they donot subscribe to data // Widgets where we do not want to show the CTA @@ -40,6 +54,7 @@ export const excludeList: WidgetType[] = [ "FILE_PICKER_WIDGET", "FILE_PICKER_WIDGET_V2", "TABLE_WIDGET_V2", + "BUTTON_WIDGET_V2", ]; function PropertyPaneView( @@ -64,6 +79,52 @@ function PropertyPaneView( return true; }, [widgetProperties?.type, excludeList]); const { searchText, setSearchText } = useSearchText(""); + const { pushFeature } = useContext(WalkthroughContext) || {}; + const widgets = useSelector(getWidgets); + + const showWalkthroughIfWidgetIdSet = async () => { + const widgetId: string | null = await localStorage.getItem( + WIDGET_ID_SHOW_WALKTHROUGH, + ); + + // Adding table condition as connecting to select, chart widgets is currently not working as expected + // When we fix those, we can remove this table condtion + const isTableWidget = !!widgetId + ? widgets[widgetId]?.type === "TABLE_WIDGET_V2" + : false; + + if (widgetId && pushFeature && isTableWidget) { + pushFeature({ + targetId: PROPERTY_PANE_ID, + onDismiss: async () => { + await localStorage.removeItem(WIDGET_ID_SHOW_WALKTHROUGH); + await setFeatureWalkthroughShown( + FEATURE_WALKTHROUGH_KEYS.binding_widget, + true, + ); + }, + details: { + title: createMessage(BINDING_WIDGET_WALKTHROUGH_TITLE), + description: createMessage(BINDING_WIDGET_WALKTHROUGH_DESC), + }, + offset: { + position: "left", + left: -40, + top: 250, + highlightPad: 2, + indicatorLeft: -3, + indicatorTop: 230, + }, + eventParams: { + [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: + FEATURE_WALKTHROUGH_KEYS.binding_widget, + [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: true, + }, + multipleHighlights: [widgetId, PROPERTY_PANE_ID], + delay: 5000, + }); + } + }; const handleKbdEvent = (e: Event) => { const event = e as CustomEvent; @@ -80,6 +141,7 @@ function PropertyPaneView( INTERACTION_ANALYTICS_EVENT, handleKbdEvent, ); + showWalkthroughIfWidgetIdSet(); return () => { containerRef.current?.removeEventListener( INTERACTION_ANALYTICS_EVENT, @@ -184,7 +246,7 @@ function PropertyPaneView( return (
diff --git a/app/client/src/pages/Editor/WidgetsEditor/CanvasContainer.tsx b/app/client/src/pages/Editor/WidgetsEditor/CanvasContainer.tsx index f326aaca07..7db7ec79ce 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/CanvasContainer.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/CanvasContainer.tsx @@ -25,15 +25,16 @@ import { getSelectedAppTheme, } from "selectors/appThemingSelectors"; import { getIsAutoLayout } from "selectors/canvasSelectors"; -import { getCanvasWidgetsStructure } from "selectors/entitiesSelector"; import { getCurrentThemeDetails } from "selectors/themeSelectors"; +import { getCanvasWidgetsStructure } from "selectors/entitiesSelector"; import { AUTOLAYOUT_RESIZER_WIDTH_BUFFER, useDynamicAppLayout, } from "utils/hooks/useDynamicAppLayout"; import Canvas from "../Canvas"; -import { CanvasResizer } from "widgets/CanvasResizer"; import type { AppState } from "@appsmith/reducers"; +import { CanvasResizer } from "widgets/CanvasResizer"; +import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { getIsAnonymousDataPopupVisible } from "selectors/onboardingSelectors"; type CanvasContainerProps = { @@ -119,9 +120,9 @@ function CanvasContainer(props: CanvasContainerProps) { const isAppThemeChanging = useSelector(getAppThemeIsChanging); const showCanvasTopSection = useSelector(showCanvasTopSectionSelector); const showAnonymousDataPopup = useSelector(getIsAnonymousDataPopupVisible); - const isLayoutingInitialized = useDynamicAppLayout(); const isPageInitializing = isFetchingPage || !isLayoutingInitialized; + const isWDSV2Enabled = useFeatureFlag("ab_wds_enabled"); useEffect(() => { return () => { @@ -184,7 +185,9 @@ function CanvasContainer(props: CanvasContainerProps) { $isAutoLayout={isAutoLayout} background={ isPreviewMode || isAppSettingsPaneWithNavigationTabOpen - ? selectedTheme.properties.colors.backgroundColor + ? isWDSV2Enabled + ? "var(--bg-color)" + : selectedTheme.properties.colors.backgroundColor : "initial" } className={classNames({ @@ -214,10 +217,12 @@ function CanvasContainer(props: CanvasContainerProps) { pointerEvents: isAutoCanvasResizing ? "none" : "auto", }} > - + {!isWDSV2Enabled && ( + + )} {isAppThemeChanging && (
diff --git a/app/client/src/preload-route-chunks.ts b/app/client/src/preload-route-chunks.ts index 64be192133..d150c06835 100644 --- a/app/client/src/preload-route-chunks.ts +++ b/app/client/src/preload-route-chunks.ts @@ -28,7 +28,7 @@ if ( currentMode ) { window.__APPSMITH_CHUNKS_TO_PRELOAD[currentMode] - // __webpack_public_path__ might be set on runtime when the CDN is used in EE + // @ts-expect-error __webpack_public_path__ might be set on runtime when the CDN is used in EE .map((url) => __webpack_public_path__ + url) .forEach((url) => { const link = document.createElement("link"); diff --git a/app/client/src/reducers/uiReducers/appThemingReducer.ts b/app/client/src/reducers/uiReducers/appThemingReducer.ts index e1579ad5bf..d4e2c5614e 100644 --- a/app/client/src/reducers/uiReducers/appThemingReducer.ts +++ b/app/client/src/reducers/uiReducers/appThemingReducer.ts @@ -42,7 +42,7 @@ const initialState: AppThemingState = { properties: { colors: { backgroundColor: "#F8FAFC", - primaryColor: "", + primaryColor: "#000", secondaryColor: "", }, borderRadius: {}, diff --git a/app/client/src/sagas/ActionExecution/PluginActionSaga.ts b/app/client/src/sagas/ActionExecution/PluginActionSaga.ts index f2ccfd67ae..877d7e6eae 100644 --- a/app/client/src/sagas/ActionExecution/PluginActionSaga.ts +++ b/app/client/src/sagas/ActionExecution/PluginActionSaga.ts @@ -534,6 +534,7 @@ export default function* executePluginActionTriggerSaga( datasourceId: datasourceId, isMock: !!datasource?.isMock, actionId: action?.id, + inputParams: Object.keys(params).length, }); const pagination = eventType === EventType.ON_NEXT_PAGE @@ -608,6 +609,7 @@ export default function* executePluginActionTriggerSaga( isMock: !!datasource?.isMock, actionId: action?.id, ...payload.pluginErrorDetails, + inputParams: Object.keys(params).length, }); if (onError) { throw new PluginTriggerFailureError( @@ -635,6 +637,7 @@ export default function* executePluginActionTriggerSaga( datasourceId: datasourceId, isMock: !!datasource?.isMock, actionId: action?.id, + inputParams: Object.keys(params).length, }); AppsmithConsole.info({ logType: LOG_TYPE.ACTION_EXECUTION_SUCCESS, @@ -1089,6 +1092,7 @@ function* executePageLoadAction(pageAction: PageAction) { datasourceId: datasourceId, isMock: !!datasource?.isMock, actionId: pageAction?.id, + inputParams: 0, }); let payload = EMPTY_RESPONSE; @@ -1177,6 +1181,7 @@ function* executePageLoadAction(pageAction: PageAction) { datasourceId: datasourceId, isMock: !!datasource?.isMock, actionId: pageAction?.id, + inputParams: 0, ...payload.pluginErrorDetails, }); } else { @@ -1195,6 +1200,7 @@ function* executePageLoadAction(pageAction: PageAction) { datasourceId: datasourceId, isMock: !!datasource?.isMock, actionId: pageAction?.id, + inputParams: 0, }); PerformanceTracker.stopAsyncTracking( PerformanceTransactionName.EXECUTE_ACTION, diff --git a/app/client/src/sagas/DatasourcesSagas.ts b/app/client/src/sagas/DatasourcesSagas.ts index 839dae8633..d83dd60ab7 100644 --- a/app/client/src/sagas/DatasourcesSagas.ts +++ b/app/client/src/sagas/DatasourcesSagas.ts @@ -777,10 +777,15 @@ function* testDatasourceSaga(actionPayload: ReduxAction) { let messages: Array = []; if (isValidResponse) { const responseData = response.data; - if ( - (responseData.invalids && responseData.invalids.length) || - (responseData.messages && responseData.messages.length) - ) { + if (responseData.messages && responseData.messages.length) { + messages = responseData.messages; + if (responseData.success) { + toast.show(createMessage(DATASOURCE_VALID, payload.name), { + kind: "success", + }); + } + } + if (responseData.invalids && responseData.invalids.length) { AnalyticsUtil.logEvent("TEST_DATA_SOURCE_FAILED", { datasoureId: datasource?.id, environmentId: currentEnvironment, @@ -789,21 +794,11 @@ function* testDatasourceSaga(actionPayload: ReduxAction) { errorMessages: responseData.invalids, messages: responseData.messages, }); - if (responseData.invalids && responseData.invalids.length) { - responseData.invalids.forEach((message: string) => { - toast.show(message, { - kind: "error", - }); + responseData.invalids.forEach((message: string) => { + toast.show(message, { + kind: "error", }); - } - if (responseData.messages && responseData.messages.length) { - messages = responseData.messages; - if (responseData.success) { - toast.show(createMessage(DATASOURCE_VALID, payload.name), { - kind: "success", - }); - } - } + }); yield put({ type: ReduxActionErrorTypes.TEST_DATASOURCE_ERROR, payload: { @@ -844,7 +839,7 @@ function* testDatasourceSaga(actionPayload: ReduxAction) { show: false, id: datasource.id, environmentId: currentEnvironment, - messages: [], + messages: messages, }, }); AppsmithConsole.info({ diff --git a/app/client/src/sagas/EvalWorkerActionSagas.ts b/app/client/src/sagas/EvalWorkerActionSagas.ts index e001e4337d..7b3ae0b01a 100644 --- a/app/client/src/sagas/EvalWorkerActionSagas.ts +++ b/app/client/src/sagas/EvalWorkerActionSagas.ts @@ -30,7 +30,6 @@ import isEmpty from "lodash/isEmpty"; import type { UnEvalTree } from "entities/DataTree/dataTreeFactory"; import { sortJSExecutionDataByCollectionId } from "workers/Evaluation/JSObject/utils"; import type { LintTreeSagaRequestData } from "plugins/Linting/types"; -import AnalyticsUtil from "utils/AnalyticsUtil"; export type UpdateDataTreeMessageData = { workerResponse: EvalTreeResponseData; unevalTree: UnEvalTree; @@ -106,19 +105,6 @@ export function* processTriggerHandler(message: any) { if (messageType === MessageType.REQUEST) yield call(evalWorker.respond, message.messageId, result); } -export function* handleJSExecutionLog(data: TMessage<{ data: string[] }>) { - const { - body: { data: executedFns }, - } = data; - - for (const executedFn of executedFns) { - AnalyticsUtil.logEvent("EXECUTE_ACTION", { - type: "JS", - name: executedFn, - }); - } - yield call(logJSFunctionExecution, data); -} export function* handleEvalWorkerMessage(message: TMessage) { const { body } = message; @@ -145,7 +131,7 @@ export function* handleEvalWorkerMessage(message: TMessage) { break; } case MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION: { - yield call(handleJSExecutionLog, message); + yield call(logJSFunctionExecution, message); break; } case MAIN_THREAD_ACTION.PROCESS_BATCHED_TRIGGERS: { diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index 038f42a853..a2042512c1 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -100,6 +100,7 @@ import { getAppsmithConfigs } from "@appsmith/configs"; import { executeJSUpdates } from "actions/pluginActionActions"; import { setEvaluatedActionSelectorField } from "actions/actionSelectorActions"; import { waitForWidgetConfigBuild } from "./InitSagas"; +import { logDynamicTriggerExecution } from "@appsmith/sagas/analyticsSaga"; const APPSMITH_CONFIGS = getAppsmithConfigs(); @@ -315,7 +316,6 @@ export function* evaluateAndExecuteDynamicTrigger( const unEvalTree: ReturnType = yield select( getUnevaluatedDataTree, ); - // const unEvalTree = unEvalAndConfigTree.unEvalTree; log.debug({ execute: dynamicTrigger }); const response: { errors: EvaluationError[]; result: unknown } = yield call( evalWorker.request, @@ -331,6 +331,11 @@ export function* evaluateAndExecuteDynamicTrigger( ); const { errors = [] } = response as any; yield call(dynamicTriggerErrorHandler, errors); + yield fork(logDynamicTriggerExecution, { + dynamicTrigger, + errors, + triggerMeta, + }); return response; } diff --git a/app/client/src/sagas/JSPaneSagas.ts b/app/client/src/sagas/JSPaneSagas.ts index 7686b69e9c..4b3661dad3 100644 --- a/app/client/src/sagas/JSPaneSagas.ts +++ b/app/client/src/sagas/JSPaneSagas.ts @@ -87,6 +87,9 @@ import { toast } from "design-system"; import { setDebuggerSelectedTab, showDebugger } from "actions/debuggerActions"; import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers"; +const CONSOLE_DOT_LOG_INVOCATION_REGEX = + /console.log[.call | .apply]*\s*\(.*?\)/gm; + function* handleCreateNewJsActionSaga( action: ReduxAction<{ pageId: string; from: EventLocation }>, ) { @@ -470,10 +473,14 @@ export function* handleStartExecuteJSFunctionSaga( throw new UserCancelledActionExecutionError(); } } + AnalyticsUtil.logEvent("JS_OBJECT_FUNCTION_RUN", { name: action.name, num_params: action.actionConfiguration?.jsArguments?.length, - from: from, + from, + consoleStatements: + action.actionConfiguration?.body?.match(CONSOLE_DOT_LOG_INVOCATION_REGEX) + ?.length || 0, }); yield call(handleExecuteJSFunctionSaga, { collectionName: collectionName, diff --git a/app/client/src/sagas/OnboardingSagas.ts b/app/client/src/sagas/OnboardingSagas.ts index e5490e8b1c..c9e7703ff6 100644 --- a/app/client/src/sagas/OnboardingSagas.ts +++ b/app/client/src/sagas/OnboardingSagas.ts @@ -86,6 +86,7 @@ import type { SIGNPOSTING_STEP } from "pages/Editor/FirstTimeUserOnboarding/Util import type { StepState } from "reducers/uiReducers/onBoardingReducer"; import { isUndefined } from "lodash"; import { isAirgapped } from "@appsmith/utils/airgapHelpers"; +import { SIGNPOSTING_ANALYTICS_STEP_NAME } from "pages/Editor/FirstTimeUserOnboarding/constants"; const GUIDED_TOUR_STORAGE_KEY = "GUIDED_TOUR_STORAGE_KEY"; @@ -505,6 +506,9 @@ function* setSignpostingStepStateSaga( if (!isUndefined(readProps.read) && !readProps.read) { // Show tooltip after a small delay to not be abrupt yield delay(1000); + AnalyticsUtil.logEvent("SIGNPOSTING_STEP_COMPLETE", { + step_name: SIGNPOSTING_ANALYTICS_STEP_NAME[step], + }); yield put(showSignpostingTooltip(true)); } } diff --git a/app/client/src/sagas/SnipingModeSagas.ts b/app/client/src/sagas/SnipingModeSagas.ts index 61b348e69d..364065dcd0 100644 --- a/app/client/src/sagas/SnipingModeSagas.ts +++ b/app/client/src/sagas/SnipingModeSagas.ts @@ -5,8 +5,8 @@ import { snipingModeBindToSelector } from "selectors/editorSelectors"; import type { ActionData } from "reducers/entityReducers/actionsReducer"; import { getCanvasWidgets } from "selectors/entitiesSelector"; import { - setWidgetDynamicProperty, - updateWidgetPropertyRequest, + batchUpdateWidgetDynamicProperty, + batchUpdateWidgetProperty, } from "actions/controlActions"; import AnalyticsUtil from "utils/AnalyticsUtil"; @@ -26,8 +26,8 @@ import { FEATURE_FLAG, } from "@appsmith/entities/FeatureFlag"; import { selectFeatureFlagCheck } from "@appsmith/selectors/featureFlagsSelectors"; - -const WidgetTypes = WidgetFactory.widgetTypes; +import { FEATURE_WALKTHROUGH_KEYS } from "constants/WalkthroughConstants"; +import type { PropertyUpdates } from "widgets/constants"; export function* bindDataToWidgetSaga( action: ReduxAction<{ @@ -54,120 +54,58 @@ export function* bindDataToWidgetSaga( return; } const { widgetId } = action.payload; - let propertyPath = ""; - let propertyValue: any = ""; + let isValidProperty = true; // Pranav has an Open PR for this file so just returning for now if (!currentAction) return; - //TODO (Balaji): Abstraction leak. propertyPath should come from the widget - switch (selectedWidget.type) { - case WidgetTypes.BUTTON_WIDGET: - case WidgetTypes.FORM_BUTTON_WIDGET: - propertyPath = "onClick"; - propertyValue = `{{${currentAction.config.name}.run()}}`; - break; - case WidgetTypes.CHECKBOX_WIDGET: - propertyPath = "defaultCheckedState"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.DATE_PICKER_WIDGET2: - propertyPath = "defaultDate"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.FILE_PICKER_WIDGET: - propertyPath = "onFilesSelected"; - propertyValue = `{{${currentAction.config.name}.run()}}`; - break; - case WidgetTypes.IFRAME_WIDGET: - propertyPath = "source"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.INPUT_WIDGET: - propertyPath = "defaultText"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.INPUT_WIDGET_V2: - propertyPath = "defaultText"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.LIST_WIDGET: - propertyPath = "listData"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.LIST_WIDGET_V2: - propertyPath = "listData"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.MAP_WIDGET: - propertyPath = "defaultMarkers"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.RADIO_GROUP_WIDGET: - propertyPath = "options"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.RATE_WIDGET: - propertyPath = "onRateChanged"; - propertyValue = `{{${currentAction.config.name}.run()}}`; - break; - case WidgetTypes.RICH_TEXT_EDITOR_WIDGET: - propertyPath = "defaultText"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.DROP_DOWN_WIDGET: - propertyPath = "options"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.SELECT_WIDGET: - propertyPath = "sourceData"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.SWITCH_WIDGET: - propertyPath = "defaultSwitchState"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.TABLE_WIDGET: - propertyPath = "tableData"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.TABLE_WIDGET_V2: - propertyPath = "tableData"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.TEXT_WIDGET: - propertyPath = "text"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.VIDEO_WIDGET: - propertyPath = "url"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - case WidgetTypes.JSON_FORM_WIDGET: - propertyPath = "sourceData"; - propertyValue = `{{${currentAction.config.name}.data}}`; - break; - default: - isValidProperty = false; - break; + const { getSnipingModeUpdates } = WidgetFactory.getWidgetMethods( + selectedWidget.type, + ); + + let updates: Array = []; + + if (getSnipingModeUpdates) { + updates = getSnipingModeUpdates?.({ + data: `{{${currentAction.config.name}.data}}`, + run: `{{${currentAction.config.name}.run()}}`, + }); + + AnalyticsUtil.logEvent("WIDGET_SELECTED_VIA_SNIPING_MODE", { + widgetType: selectedWidget.type, + actionName: currentAction.config.name, + apiId: queryId, + propertyPath: updates?.map((update) => update.propertyPath).toString(), + propertyValue: updates?.map((update) => update.propertyPath).toString(), + [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: + FEATURE_WALKTHROUGH_KEYS.ab_ds_binding_enabled, + [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: isDSBindingEnabled, + }); + } else { + isValidProperty = false; } - AnalyticsUtil.logEvent("WIDGET_SELECTED_VIA_SNIPING_MODE", { - widgetType: selectedWidget.type, - actionName: currentAction.config.name, - apiId: queryId, - propertyPath, - propertyValue, - [AB_TESTING_EVENT_KEYS.abTestingFlagLabel]: - FEATURE_FLAG.ab_ds_binding_enabled, - [AB_TESTING_EVENT_KEYS.abTestingFlagValue]: isDSBindingEnabled, - }); - if (queryId && isValidProperty) { - // set the property path to dynamic, i.e. enable JS mode - yield put(setWidgetDynamicProperty(widgetId, propertyPath, true)); - yield put( - updateWidgetPropertyRequest(widgetId, propertyPath, propertyValue), + + if (queryId && isValidProperty && updates.length > 0) { + const updatesMap: Record = updates?.reduce( + (acc: Record, update) => { + acc[update.propertyPath] = update.propertyValue as string; + return acc; + }, + {}, ); + + const batchUpdateArray = updates.map((update) => { + return { + propertyPath: update.propertyPath, + isDynamic: !!update.isDynamicPropertyPath, + skipValidation: true, // Since we are coming up with the dynamic string, we can skip validation + }; + }); + + // set the property path to dynamic, i.e. enable JS mode + yield put(batchUpdateWidgetDynamicProperty(widgetId, batchUpdateArray)); + yield put(batchUpdateWidgetProperty(widgetId, { modify: updatesMap })); yield call(resetSnipingModeSaga); yield put(selectWidgetInitAction(SelectionRequestType.One, [widgetId])); } else { diff --git a/app/client/src/sagas/WidgetOperationSaga.test.tsx b/app/client/src/sagas/WidgetOperationSaga.test.tsx index 0fd8c35924..b8b963d4e5 100644 --- a/app/client/src/sagas/WidgetOperationSaga.test.tsx +++ b/app/client/src/sagas/WidgetOperationSaga.test.tsx @@ -3,6 +3,8 @@ const updateAndSaveLayoutMock = jest.fn(); import { setWidgetDynamicPropertySaga, removeDynamicBindingProperties, + handleUpdateWidgetDynamicProperty, + batchUpdateWidgetDynamicPropertySaga, } from "./WidgetOperationSagas"; const widget = { @@ -61,6 +63,14 @@ describe("WidgetOperationSaga - ", () => { value.next(); // start value.next(widget as any); // yield select + value.next({ + ...widget, + dynamicPropertyPathList: [ + { + key: "isVisible", + }, + ], + } as any); value.next({ test: widget, } as any); // yield select @@ -88,7 +98,12 @@ describe("WidgetOperationSaga - ", () => { }); value.next(); // start value.next(widget1 as any); // yield select - value.next({ parsed: 1 } as any); // yield call + value.next({ + ...widget1, + dynamicPropertyPathList: [], + dynamicBindingPathList: [], + isVisible: 1, + } as any); value.next({ test: widget1, } as any); // yield select @@ -104,6 +119,105 @@ describe("WidgetOperationSaga - ", () => { }); }); +describe("Should test handleUpdateWidgetDynamicProperty ", () => { + it("should update dynamicBindingPathList on js toggle and return the widget with dynamicBindingPath", () => { + const value = handleUpdateWidgetDynamicProperty(widget as any, { + isDynamic: true, + propertyPath: "isVisible", + }); + value.next(); // start + value.next(widget as any); // yield select + value.next({ + test: widget, + } as any); // yield select + value.return({ + test: { + ...widget, + dynamicPropertyPathList: [ + { + key: "isVisible", + }, + ], + }, + } as any); + expect(value.next().done).toEqual(true); + }); +}); + +describe("Should test batchUpdateWidgetDynamicPropertySaga ", () => { + it("should update dynamicBindingPathList on js toggle and return the widget with dynamicBindingPath", () => { + const value = batchUpdateWidgetDynamicPropertySaga({ + type: "test", + payload: { + updates: [ + { + isDynamic: true, + propertyPath: "isVisible", + }, + ], + widgetId: "test", + }, + }); + value.next(); // start + value.next(widget as any); // yield select + value.next({ + ...widget, + dynamicPropertyPathList: [ + { + key: "isVisible", + }, + ], + } as any); + value.next({ + test: widget, + } as any); // yield select + value.next(); //yield put + expect(updateAndSaveLayoutMock).toHaveBeenCalledWith({ + test: { + ...widget, + dynamicPropertyPathList: [ + { + key: "isVisible", + }, + ], + }, + }); + }); + it("should remove property from dynamicBindingList on js toggle off when calling batchUpdateWidgetDynamicPropertySaga", () => { + const value = batchUpdateWidgetDynamicPropertySaga({ + type: "test", + payload: { + updates: [ + { + isDynamic: false, + propertyPath: "isVisible", + }, + ], + widgetId: "test", + }, + }); + value.next(); // start + value.next(widget1 as any); // yield select + value.next({ + ...widget1, + dynamicPropertyPathList: [], + dynamicBindingPathList: [], + isVisible: 1, + } as any); + value.next({ + test: widget1, + } as any); // yield select + value.next(); //yield put + expect(updateAndSaveLayoutMock).toHaveBeenCalledWith({ + test: { + dynamicPropertyPathList: [], + dynamicBindingPathList: [], + isVisible: 1, + }, + }); + }); +}); + describe("test removeDynamicBindingList", () => { it("should remove table derived binding properties", () => { // table bindings with derived properties diff --git a/app/client/src/sagas/WidgetOperationSagas.tsx b/app/client/src/sagas/WidgetOperationSagas.tsx index 123b815d81..9089d58bf9 100644 --- a/app/client/src/sagas/WidgetOperationSagas.tsx +++ b/app/client/src/sagas/WidgetOperationSagas.tsx @@ -13,6 +13,7 @@ import { GridDefaults, MAIN_CONTAINER_WIDGET_ID, RenderModes, + WIDGET_ID_SHOW_WALKTHROUGH, } from "constants/WidgetConstants"; import log from "loglevel"; import type { WidgetResize } from "actions/pageActions"; @@ -44,6 +45,8 @@ import { import AnalyticsUtil from "utils/AnalyticsUtil"; import { convertToString } from "utils/AppsmithUtils"; import type { + BatchUpdateDynamicPropertyUpdates, + BatchUpdateWidgetDynamicPropertyPayload, DeleteWidgetPropertyPayload, SetWidgetDynamicPropertyPayload, UpdateWidgetPropertyPayload, @@ -179,6 +182,7 @@ import { FlexLayerAlignment, LayoutDirection, } from "utils/autoLayout/constants"; +import localStorage from "utils/localStorage"; export function* resizeSaga(resizeAction: ReduxAction) { try { @@ -480,22 +484,21 @@ export function removeDynamicBindingProperties( } } -export function* setWidgetDynamicPropertySaga( - action: ReduxAction, +export function* handleUpdateWidgetDynamicProperty( + widget: WidgetProps, + update: BatchUpdateDynamicPropertyUpdates, ) { const { isDynamic, propertyPath, shouldRejectDynamicBindingPathList = true, skipValidation = false, - widgetId, - } = action.payload; - const stateWidget: WidgetProps = yield select(getWidget, widgetId); - let widget = cloneDeep({ ...stateWidget }); - const propertyValue = _.get(widget, propertyPath); + } = update; + const propertyValue = _.get(widget, propertyPath); let dynamicPropertyPathList = getWidgetDynamicPropertyPathList(widget); let dynamicBindingPathList = getEntityDynamicBindingPathList(widget); + if (isDynamic) { const keyExists = dynamicPropertyPathList.findIndex((path) => path.key === propertyPath) > @@ -540,9 +543,49 @@ export function* setWidgetDynamicPropertySaga( widget = set(widget, propertyPath, parsed); } } - widget.dynamicPropertyPathList = dynamicPropertyPathList; widget.dynamicBindingPathList = dynamicBindingPathList; + return widget; +} + +export function* batchUpdateWidgetDynamicPropertySaga( + action: ReduxAction, +) { + const { updates, widgetId } = action.payload; + const stateWidget: WidgetProps = yield select(getWidget, widgetId); + let widget = cloneDeep({ ...stateWidget }); + + for (const update of updates) { + widget = yield call(handleUpdateWidgetDynamicProperty, widget, update); + } + + const stateWidgets: CanvasWidgetsReduxState = yield select(getWidgets); + const widgets = { ...stateWidgets, [widgetId]: widget }; + // Save the layout + yield put(updateAndSaveLayout(widgets)); +} + +export function* setWidgetDynamicPropertySaga( + action: ReduxAction, +) { + const { + isDynamic, + propertyPath, + shouldRejectDynamicBindingPathList = true, + skipValidation = false, + widgetId, + } = action.payload; + const stateWidget: WidgetProps = yield select(getWidget, widgetId); + let widget = cloneDeep({ ...stateWidget }); + const update = { + isDynamic, + propertyPath, + shouldRejectDynamicBindingPathList, + skipValidation, + }; + + widget = yield call(handleUpdateWidgetDynamicProperty, widget, update); + const stateWidgets: CanvasWidgetsReduxState = yield select(getWidgets); const widgets = { ...stateWidgets, [widgetId]: widget }; @@ -1976,7 +2019,11 @@ function* cutWidgetSaga() { } function* addSuggestedWidget(action: ReduxAction>) { + const isSetWidgetIdForWalkthrough = !!( + action.payload.props.setWidgetIdForWalkthrough === "true" + ); const widgetConfig = action.payload; + delete widgetConfig.props?.setWidgetIdForWalkthrough; if (!widgetConfig.type) return; @@ -2038,6 +2085,10 @@ function* addSuggestedWidget(action: ReduxAction>) { yield take(ReduxActionTypes.UPDATE_LAYOUT); + if (isSetWidgetIdForWalkthrough) { + localStorage.setItem(WIDGET_ID_SHOW_WALKTHROUGH, newWidget.newWidgetId); + } + yield put( selectWidgetInitAction(SelectionRequestType.One, [newWidget.newWidgetId]), ); @@ -2110,6 +2161,10 @@ export default function* widgetOperationSagas() { ReduxActionTypes.SET_WIDGET_DYNAMIC_PROPERTY, setWidgetDynamicPropertySaga, ), + takeEvery( + ReduxActionTypes.BATCH_SET_WIDGET_DYNAMIC_PROPERTY, + batchUpdateWidgetDynamicPropertySaga, + ), takeEvery( ReduxActionTypes.RESET_CHILDREN_WIDGET_META, resetChildrenMetaSaga, diff --git a/app/client/src/selectors/editorSelectors.tsx b/app/client/src/selectors/editorSelectors.tsx index 2b75733d34..c936780c95 100644 --- a/app/client/src/selectors/editorSelectors.tsx +++ b/app/client/src/selectors/editorSelectors.tsx @@ -9,7 +9,6 @@ import type { AppLayoutConfig, PageListReduxState, } from "reducers/entityReducers/pageListReducer"; -import type { WidgetConfigReducerState } from "reducers/entityReducers/widgetConfigReducer"; import type { WidgetCardProps, WidgetProps } from "widgets/BaseWidget"; import type { Page } from "@appsmith/constants/ReduxActionConstants"; @@ -61,6 +60,9 @@ import WidgetFactory from "utils/WidgetFactory"; import { isAirgapped } from "@appsmith/utils/airgapHelpers"; import { nestDSL } from "@shared/dsl"; import { getIsAnonymousDataPopupVisible } from "./onboardingSelectors"; +import { WDS_V2_WIDGET_MAP } from "components/wds/constants"; +import { selectFeatureFlagCheck } from "@appsmith/selectors/featureFlagsSelectors"; +import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; const getIsDraggingOrResizing = (state: AppState) => state.ui.widgetDragResize.isResizing || state.ui.widgetDragResize.isDragging; @@ -336,12 +338,29 @@ export const getCurrentPageName = createSelector( export const getWidgetCards = createSelector( getWidgetConfigs, getIsAutoLayout, - (widgetConfigs: WidgetConfigReducerState, isAutoLayout: boolean) => { + (_state) => selectFeatureFlagCheck(_state, FEATURE_FLAG.ab_wds_enabled), + (widgetConfigs, isAutoLayout, isWDSEnabled) => { const cards = Object.values(widgetConfigs.config).filter((config) => { - return isAirgapped() - ? config.widgetName !== "Map" && !config.hideCard - : !config.hideCard; + if (isAirgapped()) { + return config.widgetName !== "Map" && !config.hideCard; + } + + // if wds_vs is not enabled, hide all wds_v2 widgets + if ( + Object.values(WDS_V2_WIDGET_MAP).includes(config.type) && + isWDSEnabled === false + ) { + return false; + } + + // if wds is enabled, only show the wds_v2 widgets + if (isWDSEnabled === true) { + return Object.values(WDS_V2_WIDGET_MAP).includes(config.type); + } + + return !config.hideCard; }); + const _cards: WidgetCardProps[] = cards.map((config) => { const { detachFromLayout = false, @@ -374,6 +393,7 @@ export const getWidgetCards = createSelector( }; }); const sortedCards = sortBy(_cards, ["displayName"]); + return sortedCards; }, ); diff --git a/app/client/src/selectors/entitiesSelector.ts b/app/client/src/selectors/entitiesSelector.ts index 16af507bb7..e337b785d8 100644 --- a/app/client/src/selectors/entitiesSelector.ts +++ b/app/client/src/selectors/entitiesSelector.ts @@ -515,6 +515,24 @@ export const getJSCollectionFromName = createSelector( return currentJSCollection; }, ); +export const getJSActionFromName = createSelector( + [ + (state: AppState, jsCollectionName: string) => + getJSCollectionFromName(state, jsCollectionName), + (_state: AppState, jsCollectionName: string, functionName: string) => ({ + jsCollectionName, + functionName, + }), + ], + (JSCollectionData, { functionName }) => { + if (!JSCollectionData) return null; + const jsFunction = find( + JSCollectionData.config.actions, + (action) => action.name === functionName, + ); + return jsFunction || null; + }, +); export const getJSActionFromJSCollection = ( JSCollection: JSCollectionData, diff --git a/app/client/src/utils/AnalyticsUtil.tsx b/app/client/src/utils/AnalyticsUtil.tsx index 899d134a9a..7ba9fb532c 100644 --- a/app/client/src/utils/AnalyticsUtil.tsx +++ b/app/client/src/utils/AnalyticsUtil.tsx @@ -196,6 +196,7 @@ export type EventName = | "SIGNPOSTING_MODAL_CLOSE_CLICK" | "SIGNPOSTING_INFO_CLICK" | "SIGNPOSTING_MODAL_FIRST_TIME_OPEN" + | "SIGNPOSTING_STEP_COMPLETE" | "GS_BRANCH_MORE_MENU_OPEN" | "GIT_DISCARD_WARNING" | "GIT_DISCARD_CANCEL" diff --git a/app/client/src/utils/DSLMigration.test.ts b/app/client/src/utils/DSLMigration.test.ts index f5edb144dc..1600013633 100644 --- a/app/client/src/utils/DSLMigration.test.ts +++ b/app/client/src/utils/DSLMigration.test.ts @@ -23,6 +23,7 @@ import * as rateWidgetMigrations from "./migrations/RateWidgetMigrations"; import * as codeScannerWidgetMigrations from "./migrations/CodeScannerWidgetMigrations"; import * as migrateLabelPosition from "./migrations/MigrateLabelPosition"; import * as migrateAutoHeight from "./migrations/autoHeightMigrations"; +import * as chartMigrations from "./migrations/ChartWidget"; type Migration = { functionLookup: { @@ -791,6 +792,15 @@ const migrations: Migration[] = [ ], version: 81, }, + { + functionLookup: [ + { + moduleObj: chartMigrations, + functionName: "migrateChartWidgetLabelOrientationStaggerOption", + }, + ], + version: 82, + }, ]; const mockFnObj: Record = {}; diff --git a/app/client/src/utils/DSLMigrations.ts b/app/client/src/utils/DSLMigrations.ts index 36534ca5d3..6903f56dfe 100644 --- a/app/client/src/utils/DSLMigrations.ts +++ b/app/client/src/utils/DSLMigrations.ts @@ -88,6 +88,8 @@ import { migrateListWidgetChildrenForAutoHeight, migratePropertiesForDynamicHeight, } from "./migrations/autoHeightMigrations"; + +import { migrateChartWidgetLabelOrientationStaggerOption } from "./migrations/ChartWidget"; import { flattenDSL } from "@shared/dsl"; /** @@ -1200,6 +1202,11 @@ export const transformDSL = (currentDSL: DSLWidget, newPage = false) => { if (currentDSL.version === 81) { currentDSL = migrateSelectWidgetSourceDataBindingPathList(currentDSL); + currentDSL.version = 82; + } + + if (currentDSL.version == 82) { + currentDSL = migrateChartWidgetLabelOrientationStaggerOption(currentDSL); currentDSL.version = LATEST_PAGE_VERSION; } diff --git a/app/client/src/utils/WidgetRegistry.tsx b/app/client/src/utils/WidgetRegistry.tsx index 96766a4cd1..ae05ea1970 100644 --- a/app/client/src/utils/WidgetRegistry.tsx +++ b/app/client/src/utils/WidgetRegistry.tsx @@ -164,6 +164,10 @@ import CodeScannerWidget, { import ListWidgetV2, { CONFIG as LIST_WIDGET_CONFIG_V2, } from "widgets/ListWidgetV2"; +import { + ButtonWidget as ButtonWidgetV2, + CONFIG as BUTTON_WIDGET_CONFIG_V2, +} from "widgets/ButtonWidgetV2"; export const ALL_WIDGETS_AND_CONFIG: [any, WidgetConfiguration][] = [ [CanvasWidget, CANVAS_WIDGET_CONFIG], @@ -215,6 +219,7 @@ export const ALL_WIDGETS_AND_CONFIG: [any, WidgetConfiguration][] = [ [CategorySliderWidget, CATEGORY_SLIDER_WIDGET_CONFIG], [CodeScannerWidget, CODE_SCANNER_WIDGET_CONFIG], [ListWidgetV2, LIST_WIDGET_CONFIG_V2], + [ButtonWidgetV2, BUTTON_WIDGET_CONFIG_V2], //Deprecated Widgets [InputWidget, INPUT_WIDGET_CONFIG], diff --git a/app/client/src/utils/hooks/useFeatureFlag.ts b/app/client/src/utils/hooks/useFeatureFlag.ts new file mode 100644 index 0000000000..32a6bcd5f5 --- /dev/null +++ b/app/client/src/utils/hooks/useFeatureFlag.ts @@ -0,0 +1,11 @@ +import { useSelector } from "react-redux"; +import type { FeatureFlag } from "@appsmith/entities/FeatureFlag"; +import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors"; + +export function useFeatureFlag(flagName: FeatureFlag): boolean { + const flagValues = useSelector(selectFeatureFlags); + if (flagName in flagValues) { + return flagValues[flagName]; + } + return false; +} diff --git a/app/client/src/utils/hooks/useOnUpgrade.ts b/app/client/src/utils/hooks/useOnUpgrade.ts index f2656cd80b..b21fb021bb 100644 --- a/app/client/src/utils/hooks/useOnUpgrade.ts +++ b/app/client/src/utils/hooks/useOnUpgrade.ts @@ -4,6 +4,7 @@ import { PRICING_PAGE_URL } from "constants/ThirdPartyConstants"; import type { EventName } from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil"; import { getAppsmithConfigs } from "@appsmith/configs"; +import { pricingPageUrlSource } from "@appsmith/utils/licenseHelpers"; type Props = { logEventName?: EventName; @@ -21,7 +22,11 @@ const useOnUpgrade = (props: Props) => { logEventData, ); window.open( - PRICING_PAGE_URL(appsmithConfigs.pricingUrl, "CE", instanceId), + PRICING_PAGE_URL( + appsmithConfigs.pricingUrl, + pricingPageUrlSource, + instanceId, + ), "_blank", ); }; diff --git a/app/client/src/utils/migrations/ChartWidget.test.ts b/app/client/src/utils/migrations/ChartWidget.test.ts new file mode 100644 index 0000000000..8e5342cbad --- /dev/null +++ b/app/client/src/utils/migrations/ChartWidget.test.ts @@ -0,0 +1,46 @@ +import type { DSLWidget } from "widgets/constants"; +import { migrateChartWidgetLabelOrientationStaggerOption } from "./ChartWidget"; +import type { ChartWidgetProps } from "widgets/ChartWidget/widget"; +import { LabelOrientation } from "widgets/ChartWidget/constants"; + +const inputDSL: DSLWidget = { + widgetId: "", + widgetName: "canvas widget", + type: "CANVAS_WIDGET", + renderMode: "CANVAS", + version: 1, + parentColumnSpace: 1, + parentRowSpace: 1, + isLoading: false, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + children: [ + { + widgetId: "", + widgetName: "chart widget", + type: "CHART_WIDGET", + renderMode: "CANVAS", + version: 1, + parentColumnSpace: 1, + parentRowSpace: 1, + isLoading: false, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + labelOrientation: LabelOrientation.STAGGER, + children: [], + }, + ], +}; + +describe("Migrate Label Orientation from type stagger to auto", () => { + it("migrates label orientation from type stagger to auto", () => { + const outputDSL = migrateChartWidgetLabelOrientationStaggerOption(inputDSL); + const outputChartWidgetDSL = (outputDSL.children && + outputDSL.children[0]) as ChartWidgetProps; + expect(outputChartWidgetDSL.labelOrientation).toEqual("auto"); + }); +}); diff --git a/app/client/src/utils/migrations/ChartWidget.ts b/app/client/src/utils/migrations/ChartWidget.ts new file mode 100644 index 0000000000..6fafd0a463 --- /dev/null +++ b/app/client/src/utils/migrations/ChartWidget.ts @@ -0,0 +1,18 @@ +import type { WidgetProps } from "widgets/BaseWidget"; +import type { DSLWidget } from "widgets/constants"; +import type { ChartWidgetProps } from "widgets/ChartWidget/widget"; +import { LabelOrientation } from "widgets/ChartWidget/constants"; +import { traverseDSLAndMigrate } from "utils/WidgetMigrationUtils"; + +export const migrateChartWidgetLabelOrientationStaggerOption = ( + currentDSL: DSLWidget, +) => { + return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => { + if (widget.type == "CHART_WIDGET") { + const chartWidgetProps = widget as ChartWidgetProps; + if (chartWidgetProps.labelOrientation == LabelOrientation.STAGGER) { + chartWidgetProps.labelOrientation = LabelOrientation.AUTO; + } + } + }); +}; diff --git a/app/client/src/utils/storage.ts b/app/client/src/utils/storage.ts index 1b8220688b..f007ecd425 100644 --- a/app/client/src/utils/storage.ts +++ b/app/client/src/utils/storage.ts @@ -457,7 +457,7 @@ export const getAIPromptTriggered = async () => { return 0; } }; -export const setFeatureFlagShownStatus = async (key: string, value: any) => { +export const setFeatureWalkthroughShown = async (key: string, value: any) => { try { let flagsJSON: Record | null = await store.getItem( STORAGE_KEYS.FEATURE_WALKTHROUGH, @@ -477,7 +477,7 @@ export const setFeatureFlagShownStatus = async (key: string, value: any) => { } }; -export const getFeatureFlagShownStatus = async (key: string) => { +export const getFeatureWalkthroughShown = async (key: string) => { try { const flagsJSON: Record | null = await store.getItem( STORAGE_KEYS.FEATURE_WALKTHROUGH, diff --git a/app/client/src/utils/widgetRenderUtils.test.ts b/app/client/src/utils/widgetRenderUtils.test.ts index 28ec42779b..0737707fb7 100644 --- a/app/client/src/utils/widgetRenderUtils.test.ts +++ b/app/client/src/utils/widgetRenderUtils.test.ts @@ -41,7 +41,7 @@ describe("createCanvasWidget functionality", () => { const dataTree = { __evaluation__: { errors: { - text: [ + propertyPath: [ { errorMessage: { name: "Validation Error", @@ -64,6 +64,7 @@ describe("createCanvasWidget functionality", () => { expect(response.errors[0].message).toStrictEqual("Error Message"); expect(response.errors[0].stack).toStrictEqual("Error Message Stack"); expect(response.errors[0].type).toStrictEqual("property"); + expect(response.errors[0].path).toStrictEqual("propertyPath"); }); }); diff --git a/app/client/src/utils/widgetRenderUtils.tsx b/app/client/src/utils/widgetRenderUtils.tsx index e35444485d..985b979a27 100644 --- a/app/client/src/utils/widgetRenderUtils.tsx +++ b/app/client/src/utils/widgetRenderUtils.tsx @@ -65,19 +65,24 @@ function widgetErrorsFromStaticProps(props: Record) { string, DataTreeError[] >; - const evaluationErrors: DataTreeError[] = - Object.values(evaluationErrorMap).flat(); const widgetErrors: WidgetError[] = []; - for (const evalError of evaluationErrors) { - const widgetError: WidgetError = { - name: evalError.errorMessage.name, - message: evalError.errorMessage.message, - stack: evalError.raw, - type: "property", - }; - widgetErrors.push(widgetError); - } + Object.keys(evaluationErrorMap).forEach((propertyPath) => { + const propertyErrors = evaluationErrorMap[propertyPath]; + + propertyErrors.forEach((evalError) => { + const widgetError: WidgetError = { + name: evalError.errorMessage.name, + message: evalError.errorMessage.message, + stack: evalError.raw, + type: "property", + path: propertyPath, + }; + + widgetErrors.push(widgetError); + }); + }); + return widgetErrors; } diff --git a/app/client/src/widgets/BaseWidget.tsx b/app/client/src/widgets/BaseWidget.tsx index a7d5b777e1..67725e2e86 100644 --- a/app/client/src/widgets/BaseWidget.tsx +++ b/app/client/src/widgets/BaseWidget.tsx @@ -871,6 +871,7 @@ export const WIDGET_DISPLAY_PROPS = { }; export interface WidgetError extends Error { type: "property" | "configuration" | "other"; + path?: string; } export interface WidgetErrorProps { errors?: WidgetError[]; diff --git a/app/client/src/widgets/ButtonWidget/index.ts b/app/client/src/widgets/ButtonWidget/index.ts index 2e5593744c..740de16dd9 100644 --- a/app/client/src/widgets/ButtonWidget/index.ts +++ b/app/client/src/widgets/ButtonWidget/index.ts @@ -7,6 +7,7 @@ import { BUTTON_MIN_WIDTH } from "constants/minWidthConstants"; import { ResponsiveBehavior } from "utils/autoLayout/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { PropertyUpdates, SnipingModeProperty } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -45,6 +46,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "onClick", + propertyValue: propValueMap.run, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { defaults: { rows: 4, diff --git a/app/client/src/widgets/ButtonWidgetV2/component/Container.tsx b/app/client/src/widgets/ButtonWidgetV2/component/Container.tsx new file mode 100644 index 0000000000..a09eb4e7dc --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/component/Container.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import styled, { css } from "styled-components"; + +import type { RenderMode } from "constants/WidgetConstants"; + +const StyledContainer = styled.div` + height: 100%; + position: relative; + + ${({ maxWidth, minHeight, minWidth }) => + css` + & [data-button] { + display: flex; + width: auto; + ${minWidth ? `min-width: ${minWidth}px;` : ""} + ${minHeight ? `min-height: ${minHeight}px;` : ""} + ${maxWidth ? `max-width: ${maxWidth}px;` : ""} + } + `} + + .grecaptcha-badge { + visibility: hidden; + } +`; + +type ContainerProps = { + children?: React.ReactNode; + renderMode?: RenderMode; + showInAllModes?: boolean; + minWidth?: number; + maxWidth?: number; + minHeight?: number; +}; + +export function Container(props: ContainerProps) { + const { children, ...rest } = props; + + return {children}; +} diff --git a/app/client/src/widgets/ButtonWidgetV2/component/RecaptchaV2.tsx b/app/client/src/widgets/ButtonWidgetV2/component/RecaptchaV2.tsx new file mode 100644 index 0000000000..fab1348d9c --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/component/RecaptchaV2.tsx @@ -0,0 +1,71 @@ +import React from "react"; +import { noop } from "lodash"; +import { useRef, useState } from "react"; +import ReCAPTCHA from "react-google-recaptcha"; + +import { + GOOGLE_RECAPTCHA_KEY_ERROR, + GOOGLE_RECAPTCHA_DOMAIN_ERROR, + createMessage, +} from "@appsmith/constants/messages"; +import type { RecaptchaProps } from "./useRecaptcha"; + +export type RecaptchaV2Props = RecaptchaProps; + +export function RecaptchaV2(props: RecaptchaV2Props) { + const recaptchaRef = useRef(null); + const [isInvalidKey, setInvalidKey] = useState(false); + const handleRecaptchaLoading = (isloading: boolean) => { + props.handleRecaptchaV2Loading && props.handleRecaptchaV2Loading(isloading); + }; + const { + isLoading, + isDisabled, + recaptchaKey, + onRecaptchaSubmitSuccess, + onRecaptchaSubmitError = noop, + onPress: onClickProp, + } = props; + const onClick = () => { + if (isDisabled) return onClickProp; + if (isLoading) return onClickProp; + + if (isInvalidKey) { + // Handle incorrent google recaptcha site key + onRecaptchaSubmitError(createMessage(GOOGLE_RECAPTCHA_KEY_ERROR)); + } else { + handleRecaptchaLoading(true); + recaptchaRef?.current?.reset(); + recaptchaRef?.current + ?.executeAsync() + .then((token: any) => { + if (token) { + if (typeof onRecaptchaSubmitSuccess === "function") { + onRecaptchaSubmitSuccess(token); + } + } else { + // Handle incorrent google recaptcha site key + onRecaptchaSubmitError(createMessage(GOOGLE_RECAPTCHA_KEY_ERROR)); + } + + handleRecaptchaLoading(false); + }) + .catch(() => { + handleRecaptchaLoading(false); + // Handle error due to google recaptcha key of different domain + onRecaptchaSubmitError(createMessage(GOOGLE_RECAPTCHA_DOMAIN_ERROR)); + }); + } + }; + + const recaptcha = ( + setInvalidKey(true)} + ref={recaptchaRef} + sitekey={recaptchaKey || ""} + size="invisible" + /> + ); + + return { onClick, recaptcha }; +} diff --git a/app/client/src/widgets/ButtonWidgetV2/component/RecaptchaV3.tsx b/app/client/src/widgets/ButtonWidgetV2/component/RecaptchaV3.tsx new file mode 100644 index 0000000000..b37f11ae67 --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/component/RecaptchaV3.tsx @@ -0,0 +1,64 @@ +import { noop } from "lodash"; + +import { + GOOGLE_RECAPTCHA_KEY_ERROR, + GOOGLE_RECAPTCHA_DOMAIN_ERROR, + createMessage, +} from "@appsmith/constants/messages"; +import type { ButtonComponentProps } from "."; +import type { RecaptchaProps } from "./useRecaptcha"; +import { useScript, ScriptStatus, AddScriptTo } from "utils/hooks/useScript"; + +type RecaptchaV3Props = RecaptchaProps; + +export function RecaptchaV3(props: RecaptchaV3Props) { + const checkValidJson = (inputString: string): boolean => { + return !inputString.includes('"'); + }; + + const { + recaptchaKey, + onPress: onClickProp, + onRecaptchaSubmitSuccess, + onRecaptchaSubmitError = noop, + } = props; + + const onClick: ButtonComponentProps["onPress"] = () => { + if (props.isDisabled) return onClickProp; + if (props.isLoading) return onClickProp; + + if (status === ScriptStatus.READY) { + (window as any).grecaptcha.ready(() => { + try { + (window as any).grecaptcha + .execute(recaptchaKey, { + action: "submit", + }) + .then((token: any) => { + if (typeof onRecaptchaSubmitSuccess === "function") { + onRecaptchaSubmitSuccess(token); + } + }) + .catch(() => { + // Handle incorrent google recaptcha site key + onRecaptchaSubmitError(createMessage(GOOGLE_RECAPTCHA_KEY_ERROR)); + }); + } catch (err) { + // Handle error due to google recaptcha key of different domain + onRecaptchaSubmitError(createMessage(GOOGLE_RECAPTCHA_DOMAIN_ERROR)); + } + }); + } + }; + + let validGoogleRecaptchaKey = recaptchaKey; + if (validGoogleRecaptchaKey && !checkValidJson(validGoogleRecaptchaKey)) { + validGoogleRecaptchaKey = undefined; + } + const status = useScript( + `https://www.google.com/recaptcha/api.js?render=${validGoogleRecaptchaKey}`, + AddScriptTo.HEAD, + ); + + return { onClick }; +} diff --git a/app/client/src/widgets/ButtonWidgetV2/component/index.tsx b/app/client/src/widgets/ButtonWidgetV2/component/index.tsx new file mode 100644 index 0000000000..b81b37026d --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/component/index.tsx @@ -0,0 +1,53 @@ +import React from "react"; +import { Icon as BIcon } from "@blueprintjs/core"; +import type { IconName } from "@blueprintjs/icons"; + +import { Container } from "./Container"; +import { useRecaptcha } from "./useRecaptcha"; +import type { UseRecaptchaProps } from "./useRecaptcha"; +import type { ButtonProps } from "@design-system/widgets"; +import { Button, Icon, Tooltip } from "@design-system/widgets"; + +export type ButtonComponentProps = { + text?: string; + tooltip?: string; + minWidth?: number; + maxWidth?: number; + minHeight?: number; + isVisible?: boolean; + isLoading: boolean; + iconName?: IconName; + isDisabled?: boolean; + variant?: ButtonProps["variant"]; + color?: ButtonProps["color"]; + type: ButtonProps["type"]; + onPress?: ButtonProps["onPress"]; + iconPosition?: ButtonProps["iconPosition"]; +}; + +function ButtonComponent(props: ButtonComponentProps & UseRecaptchaProps) { + const { iconName, maxWidth, minHeight, minWidth, text, tooltip, ...rest } = + props; + const containerProps = { maxWidth, minHeight, minWidth }; + + const icon = iconName && ( + + + + ); + + const { onClick, recpatcha } = useRecaptcha(props); + + return ( + + + + + {recpatcha} + + ); +} + +export default ButtonComponent; diff --git a/app/client/src/widgets/ButtonWidgetV2/component/useRecaptcha.tsx b/app/client/src/widgets/ButtonWidgetV2/component/useRecaptcha.tsx new file mode 100644 index 0000000000..197f4c4030 --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/component/useRecaptcha.tsx @@ -0,0 +1,37 @@ +import { RecaptchaV2 } from "./RecaptchaV2"; +import { RecaptchaV3 } from "./RecaptchaV3"; +import type { ButtonComponentProps } from "."; +import type { RecaptchaType } from "components/constants"; + +export type UseRecaptchaProps = { + recaptchaKey?: string; + recaptchaType?: RecaptchaType; + onRecaptchaSubmitError?: (error: string) => void; + onRecaptchaSubmitSuccess?: (token: string) => void; + handleRecaptchaV2Loading?: (isLoading: boolean) => void; +}; + +export type RecaptchaProps = ButtonComponentProps & UseRecaptchaProps; + +type UseRecaptchaReturn = { + onClick?: (...args: any[]) => void; + recpatcha?: React.ReactElement; +}; + +export const useRecaptcha = (props: RecaptchaProps): UseRecaptchaReturn => { + const { onPress: onClickProp, recaptchaKey } = props; + + if (!recaptchaKey) { + return { onClick: onClickProp }; + } + + if (props.recaptchaType === "V2") { + return RecaptchaV2(props); + } + + if (props.recaptchaType === "V3") { + return RecaptchaV3(props); + } + + return { onClick: onClickProp }; +}; diff --git a/app/client/src/widgets/ButtonWidgetV2/icon.svg b/app/client/src/widgets/ButtonWidgetV2/icon.svg new file mode 100644 index 0000000000..9693e6f256 --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/client/src/widgets/ButtonWidgetV2/index.tsx b/app/client/src/widgets/ButtonWidgetV2/index.tsx new file mode 100644 index 0000000000..cd6dd6a9d8 --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/index.tsx @@ -0,0 +1,76 @@ +import { ButtonWidget } from "./widget"; +import IconSVG from "./icon.svg"; +import { WIDGET_TAGS } from "constants/WidgetConstants"; +import { ButtonPlacementTypes, RecaptchaTypes } from "components/constants"; +import { BUTTON_MIN_WIDTH } from "constants/minWidthConstants"; +import { ResponsiveBehavior } from "utils/autoLayout/constants"; +import { BUTTON_COLORS, BUTTON_VARIANTS } from "@design-system/widgets"; + +export const CONFIG = { + type: ButtonWidget.getWidgetType(), + name: "Button", + iconSVG: IconSVG, + needsMeta: false, + isCanvas: false, + tags: [WIDGET_TAGS.BUTTONS], + searchTags: ["click", "submit"], + features: { + dynamicHeight: { + sectionIndex: 0, + active: false, + }, + }, + defaults: { + animateLoading: true, + text: "Submit", + buttonVariant: BUTTON_VARIANTS.FILLED, + buttonColor: BUTTON_COLORS.ACCENT, + placement: ButtonPlacementTypes.CENTER, + rows: 4, + columns: 16, + widgetName: "Button", + isDisabled: false, + isVisible: true, + isDefaultClickDisabled: true, + disabledWhenInvalid: false, + resetFormOnClick: false, + recaptchaType: RecaptchaTypes.V3, + version: 1, + responsiveBehavior: ResponsiveBehavior.Hug, + minWidth: BUTTON_MIN_WIDTH, + }, + properties: { + derived: ButtonWidget.getDerivedPropertiesMap(), + default: ButtonWidget.getDefaultPropertiesMap(), + meta: ButtonWidget.getMetaPropertiesMap(), + contentConfig: ButtonWidget.getPropertyPaneContentConfig(), + styleConfig: ButtonWidget.getPropertyPaneStyleConfig(), + }, + autoLayout: { + defaults: { + rows: 4, + columns: 6.453, + }, + autoDimension: { + width: true, + }, + widgetSize: [ + { + viewportMinWidth: 0, + configuration: () => { + return { + minWidth: "120px", + maxWidth: "360px", + minHeight: "40px", + }; + }, + }, + ], + disableResizeHandles: { + horizontal: true, + vertical: true, + }, + }, +}; + +export { ButtonWidget }; diff --git a/app/client/src/widgets/ButtonWidgetV2/widget/contentConfig.tsx b/app/client/src/widgets/ButtonWidgetV2/widget/contentConfig.tsx new file mode 100644 index 0000000000..4e9f411cef --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/widget/contentConfig.tsx @@ -0,0 +1,145 @@ +import { RecaptchaTypes } from "components/constants"; +import { isAirgapped } from "@appsmith/utils/airgapHelpers"; +import { ValidationTypes } from "constants/WidgetValidation"; + +export const propertyPaneContentConfig = [ + { + sectionName: "Basic", + children: [ + { + propertyName: "text", + label: "Label", + helpText: "Sets the label of the button", + controlType: "INPUT_TEXT", + placeholderText: "Submit", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + helpText: "when the button is clicked", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + }, + ], + }, + { + sectionName: "General", + children: [ + { + helpText: "Show helper text with button on hover", + propertyName: "tooltip", + label: "Tooltip", + controlType: "INPUT_TEXT", + placeholderText: "Submits Form", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "isVisible", + label: "Visible", + helpText: "Controls the visibility of the widget", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "isDisabled", + label: "Disabled", + controlType: "SWITCH", + helpText: "Disables clicks to this widget", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + propertyName: "animateLoading", + label: "Animate loading", + controlType: "SWITCH", + helpText: "Controls the loading of the widget", + defaultValue: true, + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, + { + sectionName: "Validation", + hidden: isAirgapped, + children: [ + { + propertyName: "googleRecaptchaKey", + label: "Google reCAPTCHA key", + helpText: "Sets Google reCAPTCHA site key for the button", + controlType: "INPUT_TEXT", + placeholderText: "reCAPTCHA Key", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, + { + propertyName: "recaptchaType", + label: "Google reCAPTCHA version", + controlType: "DROP_DOWN", + helpText: "Select reCAPTCHA version", + options: [ + { + label: "reCAPTCHA v3", + value: RecaptchaTypes.V3, + }, + { + label: "reCAPTCHA v2", + value: RecaptchaTypes.V2, + }, + ], + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.TEXT, + params: { + allowedValues: [RecaptchaTypes.V3, RecaptchaTypes.V2], + default: RecaptchaTypes.V3, + }, + }, + }, + ], + }, + // TODO: refactor widgetParentProps implementation when we address #10659 + { + sectionName: "Form settings", + children: [ + { + helpText: + "Disabled if the form is invalid, if this widget exists directly within a Form widget.", + propertyName: "disabledWhenInvalid", + label: "Disabled invalid forms", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + { + helpText: + "Resets the fields of the form, on click, if this widget exists directly within a Form widget.", + propertyName: "resetFormOnClick", + label: "Reset form on success", + controlType: "SWITCH", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + }, + ], + }, +]; diff --git a/app/client/src/widgets/ButtonWidgetV2/widget/index.tsx b/app/client/src/widgets/ButtonWidgetV2/widget/index.tsx new file mode 100644 index 0000000000..819d4709c1 --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/widget/index.tsx @@ -0,0 +1,182 @@ +import React from "react"; +import { toast } from "design-system"; + +import BaseWidget from "widgets/BaseWidget"; +import ButtonComponent from "../component"; +import { propertyPaneStyleConfig } from "./styleConfig"; +import type { ButtonComponentProps } from "../component"; +import type { RecaptchaType } from "components/constants"; +import type { WidgetType } from "constants/WidgetConstants"; +import { propertyPaneContentConfig } from "./contentConfig"; +import type { DerivedPropertiesMap } from "utils/WidgetFactory"; +import type { WidgetProps, WidgetState } from "widgets/BaseWidget"; +import type { AutocompletionDefinitions } from "widgets/constants"; +import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import type { ExecutionResult } from "constants/AppsmithActionConstants/ActionConstants"; + +class ButtonWidget extends BaseWidget { + onButtonClickBound: () => void; + + constructor(props: ButtonWidgetProps) { + super(props); + this.onButtonClickBound = this.onButtonClick.bind(this); + this.onRecaptchaSubmitError = this.onRecaptchaSubmitError.bind(this); + this.onRecaptchaSubmitSuccess = this.onRecaptchaSubmitSuccess.bind(this); + this.state = { + isLoading: false, + }; + } + + static getAutocompleteDefinitions(): AutocompletionDefinitions { + return { + "!doc": + "Buttons are used to capture user intent and trigger actions based on that intent", + "!url": "https://docs.appsmith.com/widget-reference/button", + isVisible: DefaultAutocompleteDefinitions.isVisible, + text: "string", + isDisabled: "bool", + recaptchaToken: "string", + }; + } + + static getPropertyPaneContentConfig() { + return propertyPaneContentConfig; + } + + static getPropertyPaneStyleConfig() { + return propertyPaneStyleConfig; + } + + static getMetaPropertiesMap(): Record { + return { + recaptchaToken: undefined, + }; + } + + static getDerivedPropertiesMap(): DerivedPropertiesMap { + return {}; + } + + onButtonClick() { + if (this.props.onClick) { + this.setState({ isLoading: true }); + + super.executeAction({ + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + callback: this.handleActionComplete, + }, + }); + + return; + } + + if (this.props.resetFormOnClick && this.props.onReset) { + this.props.onReset(); + + return; + } + } + + hasOnClickAction = () => { + const { isDisabled, onClick, onReset, resetFormOnClick } = this.props; + + return Boolean((onClick || onReset || resetFormOnClick) && !isDisabled); + }; + + onRecaptchaSubmitSuccess(token: string) { + this.props.updateWidgetMetaProperty("recaptchaToken", token, { + triggerPropertyName: "onClick", + dynamicString: this.props.onClick, + event: { + type: EventType.ON_CLICK, + callback: this.handleActionComplete, + }, + }); + } + + onRecaptchaSubmitError = (error: string) => { + toast.show(error, { kind: "error" }); + + if (this.hasOnClickAction()) { + this.onButtonClickBound(); + } + }; + + handleRecaptchaV2Loading = (isLoading: boolean) => { + if (this.props.onClick) { + this.setState({ isLoading }); + } + }; + + handleActionComplete = (result: ExecutionResult) => { + this.setState({ + isLoading: false, + }); + + if (result.success) { + if (this.props.resetFormOnClick && this.props.onReset) + this.props.onReset(); + } + }; + + getPageView() { + const disabled = + this.props.disabledWhenInvalid && + "isFormValid" in this.props && + !this.props.isFormValid; + const isDisabled = this.props.isDisabled || disabled; + + return ( + + ); + } + + static getWidgetType(): WidgetType { + return "BUTTON_WIDGET_V2"; + } +} + +export interface ButtonWidgetProps extends WidgetProps { + text?: string; + isVisible?: boolean; + isDisabled?: boolean; + resetFormOnClick?: boolean; + googleRecaptchaKey?: string; + recaptchaType?: RecaptchaType; + disabledWhenInvalid?: boolean; + buttonType?: ButtonComponentProps["type"]; + iconName?: ButtonComponentProps["iconName"]; + buttonVariant?: ButtonComponentProps["variant"]; + iconAlign?: ButtonComponentProps["iconPosition"]; + buttonColor?: ButtonComponentProps["color"]; +} + +interface ButtonWidgetState extends WidgetState { + isLoading: boolean; +} + +export { ButtonWidget }; diff --git a/app/client/src/widgets/ButtonWidgetV2/widget/styleConfig.tsx b/app/client/src/widgets/ButtonWidgetV2/widget/styleConfig.tsx new file mode 100644 index 0000000000..104e27aaf0 --- /dev/null +++ b/app/client/src/widgets/ButtonWidgetV2/widget/styleConfig.tsx @@ -0,0 +1,96 @@ +import { capitalize } from "lodash"; +import { BUTTON_COLORS, BUTTON_VARIANTS } from "@design-system/widgets"; + +import { ValidationTypes } from "constants/WidgetValidation"; + +export const propertyPaneStyleConfig = [ + { + sectionName: "General", + children: [ + { + propertyName: "buttonVariant", + label: "Button variant", + controlType: "ICON_TABS", + fullWidth: true, + helpText: "Sets the variant of the button", + options: Object.values(BUTTON_VARIANTS).map((variant) => ({ + label: capitalize(variant), + value: variant, + })), + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.TEXT, + params: { + allowedValues: Object.values(BUTTON_VARIANTS), + default: BUTTON_VARIANTS.FILLED, + }, + }, + }, + { + propertyName: "buttonColor", + label: "Button color", + controlType: "DROP_DOWN", + fullWidth: true, + helpText: "Sets the semantic color of the button", + options: Object.values(BUTTON_COLORS).map((semantic) => ({ + label: capitalize(semantic), + value: semantic, + })), + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.TEXT, + params: { + allowedValues: Object.values(BUTTON_COLORS), + default: BUTTON_COLORS.ACCENT, + }, + }, + }, + ], + }, + { + sectionName: "Icon", + children: [ + { + propertyName: "iconName", + label: "Select icon", + helpText: "Sets the icon to be used for the button", + controlType: "ICON_SELECT", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: { + type: ValidationTypes.TEXT, + }, + }, + { + propertyName: "iconAlign", + label: "Position", + helpText: "Sets the icon alignment of the button", + controlType: "ICON_TABS", + fullWidth: false, + options: [ + { + startIcon: "skip-left-line", + value: "start", + }, + { + startIcon: "skip-right-line", + value: "end", + }, + ], + isBindProperty: false, + isTriggerProperty: false, + validation: { + type: ValidationTypes.TEXT, + params: { + allowedValues: ["start", "end"], + }, + }, + }, + ], + }, +]; diff --git a/app/client/src/widgets/ChartWidget/component/ChartErrorComponent.tsx b/app/client/src/widgets/ChartWidget/component/ChartErrorComponent.tsx new file mode 100644 index 0000000000..d8d19db781 --- /dev/null +++ b/app/client/src/widgets/ChartWidget/component/ChartErrorComponent.tsx @@ -0,0 +1,104 @@ +import React, { useState } from "react"; +import styled from "styled-components"; +import { Collapse } from "@blueprintjs/core"; +import { + Button, + Category, + Size, + Text, + TextType, +} from "@design-system/widgets-old"; +import { messages } from "../constants"; + +const ChartErrorContainer = styled.div` + height: 100%; + width: 100%; + background: var(--ads-v2-color-bg); + position: absolute; + top: 0px; + left: 0px; + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; +}`; + +const ErrorBox = styled.div` + height: 60%; + width: 80%; + display: flex; + align-items: center; + flex-flow: column; + gap: 8px; +}`; + +const ErrorStack = styled.div` + overflow-y: scroll; + text-align: center; +`; + +const MoreDetailsButton = styled(Button)` + flex-shrink: 2; + border-radius: 4px; + text-transform: none; +`; + +const Title = styled(Text)` + overflow: scroll; + font-weight: var(--ads-font-weight-bold-xl); +`; + +export interface ChartErrorProps { + error: Error; +} + +export function ChartErrorComponent(props: ChartErrorProps) { + const [bodyCollapsed, setBodyCollapsed] = useState(true); + + const errorMessage = () => { + const title = messages.ErrorTitle; + const subheading = props.error.message; + const body = props.error.stack ?? ""; + + return { + title: title, + subheading: subheading, + body: body, + }; + }; + + function toggleBody() { + setBodyCollapsed(!bodyCollapsed); + } + + const arrowIconName = () => { + if (bodyCollapsed) { + return "expand-more"; + } else { + return "expand-less"; + } + }; + + return ( + + + {errorMessage().title} + {errorMessage().subheading} + + + + {errorMessage().body} + + + + + ); +} diff --git a/app/client/src/widgets/ChartWidget/component/EChartsConfigurationBuilder.test.ts b/app/client/src/widgets/ChartWidget/component/EChartsConfigurationBuilder.test.ts new file mode 100644 index 0000000000..5e67db58ea --- /dev/null +++ b/app/client/src/widgets/ChartWidget/component/EChartsConfigurationBuilder.test.ts @@ -0,0 +1,567 @@ +import { Colors } from "constants/Colors"; +import type { ChartComponentProps } from "."; +import type { ChartData } from "../constants"; +import { LabelOrientation } from "../constants"; +import { EChartsConfigurationBuilder } from "./EChartsConfigurationBuilder"; + +describe("EChartsConfigurationBuilder", () => { + const builder = new EChartsConfigurationBuilder(); + + const dataZoomConfig = [ + { + filterMode: "filter", + bottom: "50", + start: "20", + type: "slider", + }, + ]; + + const chartData1: ChartData = { + seriesName: "series1", + data: [{ x: "x1", y: "y1" }], + color: "series1color", + }; + const chartData2: ChartData = { + seriesName: "series2", + data: [{ x: "x1", y: "y1" }], + color: "series2color", + }; + + const chartData = { seriesID1: chartData1, seriesID2: chartData2 }; + + const defaultProps: ChartComponentProps = { + allowScroll: false, + chartData: chartData, + chartName: "chart name", + chartType: "LINE_CHART", + customFusionChartConfig: { type: "type", dataSource: undefined }, + hasOnDataPointClick: false, + isVisible: true, + isLoading: false, + setAdaptiveYMin: false, + labelOrientation: LabelOrientation.AUTO, + onDataPointClick: (point) => { + point.x; + }, + widgetId: "widgetID", + xAxisName: "xaxisname", + yAxisName: "yaxisname", + borderRadius: "1", + boxShadow: "1", + primaryColor: "primarycolor", + fontFamily: "fontfamily", + dimensions: { componentWidth: 1, componentHeight: 1 }, + parentColumnSpace: 1, + parentRowSpace: 1, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + }; + const defaultExpectedConfig = { + dataZoom: [], + legend: { + align: "left", + left: "center", + orient: "horizontal", + textStyle: { fontFamily: "fontfamily" }, + padding: [5, 50], + top: "50", + type: "scroll", + }, + grid: { top: 100, bottom: 100, left: "100" }, + title: { + text: defaultProps.chartName, + left: "center", + padding: [5, 50], + textStyle: { + fontFamily: "fontfamily", + fontSize: 24, + color: Colors.THUNDER, + overflow: "truncate", + width: -99, + }, + }, + tooltip: { + trigger: "item", + }, + xAxis: { + type: "category", + axisLabel: { + rotate: "0", + fontFamily: "fontfamily", + color: Colors.DOVE_GRAY2, + }, + name: "xaxisname", + nameLocation: "middle", + nameGap: 40, + nameTextStyle: { + fontSize: 14, + fontFamily: "fontfamily", + color: Colors.DOVE_GRAY2, + }, + }, + yAxis: { + axisLabel: { + fontFamily: "fontfamily", + color: Colors.DOVE_GRAY2, + }, + name: "yaxisname", + nameLocation: "middle", + nameGap: 70, + nameTextStyle: { + fontSize: 14, + fontFamily: "fontfamily", + color: Colors.DOVE_GRAY2, + }, + }, + series: [ + { + type: "line", + name: "series1", + itemStyle: { color: "series1color" }, + label: { + show: true, + position: "top", + }, + }, + { + type: "line", + name: "series2", + itemStyle: { color: "series2color" }, + label: { + show: true, + position: "top", + }, + }, + ], + }; + + it("1. builds a right chart configuration", () => { + const output = builder.prepareEChartConfig(defaultProps, chartData); + expect(output).toEqual(defaultExpectedConfig); + }); + + describe("2. Allow scroll variations", () => { + it("2.1 data zoom property isn't present if allowScroll is false", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.allowScroll = false; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.dataZoom = []; + + const output = builder.prepareEChartConfig(props, chartData); + + expect(output).toStrictEqual(expectedConfig); + }); + + it("2.2 Data zoom property is present if allowScroll is true and chart type isn't PIE_CHART", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + props.allowScroll = true; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.dataZoom = dataZoomConfig; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.dataZoom).toStrictEqual(expectedConfig.dataZoom); + }); + + it("2.3 data zoom property isn't present if chart type is pie chart", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + props.chartType = "PIE_CHART"; + props.allowScroll = true; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.dataZoom = []; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.dataZoom).toStrictEqual(expectedConfig.dataZoom); + }); + }); + + describe("3. Title configuration variations", () => { + it("3.1 includes default title config for non PIE_CHART chart types", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "BAR_CHART"; + + const expectedConfig: any = { ...defaultExpectedConfig }; + expectedConfig.title = { + text: "chart name", + left: "center", + padding: [5, 50], + textStyle: { + fontFamily: "fontfamily", + fontSize: 24, + color: Colors.THUNDER, + overflow: "truncate", + width: -99, + }, + }; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.title).toStrictEqual(expectedConfig.title); + }); + + it("3.2 includes layout infomration for pie chart chart type", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "PIE_CHART"; + + const expectedConfig: any = { ...defaultExpectedConfig }; + expectedConfig.title = [ + { + text: "chart name", + left: "center", + padding: [5, 50], + textStyle: { + fontFamily: "fontfamily", + fontSize: 24, + color: Colors.THUNDER, + overflow: "truncate", + width: -99, + }, + }, + { + top: "25%", + left: "33.333333333333336%", + textAlign: "center", + text: "series1", + }, + { + top: "25%", + left: "66.66666666666667%", + textAlign: "center", + text: "series2", + }, + ]; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.title).toStrictEqual(expectedConfig.title); + }); + }); + + describe("4. x-axis configuration variations", () => { + it("4.1 returns appropriate config type for BAR_CHART", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "BAR_CHART"; + + const expectedConfig: any = { ...defaultExpectedConfig }; + expectedConfig.xAxis = { ...expectedConfig.xAxis }; + expectedConfig.xAxis.type = "value"; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.xAxis).toStrictEqual(expectedConfig.xAxis); + }); + + it("4.2 should configuration for label orientation SLANT", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.labelOrientation = LabelOrientation.SLANT; + + const expectedConfig: any = { ...defaultExpectedConfig }; + expectedConfig.xAxis = { ...expectedConfig.xAxis }; + expectedConfig.xAxis.axisLabel = { ...expectedConfig.xAxis.axisLabel }; + expectedConfig.xAxis.axisLabel.rotate = "45"; // slant configuration needs rotate = 45; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.xAxis).toStrictEqual(expectedConfig.xAxis); + }); + + describe("4.3 when label orientation is rotate", () => { + const labelRotatedProps = JSON.parse(JSON.stringify(defaultProps)); + labelRotatedProps.labelOrientation = LabelOrientation.ROTATE; + + const labelRotatedConfig = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + labelRotatedConfig.xAxis.axisLabel.rotate = "90"; + + it("4.3.1 returns correct configuration for label orientation ROTATE", () => { + const output = builder.prepareEChartConfig( + labelRotatedProps, + chartData, + ); + expect(output).toStrictEqual(labelRotatedConfig); + }); + + it("4.3.2 if chart height is greater or equal to 342, name gap is 12% of chart height", () => { + const props = JSON.parse(JSON.stringify(labelRotatedProps)); + props.dimensions.componentHeight = 342; + + const expectedConfig = JSON.parse(JSON.stringify(labelRotatedConfig)); + expectedConfig.xAxis.nameGap = 41.04; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output).toEqual(expectedConfig); + }); + }); + + it("4.4 returns correct configuration for label orientation AUTO", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.labelOrientation = LabelOrientation.AUTO; + + const expectedConfig: any = { ...defaultExpectedConfig }; + expectedConfig.xAxis = { ...expectedConfig.xAxis }; + expectedConfig.xAxis.axisLabel = { ...expectedConfig.xAxis.axisLabel }; + expectedConfig.xAxis.axisLabel.rotate = "0"; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.xAxis).toStrictEqual(expectedConfig.xAxis); + }); + + it("4.5 returns correct xAxis configuration for PIE_CHART", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "PIE_CHART"; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.xAxis = { + type: "category", + axisLabel: { ...defaultExpectedConfig.xAxis.axisLabel }, + show: false, + }; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.xAxis).toStrictEqual(expectedConfig.xAxis); + }); + }); + + describe("5. y axis configuration variations", () => { + it("5.1 returns appropriate y axis type for BAR_CHART", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "BAR_CHART"; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.yAxis.type = "category"; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.yAxis).toStrictEqual(expectedConfig.yAxis); + }); + + it("5.2 returns correct y axis config for adaptive y axis option", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.setAdaptiveYMin = true; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.yAxis.min = "dataMin"; // "datamin" means that the y axis is adaptive in echarts + + const output = builder.prepareEChartConfig(props, chartData); + expect(output).toStrictEqual(expectedConfig); + }); + + it("5.3 returns correct y axis configuration for chart type PIE_CHART", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "PIE_CHART"; + + const config = { + axisLabel: defaultExpectedConfig.yAxis.axisLabel, + }; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.yAxis).toStrictEqual(config); + }); + }); + + describe("6. series configuration", () => { + it("6.1 chooses the app primary color for first series if no series color is present", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + const modifiedChartData = JSON.parse(JSON.stringify(chartData)); + modifiedChartData.seriesID1.color = ""; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.series[0].itemStyle.color = "primarycolor"; + + const output = builder.prepareEChartConfig(props, modifiedChartData); + expect(output).toStrictEqual(expectedConfig); + }); + + it("6.2 doesn't choose the app primary color for second series if its series color isn't present", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + const modifiedChartData = JSON.parse(JSON.stringify(chartData)); + modifiedChartData.seriesID2.color = ""; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.series[1].itemStyle.color = ""; + + const output = builder.prepareEChartConfig(props, modifiedChartData); + expect(output).toStrictEqual(expectedConfig); + }); + + it("6.3 chooses the appropriate configuration for bar chart", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "BAR_CHART"; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + + expectedConfig.series[0].type = "bar"; + expectedConfig.series[0].label.position = "right"; + + expectedConfig.series[1].type = "bar"; + expectedConfig.series[1].label.position = "right"; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.series).toStrictEqual(expectedConfig.series); + }); + + it("6.4 chooses the appropriate configuration for line chart", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "LINE_CHART"; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.series[0].type = "line"; + expectedConfig.series[1].type = "line"; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.series).toStrictEqual(expectedConfig.series); + }); + + it("6.5 chooses the appropriate configuration for column chart", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "COLUMN_CHART"; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.series[0].type = "bar"; + expectedConfig.series[1].type = "bar"; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.series).toStrictEqual(expectedConfig.series); + }); + + it("6.6 chooses the appropriate configuration for area chart", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "AREA_CHART"; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.series[0].type = "line"; + expectedConfig.series[1].type = "line"; + expectedConfig.series[0].areaStyle = {}; + expectedConfig.series[1].areaStyle = {}; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.series).toStrictEqual(expectedConfig.series); + }); + + it("6.7 chooses the appropriate configuration for pie chart", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "PIE_CHART"; + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.series = [ + { + type: "pie", + radius: "40%", + center: ["50%", "55%"], + name: "series1", + encode: { + itemName: "Category", + tooltip: "seriesID1", + value: "seriesID1", + }, + label: { + show: true, + fontFamily: "fontfamily", + color: Colors.DOVE_GRAY2, + formatter: "{b}: {@series1} ({d}%)", + }, + }, + ]; + + const output = builder.prepareEChartConfig(props, { + seriesID1: chartData1, + }); + expect(output.series).toStrictEqual(expectedConfig.series); + }); + }); + + describe("7. grid bottom offsets", () => { + it("7.1 offset increases by 50 if bottom scroll bar is present", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.allowScroll = true; + + const output = builder.prepareEChartConfig(props, chartData); + + const expectedConfig: any = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + expectedConfig.dataZoom = dataZoomConfig; + expectedConfig.grid.bottom = 150; + + expect(output).toEqual(expectedConfig); + }); + + describe("7.2 when x axis labels are rotated", () => { + const labelRotatedProps = JSON.parse(JSON.stringify(defaultProps)); + labelRotatedProps.labelOrientation = LabelOrientation.ROTATE; + + const labelRotateExpectedConfig = JSON.parse( + JSON.stringify(defaultExpectedConfig), + ); + labelRotateExpectedConfig.xAxis.axisLabel.rotate = "90"; + + it("7.2.1 the minimum grid bottom offset is 100", () => { + const output = builder.prepareEChartConfig( + labelRotatedProps, + chartData, + ); + expect(output).toEqual(labelRotateExpectedConfig); + }); + + describe("7.2.2 20% of chart height is more than 100 px", () => { + const bigHeightChartProps = JSON.parse( + JSON.stringify(labelRotatedProps), + ); + bigHeightChartProps.dimensions.componentHeight = 505; + + it("7.2.2.1 bottom offset should be 20% of the chart height", () => { + const output = builder.prepareEChartConfig( + bigHeightChartProps, + chartData, + ); + const expectedConfig: any = JSON.parse( + JSON.stringify(labelRotateExpectedConfig), + ); + expectedConfig.grid.bottom = 101; + expect(output.grid).toEqual(expectedConfig.grid); + }); + + it("7.2.2.2 if allow scroll is true, 50px are added for allow scroll UI", () => { + const props = JSON.parse(JSON.stringify(bigHeightChartProps)); + props.allowScroll = true; + + const expectedConfig: any = JSON.parse( + JSON.stringify(labelRotateExpectedConfig), + ); + expectedConfig.grid.bottom = 151; + + const output = builder.prepareEChartConfig(props, chartData); + expect(output.grid).toEqual(expectedConfig.grid); + }); + }); + }); + }); +}); diff --git a/app/client/src/widgets/ChartWidget/component/EChartsConfigurationBuilder.ts b/app/client/src/widgets/ChartWidget/component/EChartsConfigurationBuilder.ts new file mode 100644 index 0000000000..85d6cbad47 --- /dev/null +++ b/app/client/src/widgets/ChartWidget/component/EChartsConfigurationBuilder.ts @@ -0,0 +1,313 @@ +import type { ChartComponentProps } from "."; +import type { AllChartData } from "../constants"; +import { LabelOrientation, type ChartData, XAxisCategory } from "../constants"; + +import { Colors } from "constants/Colors"; + +export class EChartsConfigurationBuilder { + fontFamily: string | undefined; + + #seriesConfigurationForPieChart(seriesID: string, seriesData: ChartData) { + const config = { + type: "pie", + radius: "40%", + center: ["50%", "55%"], + name: seriesData.seriesName ?? "null", + label: { + show: true, + fontFamily: this.fontFamily, + color: Colors.DOVE_GRAY2, + formatter: `{b}: {@${seriesData.seriesName}} ({d}%)`, + }, + encode: { + itemName: XAxisCategory, + tooltip: seriesID, + value: seriesID, + }, + }; + return config; + } + + #seriesConfigForChart( + props: ChartComponentProps, + allSeriesData: AllChartData, + ) { + /** + * { + * series: [ { type: "pie", radius: "40%", center: ["50%", 50%]}] + * } + */ + const configs: unknown[] = []; + + Object.keys(allSeriesData).forEach((seriesID, index) => { + const seriesData = allSeriesData[seriesID]; + let color = seriesData.color; + + if (index == 0 && (!color || color.length == 0)) { + color = props.primaryColor; + } + + let config: Record = { + label: { show: true, position: "top" }, + name: seriesData.seriesName ?? "", + itemStyle: { color: color }, + }; + + switch (props.chartType) { + case "BAR_CHART": + config = { ...config, type: "bar" }; + + // The series label should be on the right for bar chart + (config.label as Record).position = "right"; + break; + case "COLUMN_CHART": + config = { ...config, type: "bar" }; + break; + case "LINE_CHART": + config = { ...config, type: "line" }; + break; + case "AREA_CHART": + config = { + ...config, + type: "line", + areaStyle: {}, + }; + break; + case "PIE_CHART": + config = this.#seriesConfigurationForPieChart(seriesID, seriesData); + break; + } + + configs.push(config); + }); + return configs; + } + + #evaluateFontFamily(fontFamily: string | undefined) { + return fontFamily === "System Default" ? "inherit" : fontFamily; + } + + #titleConfigForPiechart(allSeriesData: AllChartData) { + const config: Record[] = []; + const numSeries = Object.keys(allSeriesData).length; + const interval = 100 / (numSeries + 1); + + Object.values(allSeriesData).forEach((seriesData, index) => { + const offset = `${(index + 1) * interval}%`; + config.push({ + top: "25%", + left: offset, + textAlign: "center", + text: seriesData.seriesName ?? "", + }); + }); + return config; + } + + #titleConfigForChart( + props: ChartComponentProps, + allSeriesData: AllChartData, + ) { + /** + * title: [ + * { + * text: "chart title", + * }, + * // Valid for PIE Chart only + * { + * + * text: "2014", + * top: "15%", + * left: "50%", + * textAlign: "center" + * } + * ] + */ + const defaultTitleConfig = { + text: props.chartName, + padding: [5, 50], + left: "center", + textStyle: { + fontFamily: this.fontFamily, + fontSize: 24, + color: Colors.THUNDER, + overflow: "truncate", + width: props.dimensions.componentWidth - 100, + }, + }; + + if (props.chartType == "PIE_CHART") { + return [ + defaultTitleConfig, + ...this.#titleConfigForPiechart(allSeriesData), + ]; + } else { + return defaultTitleConfig; + } + } + + #configForLabelOrientation(props: ChartComponentProps) { + const config: Record = { + fontFamily: this.fontFamily, + color: Colors.DOVE_GRAY2, + }; + if (props.labelOrientation == "slant") { + config.rotate = "45"; + } else if (props.labelOrientation == "rotate") { + config.rotate = "90"; + } else { + config.rotate = "0"; + } + return config; + } + + #gridBottomOffset(props: ChartComponentProps) { + let offset = 100; + if (props.labelOrientation == LabelOrientation.ROTATE) { + const offsetPercentage = 0.2 * props.dimensions.componentHeight; + if (offsetPercentage > offset) { + offset = offsetPercentage; + } + } + + if (props.allowScroll) { + offset += 50; + } + + return offset; + } + + #defaultEChartConfig = ( + props: ChartComponentProps, + ): Record => { + const config: Record = { + legend: { + type: "scroll", + left: "center", + align: "left", + top: "50", + orient: "horizontal", + textStyle: { fontFamily: this.fontFamily }, + padding: [5, 50], + }, + + tooltip: { + trigger: "item", + }, + }; + config.grid = { + top: 100, + bottom: this.#gridBottomOffset(props), + left: "100", + }; + return config; + }; + + #yAxisConfig = (props: ChartComponentProps) => { + /** + * { + * type: "value", name: "Y Axis Name", nameLocation: "end" + * } + */ + let config: Record = {}; + if (props.chartType != "PIE_CHART") { + config = { + name: props.yAxisName, + nameLocation: "middle", + nameGap: 70, + nameTextStyle: { + fontSize: 14, + fontFamily: this.fontFamily, + color: Colors.DOVE_GRAY2, + }, + }; + } + if (props.chartType == "BAR_CHART") { + config.type = "category"; + } + if (props.setAdaptiveYMin) { + config.min = "dataMin"; + } + config.axisLabel = { + fontFamily: this.fontFamily, + color: Colors.DOVE_GRAY2, + }; + return config; + }; + + #nameGapForXAxisLabel = (props: ChartComponentProps) => { + let gap = 40; + + if (props.labelOrientation == LabelOrientation.ROTATE) { + const percentageGap = 0.12 * props.dimensions.componentHeight; + if (percentageGap > gap) { + gap = percentageGap; + } + } + + return gap; + }; + + #xAxisConfig = (props: ChartComponentProps) => { + /** + * { + * type: "value", name: "X Axis Name", nameLocation: "end" + * } + */ + const config: Record = {}; + let type = "category"; + if (props.chartType == "BAR_CHART") { + type = "value"; + } + config.type = type; + config.axisLabel = this.#configForLabelOrientation(props); + + if (props.chartType == "BAR_CHART" && props.setAdaptiveYMin) { + config.min = "dataMin"; + } + + if (props.chartType != "PIE_CHART") { + config.name = props.xAxisName; + config.nameLocation = "middle"; + config.nameGap = this.#nameGapForXAxisLabel(props); + config.nameTextStyle = { + fontSize: 14, + fontFamily: this.fontFamily, + color: Colors.DOVE_GRAY2, + }; + } else { + config.show = false; + } + return config; + }; + + #scrollConfig = (props: ChartComponentProps) => { + if (props.allowScroll) { + if (props.chartType != "PIE_CHART") { + return [ + { + type: "slider", + filterMode: "filter", + start: "20", + bottom: "50", + }, + ]; + } + } + return []; + }; + + prepareEChartConfig(props: ChartComponentProps, allSeriesData: AllChartData) { + this.fontFamily = this.#evaluateFontFamily(props.fontFamily); + + const chartConfig: Record = + this.#defaultEChartConfig(props); + chartConfig.title = this.#titleConfigForChart(props, allSeriesData); + chartConfig.xAxis = this.#xAxisConfig(props); + chartConfig.yAxis = this.#yAxisConfig(props); + + chartConfig.dataZoom = this.#scrollConfig(props); + chartConfig.series = this.#seriesConfigForChart(props, allSeriesData); + return chartConfig; + } +} diff --git a/app/client/src/widgets/ChartWidget/component/EChartsDatasetBuilder.test.ts b/app/client/src/widgets/ChartWidget/component/EChartsDatasetBuilder.test.ts new file mode 100644 index 0000000000..0a52bce566 --- /dev/null +++ b/app/client/src/widgets/ChartWidget/component/EChartsDatasetBuilder.test.ts @@ -0,0 +1,102 @@ +import { EChartsDatasetBuilder } from "./EChartsDatasetBuilder"; +import type { ChartData } from "../constants"; +import { LabelOrientation } from "../constants"; +import type { ChartComponentProps } from "."; + +describe("EChartsConfigurationBuilder", () => { + describe("get chart data", () => { + const chartData1: ChartData = { + seriesName: "series1", + data: [{ x: "x1", y: "y1" }], + color: "series1color", + }; + const chartData2: ChartData = { + seriesName: "series2", + data: [{ x: "Product1", y: "y2" }], + color: "series2color", + }; + + const chartData = { seriesID1: chartData1, seriesID2: chartData2 }; + const defaultProps: ChartComponentProps = { + allowScroll: true, + chartData: chartData, + chartName: "chart name", + chartType: "AREA_CHART", + customFusionChartConfig: { type: "type", dataSource: undefined }, + hasOnDataPointClick: true, + isVisible: true, + isLoading: false, + setAdaptiveYMin: false, + labelOrientation: LabelOrientation.AUTO, + onDataPointClick: (point) => { + return point; + }, + widgetId: "widgetID", + xAxisName: "xaxisname", + yAxisName: "yaxisname", + borderRadius: "1", + boxShadow: "1", + primaryColor: "primarycolor", + fontFamily: "fontfamily", + dimensions: { componentWidth: 11, componentHeight: 11 }, + parentColumnSpace: 1, + parentRowSpace: 1, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + }; + + it("1. returns all series data if chart type is not pie", () => { + const output = EChartsDatasetBuilder.chartData(defaultProps); + expect(output).toEqual(chartData); + }); + + it("2. returns only the first series data if chart type is pie", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "PIE_CHART"; + const output = EChartsDatasetBuilder.chartData(props); + const expectedOutput = { + seriesID1: chartData1, + }; + expect(output).toEqual(expectedOutput); + }); + }); + + describe("datasetFromData", () => { + it("builds the right chart data source from chart widget props", () => { + const chartData1: ChartData = { + seriesName: "series1", + data: [{ x: "x1", y: "y1" }], + color: "series1color", + }; + const chartData2: ChartData = { + seriesName: "series2", + data: [{ x: "Product1", y: "y2" }], + color: "series2color", + }; + + const chartData3: ChartData = { + seriesName: "series3", + data: [{ x: "x1", y: "y3" }], + color: "series2color", + }; + + const chartData = { + seriesID1: chartData1, + seriesID2: chartData2, + seriesID3: chartData3, + }; + const chartDataSource = EChartsDatasetBuilder.datasetFromData(chartData); + + const expectedChartDataSource = { + source: [ + ["Category", "seriesID1", "seriesID2", "seriesID3"], + ["x1", "y1", "", "y3"], + ["Product1", "", "y2", ""], + ], + }; + expect(chartDataSource).toEqual(expectedChartDataSource); + }); + }); +}); diff --git a/app/client/src/widgets/ChartWidget/component/EChartsDatasetBuilder.ts b/app/client/src/widgets/ChartWidget/component/EChartsDatasetBuilder.ts new file mode 100644 index 0000000000..615f5aae4a --- /dev/null +++ b/app/client/src/widgets/ChartWidget/component/EChartsDatasetBuilder.ts @@ -0,0 +1,59 @@ +import type { ChartComponentProps } from "."; +import type { AllChartData } from "../constants"; +import { XAxisCategory } from "../constants"; + +export class EChartsDatasetBuilder { + static chartData(props: ChartComponentProps): AllChartData { + if (props.chartType == "PIE_CHART") { + const firstKey = Object.keys(props.chartData)[0]; + return { [firstKey]: props.chartData[firstKey] }; + } else { + return props.chartData; + } + } + + static datasetFromData(allSeriesData: AllChartData) { + // ["Category", "seriesID1", "seriesID2"] + const dimensions: string[] = [XAxisCategory]; + + // { Product1 : { "series1" : yValue1 }, "series2" : yValue2 } + const categories: Record> = {}; + + Object.keys(allSeriesData).forEach((seriesID) => { + dimensions.push(seriesID); + + const seriesData = allSeriesData[seriesID]; + const datapoints = seriesData.data; + + for (const datapoint of datapoints) { + const categoryName = datapoint.x; + const value = datapoint.y; + + if (!categories[categoryName]) { + categories[categoryName] = {}; + } + categories[categoryName][seriesID] = value; + } + }); + + const chartDatasource: unknown[] = [dimensions]; + + Object.keys(categories).forEach((categoryName) => { + const values = categories[categoryName]; + + const categoryDatapoints: unknown[] = []; + categoryDatapoints.push(categoryName); + + for (let i = 1; i < dimensions.length; i++) { + if (values.hasOwnProperty(dimensions[i])) { + categoryDatapoints.push(values[dimensions[i]]); + } else { + // datapoint doesn't exist for this category and series, so push empty value + categoryDatapoints.push(""); + } + } + chartDatasource.push(categoryDatapoints); + }); + return { source: chartDatasource }; + } +} diff --git a/app/client/src/widgets/ChartWidget/component/EmptyChartData.tsx b/app/client/src/widgets/ChartWidget/component/EmptyChartData.tsx new file mode 100644 index 0000000000..0e23a40561 --- /dev/null +++ b/app/client/src/widgets/ChartWidget/component/EmptyChartData.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import styled from "styled-components"; +import { messages } from "../constants"; + +const Container = styled.div` + height: 100%; + width: 100%; + background: var(--ads-v2-color-bg); + position: absolute; + top: 0px; + left: 0px; + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; +}`; + +export function EmptyChartData() { + return ( + +

{messages.EmptyData}

+
+ ); +} diff --git a/app/client/src/widgets/ChartWidget/component/index.test.tsx b/app/client/src/widgets/ChartWidget/component/index.test.tsx new file mode 100644 index 0000000000..44508d49ad --- /dev/null +++ b/app/client/src/widgets/ChartWidget/component/index.test.tsx @@ -0,0 +1,114 @@ +import ChartComponent from "."; +import type { ChartComponentProps } from "."; +import type { ChartData } from "../constants"; +import { LabelOrientation } from "../constants"; + +import React from "react"; + +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import userEvent from "@testing-library/user-event"; +import { screen } from "@testing-library/react"; + +let container: any; + +describe("Chart Widget", () => { + const seriesData1: ChartData = { + seriesName: "series1", + data: [{ x: "x1", y: 1000 }], + color: "series1color", + }; + const seriesData2: ChartData = { + seriesName: "series2", + data: [{ x: "x1", y: 2000 }], + color: "series2color", + }; + const defaultProps: ChartComponentProps = { + allowScroll: true, + chartData: { + seriesID1: seriesData1, + seriesID2: seriesData2, + }, + chartName: "chart name", + chartType: "AREA_CHART", + customFusionChartConfig: { type: "type", dataSource: undefined }, + hasOnDataPointClick: true, + isVisible: true, + isLoading: false, + setAdaptiveYMin: false, + labelOrientation: LabelOrientation.AUTO, + onDataPointClick: (point) => { + return point; + }, + widgetId: "widgetID", + xAxisName: "xaxisname", + yAxisName: "yaxisname", + borderRadius: "1", + boxShadow: "1", + primaryColor: "primarycolor", + fontFamily: "fontfamily", + dimensions: { componentWidth: 11, componentHeight: 11 }, + parentColumnSpace: 1, + parentRowSpace: 1, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + }; + + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + afterEach(() => { + document.body.removeChild(container); + container = null; + }); + + it("1. renders the correct library for chart type", async () => { + const { container, getByText, rerender } = render( + , + ); + + const xAxisLabel = getByText("xaxisname"); + expect(xAxisLabel).toBeInTheDocument(); + + let echartsContainer = container.querySelector("#widgetIDechart-container"); + expect(echartsContainer).toBeInTheDocument(); + + let fusionContainer = container.querySelector( + "#widgetIDcustom-fusion-chart-container", + ); + expect(fusionContainer).not.toBeInTheDocument(); + + const props = { ...defaultProps }; + props.chartType = "CUSTOM_FUSION_CHART"; + + rerender(); + + echartsContainer = container.querySelector("#widgetIDechart-container"); + expect(echartsContainer).not.toBeInTheDocument(); + + fusionContainer = container.querySelector( + "#widgetIDcustom-fusion-chart-container", + ); + expect(fusionContainer).toBeInTheDocument(); + }); + + it("2. adds a click event when user adds a click callback", async () => { + const mockCallback = jest.fn(); + const props = { ...defaultProps }; + props.onDataPointClick = (point) => { + point; + mockCallback(); + }; + + render(); + + expect(mockCallback.mock.calls.length).toEqual(0); + const el = await screen.findByText("1000"); + userEvent.click(el); + expect(mockCallback.mock.calls.length).toEqual(1); + }); +}); diff --git a/app/client/src/widgets/ChartWidget/component/index.tsx b/app/client/src/widgets/ChartWidget/component/index.tsx index adc7461463..c79bcf742d 100644 --- a/app/client/src/widgets/ChartWidget/component/index.tsx +++ b/app/client/src/widgets/ChartWidget/component/index.tsx @@ -1,24 +1,23 @@ import { get } from "lodash"; -import equal from "fast-deep-equal/es6"; import React from "react"; import styled from "styled-components"; - +import * as echarts from "echarts"; import { invisible } from "constants/DefaultTheme"; import { getAppsmithConfigs } from "@appsmith/configs"; import type { - ChartDataPoint, ChartType, CustomFusionChartConfig, AllChartData, ChartSelectedDataPoint, -} from "../constants"; -import { LabelOrientation, - LABEL_ORIENTATION_COMPATIBLE_CHARTS, } from "../constants"; -import { getSeriesChartData } from "./utils"; + import log from "loglevel"; -import { Colors } from "constants/Colors"; +import equal from "fast-deep-equal/es6"; +import type { WidgetPositionProps } from "widgets/BaseWidget"; +import { ChartErrorComponent } from "./ChartErrorComponent"; +import { EChartsConfigurationBuilder } from "./EChartsConfigurationBuilder"; +import { EChartsDatasetBuilder } from "./EChartsDatasetBuilder"; // Leaving this require here. Ref: https://stackoverflow.com/questions/41292559/could-not-find-a-declaration-file-for-module-module-name-path-to-module-nam/42505940#42505940 // FusionCharts comes with its own typings so there is no need to separately import them. But an import from fusioncharts/core still requires a declaration file. const FusionCharts = require("fusioncharts"); @@ -50,7 +49,11 @@ FusionCharts.options.license({ creditLabel: false, }); -export interface ChartComponentProps { +export interface ChartComponentState { + eChartsError: Error | undefined; + chartType: ChartType; +} +export interface ChartComponentProps extends WidgetPositionProps { allowScroll: boolean; chartData: AllChartData; chartName: string; @@ -69,8 +72,18 @@ export interface ChartComponentProps { boxShadow?: string; primaryColor?: string; fontFamily?: string; + dimensions: { + componentWidth: number; + componentHeight: number; + }; } +const ChartsContainer = styled.div` + position: relative; + height: 100%; + width: 100%; +`; + const CanvasContainer = styled.div< Omit >` @@ -79,291 +92,242 @@ const CanvasContainer = styled.div< height: 100%; width: 100%; - background: ${Colors.WHITE}; + background: var(--ads-v2-color-bg); overflow: hidden; position: relative; ${(props) => (!props.isVisible ? invisible : "")}; padding: 10px 0 0 0; }`; -export const isLabelOrientationApplicableFor = (chartType: string) => - LABEL_ORIENTATION_COMPATIBLE_CHARTS.includes(chartType); +class ChartComponent extends React.Component< + ChartComponentProps, + ChartComponentState +> { + fusionChartsInstance: any = null; + echartsInstance: echarts.ECharts | undefined; -class ChartComponent extends React.Component { - chartInstance = new FusionCharts(); + customFusionChartContainerId = + this.props.widgetId + "custom-fusion-chart-container"; + eChartsContainerId = this.props.widgetId + "echart-container"; + eChartsHTMLContainer: HTMLElement | null = null; - chartContainerId = this.props.widgetId + "chart-container"; + eChartsData: AllChartData = {}; + echartsConfigurationBuilder: EChartsConfigurationBuilder; - getChartType = () => { - const { allowScroll, chartData, chartType } = this.props; - const dataLength = Object.keys(chartData).length; - const isMSChart = dataLength > 1; - switch (chartType) { - case "PIE_CHART": - return "pie2d"; - case "LINE_CHART": - return allowScroll ? "scrollline2d" : isMSChart ? "msline" : "line"; - case "BAR_CHART": - return allowScroll ? "scrollBar2D" : isMSChart ? "msbar2d" : "bar2d"; - case "AREA_CHART": - return allowScroll ? "scrollarea2d" : isMSChart ? "msarea" : "area2d"; - case "COLUMN_CHART": - return allowScroll - ? "scrollColumn2D" - : isMSChart - ? "mscolumn2d" - : "column2d"; - default: - return allowScroll ? "scrollColumn2D" : "mscolumn2d"; - } + echartConfiguration: Record = {}; + + constructor(props: ChartComponentProps) { + super(props); + this.echartsConfigurationBuilder = new EChartsConfigurationBuilder(); + + this.state = { + eChartsError: undefined, + chartType: this.props.chartType, + }; + } + + getEChartsOptions = () => { + const options = { + ...this.echartsConfigurationBuilder.prepareEChartConfig( + this.props, + this.eChartsData, + ), + dataset: { + ...EChartsDatasetBuilder.datasetFromData(this.eChartsData), + }, + }; + return options; }; - getChartData = () => { - const chartData: AllChartData = this.props.chartData; - const dataLength = Object.keys(chartData).length; - const chartType = this.props.chartType; + dataClickCallback = (params: echarts.ECElementEvent) => { + const eventData: unknown[] = params.data as unknown[]; + const x: unknown = eventData[0]; - // if datalength is zero, just pass a empty datum - if (dataLength === 0) { - return [ - { - label: "", - value: "", - }, - ]; - } + const index = (params.seriesIndex ?? 0) + 1; + const y: unknown = eventData[index]; - const firstKey = Object.keys(chartData)[0] as string; - let data = get(chartData, `${firstKey}.data`, []) as ChartDataPoint[]; - const color = chartData[firstKey] && chartData[firstKey].color; + const seriesName = + params.seriesName && params.seriesName?.length > 0 + ? params.seriesName + : "null"; - if (!Array.isArray(data)) { - data = []; - } - - if (data.length === 0) { - return [ - { - label: "", - value: "", - }, - ]; - } - - return data.map((item) => { - return { - label: item.x, - value: item.y, - color: - chartType === "PIE_CHART" - ? "" - : color - ? color - : this.props.primaryColor, - }; + this.props.onDataPointClick({ + x: x, + y: y, + seriesTitle: seriesName, }); }; - getChartCategoriesMultiSeries = (chartData: AllChartData) => { - const categories: string[] = []; + initializeEchartsInstance = () => { + this.eChartsHTMLContainer = document.getElementById( + this.eChartsContainerId, + ); + if (!this.eChartsHTMLContainer) { + return; + } - Object.keys(chartData).forEach((key: string) => { - let data = get(chartData, `${key}.data`, []) as ChartDataPoint[]; + if (!this.echartsInstance || this.echartsInstance.isDisposed()) { + this.echartsInstance = echarts.init( + this.eChartsHTMLContainer, + undefined, + { + renderer: "svg", + }, + ); + } + }; - if (!Array.isArray(data)) { - data = []; + resizeEchartsIfNeeded = () => { + if (this.echartsInstance) { + if ( + this.echartsInstance.getHeight() != + this.props.dimensions.componentHeight || + this.echartsInstance.getWidth() != this.props.dimensions.componentWidth + ) { + this.echartsInstance.resize({ + width: this.props.dimensions.componentWidth, + height: this.props.dimensions.componentHeight, + }); } + } + }; - for (let dataIndex = 0; dataIndex < data.length; dataIndex++) { - const category = data[dataIndex].x; - if (!categories.includes(category)) { - categories.push(category); + renderECharts = () => { + this.initializeEchartsInstance(); + + if (!this.echartsInstance) { + return; + } + + const newConfiguration = this.getEChartsOptions(); + let needsNewConfig = true; + + if ( + this.state.eChartsError && + equal(newConfiguration, this.echartConfiguration) + ) { + // this check is required if chartError is present and the code shouldn't calculate the same error again + needsNewConfig = false; + } else { + this.echartConfiguration = newConfiguration; + } + + try { + this.echartsInstance.off("click"); + this.echartsInstance.on("click", this.dataClickCallback); + + if (needsNewConfig) { + this.echartsInstance.setOption(this.echartConfiguration, true); + if (this.state.eChartsError) { + this.setState({ eChartsError: undefined }); } } - }); - return categories; - }; - - getChartCategories = (chartData: AllChartData) => { - const categories: string[] = this.getChartCategoriesMultiSeries(chartData); - - if (categories.length === 0) { - return [ - { - label: "", - }, - ]; - } - return categories.map((item) => { - return { - label: item, - }; - }); - }; - - /** - * creates dataset need by fusion chart from widget object-data - * - * @param chartData - * @returns - */ - getChartDataset = (chartData: AllChartData) => { - const categories: string[] = this.getChartCategoriesMultiSeries(chartData); - - const dataset = Object.keys(chartData).map((key: string, index) => { - const item = get(chartData, `${key}`); - - const seriesChartData: Array> = - getSeriesChartData(get(item, "data", []), categories); - return { - seriesName: item.seriesName, - color: item.color - ? item.color - : index === 0 - ? this.props.primaryColor - : "", - data: seriesChartData, - }; - }); - - return dataset; - }; - - getLabelOrientationConfig = () => { - switch (this.props.labelOrientation) { - case LabelOrientation.AUTO: - return {}; - case LabelOrientation.ROTATE: - return { - labelDisplay: "rotate", - slantLabel: "0", - }; - case LabelOrientation.SLANT: - return { - labelDisplay: "rotate", - slantLabel: "1", - }; - case LabelOrientation.STAGGER: - return { - labelDisplay: "stagger", - }; - default: { - return {}; - } + this.resizeEchartsIfNeeded(); + } catch (error) { + this.disposeECharts(); + this.setState({ eChartsError: error as Error }); } }; - getChartConfig = () => { - const isSingleSeriesData = this.getDatalength() === 1 ? true : false; - const paletteColorConfig = isSingleSeriesData && - this.props.chartType !== "PIE_CHART" && { - palettecolors: [this.props.primaryColor], - }; - - const fontFamily = - this.props.fontFamily === "System Default" - ? "inherit" - : this.props.fontFamily; - - const canvasPadding = - this.props.chartType === "LINE_CHART" - ? { - canvasLeftPadding: "5", - canvasTopPadding: "0", - canvasRightPadding: "5", - canvasBottomPadding: "0", - } - : { - canvasPadding: "0", - }; - - let config = { - caption: this.props.chartName, - xAxisName: this.props.xAxisName, - yAxisName: this.props.yAxisName, - theme: "fusion", - alignCaptionWithCanvas: 1, - - // Caption styling ======================= - captionFontSize: "24", - captionAlignment: "center", - captionPadding: "20", - captionFontColor: Colors.THUNDER, - - // legend position styling ========== - legendIconSides: "4", - legendIconBgAlpha: "100", - legendIconAlpha: "100", - legendItemFont: fontFamily, - legendPosition: "top", - valueFont: fontFamily, - - // Canvas styles ======== - ...canvasPadding, - - // Chart styling ======= - chartLeftMargin: "20", - chartTopMargin: "10", - chartRightMargin: "40", - chartBottomMargin: "10", - - // Axis name styling ====== - xAxisNameFontSize: "14", - labelFontSize: "12", - labelFontColor: Colors.DOVE_GRAY2, - xAxisNameFontColor: Colors.DOVE_GRAY2, - - yAxisNameFontSize: "14", - yAxisValueFontSize: "12", - yAxisValueFontColor: Colors.DOVE_GRAY2, - yAxisNameFontColor: Colors.DOVE_GRAY2, - - // Base configurations ====== - baseFont: fontFamily, - ...paletteColorConfig, - bgColor: Colors.WHITE, - setAdaptiveYMin: this.props.setAdaptiveYMin ? "1" : "0", - }; - - if (isLabelOrientationApplicableFor(this.props.chartType)) { - config = { - ...config, - ...this.getLabelOrientationConfig(), - }; - } - - return config; + disposeECharts = () => { + this.echartsInstance?.dispose(); }; - getDatalength = () => { - return Object.keys(this.props.chartData).length; - }; + componentDidMount() { + this.eChartsData = EChartsDatasetBuilder.chartData(this.props); + this.renderChartingLibrary(); + } - getChartDataSource = () => { - const dataLength = this.getDatalength(); + componentWillUnmount() { + this.disposeECharts(); + this.disposeFusionCharts(); + } - if (dataLength <= 1 || this.props.chartType === "PIE_CHART") { - return { - chart: this.getChartConfig(), - data: this.getChartData(), - }; + renderChartingLibrary() { + if (this.state.chartType === "CUSTOM_FUSION_CHART") { + this.disposeECharts(); + this.renderFusionCharts(); } else { - return { - chart: this.getChartConfig(), - categories: [ - { - category: this.getChartCategories(this.props.chartData), - }, - ], - dataset: this.getChartDataset(this.props.chartData), - }; + this.disposeFusionCharts(); + this.initializeEchartsInstance(); + this.renderECharts(); + } + } + + componentDidUpdate() { + if ( + this.props.chartType == "CUSTOM_FUSION_CHART" && + this.state.chartType != "CUSTOM_FUSION_CHART" + ) { + this.setState({ + eChartsError: undefined, + chartType: "CUSTOM_FUSION_CHART", + }); + } else if ( + this.props.chartType != "CUSTOM_FUSION_CHART" && + this.state.chartType === "CUSTOM_FUSION_CHART" + ) { + // User has selected one of the ECharts option + this.setState({ chartType: "AREA_CHART" }); + } else { + this.eChartsData = EChartsDatasetBuilder.chartData(this.props); + this.renderChartingLibrary(); + } + } + + disposeFusionCharts = () => { + this.fusionChartsInstance = null; + }; + + renderFusionCharts = () => { + if (this.fusionChartsInstance) { + const { dataSource, type } = this.getCustomFusionChartDataSource(); + this.fusionChartsInstance.chartType(type); + this.fusionChartsInstance.setChartData(dataSource); + } else { + const config = this.customFusionChartConfig(); + this.fusionChartsInstance = new FusionCharts(config); + + FusionCharts.ready(() => { + /* Component could be unmounted before FusionCharts is ready, + this check ensure we don't render on unmounted component */ + if (this.fusionChartsInstance) { + try { + this.fusionChartsInstance.render(); + } catch (e) { + log.error(e); + } + } + }); } }; + customFusionChartConfig() { + const chartConfig = { + renderAt: this.customFusionChartContainerId, + width: "100%", + height: "100%", + events: { + dataPlotClick: (evt: any) => { + const data = evt.data; + const seriesTitle = get(data, "datasetName", ""); + this.props.onDataPointClick({ + x: data.categoryLabel, + y: data.dataValue, + seriesTitle, + }); + }, + }, + ...this.getCustomFusionChartDataSource(), + }; + return chartConfig; + } + getCustomFusionChartDataSource = () => { // in case of evaluation error, customFusionChartConfig can be undefined let config = this.props.customFusionChartConfig as CustomFusionChartConfig; + if (config && config.dataSource) { config = { ...config, @@ -380,134 +344,6 @@ class ChartComponent extends React.Component { return config || {}; }; - getScrollChartDataSource = () => { - const chartConfig = this.getChartConfig(); - - return { - chart: { - ...chartConfig, - scrollheight: "10", - showvalues: "1", - numVisiblePlot: "5", - flatScrollBars: "1", - }, - categories: [ - { - category: this.getChartCategories(this.props.chartData), - }, - ], - data: this.getChartData(), - dataset: this.getChartDataset(this.props.chartData), - }; - }; - - // return series title name for in clicked data point - getSeriesTitle = (data: any) => { - const dataLength = this.getDatalength(); - // if pie chart or other chart have single dataset, - // get seriesName from chartData - if ( - (dataLength <= 1 || this.props.chartType === "PIE_CHART") && - this.props.chartType !== "CUSTOM_FUSION_CHART" - ) { - const chartData: AllChartData = this.props.chartData; - const firstKey = Object.keys(chartData)[0] as string; - return get(chartData, `${firstKey}.seriesName`, ""); - } - // other charts return datasetName from clicked data point - return get(data, "datasetName", ""); - }; - - createGraph = () => { - if (this.props.chartType === "CUSTOM_FUSION_CHART") { - const chartConfig = { - renderAt: this.chartContainerId, - width: "100%", - height: "100%", - events: { - dataPlotClick: (evt: any) => { - const data = evt.data; - const seriesTitle = this.getSeriesTitle(data); - this.props.onDataPointClick({ - x: data.categoryLabel, - y: data.dataValue, - seriesTitle, - }); - }, - }, - ...this.getCustomFusionChartDataSource(), - }; - this.chartInstance = new FusionCharts(chartConfig); - return; - } - const dataSource = - this.props.allowScroll && this.props.chartType !== "PIE_CHART" - ? this.getScrollChartDataSource() - : this.getChartDataSource(); - - const chartConfig = { - type: this.getChartType(), - renderAt: this.chartContainerId, - width: "100%", - height: "100%", - dataFormat: "json", - dataSource: dataSource, - events: { - dataPlotClick: (evt: any) => { - const data = evt.data; - const seriesTitle = this.getSeriesTitle(data); - this.props.onDataPointClick({ - x: data.categoryLabel, - y: data.dataValue, - seriesTitle, - }); - }, - }, - }; - - this.chartInstance = new FusionCharts(chartConfig); - }; - - componentDidMount() { - this.createGraph(); - FusionCharts.ready(() => { - /* Component could be unmounted before FusionCharts is ready, - this check ensure we don't render on unmounted component */ - if (this.chartInstance) { - try { - this.chartInstance.render(); - } catch (e) { - log.error(e); - } - } - }); - } - - componentWillUnmount() { - if (this.chartInstance) { - this.chartInstance = null; - } - } - - componentDidUpdate(prevProps: ChartComponentProps) { - if (!equal(prevProps, this.props)) { - const chartType = this.getChartType(); - this.chartInstance.chartType(chartType); - if (this.props.chartType === "CUSTOM_FUSION_CHART") { - const { dataSource, type } = this.getCustomFusionChartDataSource(); - this.chartInstance.chartType(type); - this.chartInstance.setChartData(dataSource); - } else if ( - this.props.allowScroll && - this.props.chartType !== "PIE_CHART" - ) { - this.chartInstance.setChartData(this.getScrollChartDataSource()); - } else { - this.chartInstance.setChartData(this.getChartDataSource()); - } - } - } - render() { //eslint-disable-next-line @typescript-eslint/no-unused-vars const { hasOnDataPointClick, onDataPointClick, ...rest } = this.props; @@ -523,8 +359,19 @@ class ChartComponent extends React.Component { className={this.props.isLoading ? "bp3-skeleton" : ""} onClick={onClick} {...rest} - id={this.chartContainerId} - /> + > + {this.state.chartType !== "CUSTOM_FUSION_CHART" && ( + + )} + + {this.state.chartType === "CUSTOM_FUSION_CHART" && ( + + )} + + {this.state.eChartsError && ( + + )} + ); } } diff --git a/app/client/src/widgets/ChartWidget/component/utils.test.ts b/app/client/src/widgets/ChartWidget/component/utils.test.ts deleted file mode 100644 index 485b2e5862..0000000000 --- a/app/client/src/widgets/ChartWidget/component/utils.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { getSeriesChartData } from "./utils"; - -describe("getSeriesChartData", () => { - it("should return 0 in value when some y axis inputs are 0", () => { - const data = [ - { x: "Jul", y: 3 }, - { x: "Aug", y: 2 }, - { x: "Sep", y: 2 }, - { x: "Oct", y: 0 }, - { x: "Nov", y: 2 }, - { x: "Dec", y: 0 }, - { x: "Jan", y: 1 }, - ]; - const categories = ["Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan"]; - - const result = getSeriesChartData(data, categories); - const expected = [ - { value: 3 }, - { value: 2 }, - { value: 2 }, - { value: 0 }, - { value: 2 }, - { value: 0 }, - { value: 1 }, - ]; - - expect(result).toStrictEqual(expected); - }); -}); diff --git a/app/client/src/widgets/ChartWidget/component/utils.ts b/app/client/src/widgets/ChartWidget/component/utils.ts deleted file mode 100644 index f732b230d6..0000000000 --- a/app/client/src/widgets/ChartWidget/component/utils.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { ChartDataPoint } from "../constants"; - -export const getSeriesChartData = ( - data: ChartDataPoint[], - categories: string[], -) => { - const dataMap: { [key: string]: string } = {}; - - // if not array or (is array and array length is zero) - if (!Array.isArray(data) || (Array.isArray(data) && data.length === 0)) { - return [ - { - value: "", - }, - ]; - } - for (let index = 0; index < data.length; index++) { - const item: ChartDataPoint = data[index]; - dataMap[item.x] = item.y; - } - return categories.map((category: string) => { - return { - value: - dataMap[category] || dataMap[category]?.toString() - ? dataMap[category] - : null, - }; - }); -}; diff --git a/app/client/src/widgets/ChartWidget/constants.ts b/app/client/src/widgets/ChartWidget/constants.ts index 8eeeb271c1..043fe718d7 100644 --- a/app/client/src/widgets/ChartWidget/constants.ts +++ b/app/client/src/widgets/ChartWidget/constants.ts @@ -7,6 +7,7 @@ export type ChartType = | "SCATTER_CHART" | "CUSTOM_FUSION_CHART"; +export const XAxisCategory = "Category"; export interface ChartDataPoint { x: any; y: any; @@ -33,6 +34,12 @@ export interface ChartSelectedDataPoint { seriesTitle: string; } +export const messages = { + ErrorTitle: "Error in Chart Data/Configuration", + MoreDetails: "More Details", + EmptyData: "No chart data to display", +}; + export const CUSTOM_CHART_TYPES = [ "area2d", "bar2d", @@ -144,14 +151,6 @@ export const CUSTOM_CHART_TYPES = [ "stackedarea2dlinedy", ]; -export const CUSTOM_CHART_DEFAULT_PARSED = { - type: "", - dataSource: { - chart: {}, - data: [], - }, -}; - export enum LabelOrientation { AUTO = "auto", SLANT = "slant", diff --git a/app/client/src/widgets/ChartWidget/index.ts b/app/client/src/widgets/ChartWidget/index.ts index 486a3d6589..9058878b9b 100644 --- a/app/client/src/widgets/ChartWidget/index.ts +++ b/app/client/src/widgets/ChartWidget/index.ts @@ -27,7 +27,7 @@ export const CONFIG = { minWidth: FILL_WIDGET_MIN_WIDTH, chartData: { [generateReactKey()]: { - seriesName: "Sales", + seriesName: "2023", data: [ { x: "Product1", diff --git a/app/client/src/widgets/ChartWidget/widget/SyntaxErrorsEvaluation.test.ts b/app/client/src/widgets/ChartWidget/widget/SyntaxErrorsEvaluation.test.ts new file mode 100644 index 0000000000..5040daa3e9 --- /dev/null +++ b/app/client/src/widgets/ChartWidget/widget/SyntaxErrorsEvaluation.test.ts @@ -0,0 +1,177 @@ +import { LabelOrientation } from "../constants"; +import type { ChartWidgetProps } from "."; +import type { ChartData } from "../constants"; +import type { WidgetError } from "widgets/BaseWidget"; +import { syntaxErrorsFromProps } from "./SyntaxErrorsEvaluation"; +import { RenderModes } from "constants/WidgetConstants"; + +describe("SyntaxErrorsEvaluation", () => { + const seriesData1: ChartData = { + seriesName: "series1", + data: [{ x: "x1", y: 1 }], + color: "series1color", + }; + const seriesData2: ChartData = { + seriesName: "series2", + data: [{ x: "x1", y: 2 }], + color: "series2color", + }; + const defaultProps: ChartWidgetProps = { + allowScroll: true, + chartData: { + seriesID1: seriesData1, + seriesID2: seriesData2, + }, + chartName: "chart name", + type: "CHART_WIDGET", + chartType: "AREA_CHART", + customFusionChartConfig: { type: "type", dataSource: undefined }, + hasOnDataPointClick: true, + isVisible: true, + isLoading: false, + setAdaptiveYMin: false, + labelOrientation: LabelOrientation.AUTO, + onDataPointClick: "", + widgetId: "widgetID", + xAxisName: "xaxisname", + yAxisName: "yaxisname", + borderRadius: "1", + boxShadow: "1", + primaryColor: "primarycolor", + fontFamily: "fontfamily", + dimensions: { componentWidth: 11, componentHeight: 11 }, + parentColumnSpace: 1, + parentRowSpace: 1, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + widgetName: "widgetName", + version: 1, + renderMode: RenderModes.CANVAS, + }; + + describe("when errors are present in non data fields", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + it("returns errors", () => { + const widgetError1: WidgetError = { + type: "property", + path: "accentColor", + name: "ErrorName", + message: "ErrorMessage", + }; + props.errors = [widgetError1]; + const syntaxErrors = syntaxErrorsFromProps(props); + expect(syntaxErrors.length).toEqual(1); + expect(syntaxErrors[0].name).toEqual("ErrorName"); + }); + }); + + describe("when errors are absent in non data fields", () => { + describe("When chart type is Custom Fusion Charts", () => { + it("returns errors when errors are presnt in customFusionCharts", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + const widgetError1: WidgetError = { + type: "property", + path: "customFusionChartConfig", + name: "ErrorName", + message: "ErrorMessage", + }; + props.errors = [widgetError1]; + props.chartType = "CUSTOM_FUSION_CHART"; + + const syntaxErrors = syntaxErrorsFromProps(props); + expect(syntaxErrors.length).toEqual(1); + expect(syntaxErrors[0].name).toEqual("ErrorName"); + }); + + it("doesn't return errors when errors are not present in customFusionCharts", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + const widgetError1: WidgetError = { + type: "property", + path: "chartData", + name: "ErrorName", + message: "ErrorMessage", + }; + props.errors = [widgetError1]; + props.chartType = "CUSTOM_FUSION_CHART"; + + const syntaxErrors = syntaxErrorsFromProps(props); + expect(syntaxErrors.length).toEqual(0); + }); + }); + + describe("When chart type is not Custom Fusion Charts", () => { + it("returns errors when errors are presnt in chart data field", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + const widgetError1: WidgetError = { + type: "property", + path: "chartData", + name: "ErrorName", + message: "ErrorMessage", + }; + props.errors = [widgetError1]; + props.chartType = "LINE_CHART"; + + const syntaxErrors = syntaxErrorsFromProps(props); + expect(syntaxErrors.length).toEqual(1); + expect(syntaxErrors[0].name).toEqual("ErrorName"); + }); + + it("doesn't return errors when errors are not present in chart data field", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + const widgetError1: WidgetError = { + type: "property", + path: "customFusionChartConfig", + name: "ErrorName", + message: "ErrorMessage", + }; + props.errors = [widgetError1]; + props.chartType = "LINE_CHART"; + + const syntaxErrors = syntaxErrorsFromProps(props); + expect(syntaxErrors.length).toEqual(0); + }); + + describe("when chart type is PIE CHART", () => { + it("returns error if there is syntax error in first series data", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + const widgetError1: WidgetError = { + type: "property", + path: "chartData.seriesID1.data", + name: "ErrorName", + message: "ErrorMessage", + }; + props.errors = [widgetError1]; + props.chartType = "PIE_CHART"; + + const syntaxErrors = syntaxErrorsFromProps(props); + expect(syntaxErrors.length).toEqual(1); + expect(syntaxErrors[0].name).toEqual("ErrorName"); + }); + + it("doesn't return an error if there is syntax error in second series data", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + + const widgetError1: WidgetError = { + type: "property", + path: "chartData.seriesID2.data", + name: "ErrorName", + message: "ErrorMessage", + }; + props.errors = [widgetError1]; + props.chartType = "PIE_CHART"; + + const syntaxErrors = syntaxErrorsFromProps(props); + expect(syntaxErrors.length).toEqual(0); + }); + }); + }); + }); +}); diff --git a/app/client/src/widgets/ChartWidget/widget/SyntaxErrorsEvaluation.ts b/app/client/src/widgets/ChartWidget/widget/SyntaxErrorsEvaluation.ts new file mode 100644 index 0000000000..3973ab27ae --- /dev/null +++ b/app/client/src/widgets/ChartWidget/widget/SyntaxErrorsEvaluation.ts @@ -0,0 +1,55 @@ +import type { WidgetError } from "widgets/BaseWidget"; + +import type { ChartWidgetProps } from "."; + +export function syntaxErrorsFromProps(props: ChartWidgetProps): WidgetError[] { + if (!props.errors || props.errors.length == 0) { + return []; + } + + const errors: WidgetError[] = []; + props.errors.forEach((error) => { + if (nonDataError(error)) { + errors.push(error); + } else { + if (props.chartType == "CUSTOM_FUSION_CHART") { + if (customFusionChartError(error)) { + errors.push(error); + } + } else { + if (eChartsError(error)) { + if (props.chartType == "PIE_CHART") { + const firstSeriesKey = Object.keys(props.chartData)[0]; + if ( + error.path && + error.path.startsWith(`chartData.${firstSeriesKey}`) + ) { + errors.push(error); + } + } else { + errors.push(error); + } + } + } + } + }); + return errors; +} + +const nonDataError = (error: WidgetError) => { + if (eChartsError(error)) { + return false; + } else if (customFusionChartError(error)) { + return false; + } else { + return true; + } +}; + +const customFusionChartError = (error: WidgetError) => { + return error.path && error.path.startsWith("customFusionChartConfig"); +}; + +const eChartsError = (error: WidgetError) => { + return error.path && error.path.startsWith("chartData"); +}; diff --git a/app/client/src/widgets/ChartWidget/widget/index.test.ts b/app/client/src/widgets/ChartWidget/widget/index.test.ts new file mode 100644 index 0000000000..15f6d34610 --- /dev/null +++ b/app/client/src/widgets/ChartWidget/widget/index.test.ts @@ -0,0 +1,95 @@ +import { emptyChartData } from "."; + +import { LabelOrientation } from "../constants"; +import type { ChartWidgetProps } from "."; +import type { ChartData } from "../constants"; +import { RenderModes } from "constants/WidgetConstants"; + +describe("emptyChartData", () => { + const seriesData1: ChartData = { + seriesName: "series1", + data: [{ x: "x1", y: 1 }], + color: "series1color", + }; + const seriesData2: ChartData = { + seriesName: "series2", + data: [{ x: "x1", y: 2 }], + color: "series2color", + }; + const defaultProps: ChartWidgetProps = { + allowScroll: true, + chartData: { + seriesID1: seriesData1, + seriesID2: seriesData2, + }, + chartName: "chart name", + type: "CHART_WIDGET", + chartType: "AREA_CHART", + customFusionChartConfig: { type: "type", dataSource: undefined }, + hasOnDataPointClick: true, + isVisible: true, + isLoading: false, + setAdaptiveYMin: false, + labelOrientation: LabelOrientation.AUTO, + onDataPointClick: "", + widgetId: "widgetID", + xAxisName: "xaxisname", + yAxisName: "yaxisname", + borderRadius: "1", + boxShadow: "1", + primaryColor: "primarycolor", + fontFamily: "fontfamily", + dimensions: { componentWidth: 11, componentHeight: 11 }, + parentColumnSpace: 1, + parentRowSpace: 1, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + widgetName: "widgetName", + version: 1, + renderMode: RenderModes.CANVAS, + }; + + describe("when chart type is Echarts", () => { + it("returns true chartData property is empty", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "LINE_CHART"; + props.chartData.seriesID1 = { data: [] }; + props.chartData.seriesID2 = { data: [] }; + + expect(emptyChartData(props)).toEqual(true); + }); + + it("returns false chartData property is not empty", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "LINE_CHART"; + expect(emptyChartData(props)).toEqual(false); + }); + + it("returns false chartData property if any of the series data is present", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "LINE_CHART"; + props.chartData.seriesID1 = { data: [] }; + expect(emptyChartData(props)).toEqual(false); + }); + }); + + describe("when chart type is custom fusion charts", () => { + it("returns true customFusionChartConfig property is empty", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "CUSTOM_FUSION_CHART"; + props.customFusionChartConfig = {}; + + expect(emptyChartData(props)).toEqual(true); + }); + + it("returns false customFusionChartConfig property is not empty", () => { + const props = JSON.parse(JSON.stringify(defaultProps)); + props.chartType = "CUSTOM_FUSION_CHART"; + props.customFusionChartConfig = { key: "value" }; + + expect(emptyChartData(props)).toEqual(false); + }); + }); +}); diff --git a/app/client/src/widgets/ChartWidget/widget/index.tsx b/app/client/src/widgets/ChartWidget/widget/index.tsx index e7fc2e7fe9..aecade7085 100644 --- a/app/client/src/widgets/ChartWidget/widget/index.tsx +++ b/app/client/src/widgets/ChartWidget/widget/index.tsx @@ -6,12 +6,7 @@ import Skeleton from "components/utils/Skeleton"; import { retryPromise } from "utils/AppsmithUtils"; import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; import { contentConfig, styleConfig } from "./propertyConfig"; -import type { - ChartType, - CustomFusionChartConfig, - AllChartData, - ChartSelectedDataPoint, -} from "../constants"; +import type { ChartSelectedDataPoint } from "../constants"; import type { WidgetType } from "constants/WidgetConstants"; import type { ChartComponentProps } from "../component"; @@ -19,11 +14,31 @@ import { Colors } from "constants/Colors"; import type { Stylesheet } from "entities/AppTheming"; import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils"; import type { AutocompletionDefinitions } from "widgets/constants"; +import { ChartErrorComponent } from "../component/ChartErrorComponent"; +import { syntaxErrorsFromProps } from "./SyntaxErrorsEvaluation"; +import { EmptyChartData } from "../component/EmptyChartData"; const ChartComponent = lazy(() => retryPromise(() => import(/* webpackChunkName: "charts" */ "../component")), ); +export const emptyChartData = (props: ChartWidgetProps) => { + if (props.chartType == "CUSTOM_FUSION_CHART") { + if (!props.customFusionChartConfig) { + return true; + } else { + return Object.keys(props.customFusionChartConfig).length == 0; + } + } else { + for (const seriesID in props.chartData) { + if (props.chartData[seriesID].data.length > 0) { + return false; + } + } + return true; + } +}; + class ChartWidget extends BaseWidget { static getAutocompleteDefinitions(): AutocompletionDefinitions { return { @@ -79,51 +94,52 @@ class ChartWidget extends BaseWidget { }; getPageView() { - return ( - }> - - - ); + const errors = syntaxErrorsFromProps(this.props); + + if (errors.length == 0) { + if (emptyChartData(this.props)) { + return ; + } else { + return ( + }> + + + ); + } + } else { + return ; + } } static getWidgetType(): WidgetType { return "CHART_WIDGET"; } } -export interface ChartWidgetProps extends WidgetProps { - chartType: ChartType; - chartData: AllChartData; - customFusionChartConfig: CustomFusionChartConfig; - xAxisName: string; - yAxisName: string; - chartName: string; - isVisible?: boolean; - allowScroll: boolean; - borderRadius: string; - boxShadow?: string; - accentColor?: string; - fontFamily?: string; -} type ChartComponentPartialProps = Omit; export interface ChartWidgetProps diff --git a/app/client/src/widgets/ChartWidget/widget/propertyConfig.ts b/app/client/src/widgets/ChartWidget/widget/propertyConfig.ts index 12cd2cc2b7..a1038151e4 100644 --- a/app/client/src/widgets/ChartWidget/widget/propertyConfig.ts +++ b/app/client/src/widgets/ChartWidget/widget/propertyConfig.ts @@ -1,8 +1,14 @@ import { ValidationTypes } from "constants/WidgetValidation"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; import type { ChartWidgetProps } from "widgets/ChartWidget/widget"; -import { isLabelOrientationApplicableFor } from "../component"; -import { CUSTOM_CHART_TYPES, LabelOrientation } from "../constants"; +import { + CUSTOM_CHART_TYPES, + LabelOrientation, + LABEL_ORIENTATION_COMPATIBLE_CHARTS, +} from "../constants"; + +export const isLabelOrientationApplicableFor = (chartType: string) => + LABEL_ORIENTATION_COMPATIBLE_CHARTS.includes(chartType); export const contentConfig = [ { @@ -302,10 +308,6 @@ export const contentConfig = [ label: "Rotate", value: LabelOrientation.ROTATE, }, - { - label: "Stagger", - value: LabelOrientation.STAGGER, - }, ], }, ], diff --git a/app/client/src/widgets/CheckboxWidget/index.ts b/app/client/src/widgets/CheckboxWidget/index.ts index da20f1e752..158d449c10 100644 --- a/app/client/src/widgets/CheckboxWidget/index.ts +++ b/app/client/src/widgets/CheckboxWidget/index.ts @@ -1,7 +1,12 @@ import { LabelPosition } from "components/constants"; import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants"; import { ResponsiveBehavior } from "utils/autoLayout/constants"; -import { AlignWidgetTypes } from "widgets/constants"; +import { + AlignWidgetTypes, + type SnipingModeProperty, + type PropertyUpdates, +} from "widgets/constants"; + import IconSVG from "./icon.svg"; import Widget from "./widget"; import { WIDGET_TAGS } from "constants/WidgetConstants"; @@ -45,6 +50,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "defaultCheckedState", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { disabledPropsDefaults: { labelTextSize: "0.875rem", diff --git a/app/client/src/widgets/DatePickerWidget2/index.ts b/app/client/src/widgets/DatePickerWidget2/index.ts index 2d6df97373..cca8b45852 100644 --- a/app/client/src/widgets/DatePickerWidget2/index.ts +++ b/app/client/src/widgets/DatePickerWidget2/index.ts @@ -7,6 +7,7 @@ import { DynamicHeight } from "utils/WidgetFeatures"; import { TimePrecision } from "./constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -59,6 +60,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "defaultDate", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { disabledPropsDefaults: { labelPosition: LabelPosition.Top, diff --git a/app/client/src/widgets/DropdownWidget/index.ts b/app/client/src/widgets/DropdownWidget/index.ts index cb2ef29993..811abea031 100644 --- a/app/client/src/widgets/DropdownWidget/index.ts +++ b/app/client/src/widgets/DropdownWidget/index.ts @@ -2,6 +2,7 @@ import { Alignment } from "@blueprintjs/core"; import { LabelPosition } from "components/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; export const CONFIG = { type: Widget.getWidgetType(), @@ -42,6 +43,19 @@ export const CONFIG = { stylesheetConfig: Widget.getStylesheetConfig(), autocompleteDefinitions: Widget.getAutocompleteDefinitions(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "options", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, }; export default Widget; diff --git a/app/client/src/widgets/FilepickerWidget/index.ts b/app/client/src/widgets/FilepickerWidget/index.ts index 7c7c0cea78..0307e059d9 100644 --- a/app/client/src/widgets/FilepickerWidget/index.ts +++ b/app/client/src/widgets/FilepickerWidget/index.ts @@ -1,3 +1,4 @@ +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; import FileDataTypes from "./widget/FileDataTypes"; @@ -35,6 +36,19 @@ export const CONFIG = { setterConfig: Widget.getSetterConfig(), autocompleteDefinitions: Widget.getAutocompleteDefinitions(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "onFilesSelected", + propertyValue: propValueMap.run, + isDynamicPropertyPath: true, + }, + ]; + }, + }, }; export default Widget; diff --git a/app/client/src/widgets/FormButtonWidget/index.ts b/app/client/src/widgets/FormButtonWidget/index.ts index 4ee02be2ef..9bc3ae63cd 100644 --- a/app/client/src/widgets/FormButtonWidget/index.ts +++ b/app/client/src/widgets/FormButtonWidget/index.ts @@ -1,6 +1,7 @@ import { RecaptchaTypes } from "components/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; export const CONFIG = { type: Widget.getWidgetType(), @@ -28,6 +29,19 @@ export const CONFIG = { stylesheetConfig: Widget.getStylesheetConfig(), autocompleteDefinitions: Widget.getAutocompleteDefinitions(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "onClick", + propertyValue: propValueMap.run, + isDynamicPropertyPath: true, + }, + ]; + }, + }, }; export default Widget; diff --git a/app/client/src/widgets/IframeWidget/index.ts b/app/client/src/widgets/IframeWidget/index.ts index 1d06e97e58..7d755fbdee 100644 --- a/app/client/src/widgets/IframeWidget/index.ts +++ b/app/client/src/widgets/IframeWidget/index.ts @@ -2,6 +2,7 @@ import { ResponsiveBehavior } from "utils/autoLayout/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; import { isAirgapped } from "@appsmith/utils/airgapHelpers"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; const isAirgappedInstance = isAirgapped(); @@ -39,6 +40,19 @@ export const CONFIG = { setterConfig: Widget.getSetterConfig(), autocompleteDefinitions: Widget.getAutocompleteDefinitions(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "source", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { widgetSize: [ { diff --git a/app/client/src/widgets/InputWidget/index.ts b/app/client/src/widgets/InputWidget/index.ts index 1ca9b80e89..8d1351d833 100644 --- a/app/client/src/widgets/InputWidget/index.ts +++ b/app/client/src/widgets/InputWidget/index.ts @@ -2,6 +2,7 @@ import { Alignment } from "@blueprintjs/core"; import { LabelPosition } from "components/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; export const CONFIG = { type: Widget.getWidgetType(), @@ -40,6 +41,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "defaultText", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, }; export default Widget; diff --git a/app/client/src/widgets/InputWidgetV2/index.ts b/app/client/src/widgets/InputWidgetV2/index.ts index a6280f4e69..7ad6d9a0f0 100644 --- a/app/client/src/widgets/InputWidgetV2/index.ts +++ b/app/client/src/widgets/InputWidgetV2/index.ts @@ -7,6 +7,7 @@ import type { BaseInputWidgetProps } from "widgets/BaseInputWidget/widget"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -45,6 +46,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "defaultText", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { disabledPropsDefaults: { labelPosition: LabelPosition.Top, diff --git a/app/client/src/widgets/JSONFormWidget/index.ts b/app/client/src/widgets/JSONFormWidget/index.ts index 16f784650f..b1c65ae578 100644 --- a/app/client/src/widgets/JSONFormWidget/index.ts +++ b/app/client/src/widgets/JSONFormWidget/index.ts @@ -3,7 +3,11 @@ import { Colors } from "constants/Colors"; import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants"; import { ResponsiveBehavior } from "utils/autoLayout/constants"; import { DynamicHeight } from "utils/WidgetFeatures"; -import { BlueprintOperationTypes } from "widgets/constants"; +import { + BlueprintOperationTypes, + type SnipingModeProperty, + type PropertyUpdates, +} from "widgets/constants"; import IconSVG from "./icon.svg"; import type { JSONFormWidgetProps } from "./widget"; @@ -101,6 +105,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "sourceData", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { widgetSize: [ { diff --git a/app/client/src/widgets/ListWidget/index.ts b/app/client/src/widgets/ListWidget/index.ts index 6d39e0a7fb..11669d6667 100644 --- a/app/client/src/widgets/ListWidget/index.ts +++ b/app/client/src/widgets/ListWidget/index.ts @@ -6,7 +6,11 @@ import { getDynamicBindings, } from "utils/DynamicBindingUtils"; import type { WidgetProps } from "widgets/BaseWidget"; -import type { FlattenedWidgetProps } from "widgets/constants"; +import type { + FlattenedWidgetProps, + SnipingModeProperty, + PropertyUpdates, +} from "widgets/constants"; import { BlueprintOperationTypes } from "widgets/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; @@ -421,6 +425,19 @@ export const CONFIG = { setterConfig: Widget.getSetterConfig(), autocompleteDefinitions: Widget.getAutocompleteDefinitions(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "listData", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { widgetSize: [ { diff --git a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts index aae1af9b1f..656f857b04 100644 --- a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts +++ b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts @@ -1791,4 +1791,15 @@ describe("#updateWidgetNameInDynamicBinding", () => { }, ); }); + + it("returns same binding value when it falsy", () => { + ["", undefined, null, false].forEach((d: unknown) => { + const updatedBinding = generator.updateWidgetNameInDynamicBinding( + d as string, + "test", + "test", + ); + expect(updatedBinding).toBe(d); + }); + }); }); diff --git a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts index 5c1a86867b..ecbe081018 100644 --- a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts +++ b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts @@ -942,7 +942,13 @@ class MetaWidgetGenerator { metaWidgetName: string, templateWidgetName: string, ) => { - if (metaWidgetName === templateWidgetName) return binding; + /* + * There are certain edge cases where binding would be `undefined` + * so assering type before performing replace operation + */ + if (metaWidgetName === templateWidgetName || typeof binding !== "string") { + return binding; + } const pattern = new RegExp(`${templateWidgetName}\\.`, "g"); @@ -967,7 +973,7 @@ class MetaWidgetGenerator { dynamicPaths.forEach(({ isTriggerPath, key: path }) => { if (excludedPaths.includes(path)) return; - let propertyValue: string = get(metaWidget, path); + let propertyValue = get(metaWidget, path); propertyValue = this.updateWidgetNameInDynamicBinding( propertyValue, @@ -1006,7 +1012,7 @@ class MetaWidgetGenerator { if (levelPaths) { this.addLevelProperty(metaWidget, levelPaths); - levelPaths.forEach((levelPath) => { + levelPaths.forEach((levelPath: string) => { const [level] = levelPath.split("."); pathTypes.add(level); diff --git a/app/client/src/widgets/ListWidgetV2/index.ts b/app/client/src/widgets/ListWidgetV2/index.ts index fdd468cf07..5117dac6f3 100644 --- a/app/client/src/widgets/ListWidgetV2/index.ts +++ b/app/client/src/widgets/ListWidgetV2/index.ts @@ -2,7 +2,11 @@ import { get } from "lodash"; import IconSVG from "./icon.svg"; import Widget from "./widget"; -import type { FlattenedWidgetProps } from "widgets/constants"; +import type { + FlattenedWidgetProps, + SnipingModeProperty, + PropertyUpdates, +} from "widgets/constants"; import { BlueprintOperationTypes } from "widgets/constants"; import { DynamicHeight, RegisteredWidgetFeatures } from "utils/WidgetFeatures"; import type { WidgetProps } from "widgets/BaseWidget"; @@ -480,6 +484,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "listData", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { widgetSize: [ { diff --git a/app/client/src/widgets/MapWidget/index.ts b/app/client/src/widgets/MapWidget/index.ts index 86b4dc2218..68d6de839b 100644 --- a/app/client/src/widgets/MapWidget/index.ts +++ b/app/client/src/widgets/MapWidget/index.ts @@ -2,6 +2,7 @@ import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants"; import { ResponsiveBehavior } from "utils/autoLayout/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -39,6 +40,19 @@ export const CONFIG = { setterConfig: Widget.getSetterConfig(), autocompleteDefinitions: Widget.getAutocompleteDefinitions(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "defaultMarkers", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { widgetSize: [ { diff --git a/app/client/src/widgets/RadioGroupWidget/index.ts b/app/client/src/widgets/RadioGroupWidget/index.ts index 2064dcec98..217b579c77 100644 --- a/app/client/src/widgets/RadioGroupWidget/index.ts +++ b/app/client/src/widgets/RadioGroupWidget/index.ts @@ -2,6 +2,7 @@ import { Alignment } from "@blueprintjs/core"; import { LabelPosition } from "components/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -49,6 +50,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "options", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { defaults: { columns: 14, diff --git a/app/client/src/widgets/RateWidget/index.ts b/app/client/src/widgets/RateWidget/index.ts index b69c83b4db..9bf9ccc349 100644 --- a/app/client/src/widgets/RateWidget/index.ts +++ b/app/client/src/widgets/RateWidget/index.ts @@ -2,6 +2,7 @@ import { Colors } from "constants/Colors"; import IconSVG from "./icon.svg"; import Widget from "./widget"; import type { RateWidgetProps } from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -75,6 +76,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "onRateChanged", + propertyValue: propValueMap.run, + isDynamicPropertyPath: true, + }, + ]; + }, + }, }; export default Widget; diff --git a/app/client/src/widgets/RichTextEditorWidget/index.ts b/app/client/src/widgets/RichTextEditorWidget/index.ts index 92afa75f3a..458b7f0de0 100644 --- a/app/client/src/widgets/RichTextEditorWidget/index.ts +++ b/app/client/src/widgets/RichTextEditorWidget/index.ts @@ -5,6 +5,7 @@ import { ResponsiveBehavior } from "utils/autoLayout/constants"; import { DynamicHeight } from "utils/WidgetFeatures"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -51,6 +52,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "defaultText", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { widgetSize: [ { diff --git a/app/client/src/widgets/SelectWidget/index.ts b/app/client/src/widgets/SelectWidget/index.ts index 201ac1075d..3d37241203 100644 --- a/app/client/src/widgets/SelectWidget/index.ts +++ b/app/client/src/widgets/SelectWidget/index.ts @@ -6,6 +6,7 @@ import { DynamicHeight } from "utils/WidgetFeatures"; import IconSVG from "./icon.svg"; import Widget from "./widget"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -60,6 +61,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "sourceData", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { disabledPropsDefaults: { labelPosition: LabelPosition.Top, diff --git a/app/client/src/widgets/SwitchWidget/index.ts b/app/client/src/widgets/SwitchWidget/index.ts index 5a901a812b..a115b4c46b 100644 --- a/app/client/src/widgets/SwitchWidget/index.ts +++ b/app/client/src/widgets/SwitchWidget/index.ts @@ -1,6 +1,11 @@ import { LabelPosition } from "components/constants"; import { ResponsiveBehavior } from "utils/autoLayout/constants"; -import { AlignWidgetTypes } from "widgets/constants"; +import { + AlignWidgetTypes, + type SnipingModeProperty, + type PropertyUpdates, +} from "widgets/constants"; + import IconSVG from "./icon.svg"; import Widget from "./widget"; import { WIDGET_TAGS } from "constants/WidgetConstants"; @@ -42,6 +47,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "defaultSwitchState", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { disabledPropsDefaults: { labelTextSize: "0.875rem", diff --git a/app/client/src/widgets/TableWidget/index.ts b/app/client/src/widgets/TableWidget/index.ts index 41759a067e..83ae21996b 100644 --- a/app/client/src/widgets/TableWidget/index.ts +++ b/app/client/src/widgets/TableWidget/index.ts @@ -6,7 +6,11 @@ import { getDynamicBindings, } from "utils/DynamicBindingUtils"; import type { WidgetProps } from "widgets/BaseWidget"; -import { BlueprintOperationTypes } from "widgets/constants"; +import { + BlueprintOperationTypes, + type SnipingModeProperty, + type PropertyUpdates, +} from "widgets/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; @@ -232,6 +236,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "tableData", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, }; export default Widget; diff --git a/app/client/src/widgets/TableWidgetV2/index.ts b/app/client/src/widgets/TableWidgetV2/index.ts index 1af42c05fb..eb6ae4b6e2 100644 --- a/app/client/src/widgets/TableWidgetV2/index.ts +++ b/app/client/src/widgets/TableWidgetV2/index.ts @@ -10,6 +10,7 @@ import type { WidgetQueryConfig, WidgetQueryGenerationFormConfig, } from "WidgetQueryGenerators/types"; +import type { PropertyUpdates, SnipingModeProperty } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -81,6 +82,17 @@ export const CONFIG = { formConfig, ); }, + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "tableData", + propertyValue: propValueMap.data, + isDynamicPropertyPath: false, + }, + ]; + }, }, autoLayout: { widgetSize: [ diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts index 26af146a53..52375365d7 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts @@ -14,7 +14,7 @@ import { createEditActionColumn, generateNewColumnOrderFromStickyValue, } from "./utilities"; -import type { PropertyHookUpdates } from "constants/PropertyControlConstants"; +import type { PropertyUpdates } from "widgets/constants"; import { MenuItemsSource } from "widgets/MenuButtonWidget/constants"; export function totalRecordsCountValidation( @@ -241,7 +241,7 @@ export const updateInlineEditingOptionDropdownVisibilityHook = ( props: TableWidgetProps, propertyPath: string, propertyValue: any, -): Array | undefined => { +): Array | undefined => { let propertiesToUpdate = []; if ( @@ -495,7 +495,7 @@ export const updateInlineEditingSaveOptionHook = ( props: TableWidgetProps, propertyPath: string, propertyValue: any, -): Array | undefined => { +): Array | undefined => { if (propertyValue !== InlineEditingSaveOptions.ROW_LEVEL) { const columnsArray = Object.values(props.primaryColumns); const edtiActionColumn = columnsArray.find( @@ -568,14 +568,14 @@ export function updateThemeStylesheetsInColumns( props: TableWidgetProps, propertyPath: string, propertyValue: any, -): Array | undefined { +): Array | undefined { const regex = /^primaryColumns\.(\w+)\.(.*)$/; const matches = propertyPath.match(regex); const columnId = matches?.[1]; const columnProperty = matches?.[2]; if (columnProperty === "columnType") { - const propertiesToUpdate: Array = []; + const propertiesToUpdate: Array = []; const oldColumnType = get(props, `primaryColumns.${columnId}.columnType`); const newColumnType = propertyValue; @@ -669,7 +669,7 @@ export const updateCustomColumnAliasOnLabelChange = ( props: TableWidgetProps, propertyPath: string, propertyValue: unknown, -): Array | undefined => { +): Array | undefined => { // alias will be updated along with label change only for custom columns const regex = /^primaryColumns\.(customColumn\d+)\.label$/; if (propertyPath?.length && regex.test(propertyPath)) { diff --git a/app/client/src/widgets/TextWidget/index.ts b/app/client/src/widgets/TextWidget/index.ts index 439fb19a0d..549beb415d 100644 --- a/app/client/src/widgets/TextWidget/index.ts +++ b/app/client/src/widgets/TextWidget/index.ts @@ -5,7 +5,11 @@ import { OverflowTypes } from "./constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; import { DynamicHeight } from "utils/WidgetFeatures"; -import { BlueprintOperationTypes } from "widgets/constants"; +import { + BlueprintOperationTypes, + type SnipingModeProperty, + type PropertyUpdates, +} from "widgets/constants"; import type { WidgetProps } from "widgets/BaseWidget"; import { get } from "lodash"; import type { DynamicPath } from "utils/DynamicBindingUtils"; @@ -80,6 +84,19 @@ export const CONFIG = { autocompleteDefinitions: Widget.getAutocompleteDefinitions(), setterConfig: Widget.getSetterConfig(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "text", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { autoDimension: { height: true, diff --git a/app/client/src/widgets/VideoWidget/index.ts b/app/client/src/widgets/VideoWidget/index.ts index 23703202a4..2ca567c8e6 100644 --- a/app/client/src/widgets/VideoWidget/index.ts +++ b/app/client/src/widgets/VideoWidget/index.ts @@ -3,6 +3,7 @@ import { ResponsiveBehavior } from "utils/autoLayout/constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; import { getAssetUrl } from "@appsmith/utils/airgapHelpers"; +import type { SnipingModeProperty, PropertyUpdates } from "widgets/constants"; import { WIDGET_TAGS } from "constants/WidgetConstants"; export const CONFIG = { @@ -34,6 +35,19 @@ export const CONFIG = { setterConfig: Widget.getSetterConfig(), autocompleteDefinitions: Widget.getAutocompleteDefinitions(), }, + methods: { + getSnipingModeUpdates: ( + propValueMap: SnipingModeProperty, + ): PropertyUpdates[] => { + return [ + { + propertyPath: "url", + propertyValue: propValueMap.data, + isDynamicPropertyPath: true, + }, + ]; + }, + }, autoLayout: { widgetSize: [ { diff --git a/app/client/src/widgets/WidgetUtils.test.ts b/app/client/src/widgets/WidgetUtils.test.ts index df87b3c35b..54f44ef51a 100644 --- a/app/client/src/widgets/WidgetUtils.test.ts +++ b/app/client/src/widgets/WidgetUtils.test.ts @@ -2,7 +2,7 @@ import { ButtonBorderRadiusTypes, ButtonVariantTypes, } from "components/constants"; -import type { PropertyHookUpdates } from "constants/PropertyControlConstants"; +import type { PropertyUpdates } from "widgets/constants"; import { RenderModes, TextSizes, @@ -437,7 +437,7 @@ type composePropertyUpdateHookInputType = Array< props: unknown, propertyPath: string, propertyValue: any, - ) => PropertyHookUpdates[] | undefined + ) => PropertyUpdates[] | undefined >; describe("composePropertyUpdateHook", () => { it("should test that it's returning a function", () => { diff --git a/app/client/src/widgets/WidgetUtils.ts b/app/client/src/widgets/WidgetUtils.ts index 057c24070d..185ea8840f 100644 --- a/app/client/src/widgets/WidgetUtils.ts +++ b/app/client/src/widgets/WidgetUtils.ts @@ -13,7 +13,7 @@ import { } from "components/constants"; import { BoxShadowTypes } from "components/designSystems/appsmith/WidgetStyleContainer"; import type { Theme } from "constants/DefaultTheme"; -import type { PropertyHookUpdates } from "constants/PropertyControlConstants"; +import type { PropertyUpdates } from "widgets/constants"; import { CANVAS_SELECTOR, CONTAINER_GRID_PADDING, @@ -673,7 +673,7 @@ export const getMainCanvas = () => * - Often times we would wanna call more than one hook when a property is * changed. Use this hook instead of nested calls * - * Eack hook should either return `undefined` or an array of PropertyHookUpdates + * Eack hook should either return `undefined` or an array of PropertyUpdates * this function ignores the undefined and concats all the property update array. */ export function composePropertyUpdateHook( @@ -682,16 +682,16 @@ export function composePropertyUpdateHook( props: any, propertyPath: string, propertyValue: any, - ) => Array | undefined + ) => Array | undefined >, ): ( props: any, propertyPath: string, propertyValue: any, -) => Array | undefined { +) => Array | undefined { return (props: any, propertyPath: string, propertyValue: any) => { if (updateFunctions.length) { - let updates: PropertyHookUpdates[] = []; + let updates: PropertyUpdates[] = []; updateFunctions.forEach((func) => { if (typeof func === "function") { @@ -920,6 +920,10 @@ export const checkForOnClick = (e: React.MouseEvent) => { target && target !== currentTarget ) { + /** + * NOTE: target.__reactProps$ returns undefined in cypress, therefore the below targetReactProps will be null. + * Due to this the traversed target element's react props such as onClick will get ignored. + **/ const targetReactProps = findReactInstanceProps(target); const hasOnClickableEvent = Boolean( diff --git a/app/client/src/widgets/constants.ts b/app/client/src/widgets/constants.ts index 94fdcd9ff3..6aac918512 100644 --- a/app/client/src/widgets/constants.ts +++ b/app/client/src/widgets/constants.ts @@ -80,9 +80,17 @@ export interface WidgetConfiguration { methods?: Record; } +export type PropertyUpdates = { + propertyPath: string; + propertyValue?: unknown; + isDynamicPropertyPath?: boolean; // Toggles the property mode to JS + shouldDeleteProperty?: boolean; // Deletes the property, propertyValue is ignored +}; + export type WidgetMethods = | GetQueryGenerationConfig - | GetPropertyUpdatesForQueryBinding; + | GetPropertyUpdatesForQueryBinding + | getSnipingModeUpdates; type GetQueryGenerationConfig = ( widgetProps: WidgetProps, @@ -94,6 +102,10 @@ type GetPropertyUpdatesForQueryBinding = ( formConfig: WidgetQueryGenerationFormConfig, ) => Record; +type getSnipingModeUpdates = ( + propValueMap: Record<"data" | "run", string>, +) => Array; + export const GRID_DENSITY_MIGRATION_V1 = 4; export enum BlueprintOperationTypes { @@ -363,3 +375,5 @@ export const dateFormatOptions = [ export type ThemeProp = { theme: Theme; }; + +export type SnipingModeProperty = Record<"data" | "run", string>; diff --git a/app/client/src/workers/Evaluation/JSObject/utils.ts b/app/client/src/workers/Evaluation/JSObject/utils.ts index ee09b6e699..e931a1f711 100644 --- a/app/client/src/workers/Evaluation/JSObject/utils.ts +++ b/app/client/src/workers/Evaluation/JSObject/utils.ts @@ -1,7 +1,6 @@ import type { ConfigTree, DataTree, - AppsmithEntity, DataTreeEntity, } from "entities/DataTree/dataTreeFactory"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; @@ -22,7 +21,6 @@ import { isJSAction, } from "@appsmith/workers/Evaluation/evaluationUtils"; import JSObjectCollection from "./Collection"; -import type { APP_MODE } from "entities/App"; import type { JSActionEntityConfig, JSActionEntity, @@ -272,11 +270,6 @@ export function isJSObjectVariable( ); } -export function getAppMode(dataTree: DataTree) { - const appsmithObj = dataTree.appsmith as AppsmithEntity; - return appsmithObj.mode as APP_MODE; -} - export function isPromise(value: any): value is Promise { return Boolean(value && typeof value.then === "function"); } diff --git a/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts b/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts index d46c4a303c..4d673705dd 100644 --- a/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts +++ b/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts @@ -11,6 +11,10 @@ import { get } from "lodash"; import { getType } from "utils/TypeHelpers"; import type { JSVarMutatedEvents } from "workers/Evaluation/types"; import { dataTreeEvaluator } from "workers/Evaluation/handlers/evalTree"; +import type { + TriggerKind, + TriggerSource, +} from "constants/AppsmithActionConstants/ActionConstants"; const _internalSetTimeout = self.setTimeout; const _internalClearTimeout = self.clearTimeout; @@ -182,15 +186,20 @@ TriggerEmitter.on( jsVariableUpdatesHandlerWrapper, ); -export const fnInvokeLogHandler = priorityBatchedActionHandler( - (data) => { - const set = new Set([...data]); - WorkerMessenger.ping({ - method: MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION, - data: [...set], - }); - }, -); +export const fnInvokeLogHandler = deferredBatchedActionHandler<{ + jsFnFullName: string; + isSuccess: boolean; + triggerMeta: { + source: TriggerSource; + triggerPropertyName: string | undefined; + triggerKind: TriggerKind | undefined; + }; +}>((data) => { + WorkerMessenger.ping({ + method: MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION, + data, + }); +}); TriggerEmitter.on(BatchKey.process_batched_fn_invoke_log, fnInvokeLogHandler); diff --git a/app/client/src/workers/Evaluation/fns/utils/jsObjectFnFactory.ts b/app/client/src/workers/Evaluation/fns/utils/jsObjectFnFactory.ts index 6864d1f0b9..63e0f9d5f8 100644 --- a/app/client/src/workers/Evaluation/fns/utils/jsObjectFnFactory.ts +++ b/app/client/src/workers/Evaluation/fns/utils/jsObjectFnFactory.ts @@ -2,7 +2,6 @@ import { isPromise } from "workers/Evaluation/JSObject/utils"; import { postJSFunctionExecutionLog } from "@appsmith/workers/Evaluation/JSObject/postJSFunctionExecution"; import TriggerEmitter, { BatchKey } from "./TriggerEmitter"; import ExecutionMetaData from "./ExecutionMetaData"; -import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants"; declare global { interface Window { @@ -16,6 +15,7 @@ export type PostProcessorArg = { executionMetaData: ReturnType; jsFnFullName: string; executionResponse: unknown; + isSuccess: boolean; }; export type PostProcessor = (args: PostProcessorArg) => void; @@ -34,23 +34,13 @@ function saveExecutionData({ }); } -function logJSExecution({ executionMetaData, jsFnFullName }: PostProcessorArg) { - switch (executionMetaData.triggerMeta.triggerKind) { - case TriggerKind.EVENT_EXECUTION: { - TriggerEmitter.emit(BatchKey.process_batched_fn_invoke_log, jsFnFullName); - break; - } - default: { - break; - } - } - postJSFunctionExecutionLog(jsFnFullName); -} - export function jsObjectFunctionFactory

>( fn: (...args: P) => unknown, name: string, - postProcessors: PostProcessor[] = [saveExecutionData, logJSExecution], + postProcessors: PostProcessor[] = [ + saveExecutionData, + postJSFunctionExecutionLog, + ], ) { return function (this: unknown, ...args: P) { if (!ExecutionMetaData.getExecutionMetaData().enableJSFnPostProcessors) { @@ -66,6 +56,7 @@ export function jsObjectFunctionFactory

>( executionMetaData, jsFnFullName: name, executionResponse: res, + isSuccess: true, }), ); return res; @@ -76,6 +67,7 @@ export function jsObjectFunctionFactory

>( executionMetaData, jsFnFullName: name, executionResponse: undefined, + isSuccess: true, }), ); throw e; @@ -86,6 +78,7 @@ export function jsObjectFunctionFactory

>( executionMetaData, jsFnFullName: name, executionResponse: result, + isSuccess: true, }), ); } @@ -96,6 +89,7 @@ export function jsObjectFunctionFactory

>( executionMetaData, jsFnFullName: name, executionResponse: undefined, + isSuccess: false, }); }); throw e; diff --git a/app/client/tsconfig.json b/app/client/tsconfig.json index 9414f93fc0..ca26c7edc4 100644 --- a/app/client/tsconfig.json +++ b/app/client/tsconfig.json @@ -35,5 +35,5 @@ "importsNotUsedAsValues": "error" }, "include": ["./src/**/*", "./packages"], - "exclude": ["./packages/rts", "**/*.stories.tsx"] + "exclude": ["./packages/rts"] } diff --git a/app/client/yarn.lock b/app/client/yarn.lock index f7a36e9760..94b9c818ad 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -160,6 +160,17 @@ __metadata: languageName: node linkType: hard +"@aw-web-design/x-default-browser@npm:1.4.126": + version: 1.4.126 + resolution: "@aw-web-design/x-default-browser@npm:1.4.126" + dependencies: + default-browser-id: 3.0.0 + bin: + x-default-browser: bin/x-default-browser.js + checksum: f63b68a0ff41c8fe478b1b4822e169cac0d26c61b123c0400d5e16a8a5987732b85795aff16d6b21936f9c955f0d32bffbfc166890d3446f74a72a7a2c9633ea + languageName: node + linkType: hard + "@babel/cli@npm:^7.21.0": version: 7.22.6 resolution: "@babel/cli@npm:7.22.6" @@ -187,7 +198,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.22.5, @babel/code-frame@npm:^7.5.5, @babel/code-frame@npm:^7.8.3": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.5, @babel/code-frame@npm:^7.8.3": version: 7.22.5 resolution: "@babel/code-frame@npm:7.22.5" dependencies: @@ -196,57 +207,33 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.22.5, @babel/compat-data@npm:^7.22.6": - version: 7.22.6 - resolution: "@babel/compat-data@npm:7.22.6" - checksum: b88631143a2ebdb75e5bac47984e950983294f1739c2133f32569c6f2fcee85f83634bb6cf4378afb44fa8eb7877d11e48811d1e6a52afa161f82276ffdc3fb4 +"@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.22.5, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9": + version: 7.22.9 + resolution: "@babel/compat-data@npm:7.22.9" + checksum: bed77d9044ce948b4327b30dd0de0779fa9f3a7ed1f2d31638714ed00229fa71fc4d1617ae0eb1fad419338d3658d0e9a5a083297451e09e73e078d0347ff808 languageName: node linkType: hard -"@babel/core@npm:7.12.9": - version: 7.12.9 - resolution: "@babel/core@npm:7.12.9" - dependencies: - "@babel/code-frame": ^7.10.4 - "@babel/generator": ^7.12.5 - "@babel/helper-module-transforms": ^7.12.1 - "@babel/helpers": ^7.12.5 - "@babel/parser": ^7.12.7 - "@babel/template": ^7.12.7 - "@babel/traverse": ^7.12.9 - "@babel/types": ^7.12.7 - convert-source-map: ^1.7.0 - debug: ^4.1.0 - gensync: ^1.0.0-beta.1 - json5: ^2.1.2 - lodash: ^4.17.19 - resolve: ^1.3.2 - semver: ^5.4.1 - source-map: ^0.5.0 - checksum: 4d34eca4688214a4eb6bd5dde906b69a7824f17b931f52cd03628a8ac94d8fbe15565aebffdde106e974c8738cd64ac62c6a6060baa7139a06db1f18c4ff872d - languageName: node - linkType: hard - -"@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.1, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.10, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.19.6, @babel/core@npm:^7.21.0, @babel/core@npm:^7.7.2, @babel/core@npm:^7.7.5, @babel/core@npm:^7.8.0": - version: 7.22.6 - resolution: "@babel/core@npm:7.22.6" +"@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.1, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.16.0, @babel/core@npm:^7.19.6, @babel/core@npm:^7.21.0, @babel/core@npm:^7.22.9, @babel/core@npm:^7.7.2, @babel/core@npm:^7.7.5, @babel/core@npm:^7.8.0": + version: 7.22.9 + resolution: "@babel/core@npm:7.22.9" dependencies: "@ampproject/remapping": ^2.2.0 "@babel/code-frame": ^7.22.5 - "@babel/generator": ^7.22.5 - "@babel/helper-compilation-targets": ^7.22.6 - "@babel/helper-module-transforms": ^7.22.5 + "@babel/generator": ^7.22.9 + "@babel/helper-compilation-targets": ^7.22.9 + "@babel/helper-module-transforms": ^7.22.9 "@babel/helpers": ^7.22.6 - "@babel/parser": ^7.22.6 + "@babel/parser": ^7.22.7 "@babel/template": ^7.22.5 - "@babel/traverse": ^7.22.6 + "@babel/traverse": ^7.22.8 "@babel/types": ^7.22.5 - "@nicolo-ribaudo/semver-v6": ^6.3.3 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.2 - checksum: 6113ff87c0b707f9c2216285cd3e0a02088ecee427a75a6f3f865da7db25a4863ceb34950248df6ad86f6dd5c608b0f7220f972533f1cc27ff6a9b4380d6ef2c + semver: ^6.3.1 + checksum: 7bf069aeceb417902c4efdaefab1f7b94adb7dea694a9aed1bda2edf4135348a080820529b1a300c6f8605740a00ca00c19b2d5e74b5dd489d99d8c11d5e56d1 languageName: node linkType: hard @@ -264,15 +251,15 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.12.5, @babel/generator@npm:^7.22.5, @babel/generator@npm:^7.7.2": - version: 7.22.5 - resolution: "@babel/generator@npm:7.22.5" +"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.22.7, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.7.2": + version: 7.22.9 + resolution: "@babel/generator@npm:7.22.9" dependencies: "@babel/types": ^7.22.5 "@jridgewell/gen-mapping": ^0.3.2 "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: efa64da70ca88fe69f05520cf5feed6eba6d30a85d32237671488cc355fdc379fe2c3246382a861d49574c4c2f82a317584f8811e95eb024e365faff3232b49d + checksum: 7c9d2c58b8d5ac5e047421a6ab03ec2ff5d9a5ff2c2212130a0055e063ac349e0b19d435537d6886c999771aef394832e4f54cd9fc810100a7f23d982f6af06b languageName: node linkType: hard @@ -294,18 +281,18 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.13.0, @babel/helper-compilation-targets@npm:^7.17.7, @babel/helper-compilation-targets@npm:^7.20.7, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6": - version: 7.22.6 - resolution: "@babel/helper-compilation-targets@npm:7.22.6" +"@babel/helper-compilation-targets@npm:^7.17.7, @babel/helper-compilation-targets@npm:^7.20.7, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.22.9": + version: 7.22.9 + resolution: "@babel/helper-compilation-targets@npm:7.22.9" dependencies: - "@babel/compat-data": ^7.22.6 + "@babel/compat-data": ^7.22.9 "@babel/helper-validator-option": ^7.22.5 - "@nicolo-ribaudo/semver-v6": ^6.3.3 browserslist: ^4.21.9 lru-cache: ^5.1.1 + semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: c7788c48099c4f0edf2adeb367a941a930d39ed7453140ceb10d7114c4091922adf56d3cdd832050fd4501f25e872886390629042ddd365d3bce2ecad69ed394 + checksum: ea0006c6a93759025f4a35a25228ae260538c9f15023e8aac2a6d45ca68aef4cf86cfc429b19af9a402cbdd54d5de74ad3fbcf6baa7e48184dc079f1a791e178 languageName: node linkType: hard @@ -341,24 +328,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.1.5": - version: 0.1.5 - resolution: "@babel/helper-define-polyfill-provider@npm:0.1.5" - dependencies: - "@babel/helper-compilation-targets": ^7.13.0 - "@babel/helper-module-imports": ^7.12.13 - "@babel/helper-plugin-utils": ^7.13.0 - "@babel/traverse": ^7.13.0 - debug: ^4.1.1 - lodash.debounce: ^4.0.8 - resolve: ^1.14.2 - semver: ^6.1.2 - peerDependencies: - "@babel/core": ^7.4.0-0 - checksum: 6f8b61b41730bedc9c4511035b7f2407ea30176c379107dd735aac7d010317a99171bf420959ba37418fb8a857dac7c0e36e1c8576a6560bdd9b690eb4314a95 - languageName: node - linkType: hard - "@babel/helper-define-polyfill-provider@npm:^0.3.3": version: 0.3.3 resolution: "@babel/helper-define-polyfill-provider@npm:0.3.3" @@ -375,19 +344,18 @@ __metadata: languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.4.0": - version: 0.4.0 - resolution: "@babel/helper-define-polyfill-provider@npm:0.4.0" +"@babel/helper-define-polyfill-provider@npm:^0.4.2": + version: 0.4.2 + resolution: "@babel/helper-define-polyfill-provider@npm:0.4.2" dependencies: - "@babel/helper-compilation-targets": ^7.17.7 - "@babel/helper-plugin-utils": ^7.16.7 + "@babel/helper-compilation-targets": ^7.22.6 + "@babel/helper-plugin-utils": ^7.22.5 debug: ^4.1.1 lodash.debounce: ^4.0.8 resolve: ^1.14.2 - semver: ^6.1.2 peerDependencies: - "@babel/core": ^7.4.0-0 - checksum: 5dca4c5e78457c5ced366bea601efa4e8c69bf5d53b0fe540283897575c49b1b88191c8ef062110de9046e886703ed3270fcda3a87f0886cdbb549204d3ff63f + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 1f6dec0c5d0876d278fe15b71238eccc5f74c4e2efa2c78aaafa8bc2cc96336b8e68d94cd1a78497356c96e8b91b8c1f4452179820624d1702aee2f9832e6569 languageName: node linkType: hard @@ -426,7 +394,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.0.0-beta.49, @babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.18.6, @babel/helper-module-imports@npm:^7.21.4, @babel/helper-module-imports@npm:^7.22.5": +"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.0.0-beta.49, @babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.18.6, @babel/helper-module-imports@npm:^7.21.4, @babel/helper-module-imports@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-module-imports@npm:7.22.5" dependencies: @@ -435,19 +403,18 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-module-transforms@npm:7.22.5" +"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.22.9": + version: 7.22.9 + resolution: "@babel/helper-module-transforms@npm:7.22.9" dependencies: "@babel/helper-environment-visitor": ^7.22.5 "@babel/helper-module-imports": ^7.22.5 "@babel/helper-simple-access": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 "@babel/helper-validator-identifier": ^7.22.5 - "@babel/template": ^7.22.5 - "@babel/traverse": ^7.22.5 - "@babel/types": ^7.22.5 - checksum: 8985dc0d971fd17c467e8b84fe0f50f3dd8610e33b6c86e5b3ca8e8859f9448bcc5c84e08a2a14285ef388351c0484797081c8f05a03770bf44fc27bf4900e68 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 2751f77660518cf4ff027514d6f4794f04598c6393be7b04b8e46c6e21606e11c19f3f57ab6129a9c21bacdf8b3ffe3af87bb401d972f34af2d0ffde02ac3001 languageName: node linkType: hard @@ -460,14 +427,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:7.10.4": - version: 7.10.4 - resolution: "@babel/helper-plugin-utils@npm:7.10.4" - checksum: 639ed8fc462b97a83226cee6bb081b1d77e7f73e8b033d2592ed107ee41d96601e321e5ea53a33e47469c7f1146b250a3dcda5ab873c7de162ab62120c341a41 - languageName: node - linkType: hard - -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.13.0, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.16.7, @babel/helper-plugin-utils@npm:^7.17.12, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.18.9, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.16.7, @babel/helper-plugin-utils@npm:^7.17.12, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": version: 7.22.5 resolution: "@babel/helper-plugin-utils@npm:7.22.5" checksum: c0fc7227076b6041acd2f0e818145d2e8c41968cc52fb5ca70eed48e21b8fe6dd88a0a91cbddf4951e33647336eb5ae184747ca706817ca3bef5e9e905151ff5 @@ -520,7 +480,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.18.6, @babel/helper-split-export-declaration@npm:^7.22.5, @babel/helper-split-export-declaration@npm:^7.22.6": +"@babel/helper-split-export-declaration@npm:^7.18.6, @babel/helper-split-export-declaration@npm:^7.22.6": version: 7.22.6 resolution: "@babel/helper-split-export-declaration@npm:7.22.6" dependencies: @@ -543,7 +503,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.18.6, @babel/helper-validator-option@npm:^7.22.5": +"@babel/helper-validator-option@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-validator-option@npm:7.22.5" checksum: bbeca8a85ee86990215c0424997438b388b8d642d69b9f86c375a174d3cdeb270efafd1ff128bc7a1d370923d13b6e45829ba8581c027620e83e3a80c5c414b3 @@ -562,7 +522,7 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.12.5, @babel/helpers@npm:^7.22.6": +"@babel/helpers@npm:^7.22.6": version: 7.22.6 resolution: "@babel/helpers@npm:7.22.6" dependencies: @@ -584,12 +544,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.11, @babel/parser@npm:^7.12.7, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.5, @babel/parser@npm:^7.22.6": - version: 7.22.6 - resolution: "@babel/parser@npm:7.22.6" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.5, @babel/parser@npm:^7.22.7": + version: 7.22.7 + resolution: "@babel/parser@npm:7.22.7" bin: parser: ./bin/babel-parser.js - checksum: 1f81e2e82a0e931b33ae739d47987ba5d6736d47867df7cb7cab5edd5a908402f27964f1a1b383e8b80512585182187094cc951dbc9bab776a65532e864b3ce7 + checksum: 02209ddbd445831ee8bf966fdf7c29d189ed4b14343a68eb2479d940e7e3846340d7cc6bd654a5f3d87d19dc84f49f50a58cf9363bee249dc5409ff3ba3dab54 languageName: node linkType: hard @@ -628,7 +588,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-class-properties@npm:^7.12.1, @babel/plugin-proposal-class-properties@npm:^7.16.0, @babel/plugin-proposal-class-properties@npm:^7.18.6": +"@babel/plugin-proposal-class-properties@npm:^7.13.0, @babel/plugin-proposal-class-properties@npm:^7.16.0, @babel/plugin-proposal-class-properties@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-proposal-class-properties@npm:7.18.6" dependencies: @@ -640,7 +600,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-decorators@npm:^7.12.12, @babel/plugin-proposal-decorators@npm:^7.16.4": +"@babel/plugin-proposal-decorators@npm:^7.16.4": version: 7.21.0 resolution: "@babel/plugin-proposal-decorators@npm:7.21.0" dependencies: @@ -655,19 +615,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-export-default-from@npm:^7.12.1": - version: 7.18.10 - resolution: "@babel/plugin-proposal-export-default-from@npm:7.18.10" - dependencies: - "@babel/helper-plugin-utils": ^7.18.9 - "@babel/plugin-syntax-export-default-from": ^7.18.6 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 2a12387e095ccd02a1560e5dd40812a83befe581d319685ae2a95f0650a4500381c1d9c710e6e29b34a1b053f9632ee2d3827b937e1cc5c9d2555280da22df53 - languageName: node - linkType: hard - -"@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.12.1, @babel/plugin-proposal-nullish-coalescing-operator@npm:^7.16.0": +"@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.13.8, @babel/plugin-proposal-nullish-coalescing-operator@npm:^7.16.0": version: 7.18.6 resolution: "@babel/plugin-proposal-nullish-coalescing-operator@npm:7.18.6" dependencies: @@ -691,20 +639,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-object-rest-spread@npm:7.12.1": - version: 7.12.1 - resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.12.1" - dependencies: - "@babel/helper-plugin-utils": ^7.10.4 - "@babel/plugin-syntax-object-rest-spread": ^7.8.0 - "@babel/plugin-transform-parameters": ^7.12.1 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 221a41630c9a7162bf0416c71695b3f7f38482078a1d0d3af7abdc4f07ea1c9feed890399158d56c1d0278c971fe6f565ce822e9351e4481f7d98e9ff735dced - languageName: node - linkType: hard - -"@babel/plugin-proposal-object-rest-spread@npm:^7.12.1, @babel/plugin-proposal-object-rest-spread@npm:^7.16.0, @babel/plugin-proposal-object-rest-spread@npm:^7.20.7": +"@babel/plugin-proposal-object-rest-spread@npm:^7.16.0, @babel/plugin-proposal-object-rest-spread@npm:^7.20.7": version: 7.20.7 resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.20.7" dependencies: @@ -719,7 +654,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-optional-chaining@npm:^7.12.7, @babel/plugin-proposal-optional-chaining@npm:^7.16.0": +"@babel/plugin-proposal-optional-chaining@npm:^7.13.12, @babel/plugin-proposal-optional-chaining@npm:^7.16.0": version: 7.21.0 resolution: "@babel/plugin-proposal-optional-chaining@npm:7.21.0" dependencies: @@ -732,7 +667,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-private-methods@npm:^7.12.1, @babel/plugin-proposal-private-methods@npm:^7.16.0": +"@babel/plugin-proposal-private-methods@npm:^7.16.0": version: 7.18.6 resolution: "@babel/plugin-proposal-private-methods@npm:7.18.6" dependencies: @@ -753,7 +688,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-private-property-in-object@npm:^7.12.1, @babel/plugin-proposal-private-property-in-object@npm:^7.16.0": +"@babel/plugin-proposal-private-property-in-object@npm:^7.16.0": version: 7.21.0 resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0" dependencies: @@ -845,17 +780,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-export-default-from@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-syntax-export-default-from@npm:7.18.6" - dependencies: - "@babel/helper-plugin-utils": ^7.18.6 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 4258156553d825abb2ebac920eae6837087b485eb8e0011e05ad1e57004a03441335325feb18185ffbfa0c33a340673e7ab79549080ff2beb4607f88936fedf2 - languageName: node - linkType: hard - "@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" @@ -867,14 +791,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-flow@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-syntax-flow@npm:7.18.6" +"@babel/plugin-syntax-flow@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-flow@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: abe82062b3eef14de7d2b3c0e4fecf80a3e796ca497e9df616d12dd250968abf71495ee85a955b43a6c827137203f0c409450cf792732ed0d6907c806580ea71 + checksum: 84c8c40fcfe8e78cecdd6fb90e8f97f419e3f3b27a33de8324ae97d5ce1b87cdd98a636fa21a68d4d2c37c7d63f3a279bb84b6956b849921affed6b806b6ffe7 languageName: node linkType: hard @@ -922,17 +846,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:7.12.1": - version: 7.12.1 - resolution: "@babel/plugin-syntax-jsx@npm:7.12.1" - dependencies: - "@babel/helper-plugin-utils": ^7.10.4 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: d4b9b589c484b2e0856799770f060dff34c67b24d7f4526f66309a0e0e9cf388a5c1f2c0da329d1973cc87d1b2cede8f3dc8facfac59e785d6393a003bcdd0f9 - languageName: node - linkType: hard - "@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.7.2": version: 7.22.5 resolution: "@babel/plugin-syntax-jsx@npm:7.22.5" @@ -977,7 +890,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-object-rest-spread@npm:7.8.3, @babel/plugin-syntax-object-rest-spread@npm:^7.8.0, @babel/plugin-syntax-object-rest-spread@npm:^7.8.3": +"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" dependencies: @@ -1055,7 +968,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.12.1, @babel/plugin-transform-arrow-functions@npm:^7.22.5": +"@babel/plugin-transform-arrow-functions@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-arrow-functions@npm:7.22.5" dependencies: @@ -1066,9 +979,9 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.22.5" +"@babel/plugin-transform-async-generator-functions@npm:^7.22.7": + version: 7.22.7 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.22.7" dependencies: "@babel/helper-environment-visitor": ^7.22.5 "@babel/helper-plugin-utils": ^7.22.5 @@ -1076,7 +989,7 @@ __metadata: "@babel/plugin-syntax-async-generators": ^7.8.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 32890b69ec5627eb46ee8e084bddc6b98d85b66cae5e015f3a23924611a759789d2ff836406605f5293b5c2bad306b20cb1f5b7a46ed549b07bfec634bcd31f9 + checksum: 57cd2cce3fb696dadf00e88f168683df69e900b92dadeae07429243c43bc21d5ccdc0c2db61cf5c37bd0fbd893fc455466bef6babe4aa5b79d9cb8ba89f40ae7 languageName: node linkType: hard @@ -1104,7 +1017,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.12.12, @babel/plugin-transform-block-scoping@npm:^7.22.5": +"@babel/plugin-transform-block-scoping@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-block-scoping@npm:7.22.5" dependencies: @@ -1140,7 +1053,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.12.1, @babel/plugin-transform-classes@npm:^7.22.6": +"@babel/plugin-transform-classes@npm:^7.22.6": version: 7.22.6 resolution: "@babel/plugin-transform-classes@npm:7.22.6" dependencies: @@ -1171,7 +1084,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.12.1, @babel/plugin-transform-destructuring@npm:^7.22.5": +"@babel/plugin-transform-destructuring@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-destructuring@npm:7.22.5" dependencies: @@ -1241,19 +1154,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-flow-strip-types@npm:^7.16.0, @babel/plugin-transform-flow-strip-types@npm:^7.18.6": - version: 7.21.0 - resolution: "@babel/plugin-transform-flow-strip-types@npm:7.21.0" +"@babel/plugin-transform-flow-strip-types@npm:^7.16.0, @babel/plugin-transform-flow-strip-types@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-flow-strip-types@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 - "@babel/plugin-syntax-flow": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/plugin-syntax-flow": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a45951c57265c366f95db9a5e70a62cfc3eafafa3f3d23295357577b5fc139d053d45416cdbdf4a0a387e41cefc434ab94dd6c3048d03b094ff6d041dd10a0b0 + checksum: 1ba48187d6f33814be01c6870489f0b1858256cf2b9dd7e62f02af8b30049bf375112f1d44692c5fed3cb9cd26ee2fb32e358cd79b6ad2360a51e8f993e861bf languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.12.1, @babel/plugin-transform-for-of@npm:^7.22.5": +"@babel/plugin-transform-for-of@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-for-of@npm:7.22.5" dependencies: @@ -1335,7 +1248,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.22.5": +"@babel/plugin-transform-modules-commonjs@npm:^7.13.8, @babel/plugin-transform-modules-commonjs@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.22.5" dependencies: @@ -1473,7 +1386,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.12.1, @babel/plugin-transform-parameters@npm:^7.20.7, @babel/plugin-transform-parameters@npm:^7.22.5": +"@babel/plugin-transform-parameters@npm:^7.20.7, @babel/plugin-transform-parameters@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-parameters@npm:7.22.5" dependencies: @@ -1554,7 +1467,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.12.12, @babel/plugin-transform-react-jsx@npm:^7.22.5": +"@babel/plugin-transform-react-jsx@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-react-jsx@npm:7.22.5" dependencies: @@ -1620,7 +1533,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.12.1, @babel/plugin-transform-shorthand-properties@npm:^7.22.5": +"@babel/plugin-transform-shorthand-properties@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.22.5" dependencies: @@ -1631,7 +1544,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.12.1, @babel/plugin-transform-spread@npm:^7.22.5": +"@babel/plugin-transform-spread@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-spread@npm:7.22.5" dependencies: @@ -1654,7 +1567,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.12.1, @babel/plugin-transform-template-literals@npm:^7.22.5": +"@babel/plugin-transform-template-literals@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-template-literals@npm:7.22.5" dependencies: @@ -1737,12 +1650,12 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.12.11, @babel/preset-env@npm:^7.16.0, @babel/preset-env@npm:^7.16.4, @babel/preset-env@npm:^7.20.2": - version: 7.22.6 - resolution: "@babel/preset-env@npm:7.22.6" +"@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.16.0, @babel/preset-env@npm:^7.16.4, @babel/preset-env@npm:^7.20.2, @babel/preset-env@npm:^7.22.9": + version: 7.22.9 + resolution: "@babel/preset-env@npm:7.22.9" dependencies: - "@babel/compat-data": ^7.22.6 - "@babel/helper-compilation-targets": ^7.22.6 + "@babel/compat-data": ^7.22.9 + "@babel/helper-compilation-targets": ^7.22.9 "@babel/helper-plugin-utils": ^7.22.5 "@babel/helper-validator-option": ^7.22.5 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.22.5 @@ -1767,7 +1680,7 @@ __metadata: "@babel/plugin-syntax-top-level-await": ^7.14.5 "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 "@babel/plugin-transform-arrow-functions": ^7.22.5 - "@babel/plugin-transform-async-generator-functions": ^7.22.5 + "@babel/plugin-transform-async-generator-functions": ^7.22.7 "@babel/plugin-transform-async-to-generator": ^7.22.5 "@babel/plugin-transform-block-scoped-functions": ^7.22.5 "@babel/plugin-transform-block-scoping": ^7.22.5 @@ -1816,27 +1729,27 @@ __metadata: "@babel/plugin-transform-unicode-sets-regex": ^7.22.5 "@babel/preset-modules": ^0.1.5 "@babel/types": ^7.22.5 - "@nicolo-ribaudo/semver-v6": ^6.3.3 - babel-plugin-polyfill-corejs2: ^0.4.3 - babel-plugin-polyfill-corejs3: ^0.8.1 - babel-plugin-polyfill-regenerator: ^0.5.0 + babel-plugin-polyfill-corejs2: ^0.4.4 + babel-plugin-polyfill-corejs3: ^0.8.2 + babel-plugin-polyfill-regenerator: ^0.5.1 core-js-compat: ^3.31.0 + semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0e56f737a737de8dab192ac65c5c26a05872094a6b90ed4c23d620e483adf1d6c9a385d6973c8d752f0f54e2a1d6330bdd4cddf474619fc4815fb44ece82bae5 + checksum: 6caa2897bbda30c6932aed0a03827deb1337c57108050c9f97dc9a857e1533c7125b168b6d70b9d191965bf05f9f233f0ad20303080505dff7ce39740aaa759d languageName: node linkType: hard -"@babel/preset-flow@npm:^7.12.1": - version: 7.18.6 - resolution: "@babel/preset-flow@npm:7.18.6" +"@babel/preset-flow@npm:^7.13.13, @babel/preset-flow@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/preset-flow@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 - "@babel/helper-validator-option": ^7.18.6 - "@babel/plugin-transform-flow-strip-types": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-validator-option": ^7.22.5 + "@babel/plugin-transform-flow-strip-types": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9100d4eab3402e6601e361a5b235e46d90cfd389c12db19e2a071e1082ca2a00c04bd47eb185ce68d8979e7c8f3e548cd5d61b86dcd701135468fb929c3aecb6 + checksum: 0bf6f587e952f8945d348cf0f25cbc3e50697f2cdc4e1394badfb76cfdde0cc2f2c9250bda3d28ecc6c196b89de7c8e72b8ffbf3086e604b959cce352dd2b34e languageName: node linkType: hard @@ -1855,7 +1768,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-react@npm:^7.12.10, @babel/preset-react@npm:^7.12.5, @babel/preset-react@npm:^7.16.0, @babel/preset-react@npm:^7.18.6": +"@babel/preset-react@npm:^7.12.5, @babel/preset-react@npm:^7.16.0, @babel/preset-react@npm:^7.18.6, @babel/preset-react@npm:^7.22.5": version: 7.22.5 resolution: "@babel/preset-react@npm:7.22.5" dependencies: @@ -1871,7 +1784,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.12.7, @babel/preset-typescript@npm:^7.16.0, @babel/preset-typescript@npm:^7.17.12, @babel/preset-typescript@npm:^7.21.0": +"@babel/preset-typescript@npm:^7.13.0, @babel/preset-typescript@npm:^7.16.0, @babel/preset-typescript@npm:^7.17.12, @babel/preset-typescript@npm:^7.21.0": version: 7.22.5 resolution: "@babel/preset-typescript@npm:7.22.5" dependencies: @@ -1886,9 +1799,9 @@ __metadata: languageName: node linkType: hard -"@babel/register@npm:^7.12.1": - version: 7.21.0 - resolution: "@babel/register@npm:7.21.0" +"@babel/register@npm:^7.13.16": + version: 7.22.5 + resolution: "@babel/register@npm:7.22.5" dependencies: clone-deep: ^4.0.1 find-cache-dir: ^2.0.0 @@ -1897,7 +1810,7 @@ __metadata: source-map-support: ^0.5.16 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9745cc7520b4c5e64cc54f4851c3b78af82e1f8cffc9041f5cc0b9aef62d86a9a8617327fc975b5e0e39cb5cc0aba7ae02429884390ee93e0de29152fa849b4f + checksum: 723ce27fdad6faee5b3f51ef4f5154f7f285d61da665367de14de85abbe1c81ccbac11f699671cd0ed6b755dd430f28a62364fed5d49f2527625a9ea3bf40056 languageName: node linkType: hard @@ -1928,16 +1841,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:7.7.2": - version: 7.7.2 - resolution: "@babel/runtime@npm:7.7.2" - dependencies: - regenerator-runtime: ^0.13.2 - checksum: 4319b6a1771f2e0181de26a983ae2788f1af428dcac3c0225d459be8a50167cee5be0d66856306b8eab53c1b3e1cae68cb481ef1be5ca2259f997ce3b12557b7 - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.16.0, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.7.7, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.1, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.16.0, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.7.7, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.21.5 resolution: "@babel/runtime@npm:7.21.5" dependencies: @@ -1946,16 +1850,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:~7.5.4": - version: 7.5.5 - resolution: "@babel/runtime@npm:7.5.5" - dependencies: - regenerator-runtime: ^0.13.2 - checksum: b04ed65993bbf4371a880f7afc289f1f2a5f5a9e882c64448b41481aa289ed650a2b6155c6179f3d32fccf159f9be947989af5ff7a4f9b847f60f25e631ad533 - languageName: node - linkType: hard - -"@babel/template@npm:^7.12.7, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3": version: 7.22.5 resolution: "@babel/template@npm:7.22.5" dependencies: @@ -1966,25 +1861,25 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.12.11, @babel/traverse@npm:^7.12.9, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.21.2, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.22.6, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.2": - version: 7.22.6 - resolution: "@babel/traverse@npm:7.22.6" +"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.21.2, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.22.6, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.2": + version: 7.22.8 + resolution: "@babel/traverse@npm:7.22.8" dependencies: "@babel/code-frame": ^7.22.5 - "@babel/generator": ^7.22.5 + "@babel/generator": ^7.22.7 "@babel/helper-environment-visitor": ^7.22.5 "@babel/helper-function-name": ^7.22.5 "@babel/helper-hoist-variables": ^7.22.5 "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/parser": ^7.22.6 + "@babel/parser": ^7.22.7 "@babel/types": ^7.22.5 debug: ^4.1.0 globals: ^11.1.0 - checksum: e38c6bf31c62b646dab0e90b86ed4fd03ba5be2f14bbdb5370939b9479c477633c33c34efd2ea45f24aa41ac50605cb41d7f1f4281193f79dcf99e999ebe6166 + checksum: a381369bc3eedfd13ed5fef7b884657f1c29024ea7388198149f0edc34bd69ce3966e9f40188d15f56490a5e12ba250ccc485f2882b53d41b054fccefb233e33 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.12.7, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.6, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.22.5 resolution: "@babel/types@npm:7.22.5" dependencies: @@ -2131,18 +2026,6 @@ __metadata: languageName: node linkType: hard -"@cnakazawa/watch@npm:^1.0.3": - version: 1.0.4 - resolution: "@cnakazawa/watch@npm:1.0.4" - dependencies: - exec-sh: ^0.3.2 - minimist: ^1.2.0 - bin: - watch: cli.js - checksum: 88f395ca0af2f3c0665b8ce7bb29e83647ec5d141e8735712aeeee4117081555436712966b6957aa1c461f6f826a4d23b0034e379c443a10e919f81c8748bf29 - languageName: node - linkType: hard - "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -2345,9 +2228,9 @@ __metadata: languageName: node linkType: hard -"@cypress/request@npm:^2.88.10": - version: 2.88.10 - resolution: "@cypress/request@npm:2.88.10" +"@cypress/request@npm:^2.88.11": + version: 2.88.11 + resolution: "@cypress/request@npm:2.88.11" dependencies: aws-sign2: ~0.7.0 aws4: ^1.8.0 @@ -2362,12 +2245,12 @@ __metadata: json-stringify-safe: ~5.0.1 mime-types: ~2.1.19 performance-now: ^2.1.0 - qs: ~6.5.2 + qs: ~6.10.3 safe-buffer: ^5.1.2 tough-cookie: ~2.5.0 tunnel-agent: ^0.6.0 uuid: ^8.3.2 - checksum: 69c3e3b332e9be4866a900f6bcca5d274d8cea6c99707fbcce061de8dbab11c9b1e39f4c017f6e83e6e682717781d4f6106fd6b7cf9546580fcfac353b6676cf + checksum: e4b3f62e0c41c4ccca6c942828461d8ea717e752fd918d685e9f74e2ebcfa8b7942427f7ce971e502635c3bf3d40011476db84dc753d3dc360c6d08350da6f93 languageName: node linkType: hard @@ -2391,6 +2274,7 @@ __metadata: "@react-aria/focus": ^3.11.0 "@react-aria/interactions": ^3.14.0 "@react-aria/radio": ^3.6.1 + "@react-aria/switch": ^3.5.2 "@react-aria/utils": ^3.16.0 "@react-aria/visually-hidden": ^3.8.0 "@react-spectrum/utils": ^3.9.0 @@ -2415,27 +2299,29 @@ __metadata: "@babel/preset-env": ^7.20.2 "@babel/preset-react": ^7.18.6 "@babel/preset-typescript": ^7.21.0 - "@storybook/addon-actions": ^6.5.16 - "@storybook/addon-essentials": ^6.5.16 - "@storybook/addon-interactions": ^6.5.16 - "@storybook/addon-links": ^6.5.16 - "@storybook/addon-postcss": ^2.0.0 - "@storybook/builder-webpack5": ^6.5.16 - "@storybook/manager-webpack5": ^6.5.16 - "@storybook/node-logger": ^6.5.16 - "@storybook/preset-create-react-app": ^4.1.2 - "@storybook/react": ^6.5.16 - "@storybook/testing-library": ^0.0.13 - "@types/react": ^17.0.2 - "@types/react-dom": ^17.0.2 - autoprefixer: ^9.0.0 + "@design-system/headless": "workspace:^" + "@design-system/theming": "workspace:^" + "@design-system/widgets": "workspace:^" + "@design-system/widgets-old": "workspace:^" + "@storybook/addon-actions": ^7.1.1 + "@storybook/addon-controls": ^7.1.1 + "@storybook/addon-docs": ^7.1.1 + "@storybook/addon-measure": ^7.1.1 + "@storybook/addon-outline": ^7.1.1 + "@storybook/addon-toolbars": ^7.1.1 + "@storybook/addon-viewport": ^7.1.1 + "@storybook/blocks": ^7.1.1 + "@storybook/components": ^7.1.1 + "@storybook/manager-api": ^7.1.1 + "@storybook/preset-create-react-app": ^7.1.1 + "@storybook/react": ^7.1.1 + "@storybook/react-webpack5": ^7.1.1 + "@storybook/theming": ^7.1.1 babel-loader: 9.1.2 - chromatic: ^6.19.8 + chromatic: ^6.20.0 colorjs.io: ^0.4.3 - postcss: ^8.4.23 react-docgen-typescript: ^2.2.2 - storybook-addon-pseudo-states: ^1.15.2 - storybook-color-picker: ^3.1.0 + storybook: ^7.1.1 tsconfig-paths-webpack-plugin: ^4.0.1 languageName: unknown linkType: soft @@ -2509,72 +2395,6 @@ __metadata: languageName: unknown linkType: soft -"@design-systems/utils@npm:2.12.0": - version: 2.12.0 - resolution: "@design-systems/utils@npm:2.12.0" - dependencies: - "@babel/runtime": ^7.11.2 - clsx: ^1.0.4 - focus-lock: ^0.8.0 - react-merge-refs: ^1.0.0 - peerDependencies: - "@types/react": "*" - react: ">= 16.8.6" - react-dom: ">= 16.8.6" - checksum: 6659eadb485b55d25d465b0b262c22e7d196f35b27aa1f8f7b6f3bacda9d7c5f6186a46afe56dd223c70f91c61392c81a541ea7dec588960499d049a8c06f3b7 - languageName: node - linkType: hard - -"@devtools-ds/object-inspector@npm:^1.1.2": - version: 1.2.1 - resolution: "@devtools-ds/object-inspector@npm:1.2.1" - dependencies: - "@babel/runtime": 7.7.2 - "@devtools-ds/object-parser": ^1.2.1 - "@devtools-ds/themes": ^1.2.1 - "@devtools-ds/tree": ^1.2.1 - clsx: 1.1.0 - peerDependencies: - react: ">= 16.8.6" - checksum: fc9393b08b1559743dbcb153deb82ab112c47c72ca1751001e8a0385b67307de5cf191a073335d671059bb6f850ecd1e96f0807edee1d192cb3c92d8802323bb - languageName: node - linkType: hard - -"@devtools-ds/object-parser@npm:^1.2.1": - version: 1.2.1 - resolution: "@devtools-ds/object-parser@npm:1.2.1" - dependencies: - "@babel/runtime": ~7.5.4 - checksum: 1213976189a5cf0095bba96e529c2e61cdbffb1a4bc5b7e5a5740d64ad14178788ad734f7a56ab0e6ac715d8a61e30f5e002cc3591f3ff35f16a50ccc0efa644 - languageName: node - linkType: hard - -"@devtools-ds/themes@npm:^1.2.1": - version: 1.2.1 - resolution: "@devtools-ds/themes@npm:1.2.1" - dependencies: - "@babel/runtime": ~7.5.4 - "@design-systems/utils": 2.12.0 - clsx: 1.1.0 - peerDependencies: - react: ">= 16.8.6" - checksum: 00396c5bf833b1e86ff43b8d4e09be904c9086b95570fef0740e913b805984b249820af7e9e04afb36f4cdc296217f09f96d9178be86f2c02352d7395384bc9e - languageName: node - linkType: hard - -"@devtools-ds/tree@npm:^1.2.1": - version: 1.2.1 - resolution: "@devtools-ds/tree@npm:1.2.1" - dependencies: - "@babel/runtime": 7.7.2 - "@devtools-ds/themes": ^1.2.1 - clsx: 1.1.0 - peerDependencies: - react: ">= 16.8.6" - checksum: d895cfb483404af28e1275400d015c003bf14b3201d0951b4c7a9a47319e029383115881ea69d902459a8c53b93e24210026427192ad682e9f752be40abef923 - languageName: node - linkType: hard - "@discoveryjs/json-ext@npm:^0.5.3": version: 0.5.7 resolution: "@discoveryjs/json-ext@npm:0.5.7" @@ -2582,25 +2402,6 @@ __metadata: languageName: node linkType: hard -"@emotion/babel-plugin@npm:^11.10.6": - version: 11.10.6 - resolution: "@emotion/babel-plugin@npm:11.10.6" - dependencies: - "@babel/helper-module-imports": ^7.16.7 - "@babel/runtime": ^7.18.3 - "@emotion/hash": ^0.9.0 - "@emotion/memoize": ^0.8.0 - "@emotion/serialize": ^1.1.1 - babel-plugin-macros: ^3.1.0 - convert-source-map: ^1.5.0 - escape-string-regexp: ^4.0.0 - find-root: ^1.1.0 - source-map: ^0.5.7 - stylis: 4.1.3 - checksum: 3eed138932e8edf2598352e69ad949b9db3051a4d6fcff190dacbac9aa838d7ef708b9f3e6c48660625d9311dae82d73477ae4e7a31139feef5eb001a5528421 - languageName: node - linkType: hard - "@emotion/cache@npm:^10.0.27, @emotion/cache@npm:^10.0.9": version: 10.0.29 resolution: "@emotion/cache@npm:10.0.29" @@ -2613,19 +2414,6 @@ __metadata: languageName: node linkType: hard -"@emotion/cache@npm:^11.10.5": - version: 11.10.5 - resolution: "@emotion/cache@npm:11.10.5" - dependencies: - "@emotion/memoize": ^0.8.0 - "@emotion/sheet": ^1.2.1 - "@emotion/utils": ^1.2.0 - "@emotion/weak-memoize": ^0.3.0 - stylis: 4.1.3 - checksum: 1dd2d9af2d3ecbd3d4469ecdf91a335eef6034c851b57a474471b2d2280613eb35bbed98c0368cc4625f188619fbdaf04cf07e8107aaffce94b2178444c0fe7b - languageName: node - linkType: hard - "@emotion/core@npm:^10.0.9": version: 10.0.35 resolution: "@emotion/core@npm:10.0.35" @@ -2660,13 +2448,6 @@ __metadata: languageName: node linkType: hard -"@emotion/hash@npm:^0.9.0": - version: 0.9.0 - resolution: "@emotion/hash@npm:0.9.0" - checksum: b63428f7c8186607acdca5d003700cecf0ded519d0b5c5cc3b3154eafcad6ff433f8361bd2bac8882715b557e6f06945694aeb6ba8b25c6095d7a88570e2e0bb - languageName: node - linkType: hard - "@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.1": version: 1.2.1 resolution: "@emotion/is-prop-valid@npm:1.2.1" @@ -2683,34 +2464,13 @@ __metadata: languageName: node linkType: hard -"@emotion/memoize@npm:^0.8.0, @emotion/memoize@npm:^0.8.1": +"@emotion/memoize@npm:^0.8.1": version: 0.8.1 resolution: "@emotion/memoize@npm:0.8.1" checksum: a19cc01a29fcc97514948eaab4dc34d8272e934466ed87c07f157887406bc318000c69ae6f813a9001c6a225364df04249842a50e692ef7a9873335fbcc141b0 languageName: node linkType: hard -"@emotion/react@npm:^11.10.5": - version: 11.10.6 - resolution: "@emotion/react@npm:11.10.6" - dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/babel-plugin": ^11.10.6 - "@emotion/cache": ^11.10.5 - "@emotion/serialize": ^1.1.1 - "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0 - "@emotion/utils": ^1.2.0 - "@emotion/weak-memoize": ^0.3.0 - hoist-non-react-statics: ^3.3.1 - peerDependencies: - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 4762042e39126ffaffe76052dc65c9bb0ba6b8893013687ba3cc13ed4dd834c31597f1230684c3c078e90aecc13ab6cd0e3cde0dec8b7761affd2571f4d80019 - languageName: node - linkType: hard - "@emotion/serialize@npm:^0.11.15, @emotion/serialize@npm:^0.11.16": version: 0.11.16 resolution: "@emotion/serialize@npm:0.11.16" @@ -2724,19 +2484,6 @@ __metadata: languageName: node linkType: hard -"@emotion/serialize@npm:^1.1.1": - version: 1.1.1 - resolution: "@emotion/serialize@npm:1.1.1" - dependencies: - "@emotion/hash": ^0.9.0 - "@emotion/memoize": ^0.8.0 - "@emotion/unitless": ^0.8.0 - "@emotion/utils": ^1.2.0 - csstype: ^3.0.2 - checksum: 24cfd5b16e6f2335c032ca33804a876e0442aaf8f9c94d269d23735ebd194fb1ed142542dd92191a3e6ef8bad5bd560dfc5aaf363a1b70954726dbd4dd93085c - languageName: node - linkType: hard - "@emotion/sheet@npm:0.9.4": version: 0.9.4 resolution: "@emotion/sheet@npm:0.9.4" @@ -2744,13 +2491,6 @@ __metadata: languageName: node linkType: hard -"@emotion/sheet@npm:^1.2.1": - version: 1.2.1 - resolution: "@emotion/sheet@npm:1.2.1" - checksum: ce78763588ea522438156344d9f592203e2da582d8d67b32e1b0b98eaba26994c6c270f8c7ad46442fc9c0a9f048685d819cd73ca87e544520fd06f0e24a1562 - languageName: node - linkType: hard - "@emotion/stylis@npm:0.8.5, @emotion/stylis@npm:^0.8.4": version: 0.8.5 resolution: "@emotion/stylis@npm:0.8.5" @@ -2788,13 +2528,6 @@ __metadata: languageName: node linkType: hard -"@emotion/utils@npm:^1.2.0": - version: 1.2.0 - resolution: "@emotion/utils@npm:1.2.0" - checksum: 55457a49ddd4db6a014ea0454dc09eaa23eedfb837095c8ff90470cb26a303f7ceb5fcc1e2190ef64683e64cfd33d3ba3ca3109cd87d12bc9e379e4195c9a4dd - languageName: node - linkType: hard - "@emotion/weak-memoize@npm:0.2.5": version: 0.2.5 resolution: "@emotion/weak-memoize@npm:0.2.5" @@ -2802,10 +2535,157 @@ __metadata: languageName: node linkType: hard -"@emotion/weak-memoize@npm:^0.3.0": - version: 0.3.0 - resolution: "@emotion/weak-memoize@npm:0.3.0" - checksum: f43ef4c8b7de70d9fa5eb3105921724651e4188e895beb71f0c5919dc899a7b8743e1fdd99d38b9092dd5722c7be2312ebb47fbdad0c4e38bea58f6df5885cc0 +"@esbuild/android-arm64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/android-arm64@npm:0.18.17" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/android-arm@npm:0.18.17" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/android-x64@npm:0.18.17" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/darwin-arm64@npm:0.18.17" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/darwin-x64@npm:0.18.17" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/freebsd-arm64@npm:0.18.17" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/freebsd-x64@npm:0.18.17" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-arm64@npm:0.18.17" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-arm@npm:0.18.17" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-ia32@npm:0.18.17" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-loong64@npm:0.18.17" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-mips64el@npm:0.18.17" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-ppc64@npm:0.18.17" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-riscv64@npm:0.18.17" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-s390x@npm:0.18.17" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/linux-x64@npm:0.18.17" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/netbsd-x64@npm:0.18.17" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/openbsd-x64@npm:0.18.17" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/sunos-x64@npm:0.18.17" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/win32-arm64@npm:0.18.17" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/win32-ia32@npm:0.18.17" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.18.17": + version: 0.18.17 + resolution: "@esbuild/win32-x64@npm:0.18.17" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2858,6 +2738,13 @@ __metadata: languageName: node linkType: hard +"@fal-works/esbuild-plugin-global-externals@npm:^2.1.2": + version: 2.1.2 + resolution: "@fal-works/esbuild-plugin-global-externals@npm:2.1.2" + checksum: c59715902b9062aa7ff38973f298b509499fd146dbf564dc338b3f9e896da5bffb4ca676c27587fde79b3586003e24d65960acb62f009bca43dca34c76f8cbf7 + languageName: node + linkType: hard + "@floating-ui/core@npm:^0.7.3": version: 0.7.3 resolution: "@floating-ui/core@npm:0.7.3" @@ -2978,43 +2865,6 @@ __metadata: languageName: node linkType: hard -"@fortawesome/fontawesome-common-types@npm:6.3.0": - version: 6.3.0 - resolution: "@fortawesome/fontawesome-common-types@npm:6.3.0" - checksum: ece71539190abb17144861c58d65b6cd818d38a28cc3c9694325f5dca13739b2d78655e7bc1cba58cc13947f5ca80659e87c5c8bee7beb77d7f991e508312146 - languageName: node - linkType: hard - -"@fortawesome/fontawesome-svg-core@npm:^6.2.1": - version: 6.3.0 - resolution: "@fortawesome/fontawesome-svg-core@npm:6.3.0" - dependencies: - "@fortawesome/fontawesome-common-types": 6.3.0 - checksum: 2479d4b0dc45bba2638b05ba816df91fad6331cd3254d846705a0c342dc12259724706066c71461809804b4f41f15425439cfbabc42d7918e6c26b2b467b4b59 - languageName: node - linkType: hard - -"@fortawesome/free-solid-svg-icons@npm:^6.2.1": - version: 6.3.0 - resolution: "@fortawesome/free-solid-svg-icons@npm:6.3.0" - dependencies: - "@fortawesome/fontawesome-common-types": 6.3.0 - checksum: 5cffcdb954f9ea8d48c6872118f21840f206d6279a6b803a31563e48fee34fbf5bc05848f5dedf07fc16f60910712c6bd0dc83f7a4e408cf062153a48022525d - languageName: node - linkType: hard - -"@fortawesome/react-fontawesome@npm:^0.2.0": - version: 0.2.0 - resolution: "@fortawesome/react-fontawesome@npm:0.2.0" - dependencies: - prop-types: ^15.8.1 - peerDependencies: - "@fortawesome/fontawesome-svg-core": ~1 || ~6 - react: ">=16.3" - checksum: f652a0c2172e7b209e2d9e7e511f9b8c17abad85f55e0bd09bb1175ea1927693215da47eb6cd95b1f3a23bd124368553c677907fa76cb17c5093afc1fcffe338 - languageName: node - linkType: hard - "@fusioncharts/accessibility@npm:^1.5.0": version: 1.5.0 resolution: "@fusioncharts/accessibility@npm:1.5.0" @@ -3140,7 +2990,7 @@ __metadata: languageName: node linkType: hard -"@gar/promisify@npm:^1.0.1, @gar/promisify@npm:^1.1.3": +"@gar/promisify@npm:^1.1.3": version: 1.1.3 resolution: "@gar/promisify@npm:1.1.3" checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1 @@ -3275,6 +3125,20 @@ __metadata: languageName: node linkType: hard +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: ^5.1.2 + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: ^7.0.1 + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: ^8.1.0 + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb + languageName: node + linkType: hard + "@istanbuljs/load-nyc-config@npm:^1.0.0": version: 1.1.0 resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" @@ -3597,12 +3461,12 @@ __metadata: languageName: node linkType: hard -"@jest/schemas@npm:^29.4.3": - version: 29.4.3 - resolution: "@jest/schemas@npm:29.4.3" +"@jest/schemas@npm:^29.4.3, @jest/schemas@npm:^29.6.0": + version: 29.6.0 + resolution: "@jest/schemas@npm:29.6.0" dependencies: - "@sinclair/typebox": ^0.25.16 - checksum: ac754e245c19dc39e10ebd41dce09040214c96a4cd8efa143b82148e383e45128f24599195ab4f01433adae4ccfbe2db6574c90db2862ccd8551a86704b5bebd + "@sinclair/typebox": ^0.27.8 + checksum: c00511c69cf89138a7d974404d3a5060af375b5a52b9c87215d91873129b382ca11c1ff25bd6d605951404bb381ddce5f8091004a61e76457da35db1f5c51365 languageName: node linkType: hard @@ -3688,29 +3552,6 @@ __metadata: languageName: node linkType: hard -"@jest/transform@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/transform@npm:26.6.2" - dependencies: - "@babel/core": ^7.1.0 - "@jest/types": ^26.6.2 - babel-plugin-istanbul: ^6.0.0 - chalk: ^4.0.0 - convert-source-map: ^1.4.0 - fast-json-stable-stringify: ^2.0.0 - graceful-fs: ^4.2.4 - jest-haste-map: ^26.6.2 - jest-regex-util: ^26.0.0 - jest-util: ^26.6.2 - micromatch: ^4.0.2 - pirates: ^4.0.1 - slash: ^3.0.0 - source-map: ^0.6.1 - write-file-atomic: ^3.0.0 - checksum: 31667b925a2f3b310d854495da0ab67be8f5da24df76ecfc51162e75f1140aed5d18069ba190cb5e0c7e492b04272c8c79076ddf5bbcff530ee80a16a02c4545 - languageName: node - linkType: hard - "@jest/transform@npm:^27.5.1": version: 27.5.1 resolution: "@jest/transform@npm:27.5.1" @@ -3734,39 +3575,26 @@ __metadata: languageName: node linkType: hard -"@jest/transform@npm:^29.5.0": - version: 29.5.0 - resolution: "@jest/transform@npm:29.5.0" +"@jest/transform@npm:^29.3.1, @jest/transform@npm:^29.5.0": + version: 29.6.2 + resolution: "@jest/transform@npm:29.6.2" dependencies: "@babel/core": ^7.11.6 - "@jest/types": ^29.5.0 - "@jridgewell/trace-mapping": ^0.3.15 + "@jest/types": ^29.6.1 + "@jridgewell/trace-mapping": ^0.3.18 babel-plugin-istanbul: ^6.1.1 chalk: ^4.0.0 convert-source-map: ^2.0.0 fast-json-stable-stringify: ^2.1.0 graceful-fs: ^4.2.9 - jest-haste-map: ^29.5.0 + jest-haste-map: ^29.6.2 jest-regex-util: ^29.4.3 - jest-util: ^29.5.0 + jest-util: ^29.6.2 micromatch: ^4.0.4 pirates: ^4.0.4 slash: ^3.0.0 write-file-atomic: ^4.0.2 - checksum: d55d604085c157cf5112e165ff5ac1fa788873b3b31265fb4734ca59892ee24e44119964cc47eb6d178dd9512bbb6c576d1e20e51a201ff4e24d31e818a1c92d - languageName: node - linkType: hard - -"@jest/types@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/types@npm:26.6.2" - dependencies: - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^15.0.0 - chalk: ^4.0.0 - checksum: a0bd3d2f22f26ddb23f41fddf6e6a30bf4fab2ce79ec1cb6ce6fdfaf90a72e00f4c71da91ec61e13db3b10c41de22cf49d07c57ff2b59171d64b29f909c1d8d6 + checksum: ffb8c3c344cd48bedadec295d9c436737eccc39c1f0868aa9753b76397b33b2e5b121058af6f287ba6f2036181137e37df1212334bfa9d9a712986a4518cdc18 languageName: node linkType: hard @@ -3797,17 +3625,17 @@ __metadata: languageName: node linkType: hard -"@jest/types@npm:^29.0.3, @jest/types@npm:^29.5.0": - version: 29.5.0 - resolution: "@jest/types@npm:29.5.0" +"@jest/types@npm:^29.0.3, @jest/types@npm:^29.5.0, @jest/types@npm:^29.6.1": + version: 29.6.1 + resolution: "@jest/types@npm:29.6.1" dependencies: - "@jest/schemas": ^29.4.3 + "@jest/schemas": ^29.6.0 "@types/istanbul-lib-coverage": ^2.0.0 "@types/istanbul-reports": ^3.0.0 "@types/node": "*" "@types/yargs": ^17.0.8 chalk: ^4.0.0 - checksum: 1811f94b19cf8a9460a289c4f056796cfc373480e0492692a6125a553cd1a63824bd846d7bb78820b7b6f758f6dd3c2d4558293bb676d541b2fa59c70fdf9d39 + checksum: 89fc1ccf71a84fe0da643e0675b1cfe6a6f19ea72e935b2ab1dbdb56ec547e94433fb59b3536d3832a6e156c077865b7176fe9dae707dab9c3d2f9405ba6233c languageName: node linkType: hard @@ -3846,13 +3674,13 @@ __metadata: languageName: node linkType: hard -"@jridgewell/source-map@npm:^0.3.2": - version: 0.3.2 - resolution: "@jridgewell/source-map@npm:0.3.2" +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.5 + resolution: "@jridgewell/source-map@npm:0.3.5" dependencies: "@jridgewell/gen-mapping": ^0.3.0 "@jridgewell/trace-mapping": ^0.3.9 - checksum: 1b83f0eb944e77b70559a394d5d3b3f98a81fcc186946aceb3ef42d036762b52ef71493c6c0a3b7c1d2f08785f53ba2df1277fe629a06e6109588ff4cdcf7482 + checksum: 1ad4dec0bdafbade57920a50acec6634f88a0eb735851e0dda906fa9894e7f0549c492678aad1a10f8e144bfe87f238307bf2a914a1bc85b7781d345417e9f6f languageName: node linkType: hard @@ -3873,13 +3701,13 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.14, @jridgewell/trace-mapping@npm:^0.3.15, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": - version: 0.3.17 - resolution: "@jridgewell/trace-mapping@npm:0.3.17" +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.15, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.9": + version: 0.3.18 + resolution: "@jridgewell/trace-mapping@npm:0.3.18" dependencies: "@jridgewell/resolve-uri": 3.1.0 "@jridgewell/sourcemap-codec": 1.4.14 - checksum: 9d703b859cff5cd83b7308fd457a431387db5db96bd781a63bf48e183418dd9d3d44e76b9e4ae13237f6abeeb25d739ec9215c1d5bfdd08f66f750a50074a339 + checksum: 0572669f855260808c16fe8f78f5f1b4356463b11d3f2c7c0b5580c8ba1cbf4ae53efe9f627595830856e57dbac2325ac17eb0c3dd0ec42102e6f227cc289c02 languageName: node linkType: hard @@ -3928,56 +3756,15 @@ __metadata: languageName: node linkType: hard -"@mdx-js/mdx@npm:^1.6.22": - version: 1.6.22 - resolution: "@mdx-js/mdx@npm:1.6.22" +"@mdx-js/react@npm:^2.1.5": + version: 2.3.0 + resolution: "@mdx-js/react@npm:2.3.0" dependencies: - "@babel/core": 7.12.9 - "@babel/plugin-syntax-jsx": 7.12.1 - "@babel/plugin-syntax-object-rest-spread": 7.8.3 - "@mdx-js/util": 1.6.22 - babel-plugin-apply-mdx-type-prop: 1.6.22 - babel-plugin-extract-import-names: 1.6.22 - camelcase-css: 2.0.1 - detab: 2.0.4 - hast-util-raw: 6.0.1 - lodash.uniq: 4.5.0 - mdast-util-to-hast: 10.0.1 - remark-footnotes: 2.0.0 - remark-mdx: 1.6.22 - remark-parse: 8.0.3 - remark-squeeze-paragraphs: 4.0.0 - style-to-object: 0.3.0 - unified: 9.2.0 - unist-builder: 2.0.3 - unist-util-visit: 2.0.3 - checksum: 0839b4a3899416326ea6578fe9e470af319da559bc6d3669c60942e456b49a98eebeb3358c623007b4786a2175a450d2c51cd59df64639013c5a3d22366931a6 - languageName: node - linkType: hard - -"@mdx-js/react@npm:^1.6.22": - version: 1.6.22 - resolution: "@mdx-js/react@npm:1.6.22" + "@types/mdx": ^2.0.0 + "@types/react": ">=16" peerDependencies: - react: ^16.13.1 || ^17.0.0 - checksum: bc84bd514bc127f898819a0c6f1a6915d9541011bd8aefa1fcc1c9bea8939f31051409e546bdec92babfa5b56092a16d05ef6d318304ac029299df5181dc94c8 - languageName: node - linkType: hard - -"@mdx-js/util@npm:1.6.22": - version: 1.6.22 - resolution: "@mdx-js/util@npm:1.6.22" - checksum: 4b393907e39a1a75214f0314bf72a0adfa5e5adffd050dd5efe9c055b8549481a3cfc9f308c16dfb33311daf3ff63added7d5fd1fe52db614c004f886e0e559a - languageName: node - linkType: hard - -"@mrmlnc/readdir-enhanced@npm:^2.2.1": - version: 2.2.1 - resolution: "@mrmlnc/readdir-enhanced@npm:2.2.1" - dependencies: - call-me-maybe: ^1.0.1 - glob-to-regexp: ^0.3.0 - checksum: d3b82b29368821154ce8e10bef5ccdbfd070d3e9601643c99ea4607e56f3daeaa4e755dd6d2355da20762c695c1b0570543d9f84b48f70c211ec09c4aaada2e1 + react: ">=16" + checksum: f45fe779556e6cd9a787f711274480e0638b63c460f192ebdcd77cc07ffa61e23c98cb46dd46e577093e1cb4997a232a848d1fb0ba850ae204422cf603add524 languageName: node linkType: hard @@ -4003,6 +3790,17 @@ __metadata: languageName: node linkType: hard +"@ndelangen/get-tarball@npm:^3.0.7": + version: 3.0.9 + resolution: "@ndelangen/get-tarball@npm:3.0.9" + dependencies: + gunzip-maybe: ^1.4.2 + pump: ^3.0.0 + tar-fs: ^2.1.1 + checksum: 7fa8ac40b4e85738a4ee6bf891bc27fce2445b65b4477e0ec86aed0fa62ab18bdf5d193ce04553ad9bfa639e1eef33b8b30da4ef3e7218f12bf95f24c8786e5b + languageName: node + linkType: hard + "@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3": version: 2.1.8-no-fsevents.3 resolution: "@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3" @@ -4036,13 +3834,6 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.stat@npm:^1.1.2": - version: 1.1.3 - resolution: "@nodelib/fs.stat@npm:1.1.3" - checksum: 318deab369b518a34778cdaa0054dd28a4381c0c78e40bbd20252f67d084b1d7bf9295fea4423de2c19ac8e1a34f120add9125f481b2a710f7068bcac7e3e305 - languageName: node - linkType: hard - "@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" @@ -4053,16 +3844,6 @@ __metadata: languageName: node linkType: hard -"@npmcli/fs@npm:^1.0.0": - version: 1.1.1 - resolution: "@npmcli/fs@npm:1.1.1" - dependencies: - "@gar/promisify": ^1.0.1 - semver: ^7.3.5 - checksum: f5ad92f157ed222e4e31c352333d0901df02c7c04311e42a81d8eb555d4ec4276ea9c635011757de20cc476755af33e91622838de573b17e52e2e7703f0a9965 - languageName: node - linkType: hard - "@npmcli/fs@npm:^2.1.0": version: 2.1.2 resolution: "@npmcli/fs@npm:2.1.2" @@ -4073,16 +3854,6 @@ __metadata: languageName: node linkType: hard -"@npmcli/move-file@npm:^1.0.1": - version: 1.1.2 - resolution: "@npmcli/move-file@npm:1.1.2" - dependencies: - mkdirp: ^1.0.4 - rimraf: ^3.0.2 - checksum: c96381d4a37448ea280951e46233f7e541058cf57a57d4094dd4bdcaae43fa5872b5f2eb6bfb004591a68e29c5877abe3cdc210cb3588cbf20ab2877f31a7de7 - languageName: node - linkType: hard - "@npmcli/move-file@npm:^2.0.0": version: 2.0.1 resolution: "@npmcli/move-file@npm:2.0.1" @@ -4100,7 +3871,14 @@ __metadata: languageName: node linkType: hard -"@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.1, @pmmmwh/react-refresh-webpack-plugin@npm:^0.5.3": +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + languageName: node + linkType: hard + +"@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.1, @pmmmwh/react-refresh-webpack-plugin@npm:^0.5.3, @pmmmwh/react-refresh-webpack-plugin@npm:^0.5.5": version: 0.5.10 resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.10" dependencies: @@ -4146,7 +3924,7 @@ __metadata: languageName: node linkType: hard -"@popperjs/core@npm:^2.11.5, @popperjs/core@npm:^2.5.4, @popperjs/core@npm:^2.9.2": +"@popperjs/core@npm:^2.5.4, @popperjs/core@npm:^2.9.2": version: 2.11.7 resolution: "@popperjs/core@npm:2.11.7" checksum: 5b6553747899683452a1d28898c1b39173a4efd780e74360bfcda8eb42f1c5e819602769c81a10920fc68c881d07fb40429604517d499567eac079cfa6470f19 @@ -4615,18 +4393,18 @@ __metadata: languageName: node linkType: hard -"@react-aria/focus@npm:^3.10.1, @react-aria/focus@npm:^3.11.0, @react-aria/focus@npm:^3.12.0, @react-aria/focus@npm:^3.12.1": - version: 3.12.1 - resolution: "@react-aria/focus@npm:3.12.1" +"@react-aria/focus@npm:^3.10.1, @react-aria/focus@npm:^3.11.0, @react-aria/focus@npm:^3.12.0, @react-aria/focus@npm:^3.12.1, @react-aria/focus@npm:^3.13.0": + version: 3.13.0 + resolution: "@react-aria/focus@npm:3.13.0" dependencies: - "@react-aria/interactions": ^3.15.1 - "@react-aria/utils": ^3.17.0 + "@react-aria/interactions": ^3.16.0 + "@react-aria/utils": ^3.18.0 "@react-types/shared": ^3.18.1 - "@swc/helpers": ^0.4.14 + "@swc/helpers": ^0.5.0 clsx: ^1.1.1 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: 38878d9ca5026a966d322f357438a2eea594ebcd0cdf0aaac7129224d4f9ae2408c76e7addb8c07c6dfa196c7ca84d2cf15cf67fbca7594585a427787c08f66b + checksum: ef78efc7b1e2cc9e7c23cf61d1fa533f7d0ab4b231082ef7aacff002d79c53d3fff2861c4b660693f6c2122c2f6b2ac42ddb7c3768a68880a025cf3c1cac9d29 languageName: node linkType: hard @@ -4648,17 +4426,17 @@ __metadata: languageName: node linkType: hard -"@react-aria/interactions@npm:^3.14.0, @react-aria/interactions@npm:^3.15.0, @react-aria/interactions@npm:^3.15.1": - version: 3.15.1 - resolution: "@react-aria/interactions@npm:3.15.1" +"@react-aria/interactions@npm:^3.14.0, @react-aria/interactions@npm:^3.15.0, @react-aria/interactions@npm:^3.15.1, @react-aria/interactions@npm:^3.16.0": + version: 3.16.0 + resolution: "@react-aria/interactions@npm:3.16.0" dependencies: - "@react-aria/ssr": ^3.6.0 - "@react-aria/utils": ^3.17.0 + "@react-aria/ssr": ^3.7.0 + "@react-aria/utils": ^3.18.0 "@react-types/shared": ^3.18.1 - "@swc/helpers": ^0.4.14 + "@swc/helpers": ^0.5.0 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: 31a4bef77754bfdd57430975addc5e000332483fe8c87eeff006c7155f6921c67cbdad0781d5cc8aab60b89d6ac94914d64ee39b337c17a9d9086168cdb0961a + checksum: 17b1f7c738f858b751206c659551ef860ab8e4de86fe765859a35c805767c2e8b5a0867b722da460301d14f238e608269932da579b69846ec4928c0480bac7fa languageName: node linkType: hard @@ -4711,28 +4489,28 @@ __metadata: languageName: node linkType: hard -"@react-aria/ssr@npm:^3.6.0": - version: 3.6.0 - resolution: "@react-aria/ssr@npm:3.6.0" +"@react-aria/ssr@npm:^3.6.0, @react-aria/ssr@npm:^3.7.0": + version: 3.7.0 + resolution: "@react-aria/ssr@npm:3.7.0" dependencies: - "@swc/helpers": ^0.4.14 + "@swc/helpers": ^0.5.0 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: fab5cf0efb6eea28ae27a74a1ae1724536731f6ea556f7e22f1100e809af5a27c7bfcf6898a0b4d880b374e4b11b782aeadb19b34e26ec10e4e75beb820293e1 + checksum: cf4af47feb47c72ad1a5987b6ca341cba44687fd9bea6155e672c44dcb575e6801c3aaf4a036bb36da9e72f509eaf99c35c993a121017a8c0b0569125b27edfe languageName: node linkType: hard -"@react-aria/switch@npm:^3.3.1": - version: 3.5.0 - resolution: "@react-aria/switch@npm:3.5.0" +"@react-aria/switch@npm:^3.3.1, @react-aria/switch@npm:^3.5.2": + version: 3.5.2 + resolution: "@react-aria/switch@npm:3.5.2" dependencies: - "@react-aria/toggle": ^3.6.0 - "@react-stately/toggle": ^3.5.1 - "@react-types/switch": ^3.3.1 - "@swc/helpers": ^0.4.14 + "@react-aria/toggle": ^3.6.2 + "@react-stately/toggle": ^3.6.0 + "@react-types/switch": ^3.3.2 + "@swc/helpers": ^0.5.0 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: 4d2d414410a8f33e14a8a75156cafcc15b35879f655bc118f08334ec717489bbc497405d05c569cabad61adc0c8d5b7149bda4a8a9520b9e65693016caf47aaf + checksum: 36136ddc45bfaf3dd52278372188438e66c74c6e17f7108f8cace8410190b53d2a78288b731203e20242735f03e494488b8ab53c1f455a7abc4118c39ac05648 languageName: node linkType: hard @@ -4752,36 +4530,36 @@ __metadata: languageName: node linkType: hard -"@react-aria/toggle@npm:^3.6.0": - version: 3.6.0 - resolution: "@react-aria/toggle@npm:3.6.0" +"@react-aria/toggle@npm:^3.6.0, @react-aria/toggle@npm:^3.6.2": + version: 3.6.2 + resolution: "@react-aria/toggle@npm:3.6.2" dependencies: - "@react-aria/focus": ^3.12.0 - "@react-aria/interactions": ^3.15.0 - "@react-aria/utils": ^3.16.0 - "@react-stately/toggle": ^3.5.1 - "@react-types/checkbox": ^3.4.3 - "@react-types/shared": ^3.18.0 - "@react-types/switch": ^3.3.1 - "@swc/helpers": ^0.4.14 + "@react-aria/focus": ^3.13.0 + "@react-aria/interactions": ^3.16.0 + "@react-aria/utils": ^3.18.0 + "@react-stately/toggle": ^3.6.0 + "@react-types/checkbox": ^3.4.4 + "@react-types/shared": ^3.18.1 + "@react-types/switch": ^3.3.2 + "@swc/helpers": ^0.5.0 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: 60deddc95eb8c7aabcfb5775712ae63d0c7ecc511645b218ac387c907df0097c850f80ebceec23fef4add984a00d2dc364a7bce8013c1da8fa6cd20f2fafeacf + checksum: 782b63b862c2976885915bf669dcfcf992fd728b1bb87c61aa85dcd740e82b3e634d7c56597d1365c2918f5744991fb4f295796255a517e5f7f4bfa0acf37e72 languageName: node linkType: hard -"@react-aria/utils@npm:^3.16.0, @react-aria/utils@npm:^3.17.0": - version: 3.17.0 - resolution: "@react-aria/utils@npm:3.17.0" +"@react-aria/utils@npm:^3.16.0, @react-aria/utils@npm:^3.17.0, @react-aria/utils@npm:^3.18.0": + version: 3.18.0 + resolution: "@react-aria/utils@npm:3.18.0" dependencies: - "@react-aria/ssr": ^3.6.0 - "@react-stately/utils": ^3.6.0 + "@react-aria/ssr": ^3.7.0 + "@react-stately/utils": ^3.7.0 "@react-types/shared": ^3.18.1 - "@swc/helpers": ^0.4.14 + "@swc/helpers": ^0.5.0 clsx: ^1.1.1 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: a7c9824441a9879ad650acac434c53ff903f2584bd67952f9002d35671497332e8c0a09e521085b60d91f95035fd2f99191dc52a08aea8a47136715f0fdf1c66 + checksum: 960b26b1c34cd10c36d9e560b2b1dc8782d7b81e23963377fadfb9a69ef34629b4361377b9fe24c1d05a4ec9f252fb29a6561f2405c1ab73e30ca713662d21e5 languageName: node linkType: hard @@ -4976,28 +4754,28 @@ __metadata: languageName: node linkType: hard -"@react-stately/toggle@npm:^3.4.4, @react-stately/toggle@npm:^3.5.1": - version: 3.5.1 - resolution: "@react-stately/toggle@npm:3.5.1" +"@react-stately/toggle@npm:^3.4.4, @react-stately/toggle@npm:^3.5.1, @react-stately/toggle@npm:^3.6.0": + version: 3.6.0 + resolution: "@react-stately/toggle@npm:3.6.0" dependencies: - "@react-stately/utils": ^3.6.0 - "@react-types/checkbox": ^3.4.3 - "@react-types/shared": ^3.18.0 - "@swc/helpers": ^0.4.14 + "@react-stately/utils": ^3.7.0 + "@react-types/checkbox": ^3.4.4 + "@react-types/shared": ^3.18.1 + "@swc/helpers": ^0.5.0 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: 0908abfb99cef2e8c39cc787c0ef0982bd227f1263d3282050056e5f9ae109fa1c0ab9b28bebca3ec094d8ba57e6763c0fcc10f853b4079440456e90df8d5593 + checksum: 8ab0bd4e65133019c74f6f30d40f620a48d3c6592f558131553181cd98b4d014fba387d554d412a65ca3b6460294f968d8ded694432635c00e11ee358e497219 languageName: node linkType: hard -"@react-stately/utils@npm:^3.6.0": - version: 3.6.0 - resolution: "@react-stately/utils@npm:3.6.0" +"@react-stately/utils@npm:^3.6.0, @react-stately/utils@npm:^3.7.0": + version: 3.7.0 + resolution: "@react-stately/utils@npm:3.7.0" dependencies: - "@swc/helpers": ^0.4.14 + "@swc/helpers": ^0.5.0 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: d2ff4cfed5555b112ad71b9bc1837abd777d8fa225043c476b7c9417f8b21a0bcddad0d7127e0acdbf4d85dc9a260c9ae97722b4e9507e6243b412c2724c5f54 + checksum: 91feaae770d38a644b9ba3f633afb0560a51fddd153f75c9e486fca86409cb1b6917366859e59d0f62eab3440e530af97452949671e0f90a8a7e5638ba15b263 languageName: node linkType: hard @@ -5012,14 +4790,14 @@ __metadata: languageName: node linkType: hard -"@react-types/checkbox@npm:^3.4.3": - version: 3.4.3 - resolution: "@react-types/checkbox@npm:3.4.3" +"@react-types/checkbox@npm:^3.4.3, @react-types/checkbox@npm:^3.4.4": + version: 3.4.4 + resolution: "@react-types/checkbox@npm:3.4.4" dependencies: - "@react-types/shared": ^3.18.0 + "@react-types/shared": ^3.18.1 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: 7b39cc56392d96ba8804228ac72859bf6ea6d35e8a32562bcca88bb705e012e9ce5af14a8027a4d3c6f440d2fdfa4014eabc33d551547b23a9a9a399c5af5331 + checksum: 147bd4288ee714ead98433388589673632d92e26a7152032809dbcab9424b219505aabed9ad49770197c5d8cc0e660cad7cb077426eb08f333b333aecacd40fc languageName: node linkType: hard @@ -5066,15 +4844,15 @@ __metadata: languageName: node linkType: hard -"@react-types/switch@npm:^3.3.1": - version: 3.3.1 - resolution: "@react-types/switch@npm:3.3.1" +"@react-types/switch@npm:^3.3.2": + version: 3.3.2 + resolution: "@react-types/switch@npm:3.3.2" dependencies: - "@react-types/checkbox": ^3.4.3 - "@react-types/shared": ^3.18.0 + "@react-types/checkbox": ^3.4.4 + "@react-types/shared": ^3.18.1 peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 - checksum: 41ac4578d3f7f8bbb058c74a958f837b56f53467386972d57a5e4b558ac92ffd5312e2791651b35a416f90568d697606201cf0bd57f825eaec5be14e189e2525 + checksum: c794f432b303fad509c892a2103c72252b2068739cffbe4e2a1468ead749ba2c47e5a71beb5d63e947af97b5b2410887a6284a0ac3855130752f734361834f06 languageName: node linkType: hard @@ -5452,10 +5230,10 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.25.16": - version: 0.25.24 - resolution: "@sinclair/typebox@npm:0.25.24" - checksum: 10219c58f40b8414c50b483b0550445e9710d4fe7b2c4dccb9b66533dd90ba8e024acc776026cebe81e87f06fa24b07fdd7bc30dd277eb9cc386ec50151a3026 +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 languageName: node linkType: hard @@ -5509,29 +5287,26 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-actions@npm:6.5.16, @storybook/addon-actions@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-actions@npm:6.5.16" +"@storybook/addon-actions@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/addon-actions@npm:7.1.1" dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/manager-api": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/theming": 7.1.1 + "@storybook/types": 7.1.1 + dequal: ^2.0.2 lodash: ^4.17.21 polished: ^4.2.2 prop-types: ^15.7.2 - react-inspector: ^5.1.0 - regenerator-runtime: ^0.13.7 - telejson: ^6.0.8 + react-inspector: ^6.0.0 + telejson: ^7.0.3 ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - uuid-browser: ^3.1.0 + uuid: ^9.0.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5540,53 +5315,23 @@ __metadata: optional: true react-dom: optional: true - checksum: d506a932f38412fc234cd58b5f2c8a0bfb8f3820b0ce8042234e9bf4bd277a2befc2d8458d061405ee72722206756375f471a22c37ea32f384259fcbb1a2b6a5 + checksum: 7be3a89c4e1e243c32099825fc8e1fcfbc4550c50407ef8afcda6d4e99b00b5cceb06fb5581d1ea3947cbaa6488151f91017c8769ccf6f35be111daf4a6c042f languageName: node linkType: hard -"@storybook/addon-backgrounds@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-backgrounds@npm:6.5.16" +"@storybook/addon-controls@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/addon-controls@npm:7.1.1" dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 - global: ^4.4.0 - memoizerific: ^1.11.3 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - checksum: d10f0a6b5bf8f9974d3be08f1c30023f3148a0121456bf6296dbf70678f2591440e6fb5fd0643bc937a822c49284d81afeeed66f1b3de775d24c1149f402824b - languageName: node - linkType: hard - -"@storybook/addon-controls@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-controls@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/node-logger": 6.5.16 - "@storybook/store": 6.5.16 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 + "@storybook/blocks": 7.1.1 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/core-common": 7.1.1 + "@storybook/manager-api": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/theming": 7.1.1 + "@storybook/types": 7.1.1 lodash: ^4.17.21 ts-dedent: ^2.0.0 peerDependencies: @@ -5597,136 +5342,52 @@ __metadata: optional: true react-dom: optional: true - checksum: a9f1f577e5d991ae271c9823662adf65952554303094a2e0127bfe9d48e2415796628dadc3cfbc767600e21588336bfd9cb43da59fe76507b2186f6a61da34b8 + checksum: a64e80e5b988b124b0601a59bbf52ea52f933ab052ce2af7380fdbc57647da014c579bcb2a65e786e01f938a6fcaf0c404d4d829584ab59fc054934203cf7a93 languageName: node linkType: hard -"@storybook/addon-docs@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-docs@npm:6.5.16" +"@storybook/addon-docs@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/addon-docs@npm:7.1.1" dependencies: - "@babel/plugin-transform-react-jsx": ^7.12.12 - "@babel/preset-env": ^7.12.11 - "@jest/transform": ^26.6.2 - "@mdx-js/react": ^1.6.22 - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/docs-tools": 6.5.16 - "@storybook/mdx1-csf": ^0.0.1 - "@storybook/node-logger": 6.5.16 - "@storybook/postinstall": 6.5.16 - "@storybook/preview-web": 6.5.16 - "@storybook/source-loader": 6.5.16 - "@storybook/store": 6.5.16 - "@storybook/theming": 6.5.16 - babel-loader: ^8.0.0 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 - lodash: ^4.17.21 - regenerator-runtime: ^0.13.7 + "@jest/transform": ^29.3.1 + "@mdx-js/react": ^2.1.5 + "@storybook/blocks": 7.1.1 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/csf-plugin": 7.1.1 + "@storybook/csf-tools": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/mdx2-csf": ^1.0.0 + "@storybook/node-logger": 7.1.1 + "@storybook/postinstall": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/react-dom-shim": 7.1.1 + "@storybook/theming": 7.1.1 + "@storybook/types": 7.1.1 + fs-extra: ^11.1.0 remark-external-links: ^8.0.0 remark-slug: ^6.0.0 ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 peerDependencies: - "@storybook/mdx2-csf": ^0.0.3 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@storybook/mdx2-csf": - optional: true - react: - optional: true - react-dom: - optional: true - checksum: 3203abc3af20bd8d22bda78c3c98b57f1c46ef29fe1942def0de687ddf08769592ec99d978048ed0aca82c13017b758392f644aaba40a0c0b68d2c61a9e5957d + checksum: 8b1d2dba07db8bfa1c75790e68ec1e02a4bc3b2d91fadb26605ccba2f8bfaa6b60e77b484576db747ace34c94297cab132245df2d1228d0c5c3e01fc0fd59e73 languageName: node linkType: hard -"@storybook/addon-essentials@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-essentials@npm:6.5.16" +"@storybook/addon-measure@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/addon-measure@npm:7.1.1" dependencies: - "@storybook/addon-actions": 6.5.16 - "@storybook/addon-backgrounds": 6.5.16 - "@storybook/addon-controls": 6.5.16 - "@storybook/addon-docs": 6.5.16 - "@storybook/addon-measure": 6.5.16 - "@storybook/addon-outline": 6.5.16 - "@storybook/addon-toolbars": 6.5.16 - "@storybook/addon-viewport": 6.5.16 - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/node-logger": 6.5.16 - core-js: ^3.8.2 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - peerDependencies: - "@babel/core": ^7.9.6 - peerDependenciesMeta: - "@storybook/angular": - optional: true - "@storybook/builder-manager4": - optional: true - "@storybook/builder-manager5": - optional: true - "@storybook/builder-webpack4": - optional: true - "@storybook/builder-webpack5": - optional: true - "@storybook/html": - optional: true - "@storybook/vue": - optional: true - "@storybook/vue3": - optional: true - "@storybook/web-components": - optional: true - lit: - optional: true - lit-html: - optional: true - react: - optional: true - react-dom: - optional: true - svelte: - optional: true - sveltedoc-parser: - optional: true - vue: - optional: true - webpack: - optional: true - checksum: f82a02d00f02c642dae01b2c6c32d48dc4647fe4adbf17d55bb517812d9e483a773084c1c5ceda39d7db5fdaebcaca324a28bb465e35fb524667ef2f5382b1d6 - languageName: node - linkType: hard - -"@storybook/addon-interactions@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-interactions@npm:6.5.16" - dependencies: - "@devtools-ds/object-inspector": ^1.1.2 - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/instrumenter": 6.5.16 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 - global: ^4.4.0 - jest-mock: ^27.0.6 - polished: ^4.2.2 - ts-dedent: ^2.2.0 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/manager-api": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/types": 7.1.1 + tiny-invariant: ^1.3.1 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5735,25 +5396,21 @@ __metadata: optional: true react-dom: optional: true - checksum: cba31aa22e684c5551b9a7af95d949aa80286179324f1ef2a42e9f8be78109c140d730244bce1236af7dc157ba241bf567c3767ca99564162307ec377dffec48 + checksum: afdbf241cbecc3d4066e8c1c65ce0b7aa5a1345547e176acf530724e40c4e34f552646f74256a9b2b1c100aede4ae9831156f76e17e6cf800242b836b5d6ceb9 languageName: node linkType: hard -"@storybook/addon-links@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-links@npm:6.5.16" +"@storybook/addon-outline@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/addon-outline@npm:7.1.1" dependencies: - "@storybook/addons": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/router": 6.5.16 - "@types/qs": ^6.9.5 - core-js: ^3.8.2 - global: ^4.4.0 - prop-types: ^15.7.2 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/manager-api": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/types": 7.1.1 ts-dedent: ^2.0.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5763,22 +5420,19 @@ __metadata: optional: true react-dom: optional: true - checksum: 40fa5fcd98df3be50b3587efda79ddf0156eb0078dd0afec43e81e961475bc8583feec1314baabe59fe2dc8e5b9b4bb4a738435172c208f828d1538cd59882fe + checksum: 3da3bc8fdb33e224a10affe7bc00cc179a3892086e66edae23fb1d78f56970065dbbeb6c504e5d6ded2437641c50c2b04ff059d873dea73f0b4fe55a97af5b25 languageName: node linkType: hard -"@storybook/addon-measure@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-measure@npm:6.5.16" +"@storybook/addon-toolbars@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/addon-toolbars@npm:7.1.1" dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - core-js: ^3.8.2 - global: ^4.4.0 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/manager-api": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/theming": 7.1.1 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5787,87 +5441,23 @@ __metadata: optional: true react-dom: optional: true - checksum: 52fc33249679bb19fdd4e7285436b925832f3d18c223c495cea2b90aa68f08bc626199064eead88ea339ce7e7fa73940daf220e4408ccd4dfd3841288dc645e4 + checksum: e62054ad02c92ed9d546ccd6fd8ec446e1e4fa6f8ec6a4490a0da12c006f87cd73d4c48c6cf3b0ab5900d73d4292d0ccc5984c4d47371d3b83812dac8e469ed8 languageName: node linkType: hard -"@storybook/addon-outline@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-outline@npm:6.5.16" +"@storybook/addon-viewport@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/addon-viewport@npm:7.1.1" dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - core-js: ^3.8.2 - global: ^4.4.0 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - checksum: cb838ecbbdb446552aab891e5fadef6663acf4b16b2bdc18b9a86c01866ccefff0129d9fb7d801604c43946fff5afdcb2c11a1a7813319948a08351c9f35bf46 - languageName: node - linkType: hard - -"@storybook/addon-postcss@npm:^2.0.0": - version: 2.0.0 - resolution: "@storybook/addon-postcss@npm:2.0.0" - dependencies: - "@storybook/node-logger": ^6.1.14 - css-loader: ^3.6.0 - postcss: ^7.0.35 - postcss-loader: ^4.2.0 - style-loader: ^1.3.0 - checksum: 3dee9003a5fa3d6348c093308b3264d58d415be06b01092c1f62e52a22c3a44f4575a49f3960fbc0f211de0608728fdb139fa0501897221fed5ffc04cd11fa09 - languageName: node - linkType: hard - -"@storybook/addon-toolbars@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-toolbars@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 - regenerator-runtime: ^0.13.7 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - checksum: 7a30259bef831769db3e8d76ad439cc5deec919abf47b27a9d0143a581434748d2c8868fbbf8b9cce2910fd61f2200415b6ab5bc0dfab02436fbea2c312da770 - languageName: node - linkType: hard - -"@storybook/addon-viewport@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/addon-viewport@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 - global: ^4.4.0 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/manager-api": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/theming": 7.1.1 memoizerific: ^1.11.3 prop-types: ^15.7.2 - regenerator-runtime: ^0.13.7 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5876,497 +5466,430 @@ __metadata: optional: true react-dom: optional: true - checksum: 4b1de32b85b305c22b976bae040c360063d6152c5077930953cc9cb565735a516c1d239b0670f9a8218264aabff9e8d6c4336fdb70698765009791f24c0fc867 + checksum: 046352de46405b1077245799bf5f4bb9fc09cd52a29162215ffa4c63a863e23a0fb02338e56eb9f260ba8025303d48c0d75abe945662d062f187b3f131b468fd languageName: node linkType: hard -"@storybook/addons@npm:6.5.16, @storybook/addons@npm:^6.5.13": - version: 6.5.16 - resolution: "@storybook/addons@npm:6.5.16" +"@storybook/addons@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/addons@npm:7.1.1" dependencies: - "@storybook/api": 6.5.16 - "@storybook/channels": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/router": 6.5.16 - "@storybook/theming": 6.5.16 - "@types/webpack-env": ^1.16.0 - core-js: ^3.8.2 - global: ^4.4.0 - regenerator-runtime: ^0.13.7 + "@storybook/manager-api": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/types": 7.1.1 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 0463150e4cf7bd2b2aaafdbaadfb4420e4e0a31eb651cfc1a2d7f4b4974caf67878712602474585dfa18f583000608598045594909959d2e9e2ec32ba004392d + checksum: 7e53075285b27117291c6947cc00b51981149c922a80537d81142c758c2cf9de4400eca18dd3ee3795d7e627e69b13dfffdb590db9c35a7d6b45f57c7448f4f5 languageName: node linkType: hard -"@storybook/api@npm:6.5.16, @storybook/api@npm:^6.5.13": - version: 6.5.16 - resolution: "@storybook/api@npm:6.5.16" +"@storybook/api@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/api@npm:7.1.1" dependencies: - "@storybook/channels": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/router": 6.5.16 - "@storybook/semver": ^7.3.2 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 + "@storybook/client-logger": 7.1.1 + "@storybook/manager-api": 7.1.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + checksum: 66645e9510de74993fa5eff3b85a742a041925ae19d57aca92256bec54445f7faf51215b9d7340449bc7c7b4194c02506e2ddb86223c0fc57d69416be36f1edc + languageName: node + linkType: hard + +"@storybook/blocks@npm:7.1.1, @storybook/blocks@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/blocks@npm:7.1.1" + dependencies: + "@storybook/channels": 7.1.1 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/csf": ^0.1.0 + "@storybook/docs-tools": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/manager-api": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/theming": 7.1.1 + "@storybook/types": 7.1.1 + "@types/lodash": ^4.14.167 + color-convert: ^2.0.1 + dequal: ^2.0.2 lodash: ^4.17.21 + markdown-to-jsx: ^7.1.8 memoizerific: ^1.11.3 - regenerator-runtime: ^0.13.7 - store2: ^2.12.0 - telejson: ^6.0.8 + polished: ^4.2.2 + react-colorful: ^5.1.2 + telejson: ^7.0.3 + tocbot: ^4.20.1 ts-dedent: ^2.0.0 util-deprecate: ^1.0.2 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: c873189ac1e501825d647903baa125899c492cee962cb86ebb7455110bd09194eeb6943f5c58a1f808ce4ee2e20e305f5604a4e60b07003c82a6fc6ceaee5ea9 + checksum: 25cdb34b98d942e9f6022736a0270833d27502e2068f964435967f28757f5a34aff8c9e015d954c24ee447353b141470cc02d01085944db9a98a6e1f52c1672e languageName: node linkType: hard -"@storybook/builder-webpack4@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/builder-webpack4@npm:6.5.16" +"@storybook/builder-manager@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/builder-manager@npm:7.1.1" dependencies: - "@babel/core": ^7.12.10 - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/channel-postmessage": 6.5.16 - "@storybook/channels": 6.5.16 - "@storybook/client-api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/node-logger": 6.5.16 - "@storybook/preview-web": 6.5.16 - "@storybook/router": 6.5.16 - "@storybook/semver": ^7.3.2 - "@storybook/store": 6.5.16 - "@storybook/theming": 6.5.16 - "@storybook/ui": 6.5.16 - "@types/node": ^14.0.10 || ^16.0.0 - "@types/webpack": ^4.41.26 - autoprefixer: ^9.8.6 - babel-loader: ^8.0.0 - case-sensitive-paths-webpack-plugin: ^2.3.0 - core-js: ^3.8.2 - css-loader: ^3.6.0 - file-loader: ^6.2.0 - find-up: ^5.0.0 - fork-ts-checker-webpack-plugin: ^4.1.6 - glob: ^7.1.6 - glob-promise: ^3.4.0 - global: ^4.4.0 - html-webpack-plugin: ^4.0.0 - pnp-webpack-plugin: 1.6.4 - postcss: ^7.0.36 - postcss-flexbugs-fixes: ^4.2.1 - postcss-loader: ^4.2.0 - raw-loader: ^4.0.2 - stable: ^0.1.8 - style-loader: ^1.3.0 - terser-webpack-plugin: ^4.2.3 - ts-dedent: ^2.0.0 - url-loader: ^4.1.1 - util-deprecate: ^1.0.2 - webpack: 4 - webpack-dev-middleware: ^3.7.3 - webpack-filter-warnings-plugin: ^1.2.1 - webpack-hot-middleware: ^2.25.1 - webpack-virtual-modules: ^0.2.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 5e9137c390db00b4e166df3ca730eb1748f6bac92c841f3f75c37ad5277d6f5565f899de3bb0357fc51ce6821c8a8a8adba724e3dd7a3d1cc80816e09e5b7128 + "@fal-works/esbuild-plugin-global-externals": ^2.1.2 + "@storybook/core-common": 7.1.1 + "@storybook/manager": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@types/ejs": ^3.1.1 + "@types/find-cache-dir": ^3.2.1 + "@yarnpkg/esbuild-plugin-pnp": ^3.0.0-rc.10 + browser-assert: ^1.2.1 + ejs: ^3.1.8 + esbuild: ^0.18.0 + esbuild-plugin-alias: ^0.2.1 + express: ^4.17.3 + find-cache-dir: ^3.0.0 + fs-extra: ^11.1.0 + process: ^0.11.10 + util: ^0.12.4 + checksum: 87e06696e8db5b97725a52fb04693d1ccb325e4a2be2e9f62c24fbfc4bc485ad91c87cbbe6bf10b36b79052baa40681a9f100b82fbfa88697e6d34407561fd48 languageName: node linkType: hard -"@storybook/builder-webpack5@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/builder-webpack5@npm:6.5.16" +"@storybook/builder-webpack5@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/builder-webpack5@npm:7.1.1" dependencies: - "@babel/core": ^7.12.10 - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/channel-postmessage": 6.5.16 - "@storybook/channels": 6.5.16 - "@storybook/client-api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/node-logger": 6.5.16 - "@storybook/preview-web": 6.5.16 - "@storybook/router": 6.5.16 - "@storybook/semver": ^7.3.2 - "@storybook/store": 6.5.16 - "@storybook/theming": 6.5.16 - "@types/node": ^14.0.10 || ^16.0.0 - babel-loader: ^8.0.0 + "@babel/core": ^7.22.9 + "@storybook/addons": 7.1.1 + "@storybook/api": 7.1.1 + "@storybook/channel-postmessage": 7.1.1 + "@storybook/channels": 7.1.1 + "@storybook/client-api": 7.1.1 + "@storybook/client-logger": 7.1.1 + "@storybook/components": 7.1.1 + "@storybook/core-common": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/core-webpack": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/manager-api": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@storybook/preview": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/router": 7.1.1 + "@storybook/store": 7.1.1 + "@storybook/theming": 7.1.1 + "@swc/core": ^1.3.49 + "@types/node": ^16.0.0 + "@types/semver": ^7.3.4 + babel-loader: ^9.0.0 babel-plugin-named-exports-order: ^0.0.2 browser-assert: ^1.2.1 - case-sensitive-paths-webpack-plugin: ^2.3.0 - core-js: ^3.8.2 - css-loader: ^5.0.1 - fork-ts-checker-webpack-plugin: ^6.0.4 - glob: ^7.1.6 - glob-promise: ^3.4.0 - html-webpack-plugin: ^5.0.0 + case-sensitive-paths-webpack-plugin: ^2.4.0 + constants-browserify: ^1.0.0 + css-loader: ^6.7.1 + express: ^4.17.3 + fork-ts-checker-webpack-plugin: ^8.0.0 + fs-extra: ^11.1.0 + html-webpack-plugin: ^5.5.0 path-browserify: ^1.0.1 process: ^0.11.10 - stable: ^0.1.8 - style-loader: ^2.0.0 - terser-webpack-plugin: ^5.0.3 + semver: ^7.3.7 + style-loader: ^3.3.1 + swc-loader: ^0.2.3 + terser-webpack-plugin: ^5.3.1 ts-dedent: ^2.0.0 + url: ^0.11.0 + util: ^0.12.4 util-deprecate: ^1.0.2 - webpack: ^5.9.0 - webpack-dev-middleware: ^4.1.0 + webpack: 5 + webpack-dev-middleware: ^6.1.1 webpack-hot-middleware: ^2.25.1 - webpack-virtual-modules: ^0.4.1 + webpack-virtual-modules: ^0.5.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 0a6631f307c5ac56423860216d42ed95757906b004e949ed3dc2cce4f81d83d38de5cddbae65a0e65083eece6e4e8af05f6aabf5d78a80a7a7f62cf157a4e577 + checksum: 6b6b175b480d65f5e560f29496589901904fb116ac089dd03f2b4727fc75bc692d104ebcfd76fa83cec742911d1125d02406047ce817fef0fe67e9289df38d64 languageName: node linkType: hard -"@storybook/channel-postmessage@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/channel-postmessage@npm:6.5.16" +"@storybook/channel-postmessage@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/channel-postmessage@npm:7.1.1" dependencies: - "@storybook/channels": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - core-js: ^3.8.2 - global: ^4.4.0 + "@storybook/channels": 7.1.1 + "@storybook/client-logger": 7.1.1 + checksum: fc574ae0a65915de912add285a112e38e26395685151b5d9e5df6d635d13c7b85b6ee81554022d56b0f3b57840eb135f3306259e7d6fc5b452049d32a1dc6899 + languageName: node + linkType: hard + +"@storybook/channels@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/channels@npm:7.1.1" + dependencies: + "@storybook/channels": 7.1.1 + "@storybook/client-logger": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/global": ^5.0.0 qs: ^6.10.0 - telejson: ^6.0.8 - checksum: d3560d81dbf4710cc23b227c12be328d87e627581afcb5fec959f1e795fb2b5824db2a7f03a4ddcd185ec9a37a7025415d8bb43b7a245f2466395908eb3e9bc3 + telejson: ^7.0.3 + tiny-invariant: ^1.3.1 + checksum: 258ef798be48907992bdec462fd2341fb64ab203c07181608cb5a3b1278353c4529aa49516458a9af9d129783fe62bdb1d1af37d0e93f213ecd081b9c44ecc15 languageName: node linkType: hard -"@storybook/channel-websocket@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/channel-websocket@npm:6.5.16" +"@storybook/cli@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/cli@npm:7.1.1" dependencies: - "@storybook/channels": 6.5.16 - "@storybook/client-logger": 6.5.16 - core-js: ^3.8.2 - global: ^4.4.0 - telejson: ^6.0.8 - checksum: 355c85f22d7cc65764871852debe347c43c3fe92d6a0caa64aecbe2dce78d4bf73b98e997099f9e4e7c204ad5821b979939b0700e446fa26478c1e1ba48e7380 - languageName: node - linkType: hard - -"@storybook/channels@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/channels@npm:6.5.16" - dependencies: - core-js: ^3.8.2 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - checksum: 3d7f7bc19ed7b250976e00e02ab544408806b439106bed18a5db9815612f6c5df9bdf7c1a97b5a40ba3194184ebe7e4c75e2bca5496025d6b26afefa95cfccbd - languageName: node - linkType: hard - -"@storybook/client-api@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/client-api@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/channel-postmessage": 6.5.16 - "@storybook/channels": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/store": 6.5.16 - "@types/qs": ^6.9.5 - "@types/webpack-env": ^1.16.0 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 - lodash: ^4.17.21 - memoizerific: ^1.11.3 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - store2: ^2.12.0 - synchronous-promise: ^2.0.15 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: a62276fa67d2c3cc766ea9145d3798c0c8ef3f9de9fb18e7c43d67e39226f47a2546c4319ccc6075545df65dc4fc65bdb97e904062daf426be6534767eacada6 - languageName: node - linkType: hard - -"@storybook/client-logger@npm:6.5.16, @storybook/client-logger@npm:^6.4.0": - version: 6.5.16 - resolution: "@storybook/client-logger@npm:6.5.16" - dependencies: - core-js: ^3.8.2 - global: ^4.4.0 - checksum: 0a86959b1bacb1b893e282173b48afe9c857b8cdc67a47ad87a7f11ba7dbc15ebc4f0d05c07dffb988e0cd3e1de0f09f300ee06c66afe4c50e9be83aaed75971 - languageName: node - linkType: hard - -"@storybook/components@npm:6.5.16, @storybook/components@npm:^6.5.13": - version: 6.5.16 - resolution: "@storybook/components@npm:6.5.16" - dependencies: - "@storybook/client-logger": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 - memoizerific: ^1.11.3 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 1caf822bf1293ca043822f1c77f05c0f01631e8a61adad6bc4651ba9be78c8f4822ba0905e39c8feaa3fb44ae10422e9ccd3004348b18531fb82c54cfcea4fa9 - languageName: node - linkType: hard - -"@storybook/core-client@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/core-client@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/channel-postmessage": 6.5.16 - "@storybook/channel-websocket": 6.5.16 - "@storybook/client-api": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/preview-web": 6.5.16 - "@storybook/store": 6.5.16 - "@storybook/ui": 6.5.16 - airbnb-js-shims: ^2.2.1 - ansi-to-html: ^0.6.11 - core-js: ^3.8.2 - global: ^4.4.0 - lodash: ^4.17.21 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - unfetch: ^4.2.0 - util-deprecate: ^1.0.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - webpack: "*" - peerDependenciesMeta: - typescript: - optional: true - checksum: 467710777ddd740c431cf65035ecc489daae2fc5f4844a40b7339b806535e239140f40442a0e1d89356e107169c39d9e84d726c01982ed4609c043b6861e0778 - languageName: node - linkType: hard - -"@storybook/core-common@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/core-common@npm:6.5.16" - dependencies: - "@babel/core": ^7.12.10 - "@babel/plugin-proposal-class-properties": ^7.12.1 - "@babel/plugin-proposal-decorators": ^7.12.12 - "@babel/plugin-proposal-export-default-from": ^7.12.1 - "@babel/plugin-proposal-nullish-coalescing-operator": ^7.12.1 - "@babel/plugin-proposal-object-rest-spread": ^7.12.1 - "@babel/plugin-proposal-optional-chaining": ^7.12.7 - "@babel/plugin-proposal-private-methods": ^7.12.1 - "@babel/plugin-proposal-private-property-in-object": ^7.12.1 - "@babel/plugin-syntax-dynamic-import": ^7.8.3 - "@babel/plugin-transform-arrow-functions": ^7.12.1 - "@babel/plugin-transform-block-scoping": ^7.12.12 - "@babel/plugin-transform-classes": ^7.12.1 - "@babel/plugin-transform-destructuring": ^7.12.1 - "@babel/plugin-transform-for-of": ^7.12.1 - "@babel/plugin-transform-parameters": ^7.12.1 - "@babel/plugin-transform-shorthand-properties": ^7.12.1 - "@babel/plugin-transform-spread": ^7.12.1 - "@babel/preset-env": ^7.12.11 - "@babel/preset-react": ^7.12.10 - "@babel/preset-typescript": ^7.12.7 - "@babel/register": ^7.12.1 - "@storybook/node-logger": 6.5.16 - "@storybook/semver": ^7.3.2 - "@types/node": ^14.0.10 || ^16.0.0 - "@types/pretty-hrtime": ^1.0.0 - babel-loader: ^8.0.0 - babel-plugin-macros: ^3.0.1 - babel-plugin-polyfill-corejs3: ^0.1.0 + "@babel/core": ^7.22.9 + "@babel/preset-env": ^7.22.9 + "@babel/types": ^7.22.5 + "@ndelangen/get-tarball": ^3.0.7 + "@storybook/codemod": 7.1.1 + "@storybook/core-common": 7.1.1 + "@storybook/core-server": 7.1.1 + "@storybook/csf-tools": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@storybook/telemetry": 7.1.1 + "@storybook/types": 7.1.1 + "@types/semver": ^7.3.4 + "@yarnpkg/fslib": 2.10.3 + "@yarnpkg/libzip": 2.3.0 chalk: ^4.1.0 - core-js: ^3.8.2 - express: ^4.17.1 - file-system-cache: ^1.0.5 + commander: ^6.2.1 + cross-spawn: ^7.0.3 + detect-indent: ^6.1.0 + envinfo: ^7.7.3 + execa: ^5.0.0 + express: ^4.17.3 find-up: ^5.0.0 - fork-ts-checker-webpack-plugin: ^6.0.4 - fs-extra: ^9.0.1 - glob: ^7.1.6 + fs-extra: ^11.1.0 + get-npm-tarball-url: ^2.0.3 + get-port: ^5.1.1 + giget: ^1.0.0 + globby: ^11.0.2 + jscodeshift: ^0.14.0 + leven: ^3.1.0 + ora: ^5.4.1 + prettier: ^2.8.0 + prompts: ^2.4.0 + puppeteer-core: ^2.1.1 + read-pkg-up: ^7.0.1 + semver: ^7.3.7 + simple-update-notifier: ^1.0.0 + strip-json-comments: ^3.0.1 + tempy: ^1.0.1 + ts-dedent: ^2.0.0 + util-deprecate: ^1.0.2 + bin: + getstorybook: ./bin/index.js + sb: ./bin/index.js + checksum: 5c509f8a8fa0fad902ef5848c114d4214f6ee8175032e12e46dc838cbced0f9f92beb448a3a106180a244e7a7ddc1d81a167ca1af28a2ac24b94d8d8308e0f4a + languageName: node + linkType: hard + +"@storybook/client-api@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/client-api@npm:7.1.1" + dependencies: + "@storybook/client-logger": 7.1.1 + "@storybook/preview-api": 7.1.1 + checksum: 5e7f79e8bcfbaf2c1ea8c3208c9fde29944693a4274deda0fde1b94d5ddf08e9e2d7ad7df42eb387380e7417e95f51b612f0734be4f01bdc2b856756edecc1ba + languageName: node + linkType: hard + +"@storybook/client-logger@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/client-logger@npm:7.1.1" + dependencies: + "@storybook/global": ^5.0.0 + checksum: eb8caac2ed8fd5049fe129f7b4e7674f6ef8b08473df4adab8e44fa7b85ba02c95077b1646ee43ff3acccbd559194eb55635c723058970db7b19a8051a2c0c17 + languageName: node + linkType: hard + +"@storybook/codemod@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/codemod@npm:7.1.1" + dependencies: + "@babel/core": ^7.22.9 + "@babel/preset-env": ^7.22.9 + "@babel/types": ^7.22.5 + "@storybook/csf": ^0.1.0 + "@storybook/csf-tools": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@storybook/types": 7.1.1 + "@types/cross-spawn": ^6.0.2 + cross-spawn: ^7.0.3 + globby: ^11.0.2 + jscodeshift: ^0.14.0 + lodash: ^4.17.21 + prettier: ^2.8.0 + recast: ^0.23.1 + checksum: 956e00f55ad46e6525068e1e4f47e56db1d6bc7a1db1189086b210bfbd3da5247ff7006eebb3bff062c4860720a1fe3c34f14bde429eb8db4d3b54b55e7c7253 + languageName: node + linkType: hard + +"@storybook/components@npm:7.1.1, @storybook/components@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/components@npm:7.1.1" + dependencies: + "@storybook/client-logger": 7.1.1 + "@storybook/csf": ^0.1.0 + "@storybook/global": ^5.0.0 + "@storybook/theming": 7.1.1 + "@storybook/types": 7.1.1 + memoizerific: ^1.11.3 + use-resize-observer: ^9.1.0 + util-deprecate: ^1.0.2 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 26df0551902404dd55c91fa883e42417c8770385161dcb336ed56d1c40edd7c2ac0d91fb64f00ae324f6d8e401252e7cea2bf0658dd5e4a4562bf02f6e19ff8c + languageName: node + linkType: hard + +"@storybook/core-client@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/core-client@npm:7.1.1" + dependencies: + "@storybook/client-logger": 7.1.1 + "@storybook/preview-api": 7.1.1 + checksum: fb9647093b4c5916977053b1bbf51b0fc7fa8f9153c8aeb52856826b7c49ada7a6abe34d9c7e01ad6199d3e42e079eecb365db7410ed5682ab7a90ff51f0a4f5 + languageName: node + linkType: hard + +"@storybook/core-common@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/core-common@npm:7.1.1" + dependencies: + "@storybook/node-logger": 7.1.1 + "@storybook/types": 7.1.1 + "@types/find-cache-dir": ^3.2.1 + "@types/node": ^16.0.0 + "@types/node-fetch": ^2.6.4 + "@types/pretty-hrtime": ^1.0.0 + chalk: ^4.1.0 + esbuild: ^0.18.0 + esbuild-register: ^3.4.0 + file-system-cache: 2.3.0 + find-cache-dir: ^3.0.0 + find-up: ^5.0.0 + fs-extra: ^11.1.0 + glob: ^10.0.0 handlebars: ^4.7.7 - interpret: ^2.2.0 - json5: ^2.2.3 - lazy-universal-dotenv: ^3.0.1 + lazy-universal-dotenv: ^4.0.0 + node-fetch: ^2.0.0 picomatch: ^2.3.0 pkg-dir: ^5.0.0 pretty-hrtime: ^1.0.3 resolve-from: ^5.0.0 - slash: ^3.0.0 - telejson: ^6.0.8 ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - webpack: 4 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 886a701876599939950c3c98e306b373cd026c7b995ca08d88475b3f35624a53763459d6b202728ec703e99126813a254b956c2d0fe7e85f99dcb5765a999b19 + checksum: d628d98bac845c3dc81f857b5c17b8ad8ae3d218955a3766de1f8c5d921708744c986b46c57c5f778da2e5176ddf385c1de9fcb6831fbf56b317ad0cfcd89fbe languageName: node linkType: hard -"@storybook/core-events@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/core-events@npm:6.5.16" - dependencies: - core-js: ^3.8.2 - checksum: 1844bdabfb7828af7ddd54129fbb321bf65d8b65459eaac99c8f3f94c7c2f0ee000468362758076444083f863a3bc835ecd1e4f2128524eb5c00c8a576473bc9 +"@storybook/core-events@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/core-events@npm:7.1.1" + checksum: 7df4f3bda05c53585234f29698563b04e7859639d2b4f23114186c4a83aa5c50434b4284101b8daea9536488a7331dbd2df0c42b4a627bee0c8ebd200cb0d59d languageName: node linkType: hard -"@storybook/core-server@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/core-server@npm:6.5.16" +"@storybook/core-server@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/core-server@npm:7.1.1" dependencies: + "@aw-web-design/x-default-browser": 1.4.126 "@discoveryjs/json-ext": ^0.5.3 - "@storybook/builder-webpack4": 6.5.16 - "@storybook/core-client": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/csf-tools": 6.5.16 - "@storybook/manager-webpack4": 6.5.16 - "@storybook/node-logger": 6.5.16 - "@storybook/semver": ^7.3.2 - "@storybook/store": 6.5.16 - "@storybook/telemetry": 6.5.16 - "@types/node": ^14.0.10 || ^16.0.0 - "@types/node-fetch": ^2.5.7 + "@storybook/builder-manager": 7.1.1 + "@storybook/channels": 7.1.1 + "@storybook/core-common": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/csf": ^0.1.0 + "@storybook/csf-tools": 7.1.1 + "@storybook/docs-mdx": ^0.1.0 + "@storybook/global": ^5.0.0 + "@storybook/manager": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/telemetry": 7.1.1 + "@storybook/types": 7.1.1 + "@types/detect-port": ^1.3.0 + "@types/node": ^16.0.0 "@types/pretty-hrtime": ^1.0.0 - "@types/webpack": ^4.41.26 - better-opn: ^2.1.1 - boxen: ^5.1.2 + "@types/semver": ^7.3.4 + better-opn: ^3.0.2 chalk: ^4.1.0 cli-table3: ^0.6.1 - commander: ^6.2.1 compression: ^1.7.4 - core-js: ^3.8.2 - cpy: ^8.1.2 detect-port: ^1.3.0 - express: ^4.17.1 - fs-extra: ^9.0.1 - global: ^4.4.0 + express: ^4.17.3 + fs-extra: ^11.1.0 globby: ^11.0.2 ip: ^2.0.0 lodash: ^4.17.21 - node-fetch: ^2.6.7 open: ^8.4.0 pretty-hrtime: ^1.0.3 prompts: ^2.4.0 - regenerator-runtime: ^0.13.7 + read-pkg-up: ^7.0.1 + semver: ^7.3.7 serve-favicon: ^2.5.0 - slash: ^3.0.0 - telejson: ^6.0.8 + telejson: ^7.0.3 + tiny-invariant: ^1.3.1 ts-dedent: ^2.0.0 + util: ^0.12.4 util-deprecate: ^1.0.2 watchpack: ^2.2.0 - webpack: 4 ws: ^8.2.3 - x-default-browser: ^0.4.0 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@storybook/builder-webpack5": - optional: true - "@storybook/manager-webpack5": - optional: true - typescript: - optional: true - checksum: 2027adba39b2e0a5c3664241f48ec256a92866755aace96f3b8e2064b50237bbcd4e814bc58a1084006baae41c48d7d0eccefc9867d84e17d68d7f969e65f149 + checksum: 27947b1593fa8ae9cbafdd3a26e03e6370fe72bd1b4dac5b7cda083fdef65dc05e6c30f20ede1f4803980067347eab7dbe3c44e2e9993807ddbda373af9425e3 languageName: node linkType: hard -"@storybook/core@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/core@npm:6.5.16" +"@storybook/core-webpack@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/core-webpack@npm:7.1.1" dependencies: - "@storybook/core-client": 6.5.16 - "@storybook/core-server": 6.5.16 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - webpack: "*" - peerDependenciesMeta: - "@storybook/builder-webpack5": - optional: true - "@storybook/manager-webpack5": - optional: true - typescript: - optional: true - checksum: f1732338741692007230a351419ef3aa4e387810d7d0c0e6ffb1159e1de4d757199f2b543cf4f6413fc40acda514b908d2fd9b3e0d56e3f6cec1e3a82c2fcc10 - languageName: node - linkType: hard - -"@storybook/csf-tools@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/csf-tools@npm:6.5.16" - dependencies: - "@babel/core": ^7.12.10 - "@babel/generator": ^7.12.11 - "@babel/parser": ^7.12.11 - "@babel/plugin-transform-react-jsx": ^7.12.12 - "@babel/preset-env": ^7.12.11 - "@babel/traverse": ^7.12.11 - "@babel/types": ^7.12.11 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/mdx1-csf": ^0.0.1 - core-js: ^3.8.2 - fs-extra: ^9.0.1 - global: ^4.4.0 - regenerator-runtime: ^0.13.7 + "@storybook/core-common": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@storybook/types": 7.1.1 + "@types/node": ^16.0.0 ts-dedent: ^2.0.0 - peerDependencies: - "@storybook/mdx2-csf": ^0.0.3 - peerDependenciesMeta: - "@storybook/mdx2-csf": - optional: true - checksum: ee71a47d90186c35fc1dbcb6ece2888ff4d730bde823bb1bd242d802b74045b482d2c469f3a91687b691b6f828ce449b182896d1912033846b9746457ee960ba + checksum: f9f023c040b2c308aced0392e310991be95f20790d56c1f708fc6c0b8812b4c148592c413210c3acbbb249265021d38eeb1cd3ed973ab9bb2b6b08375a2f908e languageName: node linkType: hard -"@storybook/csf@npm:0.0.2--canary.4566f4d.1": - version: 0.0.2--canary.4566f4d.1 - resolution: "@storybook/csf@npm:0.0.2--canary.4566f4d.1" +"@storybook/csf-plugin@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/csf-plugin@npm:7.1.1" dependencies: - lodash: ^4.17.15 - checksum: afac948e1eae72f020b3708538dd2553524f291bc129ecb2941983668fd62b17448e52f9c9be5b8edeea7a64d96f620bbac78b8acc10ece11b8279930a1deb03 + "@storybook/csf-tools": 7.1.1 + unplugin: ^1.3.1 + checksum: 1c240468178572a9142360b1ed11b33a9bfa59ddff11492dc701408fde50f4ebc8b2ed358205673f54fc4fd268ec3bb1227159a37c3ecfcec5777648648f098a + languageName: node + linkType: hard + +"@storybook/csf-tools@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/csf-tools@npm:7.1.1" + dependencies: + "@babel/generator": ^7.22.9 + "@babel/parser": ^7.22.7 + "@babel/traverse": ^7.22.8 + "@babel/types": ^7.22.5 + "@storybook/csf": ^0.1.0 + "@storybook/types": 7.1.1 + fs-extra: ^11.1.0 + recast: ^0.23.1 + ts-dedent: ^2.0.0 + checksum: 6af94d662187ae1b7bc574fb23404e88810bf225be8624600426080fb51770e90236602af557a95ec32f42da856964d082d8f5fe606a1f19ba1d4fb24980e174 languageName: node linkType: hard @@ -6379,237 +5902,181 @@ __metadata: languageName: node linkType: hard -"@storybook/docs-tools@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/docs-tools@npm:6.5.16" +"@storybook/csf@npm:^0.1.0": + version: 0.1.1 + resolution: "@storybook/csf@npm:0.1.1" dependencies: - "@babel/core": ^7.12.10 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/store": 6.5.16 - core-js: ^3.8.2 + type-fest: ^2.19.0 + checksum: 1fbb827b50f0c15f21026a95d02cc096be4f9f2705ad8fd29f0a99330233606e69f6af7551d844ace2a4b8f08fcc9f81496d4d69160ba8c458698291efb60954 + languageName: node + linkType: hard + +"@storybook/docs-mdx@npm:^0.1.0": + version: 0.1.0 + resolution: "@storybook/docs-mdx@npm:0.1.0" + checksum: a7770842c3947a761bcbe776a9c4fd35163d30c3274fca034169f69ff614242eaa4cacaa2c95fd215827081ef9a43f4774d521a6f43a4d063ea5f4ea14b1d69a + languageName: node + linkType: hard + +"@storybook/docs-tools@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/docs-tools@npm:7.1.1" + dependencies: + "@storybook/core-common": 7.1.1 + "@storybook/preview-api": 7.1.1 + "@storybook/types": 7.1.1 + "@types/doctrine": ^0.0.3 doctrine: ^3.0.0 lodash: ^4.17.21 - regenerator-runtime: ^0.13.7 - checksum: 6351c5b1cbe5820f0f0dfcc3e4e7da8cca3c8d73a06c5803e65cb86e9e81ccbae53cec8e1b579af0ac9a5bbb6d4b6ac03ffe26af2220dc5dfe8f065067f0e2d7 + checksum: b7f0a15e158c7710c241c5a6d3cea41c5f24deff9e7c9b6278c1c63b2347ce35410c7700791c06f1112316ac11c294d1427e803940690cd5069cb754beae46fe languageName: node linkType: hard -"@storybook/instrumenter@npm:6.5.16, @storybook/instrumenter@npm:^6.4.0": - version: 6.5.16 - resolution: "@storybook/instrumenter@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - core-js: ^3.8.2 - global: ^4.4.0 - checksum: f22bb4adfa848121d897a6a21e12bfe32d0e809be3480c99f681f2b6a6630b0cb93a63a4a1abea3a0e35411c4959f36fd9160e7e540cc219d45d35dce7746db6 +"@storybook/global@npm:^5.0.0": + version: 5.0.0 + resolution: "@storybook/global@npm:5.0.0" + checksum: ede0ad35ec411fe31c61150dbd118fef344d1d0e72bf5d3502368e35cf68126f6b7ae4a0ab5e2ffe2f0baa3b4286f03ad069ba3e098e1725449ef08b7e154ba8 languageName: node linkType: hard -"@storybook/manager-webpack4@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/manager-webpack4@npm:6.5.16" +"@storybook/manager-api@npm:7.1.1, @storybook/manager-api@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/manager-api@npm:7.1.1" dependencies: - "@babel/core": ^7.12.10 - "@babel/plugin-transform-template-literals": ^7.12.1 - "@babel/preset-react": ^7.12.10 - "@storybook/addons": 6.5.16 - "@storybook/core-client": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/node-logger": 6.5.16 - "@storybook/theming": 6.5.16 - "@storybook/ui": 6.5.16 - "@types/node": ^14.0.10 || ^16.0.0 - "@types/webpack": ^4.41.26 - babel-loader: ^8.0.0 - case-sensitive-paths-webpack-plugin: ^2.3.0 - chalk: ^4.1.0 - core-js: ^3.8.2 - css-loader: ^3.6.0 - express: ^4.17.1 - file-loader: ^6.2.0 - find-up: ^5.0.0 - fs-extra: ^9.0.1 - html-webpack-plugin: ^4.0.0 - node-fetch: ^2.6.7 - pnp-webpack-plugin: 1.6.4 - read-pkg-up: ^7.0.1 - regenerator-runtime: ^0.13.7 - resolve-from: ^5.0.0 - style-loader: ^1.3.0 - telejson: ^6.0.8 - terser-webpack-plugin: ^4.2.3 - ts-dedent: ^2.0.0 - url-loader: ^4.1.1 - util-deprecate: ^1.0.2 - webpack: 4 - webpack-dev-middleware: ^3.7.3 - webpack-virtual-modules: ^0.2.2 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 873c871c822ecde30fbd95e9517549a18c5bb2de46d6160d6dcd7c1b5635fda2073b5bc4bd4d87e72de6e8df8bccf39b81f062e07cd7a23ffb4b43293e488fbb - languageName: node - linkType: hard - -"@storybook/manager-webpack5@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/manager-webpack5@npm:6.5.16" - dependencies: - "@babel/core": ^7.12.10 - "@babel/plugin-transform-template-literals": ^7.12.1 - "@babel/preset-react": ^7.12.10 - "@storybook/addons": 6.5.16 - "@storybook/core-client": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/node-logger": 6.5.16 - "@storybook/theming": 6.5.16 - "@storybook/ui": 6.5.16 - "@types/node": ^14.0.10 || ^16.0.0 - babel-loader: ^8.0.0 - case-sensitive-paths-webpack-plugin: ^2.3.0 - chalk: ^4.1.0 - core-js: ^3.8.2 - css-loader: ^5.0.1 - express: ^4.17.1 - find-up: ^5.0.0 - fs-extra: ^9.0.1 - html-webpack-plugin: ^5.0.0 - node-fetch: ^2.6.7 - process: ^0.11.10 - read-pkg-up: ^7.0.1 - regenerator-runtime: ^0.13.7 - resolve-from: ^5.0.0 - style-loader: ^2.0.0 - telejson: ^6.0.8 - terser-webpack-plugin: ^5.0.3 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - webpack: ^5.9.0 - webpack-dev-middleware: ^4.1.0 - webpack-virtual-modules: ^0.4.1 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 1349c6b2af9d0cebc3c35c929e2ea0f9ff8d12f7a04c30126160d9c89a45b92412218304abda9126cf96303a2d73fb288a689a191fec12b0189f19e5f2032977 - languageName: node - linkType: hard - -"@storybook/mdx1-csf@npm:^0.0.1": - version: 0.0.1 - resolution: "@storybook/mdx1-csf@npm:0.0.1" - dependencies: - "@babel/generator": ^7.12.11 - "@babel/parser": ^7.12.11 - "@babel/preset-env": ^7.12.11 - "@babel/types": ^7.12.11 - "@mdx-js/mdx": ^1.6.22 - "@types/lodash": ^4.14.167 - js-string-escape: ^1.0.1 - loader-utils: ^2.0.0 + "@storybook/channels": 7.1.1 + "@storybook/client-logger": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/csf": ^0.1.0 + "@storybook/global": ^5.0.0 + "@storybook/router": 7.1.1 + "@storybook/theming": 7.1.1 + "@storybook/types": 7.1.1 + dequal: ^2.0.2 lodash: ^4.17.21 - prettier: ">=2.2.1 <=2.3.0" + memoizerific: ^1.11.3 + semver: ^7.3.7 + store2: ^2.14.2 + telejson: ^7.0.3 ts-dedent: ^2.0.0 - checksum: 34f952f4d00d4fbf680aadea53ca0d9b02b10c94ea492a47a6df916474ea1e36d08eece70ffaba760a4cdf6f634a8684360dc49355cf8a1461050b8a470d2666 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 3eed4e62544039b01fd2a4b6379fecc6624ddbde5eacf8ef4a62c68236cd4fbb7d68e8a44b9acaa5ef6c98bcd340d2bf0d76d6068a51cf1a7aaa1821c30682fa languageName: node linkType: hard -"@storybook/node-logger@npm:6.5.16, @storybook/node-logger@npm:^6.1.14, @storybook/node-logger@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/node-logger@npm:6.5.16" - dependencies: - "@types/npmlog": ^4.1.2 - chalk: ^4.1.0 - core-js: ^3.8.2 - npmlog: ^5.0.1 - pretty-hrtime: ^1.0.3 - checksum: 4ae47c03b6cec6b820e0e482e6f6675bf745fca5c124eb919240c0339b9f4a1b110c8fde7c5ddbc1748d3992773c61d37ba1f5c489b42279cf03517d4e1d51c5 +"@storybook/manager@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/manager@npm:7.1.1" + checksum: 6aa3cb2ba4670c8d3ed823c9102a558b749537bc5b6daf8adf0c21dcd1f20ac50d4875f01eb616171550617f420f47e86a1d9e501076451b89f5db05d4910406 languageName: node linkType: hard -"@storybook/postinstall@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/postinstall@npm:6.5.16" - dependencies: - core-js: ^3.8.2 - checksum: 023a19a0681675ce51f4acebf068f372e8657520680c67171c0a1b458f6009d1e444daa5680eeae7efb1088df184fbee61008548a73131d976201961dad65266 +"@storybook/mdx2-csf@npm:^1.0.0": + version: 1.1.0 + resolution: "@storybook/mdx2-csf@npm:1.1.0" + checksum: 5ccdb13f4e59b989499f76e54ffaffb96b5710a696346efe19989b3373f375703adf516780894b270fa64a7e765b55274dc18575fc4a84e7fa92b844a4467c5d languageName: node linkType: hard -"@storybook/preset-create-react-app@npm:^4.1.2": - version: 4.1.2 - resolution: "@storybook/preset-create-react-app@npm:4.1.2" +"@storybook/node-logger@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/node-logger@npm:7.1.1" + checksum: d89fc3317b777c727b95455578de7c6bb5354b26400aae838bf8397e69be33f5361fd40cdab505d3500f55bedc113cf1e845b467a56eaff871751440ed229d7b + languageName: node + linkType: hard + +"@storybook/postinstall@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/postinstall@npm:7.1.1" + checksum: e1742752291fa90137040d0b5f5452e9c4da6d83543ad474a4f1cca644da0bdcc5283cd36057e26e200ceaeb9cbd5c591430a06ca0faec76103bb09f8587c826 + languageName: node + linkType: hard + +"@storybook/preset-create-react-app@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/preset-create-react-app@npm:7.1.1" dependencies: "@pmmmwh/react-refresh-webpack-plugin": ^0.5.1 - "@storybook/react-docgen-typescript-plugin": canary + "@storybook/react-docgen-typescript-plugin": 1.0.6--canary.9.0c3f3b7.0 + "@storybook/types": 7.1.1 "@types/babel__core": ^7.1.7 babel-plugin-react-docgen: ^4.1.0 pnp-webpack-plugin: ^1.7.0 semver: ^7.3.5 peerDependencies: "@babel/core": "*" - "@storybook/node-logger": "*" - "@storybook/react": ">=5.2" react-scripts: ">=5.0.0" - checksum: 4d01bde6e9c31eb3ae79063bdaf283b705cfdd1399abd2879ccf273da3a3e1ae0d5947f87e07b13cee0c43249f0841cd28167fd05b7bbde9d3add2ec7f357d6f + checksum: 55bdc0a61e0d0d01cb5c53738a1e2c2bf2470655864458fd42fc43246a03bd593bea4455fa31ed1242791d117e90171708e0839e486c126215cb0303a9892e48 languageName: node linkType: hard -"@storybook/preview-web@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/preview-web@npm:6.5.16" +"@storybook/preset-react-webpack@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/preset-react-webpack@npm:7.1.1" dependencies: - "@storybook/addons": 6.5.16 - "@storybook/channel-postmessage": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/store": 6.5.16 - ansi-to-html: ^0.6.11 - core-js: ^3.8.2 - global: ^4.4.0 - lodash: ^4.17.21 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - synchronous-promise: ^2.0.15 - ts-dedent: ^2.0.0 - unfetch: ^4.2.0 - util-deprecate: ^1.0.2 + "@babel/preset-flow": ^7.22.5 + "@babel/preset-react": ^7.22.5 + "@pmmmwh/react-refresh-webpack-plugin": ^0.5.5 + "@storybook/core-webpack": 7.1.1 + "@storybook/docs-tools": 7.1.1 + "@storybook/node-logger": 7.1.1 + "@storybook/react": 7.1.1 + "@storybook/react-docgen-typescript-plugin": 1.0.6--canary.9.0c3f3b7.0 + "@types/node": ^16.0.0 + "@types/semver": ^7.3.4 + babel-plugin-add-react-displayname: ^0.0.5 + babel-plugin-react-docgen: ^4.2.1 + fs-extra: ^11.1.0 + react-refresh: ^0.11.0 + semver: ^7.3.7 + webpack: 5 peerDependencies: + "@babel/core": ^7.22.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 6161c96e9ee459ef93c3d972374ce339ae57d0c5fa25730007484e4824f79a34814110431db97031107558e5ce41259710f8a54564e8975db0215b78c5572a1b + peerDependenciesMeta: + "@babel/core": + optional: true + typescript: + optional: true + checksum: 4621c1fd50b82a3c2aa35a8b31588a62164f11dba11b09b95b831278a8dc84317f9cf906db5741c3487120e44e7433660eb63f18d8d154730765b2b766d66633 languageName: node linkType: hard -"@storybook/react-docgen-typescript-plugin@npm:1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0": - version: 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0 - resolution: "@storybook/react-docgen-typescript-plugin@npm:1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" +"@storybook/preview-api@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/preview-api@npm:7.1.1" dependencies: - debug: ^4.1.1 - endent: ^2.0.1 - find-cache-dir: ^3.3.1 - flat-cache: ^3.0.4 - micromatch: ^4.0.2 - react-docgen-typescript: ^2.1.1 - tslib: ^2.0.0 - peerDependencies: - typescript: ">= 3.x" - webpack: ">= 4" - checksum: 91a3015d384e93d9ffb4def904cad51218eb1a9eaf504c758083f2988a97d8bf8748bc280aa629864eb26fd9f7fc05bd087df95383d719e0c914c722016804b9 + "@storybook/channel-postmessage": 7.1.1 + "@storybook/channels": 7.1.1 + "@storybook/client-logger": 7.1.1 + "@storybook/core-events": 7.1.1 + "@storybook/csf": ^0.1.0 + "@storybook/global": ^5.0.0 + "@storybook/types": 7.1.1 + "@types/qs": ^6.9.5 + dequal: ^2.0.2 + lodash: ^4.17.21 + memoizerific: ^1.11.3 + qs: ^6.10.0 + synchronous-promise: ^2.0.15 + ts-dedent: ^2.0.0 + util-deprecate: ^1.0.2 + checksum: 6753e0f104762ae7c70fb8e4db23e5f83ae9b629f6a51f5703bffdc2f3a6d14e4c8d9242806fe6fbb6deefea7e6b5984c81ba6834bb4db034d009c7855a304f0 languageName: node linkType: hard -"@storybook/react-docgen-typescript-plugin@npm:canary": - version: 1.0.6--canary.9.cd77847.0 - resolution: "@storybook/react-docgen-typescript-plugin@npm:1.0.6--canary.9.cd77847.0" +"@storybook/preview@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/preview@npm:7.1.1" + checksum: 592be2664ad0f494f8ed01c1a1aa19027b941af363c5e05bf78b4f212a8450666374935bd18fffa375c90fdd928c36107ff746dab9aba560e7f0baf7b75e4c62 + languageName: node + linkType: hard + +"@storybook/react-docgen-typescript-plugin@npm:1.0.6--canary.9.0c3f3b7.0": + version: 1.0.6--canary.9.0c3f3b7.0 + resolution: "@storybook/react-docgen-typescript-plugin@npm:1.0.6--canary.9.0c3f3b7.0" dependencies: debug: ^4.1.1 endent: ^2.0.1 @@ -6621,220 +6088,142 @@ __metadata: peerDependencies: typescript: ">= 4.x" webpack: ">= 4" - checksum: 8f155cc34cb7d1f124c42b125b760fb58b4ba2ed2eaf109f363411f1c3b0cc6f3cb6dc15c1fa073bd6c0ec5e98b51ab24ff92def54505043f7a2a297a33a77af + checksum: 38c59c1dd7f9cdf5533e5ffe1991034f563f8d33c59e3cd33fa86719c72f5fe922276fde50315dd24f23f225d1ad5f3a261ecf4c70e82522805d09782272faff languageName: node linkType: hard -"@storybook/react@npm:^6.5.16": - version: 6.5.16 - resolution: "@storybook/react@npm:6.5.16" - dependencies: - "@babel/preset-flow": ^7.12.1 - "@babel/preset-react": ^7.12.10 - "@pmmmwh/react-refresh-webpack-plugin": ^0.5.3 - "@storybook/addons": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core": 6.5.16 - "@storybook/core-common": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - "@storybook/docs-tools": 6.5.16 - "@storybook/node-logger": 6.5.16 - "@storybook/react-docgen-typescript-plugin": 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0 - "@storybook/semver": ^7.3.2 - "@storybook/store": 6.5.16 - "@types/estree": ^0.0.51 - "@types/node": ^14.14.20 || ^16.0.0 - "@types/webpack-env": ^1.16.0 - acorn: ^7.4.1 - acorn-jsx: ^5.3.1 - acorn-walk: ^7.2.0 - babel-plugin-add-react-displayname: ^0.0.5 - babel-plugin-react-docgen: ^4.2.1 - core-js: ^3.8.2 - escodegen: ^2.0.0 - fs-extra: ^9.0.1 - global: ^4.4.0 - html-tags: ^3.1.0 - lodash: ^4.17.21 - prop-types: ^15.7.2 - react-element-to-jsx-string: ^14.3.4 - react-refresh: ^0.11.0 - read-pkg-up: ^7.0.1 - regenerator-runtime: ^0.13.7 - ts-dedent: ^2.0.0 - util-deprecate: ^1.0.2 - webpack: ">=4.43.0 <6.0.0" +"@storybook/react-dom-shim@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/react-dom-shim@npm:7.1.1" peerDependencies: - "@babel/core": ^7.11.5 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - require-from-string: ^2.0.2 + checksum: 67eb9239fd05b1531bd6f5b508a917d46dee5b3417ec4c31e5c679211c58833866090666d30ac274e8c6deca1b288194be23fdeb0a142632112d2570cdcd18fd + languageName: node + linkType: hard + +"@storybook/react-webpack5@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/react-webpack5@npm:7.1.1" + dependencies: + "@storybook/builder-webpack5": 7.1.1 + "@storybook/preset-react-webpack": 7.1.1 + "@storybook/react": 7.1.1 + "@types/node": ^16.0.0 + peerDependencies: + "@babel/core": ^7.22.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: "*" peerDependenciesMeta: "@babel/core": optional: true - "@storybook/builder-webpack4": - optional: true - "@storybook/builder-webpack5": - optional: true - "@storybook/manager-webpack4": - optional: true - "@storybook/manager-webpack5": - optional: true typescript: optional: true - bin: - build-storybook: bin/build.js - start-storybook: bin/index.js - storybook-server: bin/index.js - checksum: c5396e748ef13acdb2590dc15ff0b3d95d3599abd0c372786d707164d3f71e46836240195dcd6f4bce6f90d2792602f6d31373fc87e069ef3c73a63d1e9a1289 + checksum: a4d194320c11e813ca4b5a37af232074a823b5888f1415b1faa86395e8252a71dd3f5a195a34c5936a7034f40686bfa4852aaa817d5303f722fe7f04151b1e3e languageName: node linkType: hard -"@storybook/router@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/router@npm:6.5.16" +"@storybook/react@npm:7.1.1, @storybook/react@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/react@npm:7.1.1" dependencies: - "@storybook/client-logger": 6.5.16 - core-js: ^3.8.2 - memoizerific: ^1.11.3 - qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 2812b93997026b1d85f02072d04f18e98e24de288efb73402f8d15ececd390e13dc620ef011268e09986c629f497ffa03230c2431e89b4e37c01b70761be2c6d - languageName: node - linkType: hard - -"@storybook/semver@npm:^7.3.2": - version: 7.3.2 - resolution: "@storybook/semver@npm:7.3.2" - dependencies: - core-js: ^3.6.5 - find-up: ^4.1.0 - bin: - semver: bin/semver.js - checksum: c98225817af5539654ef547e33e4496edccc04a88b6091d4a5601f81b71743109074dc71cc444813f43c112273c9d54d5f99416e9ad08ee89b4913318e6aea90 - languageName: node - linkType: hard - -"@storybook/source-loader@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/source-loader@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - core-js: ^3.8.2 - estraverse: ^5.2.0 - global: ^4.4.0 - loader-utils: ^2.0.4 + "@storybook/client-logger": 7.1.1 + "@storybook/core-client": 7.1.1 + "@storybook/docs-tools": 7.1.1 + "@storybook/global": ^5.0.0 + "@storybook/preview-api": 7.1.1 + "@storybook/react-dom-shim": 7.1.1 + "@storybook/types": 7.1.1 + "@types/escodegen": ^0.0.6 + "@types/estree": ^0.0.51 + "@types/node": ^16.0.0 + acorn: ^7.4.1 + acorn-jsx: ^5.3.1 + acorn-walk: ^7.2.0 + escodegen: ^2.0.0 + html-tags: ^3.1.0 lodash: ^4.17.21 - prettier: ">=2.2.1 <=2.3.0" - regenerator-runtime: ^0.13.7 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: a299acdd6f36add3222ef294e1118b7b1f38c2cd2b4648ebf9e1803a3ccf532c147dbe643a527915b570eb3ce36c4a17ca2b3566fa58a2a0a7821f0849ec3e07 - languageName: node - linkType: hard - -"@storybook/store@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/store@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/csf": 0.0.2--canary.4566f4d.1 - core-js: ^3.8.2 - fast-deep-equal: ^3.1.3 - global: ^4.4.0 - lodash: ^4.17.21 - memoizerific: ^1.11.3 - regenerator-runtime: ^0.13.7 - slash: ^3.0.0 - stable: ^0.1.8 - synchronous-promise: ^2.0.15 + prop-types: ^15.7.2 + react-element-to-jsx-string: ^15.0.0 ts-dedent: ^2.0.0 + type-fest: ^3.11.0 util-deprecate: ^1.0.2 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: f438fb020af240e23348742b2936a326bef1f7ffd489fe9f39cfd516310ab592a11609205fdacd11090b0c0b6bc72c75dff986085a6a97acc5efa64829a49309 + typescript: "*" + peerDependenciesMeta: + typescript: + optional: true + checksum: 29ceae79691781c6981632e4835f0f53189c9363b8f6e9d725c6749dbbc781b8223405ca4739aafdb9f9cb1aba33acd048fe82e584519d72a2c6116334e4b37b languageName: node linkType: hard -"@storybook/telemetry@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/telemetry@npm:6.5.16" +"@storybook/router@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/router@npm:7.1.1" dependencies: - "@storybook/client-logger": 6.5.16 - "@storybook/core-common": 6.5.16 - chalk: ^4.1.0 - core-js: ^3.8.2 - detect-package-manager: ^2.0.1 - fetch-retry: ^5.0.2 - fs-extra: ^9.0.1 - global: ^4.4.0 - isomorphic-unfetch: ^3.1.0 - nanoid: ^3.3.1 - read-pkg-up: ^7.0.1 - regenerator-runtime: ^0.13.7 - checksum: 21eef590b04db8ee85b0b1d875d8646e26492b3e90538a248314f92d6ab0642ec65db09c5d2bc0d7f547f0fa6b83ca4442bdc115b400861360e02d8cf179497e - languageName: node - linkType: hard - -"@storybook/testing-library@npm:^0.0.13": - version: 0.0.13 - resolution: "@storybook/testing-library@npm:0.0.13" - dependencies: - "@storybook/client-logger": ^6.4.0 - "@storybook/instrumenter": ^6.4.0 - "@testing-library/dom": ^8.3.0 - "@testing-library/user-event": ^13.2.1 - ts-dedent: ^2.2.0 - checksum: 759361ad3fbc89bdfddfa6d5a15eef06ed6fa9110bfa40c08fcf2497e7acd85e8d5c73c26ea4a46934168b21db294256befb55755fee4292d3d277c576284a1c - languageName: node - linkType: hard - -"@storybook/theming@npm:6.5.16, @storybook/theming@npm:^6.5.13": - version: 6.5.16 - resolution: "@storybook/theming@npm:6.5.16" - dependencies: - "@storybook/client-logger": 6.5.16 - core-js: ^3.8.2 - memoizerific: ^1.11.3 - regenerator-runtime: ^0.13.7 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 349affa5c5208240291a5d24c73d852e220bfaf36b8fda70564aec1cac6070248ce7566ccb755c55a6ce0844ab2bbfd55881f6f788240b38cb407714e393c6f3 - languageName: node - linkType: hard - -"@storybook/ui@npm:6.5.16": - version: 6.5.16 - resolution: "@storybook/ui@npm:6.5.16" - dependencies: - "@storybook/addons": 6.5.16 - "@storybook/api": 6.5.16 - "@storybook/channels": 6.5.16 - "@storybook/client-logger": 6.5.16 - "@storybook/components": 6.5.16 - "@storybook/core-events": 6.5.16 - "@storybook/router": 6.5.16 - "@storybook/semver": ^7.3.2 - "@storybook/theming": 6.5.16 - core-js: ^3.8.2 + "@storybook/client-logger": 7.1.1 memoizerific: ^1.11.3 qs: ^6.10.0 - regenerator-runtime: ^0.13.7 - resolve-from: ^5.0.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: bfebcf4d56dc5fd6024eaa08fe50aecc3c348670b7c0ec6b467680d64d525421580b9c98839bcaf1e2a9e69b78478a21c9943a9a392b49a0405b4784038b2eba + checksum: 1c3c10cbbd0421da199763f6ada3b4961caee1241d6eb7d2dc19a68f905d3edb1fe37fb94fe54034c35158d7d84652f7ed5a650d33b59a16f2e864210c6c51a2 + languageName: node + linkType: hard + +"@storybook/store@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/store@npm:7.1.1" + dependencies: + "@storybook/client-logger": 7.1.1 + "@storybook/preview-api": 7.1.1 + checksum: 8c5de1248ff244c7eedd5a317c5761995ffd987171ceed5c8c6259f1882b6117b4b8bcb3a60512db304dacf777641d5f4333700719335735d7ed45c623cb0ad9 + languageName: node + linkType: hard + +"@storybook/telemetry@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/telemetry@npm:7.1.1" + dependencies: + "@storybook/client-logger": 7.1.1 + "@storybook/core-common": 7.1.1 + "@storybook/csf-tools": 7.1.1 + chalk: ^4.1.0 + detect-package-manager: ^2.0.1 + fetch-retry: ^5.0.2 + fs-extra: ^11.1.0 + read-pkg-up: ^7.0.1 + checksum: eb8c18a22f491c07d0035ae9d725845891f3deb1bb4559b97ab9aace22b4e8ae59f72dcdb453348f472aa0ce1800531f2f22c2e24286c0699c577aee13719f04 + languageName: node + linkType: hard + +"@storybook/theming@npm:7.1.1, @storybook/theming@npm:^7.1.1": + version: 7.1.1 + resolution: "@storybook/theming@npm:7.1.1" + dependencies: + "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0 + "@storybook/client-logger": 7.1.1 + "@storybook/global": ^5.0.0 + memoizerific: ^1.11.3 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 5a71790a34d9d1172e4c2b09f0807dba956c9cd9ee22ce3527d13d65aeab2e59b6851d2e98fb04b782df45fa0861b203e1ac76d3c6dca4564e8d3cfb406c0c46 + languageName: node + linkType: hard + +"@storybook/types@npm:7.1.1": + version: 7.1.1 + resolution: "@storybook/types@npm:7.1.1" + dependencies: + "@storybook/channels": 7.1.1 + "@types/babel__core": ^7.0.0 + "@types/express": ^4.7.0 + file-system-cache: 2.3.0 + checksum: 10268ae95cb86c0eed05924aa68ab1746b93cbb0e08135d3d28ba4b11c010733af1e1a303c941ed2aa999da0bd2ececec85ed52f76a410518a499adb4805cac7 languageName: node linkType: hard @@ -7108,6 +6497,120 @@ __metadata: languageName: node linkType: hard +"@swc/core-darwin-arm64@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-darwin-arm64@npm:1.3.71" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-darwin-x64@npm:1.3.71" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.71" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.71" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.71" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.71" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-linux-x64-musl@npm:1.3.71" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.71" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.71" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.3.71": + version: 1.3.71 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.71" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.3.49": + version: 1.3.71 + resolution: "@swc/core@npm:1.3.71" + dependencies: + "@swc/core-darwin-arm64": 1.3.71 + "@swc/core-darwin-x64": 1.3.71 + "@swc/core-linux-arm-gnueabihf": 1.3.71 + "@swc/core-linux-arm64-gnu": 1.3.71 + "@swc/core-linux-arm64-musl": 1.3.71 + "@swc/core-linux-x64-gnu": 1.3.71 + "@swc/core-linux-x64-musl": 1.3.71 + "@swc/core-win32-arm64-msvc": 1.3.71 + "@swc/core-win32-ia32-msvc": 1.3.71 + "@swc/core-win32-x64-msvc": 1.3.71 + peerDependencies: + "@swc/helpers": ^0.5.0 + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: 86389384951c531579e518c012d36b28ef070146faf8d6965a174fd2c7b18113c5939fc3ca81ec8be448188949763cc98cb20d16f44316cd209860f53b760c80 + languageName: node + linkType: hard + "@swc/helpers@npm:^0.4.14": version: 0.4.14 resolution: "@swc/helpers@npm:0.4.14" @@ -7117,6 +6620,15 @@ __metadata: languageName: node linkType: hard +"@swc/helpers@npm:^0.5.0": + version: 0.5.1 + resolution: "@swc/helpers@npm:0.5.1" + dependencies: + tslib: ^2.4.0 + checksum: 71e0e27234590435e4c62b97ef5e796f88e786841a38c7116a5e27a3eafa7b9ead7cdec5249b32165902076de78446945311c973e59bddf77c1e24f33a8f272a + languageName: node + linkType: hard + "@szmarczak/http-timer@npm:^4.0.5": version: 4.0.6 resolution: "@szmarczak/http-timer@npm:4.0.6" @@ -7133,19 +6645,19 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^8.0.0, @testing-library/dom@npm:^8.3.0": - version: 8.20.0 - resolution: "@testing-library/dom@npm:8.20.0" +"@testing-library/dom@npm:^8.0.0": + version: 8.20.1 + resolution: "@testing-library/dom@npm:8.20.1" dependencies: "@babel/code-frame": ^7.10.4 "@babel/runtime": ^7.12.5 "@types/aria-query": ^5.0.1 - aria-query: ^5.0.0 + aria-query: 5.1.3 chalk: ^4.1.0 dom-accessibility-api: ^0.5.9 - lz-string: ^1.4.4 + lz-string: ^1.5.0 pretty-format: ^27.0.2 - checksum: 1e599129a2fe91959ce80900a0a4897232b89e2a8e22c1f5950c36d39c97629ea86b4986b60b173b5525a05de33fde1e35836ea597b03de78cc51b122835c6f0 + checksum: 06fc8dc67849aadb726cbbad0e7546afdf8923bd39acb64c576d706249bd7d0d05f08e08a31913fb621162e3b9c2bd0dce15964437f030f9fa4476326fdd3007 languageName: node linkType: hard @@ -7201,7 +6713,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/user-event@npm:13.5.0, @testing-library/user-event@npm:^13.2.1": +"@testing-library/user-event@npm:13.5.0": version: 13.5.0 resolution: "@testing-library/user-event@npm:13.5.0" dependencies: @@ -7427,6 +6939,15 @@ __metadata: languageName: node linkType: hard +"@types/cross-spawn@npm:^6.0.2": + version: 6.0.2 + resolution: "@types/cross-spawn@npm:6.0.2" + dependencies: + "@types/node": "*" + checksum: fa9edd32178878cab3ea8d6d0260639e0fe4860ddb3887b8de53d6e8036e154fc5f313c653f690975aa25025aea8beb83fb0870b931bf8d9202c3ac530a24c9d + languageName: node + linkType: hard + "@types/deep-diff@npm:^1.0.0": version: 1.0.0 resolution: "@types/deep-diff@npm:1.0.0" @@ -7434,6 +6955,20 @@ __metadata: languageName: node linkType: hard +"@types/detect-port@npm:^1.3.0": + version: 1.3.3 + resolution: "@types/detect-port@npm:1.3.3" + checksum: 0dadb520286a5cfd2832d12189dc795cc3589dfd9166d1b033453fb94b0212c4067a847045833e85b0f7c73135c944cb4ccb49c8e683491845c2e8a3da5d5c1c + languageName: node + linkType: hard + +"@types/doctrine@npm:^0.0.3": + version: 0.0.3 + resolution: "@types/doctrine@npm:0.0.3" + checksum: 7ca9c8ff4d2da437785151c9eef0dd80b8fa12e0ff0fcb988458a78de4b6f0fc92727ba5bbee446e1df615a91f03053c5783b30b7c21ab6ceab6a42557e93e50 + languageName: node + linkType: hard + "@types/dom-mediacapture-record@npm:^1.0.11": version: 1.0.11 resolution: "@types/dom-mediacapture-record@npm:1.0.11" @@ -7455,6 +6990,13 @@ __metadata: languageName: node linkType: hard +"@types/ejs@npm:^3.1.1": + version: 3.1.2 + resolution: "@types/ejs@npm:3.1.2" + checksum: e4f0745b6ed53a63c08bdfdeb019a7d0e0c400896722b44d6732b4ee6bf6061d2dc965206186b8b0ae2ecd71303c29f1af1feddbca2df0acbd7bd234a74ca518 + languageName: node + linkType: hard + "@types/emoji-mart@npm:3.0.4": version: 3.0.4 resolution: "@types/emoji-mart@npm:3.0.4" @@ -7464,6 +7006,20 @@ __metadata: languageName: node linkType: hard +"@types/emscripten@npm:^1.39.6": + version: 1.39.7 + resolution: "@types/emscripten@npm:1.39.7" + checksum: 9871e4495358cc06cc45b2798022cd097d8ac2eb5b2fae7c276c6c5cadea05507150fad053c73ed346d4cbd844c50a3438604e5d7c3c2a7446b703cacb1ce172 + languageName: node + linkType: hard + +"@types/escodegen@npm:^0.0.6": + version: 0.0.6 + resolution: "@types/escodegen@npm:0.0.6" + checksum: 7b25aeedd48dbef68345224082c6bc774845cbfc1d9b2ce91a477130fe7ccabf33da126c1d6d55e5dfd838db429a7c80890628a167e5aa55b6a4620974da38d3 + languageName: node + linkType: hard + "@types/escodegen@npm:^0.0.7": version: 0.0.7 resolution: "@types/escodegen@npm:0.0.7" @@ -7533,7 +7089,7 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.14": +"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.14, @types/express@npm:^4.7.0": version: 4.17.17 resolution: "@types/express@npm:4.17.17" dependencies: @@ -7545,6 +7101,13 @@ __metadata: languageName: node linkType: hard +"@types/find-cache-dir@npm:^3.2.1": + version: 3.2.1 + resolution: "@types/find-cache-dir@npm:3.2.1" + checksum: bf5c4e96da40247cd9e6327f54dfccda961a0fb2d70e3c71bd05def94de4c2e6fb310fe8ecb0f04ecf5dbc52214e184b55a2337b0f87250d4ae1e2e7d58321e4 + languageName: node + linkType: hard + "@types/fined@npm:*": version: 1.1.2 resolution: "@types/fined@npm:1.1.2" @@ -7552,26 +7115,6 @@ __metadata: languageName: node linkType: hard -"@types/glob@npm:*": - version: 8.1.0 - resolution: "@types/glob@npm:8.1.0" - dependencies: - "@types/minimatch": ^5.1.2 - "@types/node": "*" - checksum: 9101f3a9061e40137190f70626aa0e202369b5ec4012c3fabe6f5d229cce04772db9a94fa5a0eb39655e2e4ad105c38afbb4af56a56c0996a8c7d4fc72350e3d - languageName: node - linkType: hard - -"@types/glob@npm:^7.1.1": - version: 7.2.0 - resolution: "@types/glob@npm:7.2.0" - dependencies: - "@types/minimatch": "*" - "@types/node": "*" - checksum: 6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 - languageName: node - linkType: hard - "@types/google.maps@npm:^3.51.0": version: 3.51.0 resolution: "@types/google.maps@npm:3.51.0" @@ -7614,13 +7157,6 @@ __metadata: languageName: node linkType: hard -"@types/html-minifier-terser@npm:^5.0.0": - version: 5.1.2 - resolution: "@types/html-minifier-terser@npm:5.1.2" - checksum: 4bca779c44d2aebe4cc4036c5db370abe7466249038e9c5996cb3c192debeff1c75b7a2ab78e5fd2a014ad24ebf0f357f9a174a4298540dc1e1317d43aa69cfa - languageName: node - linkType: hard - "@types/html-minifier-terser@npm:^6.0.0": version: 6.1.0 resolution: "@types/html-minifier-terser@npm:6.1.0" @@ -7671,13 +7207,6 @@ __metadata: languageName: node linkType: hard -"@types/is-function@npm:^1.0.0": - version: 1.0.1 - resolution: "@types/is-function@npm:1.0.1" - checksum: dfbb591936dfebd4686b109603bc3e2d23a17087d6ec913fb35cd6b5a4ef908ed68ab93cb27d508f1546d312edf03e663cb6738d3b67d420c68da961ac2b3d1f - languageName: node - linkType: hard - "@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": version: 2.0.4 resolution: "@types/istanbul-lib-coverage@npm:2.0.4" @@ -7810,12 +7339,17 @@ __metadata: languageName: node linkType: hard -"@types/mdast@npm:^3.0.0": - version: 3.0.10 - resolution: "@types/mdast@npm:3.0.10" - dependencies: - "@types/unist": "*" - checksum: 3f587bfc0a9a2403ecadc220e61031b01734fedaf82e27eb4d5ba039c0eb54db8c85681ccc070ab4df3f7ec711b736a82b990e69caa14c74bf7ac0ccf2ac7313 +"@types/mdx@npm:^2.0.0": + version: 2.0.5 + resolution: "@types/mdx@npm:2.0.5" + checksum: 1069baff0b2d0fb0bc724748e2386af626cc30f8ef99e680afb4dee566ed0aeabd31cea774212a7033f491e594a0acc234116078b252cba94ac413f91eb585a3 + languageName: node + linkType: hard + +"@types/mime-types@npm:^2.1.0": + version: 2.1.1 + resolution: "@types/mime-types@npm:2.1.1" + checksum: 106b5d556add46446a579ad25ff15d6b421851790d887edcad558c90c1e64b1defc72bfbaf4b08f208916e21d9cc45cdb951d77be51268b18221544cfe054a3c languageName: node linkType: hard @@ -7826,13 +7360,6 @@ __metadata: languageName: node linkType: hard -"@types/minimatch@npm:*, @types/minimatch@npm:^5.1.2": - version: 5.1.2 - resolution: "@types/minimatch@npm:5.1.2" - checksum: 0391a282860c7cb6fe262c12b99564732401bdaa5e395bee9ca323c312c1a0f45efbf34dce974682036e857db59a5c9b1da522f3d6055aeead7097264c8705a8 - languageName: node - linkType: hard - "@types/moment-timezone@npm:^0.5.10": version: 0.5.30 resolution: "@types/moment-timezone@npm:0.5.30" @@ -7851,13 +7378,13 @@ __metadata: languageName: node linkType: hard -"@types/node-fetch@npm:^2.5.7": - version: 2.6.2 - resolution: "@types/node-fetch@npm:2.6.2" +"@types/node-fetch@npm:^2.6.4": + version: 2.6.4 + resolution: "@types/node-fetch@npm:2.6.4" dependencies: "@types/node": "*" form-data: ^3.0.0 - checksum: 6f73b1470000d303d25a6fb92875ea837a216656cb7474f66cdd67bb014aa81a5a11e7ac9c21fe19bee9ecb2ef87c1962bceeaec31386119d1ac86e4c30ad7a6 + checksum: f3e1d881bb42269e676ecaf49f0e096ab345e22823a2b2d071d60619414817fe02df48a31a8d05adb23054028a2a65521bdb3906ceb763ab6d3339c8d8775058 languageName: node linkType: hard @@ -7884,13 +7411,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^14.0.10 || ^16.0.0, @types/node@npm:^14.14.20 || ^16.0.0": - version: 16.18.14 - resolution: "@types/node@npm:16.18.14" - checksum: 7865c1c3e7c7d2fef6103c6dfa181755dc48365024253d6acc460e884508b5937a222aa8bd04835988ff0bdc47867e2ada78859c0a7f9c65b44884316f3b469c - languageName: node - linkType: hard - "@types/node@npm:^14.14.31": version: 14.18.21 resolution: "@types/node@npm:14.18.21" @@ -7898,6 +7418,13 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^16.0.0": + version: 16.18.39 + resolution: "@types/node@npm:16.18.39" + checksum: eac9b202b76013256cb517ca8d3e3f61df206edb1615ca8d8df4c80616e92879fe4d3f8570a11d60f4216a82724a3265d5888b24c6994c80b057a0423c9ff1d2 + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.0": version: 2.4.1 resolution: "@types/normalize-package-data@npm:2.4.1" @@ -7905,13 +7432,6 @@ __metadata: languageName: node linkType: hard -"@types/npmlog@npm:^4.1.2": - version: 4.1.4 - resolution: "@types/npmlog@npm:4.1.4" - checksum: 740f7431ccfc0e127aa8d162fe05c6ce8aa71290be020d179b2824806d19bd2c706c7e0c9a3c9963cefcdf2ceacb1dec6988c394c3694451387759dafe0aa927 - languageName: node - linkType: hard - "@types/object-hash@npm:^2.2.1": version: 2.2.1 resolution: "@types/object-hash@npm:2.2.1" @@ -7926,13 +7446,6 @@ __metadata: languageName: node linkType: hard -"@types/parse5@npm:^5.0.0": - version: 5.0.3 - resolution: "@types/parse5@npm:5.0.3" - checksum: d6b7495cb1850f9f2e9c5e103ede9f2d30a5320669707b105c403868adc9e4bf8d3a7ff314cc23f67826bbbbbc0e6147346ce9062ab429f099dba7a01f463919 - languageName: node - linkType: hard - "@types/prettier@npm:^2.1.5": version: 2.7.0 resolution: "@types/prettier@npm:2.7.0" @@ -8000,7 +7513,16 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:*, @types/react-dom@npm:>=16.9.0, @types/react-dom@npm:^17.0.2": +"@types/react-dom@npm:*, @types/react-dom@npm:>=16.9.0": + version: 18.2.6 + resolution: "@types/react-dom@npm:18.2.6" + dependencies: + "@types/react": "*" + checksum: b56e42efab121a3a8013d2eb8c1688e6028a25ea6d33c4362d2846f0af3760b164b4d7c34846614024cfb8956cca70dd1743487f152e32ff89a00fe6fbd2be54 + languageName: node + linkType: hard + +"@types/react-dom@npm:^17.0.2": version: 17.0.18 resolution: "@types/react-dom@npm:17.0.18" dependencies: @@ -8181,7 +7703,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:>=16.9.0, @types/react@npm:^17, @types/react@npm:^17.0.2": +"@types/react@npm:^17.0.2": version: 17.0.52 resolution: "@types/react@npm:17.0.52" dependencies: @@ -8192,17 +7714,6 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^16.0.40, @types/react@npm:^16.9.35": - version: 16.14.31 - resolution: "@types/react@npm:16.14.31" - dependencies: - "@types/prop-types": "*" - "@types/scheduler": "*" - csstype: ^3.0.2 - checksum: 79a2508b55b6dc0764b312f5159ea8020f5c867bf5ad625d8bebb793cbf5997aa13611170634ca29c03e46dcd0488192f634ca48dca4ea7e1216169f24ae9451 - languageName: node - linkType: hard - "@types/redux-form@npm:^8.1.9": version: 8.3.0 resolution: "@types/redux-form@npm:8.3.0" @@ -8261,10 +7772,10 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12": - version: 7.3.13 - resolution: "@types/semver@npm:7.3.13" - checksum: 00c0724d54757c2f4bc60b5032fe91cda6410e48689633d5f35ece8a0a66445e3e57fa1d6e07eb780f792e82ac542948ec4d0b76eb3484297b79bd18b8cf1cb0 +"@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.4": + version: 7.5.0 + resolution: "@types/semver@npm:7.5.0" + checksum: 0a64b9b9c7424d9a467658b18dd70d1d781c2d6f033096a6e05762d20ebbad23c1b69b0083b0484722aabf35640b78ccc3de26368bcae1129c87e9df028a22e2 languageName: node linkType: hard @@ -8333,13 +7844,6 @@ __metadata: languageName: node linkType: hard -"@types/source-list-map@npm:*": - version: 0.1.2 - resolution: "@types/source-list-map@npm:0.1.2" - checksum: fda8f37537aca9d3ed860d559289ab1dddb6897e642e6f53e909bbd18a7ac3129a8faa2a7d093847c91346cf09c86ef36e350c715406fba1f2271759b449adf6 - languageName: node - linkType: hard - "@types/stack-utils@npm:^2.0.0": version: 2.0.1 resolution: "@types/stack-utils@npm:2.0.1" @@ -8365,13 +7869,6 @@ __metadata: languageName: node linkType: hard -"@types/tapable@npm:^1, @types/tapable@npm:^1.0.5": - version: 1.0.8 - resolution: "@types/tapable@npm:1.0.8" - checksum: b4b754dd0822c407b8f29ef6b766490721c276880f9e976d92ee2b3ef915f11a05a2442ae36c8978bcd872ad6bc833b0a2c4d267f2d611590668a366bad50652 - languageName: node - linkType: hard - "@types/tern@npm:*": version: 0.23.3 resolution: "@types/tern@npm:0.23.3" @@ -8438,16 +7935,7 @@ __metadata: languageName: node linkType: hard -"@types/uglify-js@npm:*": - version: 3.17.1 - resolution: "@types/uglify-js@npm:3.17.1" - dependencies: - source-map: ^0.6.1 - checksum: 76b9aa6b5c19690bee1fba29835ca580ec92db2b43cb8e2acd0278086138372a66e55bbd785c90d032bc890069f0cfde9c763f2d2860bb1a747b581a04d0999b - languageName: node - linkType: hard - -"@types/unist@npm:*, @types/unist@npm:^2.0.0, @types/unist@npm:^2.0.2, @types/unist@npm:^2.0.3": +"@types/unist@npm:*, @types/unist@npm:^2.0.0": version: 2.0.6 resolution: "@types/unist@npm:2.0.6" checksum: 25cb860ff10dde48b54622d58b23e66214211a61c84c0f15f88d38b61aa1b53d4d46e42b557924a93178c501c166aa37e28d7f6d994aba13d24685326272d5db @@ -8477,38 +7965,6 @@ __metadata: languageName: node linkType: hard -"@types/webpack-env@npm:^1.16.0": - version: 1.18.0 - resolution: "@types/webpack-env@npm:1.18.0" - checksum: ecf4daa31cb37d474ac0ce058d83a3cadeb9881ca8107ae93c2299eaa9954943aae09b43e143c62ccbe4288a14db00c918c9debd707afe17c3998f873eaabc59 - languageName: node - linkType: hard - -"@types/webpack-sources@npm:*": - version: 3.2.0 - resolution: "@types/webpack-sources@npm:3.2.0" - dependencies: - "@types/node": "*" - "@types/source-list-map": "*" - source-map: ^0.7.3 - checksum: fa23dcfb99f79cc0ba8e6ca41cb8dedb406f8d7772e8e3d3d9b443bfb36557a1a78f4de2b97905554db98beee1a2ef6f930e188977adde6452392a64dd4b7c2a - languageName: node - linkType: hard - -"@types/webpack@npm:^4.41.26, @types/webpack@npm:^4.41.8": - version: 4.41.33 - resolution: "@types/webpack@npm:4.41.33" - dependencies: - "@types/node": "*" - "@types/tapable": ^1 - "@types/uglify-js": "*" - "@types/webpack-sources": "*" - anymatch: ^3.0.0 - source-map: ^0.6.0 - checksum: 5f64818128c94026be0e43e77d687e2d90f0da526a3a7c308c6a0bb12e93a35c9243be427bbf6865f64fd71dc5b32715af9b9da0cd6ae8335081b6db995bad2b - languageName: node - linkType: hard - "@types/ws@npm:^8.5.1": version: 8.5.3 resolution: "@types/ws@npm:8.5.3" @@ -8525,15 +7981,6 @@ __metadata: languageName: node linkType: hard -"@types/yargs@npm:^15.0.0": - version: 15.0.15 - resolution: "@types/yargs@npm:15.0.15" - dependencies: - "@types/yargs-parser": "*" - checksum: 3420f6bcc508a895ef91858f8e6de975c710e4498cf6ed293f1174d3f1ad56edb4ab8481219bf6190f64a3d4115fab1d13ab3edc90acd54fba7983144040e446 - languageName: node - linkType: hard - "@types/yargs@npm:^16.0.0": version: 16.0.4 resolution: "@types/yargs@npm:16.0.4" @@ -9258,6 +8705,37 @@ __metadata: languageName: node linkType: hard +"@yarnpkg/esbuild-plugin-pnp@npm:^3.0.0-rc.10": + version: 3.0.0-rc.15 + resolution: "@yarnpkg/esbuild-plugin-pnp@npm:3.0.0-rc.15" + dependencies: + tslib: ^2.4.0 + peerDependencies: + esbuild: ">=0.10.0" + checksum: 04da15355a99773b441742814ba4d0f3453a83df47aa07e215f167e156f109ab8e971489c8b1a4ddf3c79d568d35213f496ad52e97298228597e1aacc22680aa + languageName: node + linkType: hard + +"@yarnpkg/fslib@npm:2.10.3": + version: 2.10.3 + resolution: "@yarnpkg/fslib@npm:2.10.3" + dependencies: + "@yarnpkg/libzip": ^2.3.0 + tslib: ^1.13.0 + checksum: 0ca693f61d47bcf165411a121ed9123f512b1b5bfa5e1c6c8f280b4ffdbea9bf2a6db418f99ecfc9624587fdc695b2b64eb0fe7b4028e44095914b25ca99655e + languageName: node + linkType: hard + +"@yarnpkg/libzip@npm:2.3.0, @yarnpkg/libzip@npm:^2.3.0": + version: 2.3.0 + resolution: "@yarnpkg/libzip@npm:2.3.0" + dependencies: + "@types/emscripten": ^1.39.6 + tslib: ^1.13.0 + checksum: 533a4883f69bb013f955d80dc19719881697e6849ea5f0cbe6d87ef1d582b05cbae8a453802f92ad0c852f976296cac3ff7834be79a7e415b65cdf213e448110 + languageName: node + linkType: hard + "@zxing/library@npm:^0.17.0": version: 0.17.1 resolution: "@zxing/library@npm:0.17.1" @@ -9392,12 +8870,12 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.5.0, acorn@npm:^8.7.1, acorn@npm:^8.8.0": - version: 8.8.2 - resolution: "acorn@npm:8.8.2" +"acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.7.1, acorn@npm:^8.8.0, acorn@npm:^8.8.2, acorn@npm:^8.9.0": + version: 8.10.0 + resolution: "acorn@npm:8.10.0" bin: acorn: bin/acorn - checksum: f790b99a1bf63ef160c967e23c46feea7787e531292bb827126334612c234ed489a0dc2c7ba33156416f0ffa8d25bf2b0fdb7f35c2ba60eb3e960572bece4001 + checksum: 538ba38af0cc9e5ef983aee196c4b8b4d87c0c94532334fa7e065b2c8a1f85863467bb774231aae91613fcda5e68740c15d97b1967ae3394d20faddddd8af61d languageName: node linkType: hard @@ -9425,6 +8903,13 @@ __metadata: languageName: node linkType: hard +"agent-base@npm:5": + version: 5.1.1 + resolution: "agent-base@npm:5.1.1" + checksum: 61ae789f3019f1dc10e8cba6d3ae9826949299a4e54aaa1cfa2fa37c95a108e70e95423b963bb987d7891a703fd9a5c383a506f4901819f3ee56f3147c0aa8ab + languageName: node + linkType: hard + "agent-base@npm:6, agent-base@npm:^6.0.2": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -9455,31 +8940,6 @@ __metadata: languageName: node linkType: hard -"airbnb-js-shims@npm:^2.2.1": - version: 2.2.1 - resolution: "airbnb-js-shims@npm:2.2.1" - dependencies: - array-includes: ^3.0.3 - array.prototype.flat: ^1.2.1 - array.prototype.flatmap: ^1.2.1 - es5-shim: ^4.5.13 - es6-shim: ^0.35.5 - function.prototype.name: ^1.1.0 - globalthis: ^1.0.0 - object.entries: ^1.1.0 - object.fromentries: ^2.0.0 || ^1.0.0 - object.getownpropertydescriptors: ^2.0.3 - object.values: ^1.1.0 - promise.allsettled: ^1.0.0 - promise.prototype.finally: ^3.1.0 - string.prototype.matchall: ^4.0.0 || ^3.0.1 - string.prototype.padend: ^3.0.0 - string.prototype.padstart: ^3.0.0 - symbol.prototype.description: ^1.0.0 - checksum: bdd96e4cac75a8a942fb93cb8b7150573363a9fb40ab8528997bc067f24ae83d3031165635075b1326e463dcf840cc036b2ceb554563e75a38faf0ca288407a3 - languageName: node - linkType: hard - "ajv-formats@npm:^2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" @@ -9590,13 +9050,6 @@ __metadata: languageName: node linkType: hard -"ansi-colors@npm:^3.0.0": - version: 3.2.4 - resolution: "ansi-colors@npm:3.2.4" - checksum: 026c51880e9f8eb59b112669a87dbea4469939ff94b131606303bbd697438a6691b16b9db3027aa9bf132a244214e83ab1508b998496a34d2aea5b437ac9e62d - languageName: node - linkType: hard - "ansi-colors@npm:^4.1.1": version: 4.1.1 resolution: "ansi-colors@npm:4.1.1" @@ -9682,35 +9135,14 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.0.0": - version: 6.1.0 - resolution: "ansi-styles@npm:6.1.0" - checksum: 7a7f8528c07a9d20c3a92bccd2b6bc3bb4d26e5cb775c02826921477377bd495d615d61f710d56216344b6238d1d11ef2b0348e146c5b128715578bfb3217229 +"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 languageName: node linkType: hard -"ansi-to-html@npm:^0.6.11": - version: 0.6.15 - resolution: "ansi-to-html@npm:0.6.15" - dependencies: - entities: ^2.0.0 - bin: - ansi-to-html: bin/ansi-to-html - checksum: c899362a29b92c8ae075b72168b826f7c233875b475719304942f80695e0ce4a6812845021192da5fb0ac80b10209b4fae5aede42620a1b1b3d3b30f3ef77a86 - languageName: node - linkType: hard - -"anymatch@npm:^2.0.0": - version: 2.0.0 - resolution: "anymatch@npm:2.0.0" - dependencies: - micromatch: ^3.1.4 - normalize-path: ^2.1.1 - checksum: f7bb1929842b4585cdc28edbb385767d499ce7d673f96a8f11348d2b2904592ffffc594fe9229b9a1e9e4dccb9329b7692f9f45e6a11dcefbb76ecdc9ab740f6 - languageName: node - linkType: hard - -"anymatch@npm:^3.0.0, anymatch@npm:^3.0.3, anymatch@npm:^3.1.0, anymatch@npm:~3.1.2": +"anymatch@npm:^3.0.3, anymatch@npm:^3.1.0, anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: @@ -9873,7 +9305,7 @@ __metadata: craco-alias: ^2.1.1 craco-babel-loader: ^1.0.4 cy-verify-downloads: ^0.0.5 - cypress: ^12.16.0 + cypress: ^12.17.0 cypress-file-upload: ^4.1.1 cypress-image-snapshot: ^4.0.1 cypress-log-to-output: ^1.1.2 @@ -9892,6 +9324,7 @@ __metadata: diff: ^5.0.0 dotenv: ^8.1.0 downloadjs: ^1.4.7 + echarts: ^5.4.2 eslint: ^8.42.0 eslint-config-prettier: ^8.6.0 eslint-import-resolver-babel-module: ^5.3.1 @@ -10069,16 +9502,6 @@ __metadata: languageName: node linkType: hard -"are-we-there-yet@npm:^2.0.0": - version: 2.0.0 - resolution: "are-we-there-yet@npm:2.0.0" - dependencies: - delegates: ^1.0.0 - readable-stream: ^3.6.0 - checksum: 6c80b4fd04ecee6ba6e737e0b72a4b41bdc64b7d279edfc998678567ff583c8df27e27523bc789f2c99be603ffa9eaa612803da1d886962d2086e7ff6fa90c7c - languageName: node - linkType: hard - "are-we-there-yet@npm:^3.0.0": version: 3.0.1 resolution: "are-we-there-yet@npm:3.0.1" @@ -10138,6 +9561,15 @@ __metadata: languageName: node linkType: hard +"aria-query@npm:5.1.3, aria-query@npm:^5.0.0": + version: 5.1.3 + resolution: "aria-query@npm:5.1.3" + dependencies: + deep-equal: ^2.0.5 + checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b + languageName: node + linkType: hard + "aria-query@npm:^4.2.2": version: 4.2.2 resolution: "aria-query@npm:4.2.2" @@ -10148,31 +9580,13 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.0.0": - version: 5.0.0 - resolution: "aria-query@npm:5.0.0" - checksum: c41f98866c5a304561ee8cae55856711cddad6f3f85d8cb43cc5f79667078d9b8979ce32d244c1ff364e6463a4d0b6865804a33ccc717fed701b281cf7dc6296 - languageName: node - linkType: hard - -"arr-diff@npm:^4.0.0": - version: 4.0.0 - resolution: "arr-diff@npm:4.0.0" - checksum: ea7c8834842ad3869297f7915689bef3494fd5b102ac678c13ffccab672d3d1f35802b79e90c4cfec2f424af3392e44112d1ccf65da34562ed75e049597276a0 - languageName: node - linkType: hard - -"arr-flatten@npm:^1.1.0": - version: 1.1.0 - resolution: "arr-flatten@npm:1.1.0" - checksum: 963fe12564fca2f72c055f3f6c206b9e031f7c433a0c66ca9858b484821f248c5b1e5d53c8e4989d80d764cd776cf6d9b160ad05f47bdc63022bfd63b5455e22 - languageName: node - linkType: hard - -"arr-union@npm:^3.1.0": - version: 3.1.0 - resolution: "arr-union@npm:3.1.0" - checksum: b5b0408c6eb7591143c394f3be082fee690ddd21f0fdde0a0a01106799e847f67fcae1b7e56b0a0c173290e29c6aca9562e82b300708a268bc8f88f3d6613cb9 +"array-buffer-byte-length@npm:^1.0.0": + version: 1.0.0 + resolution: "array-buffer-byte-length@npm:1.0.0" + dependencies: + call-bind: ^1.0.2 + is-array-buffer: ^3.0.1 + checksum: 044e101ce150f4804ad19c51d6c4d4cfa505c5b2577bd179256e4aa3f3f6a0a5e9874c78cd428ee566ac574c8a04d7ce21af9fe52e844abfdccb82b33035a7c3 languageName: node linkType: hard @@ -10183,13 +9597,6 @@ __metadata: languageName: node linkType: hard -"array-find-index@npm:^1.0.1": - version: 1.0.2 - resolution: "array-find-index@npm:1.0.2" - checksum: aac128bf369e1ac6c06ff0bb330788371c0e256f71279fb92d745e26fb4b9db8920e485b4ec25e841c93146bf71a34dcdbcefa115e7e0f96927a214d237b7081 - languageName: node - linkType: hard - "array-flatten@npm:1.1.1": version: 1.1.1 resolution: "array-flatten@npm:1.1.1" @@ -10204,7 +9611,7 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.0.3, array-includes@npm:^3.1.4, array-includes@npm:^3.1.5": +"array-includes@npm:^3.1.4, array-includes@npm:^3.1.5": version: 3.1.6 resolution: "array-includes@npm:3.1.6" dependencies: @@ -10224,15 +9631,6 @@ __metadata: languageName: node linkType: hard -"array-union@npm:^1.0.2": - version: 1.0.2 - resolution: "array-union@npm:1.0.2" - dependencies: - array-uniq: ^1.0.1 - checksum: 82cec6421b6e6766556c484835a6d476a873f1b71cace5ab2b4f1b15b1e3162dc4da0d16f7a2b04d4aec18146c6638fe8f661340b31ba8e469fd811a1b45dc8d - languageName: node - linkType: hard - "array-union@npm:^2.1.0": version: 2.1.0 resolution: "array-union@npm:2.1.0" @@ -10240,21 +9638,7 @@ __metadata: languageName: node linkType: hard -"array-uniq@npm:^1.0.1": - version: 1.0.3 - resolution: "array-uniq@npm:1.0.3" - checksum: 1625f06b093d8bf279b81adfec6e72951c0857d65b5e3f65f053fffe9f9dd61c2fc52cff57e38a4700817e7e3f01a4faa433d505ea9e33cdae4514c334e0bf9e - languageName: node - linkType: hard - -"array-unique@npm:^0.3.2": - version: 0.3.2 - resolution: "array-unique@npm:0.3.2" - checksum: da344b89cfa6b0a5c221f965c21638bfb76b57b45184a01135382186924f55973cd9b171d4dad6bf606c6d9d36b0d721d091afdc9791535ead97ccbe78f8a888 - languageName: node - linkType: hard - -"array.prototype.flat@npm:^1.2.1, array.prototype.flat@npm:^1.2.5": +"array.prototype.flat@npm:^1.2.5": version: 1.3.1 resolution: "array.prototype.flat@npm:1.3.1" dependencies: @@ -10266,7 +9650,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.2.1, array.prototype.flatmap@npm:^1.3.0": +"array.prototype.flatmap@npm:^1.3.0": version: 1.3.1 resolution: "array.prototype.flatmap@npm:1.3.1" dependencies: @@ -10278,19 +9662,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.map@npm:^1.0.5": - version: 1.0.5 - resolution: "array.prototype.map@npm:1.0.5" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - es-array-method-boxes-properly: ^1.0.0 - is-string: ^1.0.7 - checksum: 70c4ecdd39480a51cfe84d18e4839a5f05d0b5d2785fee6838cd2bd5f86a17340a734ce7bb90c16804a70cead214b6f42c3d285f92267e11ccc0abd1880fe3b5 - languageName: node - linkType: hard - "array.prototype.reduce@npm:^1.0.5": version: 1.0.5 resolution: "array.prototype.reduce@npm:1.0.5" @@ -10304,13 +9675,6 @@ __metadata: languageName: node linkType: hard -"arrify@npm:^2.0.1": - version: 2.0.1 - resolution: "arrify@npm:2.0.1" - checksum: 067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 - languageName: node - linkType: hard - "asap@npm:^2.0.0, asap@npm:^2.0.6, asap@npm:~2.0.3, asap@npm:~2.0.6": version: 2.0.6 resolution: "asap@npm:2.0.6" @@ -10363,10 +9727,15 @@ __metadata: languageName: node linkType: hard -"assign-symbols@npm:^1.0.0": - version: 1.0.0 - resolution: "assign-symbols@npm:1.0.0" - checksum: c0eb895911d05b6b2d245154f70461c5e42c107457972e5ebba38d48967870dee53bcdf6c7047990586daa80fab8dab3cc6300800fbd47b454247fdedd859a2c +"assert@npm:^2.0.0": + version: 2.0.0 + resolution: "assert@npm:2.0.0" + dependencies: + es6-object-assign: ^1.1.0 + is-nan: ^1.2.1 + object-is: ^1.0.1 + util: ^0.12.0 + checksum: bb91f181a86d10588ee16c5e09c280f9811373974c29974cbe401987ea34e966699d7989a812b0e19377b511ea0bc627f5905647ce569311824848ede382cae8 languageName: node linkType: hard @@ -10377,6 +9746,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:0.15.2": + version: 0.15.2 + resolution: "ast-types@npm:0.15.2" + dependencies: + tslib: ^2.0.1 + checksum: 24f0d86bf9e4c8dae16fa24b13c1776f2c2677040bcfbd4eb4f27911db49020be4876885e45e6cfcc548ed4dfea3a0742d77e3346b84fae47379cb0b89e9daa0 + languageName: node + linkType: hard + "ast-types@npm:^0.14.2": version: 0.14.2 resolution: "ast-types@npm:0.14.2" @@ -10386,6 +9764,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.16.1": + version: 0.16.1 + resolution: "ast-types@npm:0.16.1" + dependencies: + tslib: ^2.0.1 + checksum: 21c186da9fdb1d8087b1b7dabbc4059f91aa5a1e593a9776b4393cc1eaa857e741b2dda678d20e34b16727b78fef3ab59cf8f0c75ed1ba649c78fe194e5c114b + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -10464,23 +9851,6 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:^9.0.0, autoprefixer@npm:^9.8.6": - version: 9.8.8 - resolution: "autoprefixer@npm:9.8.8" - dependencies: - browserslist: ^4.12.0 - caniuse-lite: ^1.0.30001109 - normalize-range: ^0.1.2 - num2fraction: ^1.2.2 - picocolors: ^0.2.1 - postcss: ^7.0.32 - postcss-value-parser: ^4.1.0 - bin: - autoprefixer: bin/autoprefixer - checksum: 8f017672fbac248db0cf4e86aa707d8b148d9abadb842b5cf4c6be306d80fa6a654fadefd17e46213234c1f0947612acce2864f93e903f3e736b183fc1aedc45 - languageName: node - linkType: hard - "available-typed-arrays@npm:^1.0.5": version: 1.0.5 resolution: "available-typed-arrays@npm:1.0.5" @@ -10546,6 +9916,15 @@ __metadata: languageName: node linkType: hard +"babel-core@npm:^7.0.0-bridge.0": + version: 7.0.0-bridge.0 + resolution: "babel-core@npm:7.0.0-bridge.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 2a1cb879019dffb08d17bec36e13c3a6d74c94773f41c1fd8b14de13f149cc34b705b0a1e07b42fcf35917b49d78db6ff0c5c3b00b202a5235013d517b5c6bbb + languageName: node + linkType: hard + "babel-jest@npm:^27.4.2, babel-jest@npm:^27.5.1": version: 27.5.1 resolution: "babel-jest@npm:27.5.1" @@ -10594,7 +9973,7 @@ __metadata: languageName: node linkType: hard -"babel-loader@npm:^8.0.0, babel-loader@npm:^8.2.3": +"babel-loader@npm:^8.2.3": version: 8.3.0 resolution: "babel-loader@npm:8.3.0" dependencies: @@ -10609,6 +9988,19 @@ __metadata: languageName: node linkType: hard +"babel-loader@npm:^9.0.0": + version: 9.1.3 + resolution: "babel-loader@npm:9.1.3" + dependencies: + find-cache-dir: ^4.0.0 + schema-utils: ^4.0.0 + peerDependencies: + "@babel/core": ^7.12.0 + webpack: ">=5" + checksum: b168dde5b8cf11206513371a79f86bb3faa7c714e6ec9fffd420876b61f3d7f5f4b976431095ef6a14bc4d324505126deb91045fd41e312ba49f4deaa166fe28 + languageName: node + linkType: hard + "babel-plugin-add-module-exports@npm:^1.0.4": version: 1.0.4 resolution: "babel-plugin-add-module-exports@npm:1.0.4" @@ -10623,18 +10015,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-apply-mdx-type-prop@npm:1.6.22": - version: 1.6.22 - resolution: "babel-plugin-apply-mdx-type-prop@npm:1.6.22" - dependencies: - "@babel/helper-plugin-utils": 7.10.4 - "@mdx-js/util": 1.6.22 - peerDependencies: - "@babel/core": ^7.11.6 - checksum: 43e2100164a8f3e46fddd76afcbfb1f02cbebd5612cfe63f3d344a740b0afbdc4d2bf5659cffe9323dd2554c7b86b23ebedae9dadcec353b6594f4292a1a28e2 - languageName: node - linkType: hard - "babel-plugin-emotion@npm:^10.0.27": version: 10.0.33 resolution: "babel-plugin-emotion@npm:10.0.33" @@ -10653,16 +10033,7 @@ __metadata: languageName: node linkType: hard -"babel-plugin-extract-import-names@npm:1.6.22": - version: 1.6.22 - resolution: "babel-plugin-extract-import-names@npm:1.6.22" - dependencies: - "@babel/helper-plugin-utils": 7.10.4 - checksum: 145ccf09c96d36411d340e78086555f8d4d5924ea39fcb0eca461c066cfa98bc4344982bb35eb85d054ef88f8d4dfc0205ba27370c1d8fcc78191b02908d044d - languageName: node - linkType: hard - -"babel-plugin-istanbul@npm:^6.0.0, babel-plugin-istanbul@npm:^6.1.1": +"babel-plugin-istanbul@npm:^6.1.1": version: 6.1.1 resolution: "babel-plugin-istanbul@npm:6.1.1" dependencies: @@ -10723,7 +10094,7 @@ __metadata: languageName: node linkType: hard -"babel-plugin-macros@npm:^3.0.1, babel-plugin-macros@npm:^3.1.0": +"babel-plugin-macros@npm:^3.1.0": version: 3.1.0 resolution: "babel-plugin-macros@npm:3.1.0" dependencies: @@ -10776,28 +10147,16 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs2@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-plugin-polyfill-corejs2@npm:0.4.3" +"babel-plugin-polyfill-corejs2@npm:^0.4.4": + version: 0.4.5 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.5" dependencies: - "@babel/compat-data": ^7.17.7 - "@babel/helper-define-polyfill-provider": ^0.4.0 - semver: ^6.1.1 + "@babel/compat-data": ^7.22.6 + "@babel/helper-define-polyfill-provider": ^0.4.2 + semver: ^6.3.1 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 09ba40b9f8ac66a733628b2f12722bb764bdcc4f9600b93d60f1994418a8f84bc4b1ed9ab07c9d288debbf6210413fdff0721a3a43bd89c7f77adf76b0310adc - languageName: node - linkType: hard - -"babel-plugin-polyfill-corejs3@npm:^0.1.0": - version: 0.1.7 - resolution: "babel-plugin-polyfill-corejs3@npm:0.1.7" - dependencies: - "@babel/helper-define-polyfill-provider": ^0.1.5 - core-js-compat: ^3.8.1 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 5c420590a6e18688a868218fa1f5025e9294d093968d2fe1e6aa86981776d66826182f9b36cdd1c41741e9c401bf76164313aab6661efb56741348ed0e98448d + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 33a8e06aa54e2858d211c743d179f0487b03222f9ca1bfd7c4865bca243fca942a3358cb75f6bb894ed476cbddede834811fbd6903ff589f055821146f053e1a languageName: node linkType: hard @@ -10813,15 +10172,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.8.1": - version: 0.8.1 - resolution: "babel-plugin-polyfill-corejs3@npm:0.8.1" +"babel-plugin-polyfill-corejs3@npm:^0.8.2": + version: 0.8.3 + resolution: "babel-plugin-polyfill-corejs3@npm:0.8.3" dependencies: - "@babel/helper-define-polyfill-provider": ^0.4.0 - core-js-compat: ^3.30.1 + "@babel/helper-define-polyfill-provider": ^0.4.2 + core-js-compat: ^3.31.0 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: c23a581973c141a4687126cf964981180ef27e3eb0b34b911161db4f5caf9ba7ff60bee0ebe46d650ba09e03a6a3ac2cd6a6ae5f4f5363a148470e5cd8447df2 + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: dcbb30e551702a82cfd4d2c375da2c317658e55f95e9edcda93b9bbfdcc8fb6e5344efcb144e04d3406859e7682afce7974c60ededd9f12072a48a83dd22a0da languageName: node linkType: hard @@ -10836,14 +10195,14 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-regenerator@npm:^0.5.0": - version: 0.5.0 - resolution: "babel-plugin-polyfill-regenerator@npm:0.5.0" +"babel-plugin-polyfill-regenerator@npm:^0.5.1": + version: 0.5.2 + resolution: "babel-plugin-polyfill-regenerator@npm:0.5.2" dependencies: - "@babel/helper-define-polyfill-provider": ^0.4.0 + "@babel/helper-define-polyfill-provider": ^0.4.2 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: ef2bcffc7c9a5e4426fc2dbf89bf3a46999a8415c21cd741c3ab3cb4b5ab804aaa3d71ef733f0eda1bcc0b91d9d80f98d33983a66dab9b8bed166ec38f8f8ad1 + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: d962200f604016a9a09bc9b4aaf60a3db7af876bb65bcefaeac04d44ac9d9ec4037cf24ce117760cc141d7046b6394c7eb0320ba9665cb4a2ee64df2be187c93 languageName: node linkType: hard @@ -10966,13 +10325,6 @@ __metadata: languageName: node linkType: hard -"bail@npm:^1.0.0": - version: 1.0.5 - resolution: "bail@npm:1.0.5" - checksum: 6c334940d7eaa4e656a12fb12407b6555649b6deb6df04270fa806e0da82684ebe4a4e47815b271c794b40f8d6fa286e0c248b14ddbabb324a917fab09b7301a - languageName: node - linkType: hard - "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -11001,21 +10353,6 @@ __metadata: languageName: node linkType: hard -"base@npm:^0.11.1": - version: 0.11.2 - resolution: "base@npm:0.11.2" - dependencies: - cache-base: ^1.0.1 - class-utils: ^0.3.5 - component-emitter: ^1.2.1 - define-property: ^1.0.0 - isobject: ^3.0.1 - mixin-deep: ^1.2.0 - pascalcase: ^0.1.1 - checksum: a4a146b912e27eea8f66d09cb0c9eab666f32ce27859a7dfd50f38cd069a2557b39f16dba1bc2aecb3b44bf096738dd207b7970d99b0318423285ab1b1994edd - languageName: node - linkType: hard - "batch@npm:0.6.1": version: 0.6.1 resolution: "batch@npm:0.6.1" @@ -11032,12 +10369,12 @@ __metadata: languageName: node linkType: hard -"better-opn@npm:^2.1.1": - version: 2.1.1 - resolution: "better-opn@npm:2.1.1" +"better-opn@npm:^3.0.2": + version: 3.0.2 + resolution: "better-opn@npm:3.0.2" dependencies: - open: ^7.0.3 - checksum: 3d1a945d125cbbc6e6a841bef7540435d77d5aa61fc4d345896f5f0b3780fcf9c7145373deaedf62d674a427b187ae973f4410884f9fea0c15f7f01f9dc339c7 + open: ^8.0.4 + checksum: 1471552fa7f733561e7f49e812be074b421153006ca744de985fb6d38939807959fc5fe9cb819cf09f864782e294704fd3b31711ea14c115baf3330a2f1135de languageName: node linkType: hard @@ -11065,7 +10402,7 @@ __metadata: languageName: node linkType: hard -"big-integer@npm:^1.6.7": +"big-integer@npm:^1.6.44": version: 1.6.51 resolution: "big-integer@npm:1.6.51" checksum: 3d444173d1b2e20747e2c175568bedeebd8315b0637ea95d75fd27830d3b8e8ba36c6af40374f36bdaea7b5de376dcada1b07587cb2a79a928fccdb6e6e3c518 @@ -11086,7 +10423,7 @@ __metadata: languageName: node linkType: hard -"bl@npm:^4.1.0": +"bl@npm:^4.0.3, bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" dependencies: @@ -11189,7 +10526,7 @@ __metadata: languageName: node linkType: hard -"boxen@npm:^5.0.0, boxen@npm:^5.1.2": +"boxen@npm:^5.0.0": version: 5.1.2 resolution: "boxen@npm:5.1.2" dependencies: @@ -11205,12 +10542,12 @@ __metadata: languageName: node linkType: hard -"bplist-parser@npm:^0.1.0": - version: 0.1.1 - resolution: "bplist-parser@npm:0.1.1" +"bplist-parser@npm:^0.2.0": + version: 0.2.0 + resolution: "bplist-parser@npm:0.2.0" dependencies: - big-integer: ^1.6.7 - checksum: 1501d52f009c9f23ecee6855940e84ac55a6120c0f05570b1f51c8d494023416ec12f4d91b5ac97d6c0941d96dd41d7cb0bc1a9c0a02092df5b4b511acb8dda5 + big-integer: ^1.6.44 + checksum: d5339dd16afc51de6c88f88f58a45b72ed6a06aa31f5557d09877575f220b7c1d3fbe375da0b62e6a10d4b8ed80523567e351f24014f5bc886ad523758142cdd languageName: node linkType: hard @@ -11223,24 +10560,6 @@ __metadata: languageName: node linkType: hard -"braces@npm:^2.3.1": - version: 2.3.2 - resolution: "braces@npm:2.3.2" - dependencies: - arr-flatten: ^1.1.0 - array-unique: ^0.3.2 - extend-shallow: ^2.0.1 - fill-range: ^4.0.0 - isobject: ^3.0.1 - repeat-element: ^1.1.2 - snapdragon: ^0.8.1 - snapdragon-node: ^2.0.1 - split-string: ^3.0.2 - to-regex: ^3.0.1 - checksum: e30dcb6aaf4a31c8df17d848aa283a65699782f75ad61ae93ec25c9729c66cf58e66f0000a9fec84e4add1135bb7da40f7cb9601b36bebcfa9ca58e8d5c07de0 - languageName: node - linkType: hard - "braces@npm:^3.0.2, braces@npm:~3.0.2": version: 3.0.2 resolution: "braces@npm:3.0.2" @@ -11360,6 +10679,15 @@ __metadata: languageName: node linkType: hard +"browserify-zlib@npm:^0.1.4": + version: 0.1.4 + resolution: "browserify-zlib@npm:0.1.4" + dependencies: + pako: ~0.2.0 + checksum: abee4cb4349e8a21391fd874564f41b113fe691372913980e6fa06a777e4ea2aad4e942af14ab99bce190d5ac8f5328201432f4ef0eae48c6d02208bc212976f + languageName: node + linkType: hard + "browserify-zlib@npm:~0.2.0": version: 0.2.0 resolution: "browserify-zlib@npm:0.2.0" @@ -11619,32 +10947,6 @@ __metadata: languageName: node linkType: hard -"cacache@npm:^15.0.5": - version: 15.3.0 - resolution: "cacache@npm:15.3.0" - dependencies: - "@npmcli/fs": ^1.0.0 - "@npmcli/move-file": ^1.0.1 - chownr: ^2.0.0 - fs-minipass: ^2.0.0 - glob: ^7.1.4 - infer-owner: ^1.0.4 - lru-cache: ^6.0.0 - minipass: ^3.1.1 - minipass-collect: ^1.0.2 - minipass-flush: ^1.0.5 - minipass-pipeline: ^1.2.2 - mkdirp: ^1.0.3 - p-map: ^4.0.0 - promise-inflight: ^1.0.1 - rimraf: ^3.0.2 - ssri: ^8.0.1 - tar: ^6.0.2 - unique-filename: ^1.1.1 - checksum: a07327c27a4152c04eb0a831c63c00390d90f94d51bb80624a66f4e14a6b6360bbf02a84421267bd4d00ca73ac9773287d8d7169e8d2eafe378d2ce140579db8 - languageName: node - linkType: hard - "cacache@npm:^16.1.0": version: 16.1.3 resolution: "cacache@npm:16.1.3" @@ -11671,23 +10973,6 @@ __metadata: languageName: node linkType: hard -"cache-base@npm:^1.0.1": - version: 1.0.1 - resolution: "cache-base@npm:1.0.1" - dependencies: - collection-visit: ^1.0.0 - component-emitter: ^1.2.1 - get-value: ^2.0.6 - has-value: ^1.0.0 - isobject: ^3.0.1 - set-value: ^2.0.0 - to-object-path: ^0.3.0 - union-value: ^1.0.0 - unset-value: ^1.0.0 - checksum: 9114b8654fe2366eedc390bad0bcf534e2f01b239a888894e2928cb58cdc1e6ea23a73c6f3450dcfd2058aa73a8a981e723cd1e7c670c047bf11afdc65880107 - languageName: node - linkType: hard - "cacheable-lookup@npm:^5.0.3": version: 5.0.4 resolution: "cacheable-lookup@npm:5.0.4" @@ -11734,13 +11019,6 @@ __metadata: languageName: node linkType: hard -"call-me-maybe@npm:^1.0.1": - version: 1.0.2 - resolution: "call-me-maybe@npm:1.0.2" - checksum: 42ff2d0bed5b207e3f0122589162eaaa47ba618f79ad2382fe0ba14d9e49fbf901099a6227440acc5946f86a4953e8aa2d242b330b0a5de4d090bb18f8935cae - languageName: node - linkType: hard - "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -11748,7 +11026,7 @@ __metadata: languageName: node linkType: hard -"camel-case@npm:^4.1.1, camel-case@npm:^4.1.2": +"camel-case@npm:^4.1.2": version: 4.1.2 resolution: "camel-case@npm:4.1.2" dependencies: @@ -11758,30 +11036,13 @@ __metadata: languageName: node linkType: hard -"camelcase-css@npm:2.0.1, camelcase-css@npm:^2.0.1": +"camelcase-css@npm:^2.0.1": version: 2.0.1 resolution: "camelcase-css@npm:2.0.1" checksum: 1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1 languageName: node linkType: hard -"camelcase-keys@npm:^2.0.0": - version: 2.1.0 - resolution: "camelcase-keys@npm:2.1.0" - dependencies: - camelcase: ^2.0.0 - map-obj: ^1.0.0 - checksum: 97d2993da5db44d45e285910c70a54ce7f83a2be05afceaafd9831f7aeaf38a48dcdede5ca3aae2b2694852281d38dc459706e346942c5df0bf755f4133f5c39 - languageName: node - linkType: hard - -"camelcase@npm:^2.0.0": - version: 2.1.1 - resolution: "camelcase@npm:2.1.1" - checksum: 20a3ef08f348de832631d605362ffe447d883ada89617144a82649363ed5860923b021f8e09681624ef774afb93ff3597cfbcf8aaf0574f65af7648f1aea5e50 - languageName: node - linkType: hard - "camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" @@ -11822,7 +11083,7 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001332, caniuse-lite@npm:^1.0.30001426": +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001332, caniuse-lite@npm:^1.0.30001426": version: 1.0.30001462 resolution: "caniuse-lite@npm:1.0.30001462" checksum: e4a57d7851eec65e7c9b6c11c4bbcecdc49d87b1b01bff3c15ea27efb05f959891b4c70ac169842067c134d6fa126d9ad5a91d0f85c7387c5bd912eaf41ea647 @@ -11840,16 +11101,7 @@ __metadata: languageName: node linkType: hard -"capture-exit@npm:^2.0.0": - version: 2.0.0 - resolution: "capture-exit@npm:2.0.0" - dependencies: - rsvp: ^4.8.4 - checksum: 0b9f10daca09e521da9599f34c8e7af14ad879c336e2bdeb19955b375398ae1c5bcc91ac9f2429944343057ee9ed028b1b2fb28816c384e0e55d70c439b226f4 - languageName: node - linkType: hard - -"case-sensitive-paths-webpack-plugin@npm:^2.3.0, case-sensitive-paths-webpack-plugin@npm:^2.4.0": +"case-sensitive-paths-webpack-plugin@npm:^2.4.0": version: 2.4.0 resolution: "case-sensitive-paths-webpack-plugin@npm:2.4.0" checksum: bcf469446eeee9ac0046e30860074ebb9aa4803aab9140e6bb72b600b23b1d70635690754be4504ce35cd99cdf05226bee8d894ba362a3f5485d5f6310fc6d02 @@ -11863,13 +11115,6 @@ __metadata: languageName: node linkType: hard -"ccount@npm:^1.0.0": - version: 1.1.0 - resolution: "ccount@npm:1.1.0" - checksum: b335a79d0aa4308919cf7507babcfa04ac63d389ebed49dbf26990d4607c8a4713cde93cc83e707d84571ddfe1e7615dad248be9bc422ae4c188210f71b08b78 - languageName: node - linkType: hard - "chalk@npm:5.2.0, chalk@npm:^5.0.0, chalk@npm:^5.0.1": version: 5.2.0 resolution: "chalk@npm:5.2.0" @@ -12023,6 +11268,13 @@ __metadata: languageName: node linkType: hard +"chownr@npm:^1.1.1": + version: 1.1.4 + resolution: "chownr@npm:1.1.4" + checksum: 115648f8eb38bac5e41c3857f3e663f9c39ed6480d1349977c4d96c95a47266fcacc5a5aabf3cb6c481e22d72f41992827db47301851766c4fd77ac21a4f081d + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -12030,21 +11282,14 @@ __metadata: languageName: node linkType: hard -"chroma-js@npm:^2.1.2": - version: 2.4.2 - resolution: "chroma-js@npm:2.4.2" - checksum: cf9884c02d406286e4370599bcd1afbf089384407df46b3a69edfedcba7bb99e8f959a5cfdbfec750b305c441c06ca40cd1f70ba3a6c2ce739ac09a92520ddae - languageName: node - linkType: hard - -"chromatic@npm:^6.19.8": - version: 6.19.8 - resolution: "chromatic@npm:6.19.8" +"chromatic@npm:^6.20.0": + version: 6.20.0 + resolution: "chromatic@npm:6.20.0" bin: chroma: dist/bin.js chromatic: dist/bin.js chromatic-cli: dist/bin.js - checksum: 3f80373d9e77d3363924c274c8b9465b5f0ff835b7fb4a753848e37068a4564fa67ab205a4cf89820cf136fdefd637b54730819a5c376406a87bf8737ddf03ac + checksum: 90d413144ea9502cb96fd0065a0cf2ece63d832da2d7fd93f9577fd09080cbeb829ce9ca1d2384d4f7739cc249aa09033ca61820ac3c1656ff92d6a4ba2fbd67 languageName: node linkType: hard @@ -12100,18 +11345,6 @@ __metadata: languageName: node linkType: hard -"class-utils@npm:^0.3.5": - version: 0.3.6 - resolution: "class-utils@npm:0.3.6" - dependencies: - arr-union: ^3.1.0 - define-property: ^0.2.5 - isobject: ^3.0.0 - static-extend: ^0.1.1 - checksum: be108900801e639e50f96a7e4bfa8867c753a7750a7603879f3981f8b0a89cba657497a2d5f40cd4ea557ff15d535a100818bb486baf6e26fe5d7872e75f1078 - languageName: node - linkType: hard - "classnames@npm:*, classnames@npm:2.x, classnames@npm:^2.2, classnames@npm:^2.2.1, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1, classnames@npm:^2.3.2": version: 2.3.2 resolution: "classnames@npm:2.3.2" @@ -12119,15 +11352,6 @@ __metadata: languageName: node linkType: hard -"clean-css@npm:^4.2.3": - version: 4.2.4 - resolution: "clean-css@npm:4.2.4" - dependencies: - source-map: ~0.6.0 - checksum: 045ff6fcf4b5c76a084b24e1633e0c78a13b24080338fc8544565a9751559aa32ff4ee5886d9e52c18a644a6ff119bd8e37bc58e574377c05382a1fb7dbe39f8 - languageName: node - linkType: hard - "clean-css@npm:^5.2.2": version: 5.3.0 resolution: "clean-css@npm:5.3.0" @@ -12297,14 +11521,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:1.1.0": - version: 1.1.0 - resolution: "clsx@npm:1.1.0" - checksum: 50e889839a557b8a2fca063ee7ea22ba8c261e7f9f7aadc257065fc77f16fa0a98ce826fb2b126d05fb736560333971dbb882874054df7bb8f4317e224ec1978 - languageName: node - linkType: hard - -"clsx@npm:^1.0.4, clsx@npm:^1.1.0, clsx@npm:^1.1.1, clsx@npm:^1.2.1": +"clsx@npm:^1.1.0, clsx@npm:^1.1.1, clsx@npm:^1.2.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12 @@ -12378,13 +11595,6 @@ __metadata: languageName: node linkType: hard -"collapse-white-space@npm:^1.0.2": - version: 1.0.6 - resolution: "collapse-white-space@npm:1.0.6" - checksum: 9673fb797952c5c888341435596c69388b22cd5560c8cd3f40edb72734a9c820f56a7c9525166bcb7068b5d5805372e6fd0c4b9f2869782ad070cb5d3faf26e7 - languageName: node - linkType: hard - "collect-v8-coverage@npm:^1.0.0": version: 1.0.1 resolution: "collect-v8-coverage@npm:1.0.1" @@ -12392,16 +11602,6 @@ __metadata: languageName: node linkType: hard -"collection-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "collection-visit@npm:1.0.0" - dependencies: - map-visit: ^1.0.0 - object-visit: ^1.0.0 - checksum: 15d9658fe6eb23594728346adad5433b86bb7a04fd51bbab337755158722f9313a5376ef479de5b35fbc54140764d0d39de89c339f5d25b959ed221466981da9 - languageName: node - linkType: hard - "color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -12434,7 +11634,7 @@ __metadata: languageName: node linkType: hard -"color-support@npm:^1.1.2, color-support@npm:^1.1.3": +"color-support@npm:^1.1.3": version: 1.1.3 resolution: "color-support@npm:1.1.3" bin: @@ -12520,7 +11720,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^4.0.1, commander@npm:^4.1.1": +"commander@npm:^4.0.1": version: 4.1.1 resolution: "commander@npm:4.1.1" checksum: d7b9913ff92cae20cb577a4ac6fcc121bd6223319e54a40f51a14740a681ad5c574fd29a57da478a5f234a6fa6c52cbf0b7c641353e03c648b1ae85ba670b977 @@ -12576,7 +11776,7 @@ __metadata: languageName: node linkType: hard -"component-emitter@npm:^1.2.1, component-emitter@npm:^1.3.0": +"component-emitter@npm:^1.3.0": version: 1.3.0 resolution: "component-emitter@npm:1.3.0" checksum: b3c46de38ffd35c57d1c02488355be9f218e582aec72d72d1b8bbec95a3ac1b38c96cd6e03ff015577e68f550fbb361a3bfdbd9bb248be9390b7b3745691be6b @@ -12626,7 +11826,7 @@ __metadata: languageName: node linkType: hard -"concat-stream@npm:^1.6.0, concat-stream@npm:^1.6.1, concat-stream@npm:~1.6.0": +"concat-stream@npm:^1.6.0, concat-stream@npm:^1.6.1, concat-stream@npm:^1.6.2, concat-stream@npm:~1.6.0": version: 1.6.2 resolution: "concat-stream@npm:1.6.2" dependencies: @@ -12742,7 +11942,7 @@ __metadata: languageName: node linkType: hard -"constants-browserify@npm:~1.0.0": +"constants-browserify@npm:^1.0.0, constants-browserify@npm:~1.0.0": version: 1.0.0 resolution: "constants-browserify@npm:1.0.0" checksum: f7ac8c6d0b6e4e0c77340a1d47a3574e25abd580bfd99ad707b26ff7618596cf1a5e5ce9caf44715e9e01d4a5d12cb3b4edaf1176f34c19adb2874815a56e64f @@ -12814,14 +12014,7 @@ __metadata: languageName: node linkType: hard -"copy-descriptor@npm:^0.1.0": - version: 0.1.1 - resolution: "copy-descriptor@npm:0.1.1" - checksum: d4b7b57b14f1d256bb9aa0b479241048afd7f5bcf22035fc7b94e8af757adeae247ea23c1a774fe44869fd5694efba4a969b88d966766c5245fdee59837fe45b - languageName: node - linkType: hard - -"copy-to-clipboard@npm:^3.3.1, copy-to-clipboard@npm:^3.3.3": +"copy-to-clipboard@npm:^3.3.1": version: 3.3.3 resolution: "copy-to-clipboard@npm:3.3.3" dependencies: @@ -12830,7 +12023,7 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.25.1, core-js-compat@npm:^3.30.1, core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.8.1": +"core-js-compat@npm:^3.25.1, core-js-compat@npm:^3.31.0": version: 3.31.0 resolution: "core-js-compat@npm:3.31.0" dependencies: @@ -12853,7 +12046,7 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^3.0.1, core-js@npm:^3.0.4, core-js@npm:^3.19.2, core-js@npm:^3.5.0, core-js@npm:^3.6.5, core-js@npm:^3.8.2, core-js@npm:^3.9.1": +"core-js@npm:^3.0.1, core-js@npm:^3.19.2, core-js@npm:^3.5.0, core-js@npm:^3.9.1": version: 3.29.0 resolution: "core-js@npm:3.29.0" checksum: 2bd69d783efcd2ef9197ce892a8b91d7b2fd86dddce805a3be0ff721013a2342eeab0f7d0b4b5548c1377b9846a8fb81485054efd39618b9d1a1fca04af81ccf @@ -12924,35 +12117,6 @@ __metadata: languageName: node linkType: hard -"cp-file@npm:^7.0.0": - version: 7.0.0 - resolution: "cp-file@npm:7.0.0" - dependencies: - graceful-fs: ^4.1.2 - make-dir: ^3.0.0 - nested-error-stacks: ^2.0.0 - p-event: ^4.1.0 - checksum: dd60ed8d865d25a69548e15b21dd0d2fc66f10371e4970aa21b626a7578ebf419f44f386977ed3b3726c07401d4a64ee679cf1da566d8f66f01e9a359b85201f - languageName: node - linkType: hard - -"cpy@npm:^8.1.2": - version: 8.1.2 - resolution: "cpy@npm:8.1.2" - dependencies: - arrify: ^2.0.1 - cp-file: ^7.0.0 - globby: ^9.2.0 - has-glob: ^1.0.0 - junk: ^3.1.0 - nested-error-stacks: ^2.1.0 - p-all: ^2.1.0 - p-filter: ^2.1.0 - p-map: ^3.0.0 - checksum: e121f13f2b6af4a7c00de17984086a45b67eaaeeb0286a5cf67f2fdaf18d8ce6c2a9fe4ccfa37953e6982f55772f384f040f45f1961530655838c2b7486788a7 - languageName: node - linkType: hard - "cra-bundle-analyzer@npm:^0.1.0": version: 0.1.0 resolution: "cra-bundle-analyzer@npm:0.1.0" @@ -13147,64 +12311,21 @@ __metadata: languageName: node linkType: hard -"css-loader@npm:^3.6.0": - version: 3.6.0 - resolution: "css-loader@npm:3.6.0" - dependencies: - camelcase: ^5.3.1 - cssesc: ^3.0.0 - icss-utils: ^4.1.1 - loader-utils: ^1.2.3 - normalize-path: ^3.0.0 - postcss: ^7.0.32 - postcss-modules-extract-imports: ^2.0.0 - postcss-modules-local-by-default: ^3.0.2 - postcss-modules-scope: ^2.2.0 - postcss-modules-values: ^3.0.0 - postcss-value-parser: ^4.1.0 - schema-utils: ^2.7.0 - semver: ^6.3.0 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: a45d7ee8105eea7a76caa45286f4b31f9413520511ae99a78886c522305a94c8adf289951f989d239919a9ffc08ea8cac2bf9c362f21b65d6f54f6812e904cc0 - languageName: node - linkType: hard - -"css-loader@npm:^5.0.1": - version: 5.2.7 - resolution: "css-loader@npm:5.2.7" +"css-loader@npm:^6.5.1, css-loader@npm:^6.7.1": + version: 6.8.1 + resolution: "css-loader@npm:6.8.1" dependencies: icss-utils: ^5.1.0 - loader-utils: ^2.0.0 - postcss: ^8.2.15 + postcss: ^8.4.21 postcss-modules-extract-imports: ^3.0.0 - postcss-modules-local-by-default: ^4.0.0 - postcss-modules-scope: ^3.0.0 - postcss-modules-values: ^4.0.0 - postcss-value-parser: ^4.1.0 - schema-utils: ^3.0.0 - semver: ^7.3.5 - peerDependencies: - webpack: ^4.27.0 || ^5.0.0 - checksum: fb0742b30ac0919f94b99a323bdefe6d48ae46d66c7d966aae59031350532f368f8bba5951fcd268f2e053c5e6e4655551076268e9073ccb58e453f98ae58f8e - languageName: node - linkType: hard - -"css-loader@npm:^6.5.1": - version: 6.7.1 - resolution: "css-loader@npm:6.7.1" - dependencies: - icss-utils: ^5.1.0 - postcss: ^8.4.7 - postcss-modules-extract-imports: ^3.0.0 - postcss-modules-local-by-default: ^4.0.0 + postcss-modules-local-by-default: ^4.0.3 postcss-modules-scope: ^3.0.0 postcss-modules-values: ^4.0.0 postcss-value-parser: ^4.2.0 - semver: ^7.3.5 + semver: ^7.3.8 peerDependencies: webpack: ^5.0.0 - checksum: 170fdbc630a05a43679ef60fa97694766b568dbde37adccc0faafa964fc675f08b976bc68837bb73b61d60240e8d2cbcbf51540fe94ebc9dafc56e7c46ba5527 + checksum: 7c1784247bdbe76dc5c55fb1ac84f1d4177a74c47259942c9cfdb7a8e6baef11967a0bc85ac285f26bd26d5059decb848af8154a03fdb4f4894f41212f45eef3 languageName: node linkType: hard @@ -13471,15 +12592,6 @@ __metadata: languageName: node linkType: hard -"currently-unhandled@npm:^0.4.1": - version: 0.4.1 - resolution: "currently-unhandled@npm:0.4.1" - dependencies: - array-find-index: ^1.0.1 - checksum: 1f59fe10b5339b54b1a1eee110022f663f3495cf7cf2f480686e89edc7fa8bfe42dbab4b54f85034bc8b092a76cc7becbc2dad4f9adad332ab5831bec39ad540 - languageName: node - linkType: hard - "cy-verify-downloads@npm:^0.0.5": version: 0.0.5 resolution: "cy-verify-downloads@npm:0.0.5" @@ -13602,11 +12714,11 @@ __metadata: languageName: node linkType: hard -"cypress@npm:^12.16.0": - version: 12.16.0 - resolution: "cypress@npm:12.16.0" +"cypress@npm:^12.17.0": + version: 12.17.2 + resolution: "cypress@npm:12.17.2" dependencies: - "@cypress/request": ^2.88.10 + "@cypress/request": ^2.88.11 "@cypress/xvfb": ^1.2.4 "@types/node": ^14.14.31 "@types/sinonjs__fake-timers": 8.1.1 @@ -13643,14 +12755,14 @@ __metadata: pretty-bytes: ^5.6.0 proxy-from-env: 1.0.0 request-progress: ^3.0.0 - semver: ^7.3.2 + semver: ^7.5.3 supports-color: ^8.1.1 tmp: ~0.2.1 untildify: ^4.0.0 yauzl: ^2.10.0 bin: cypress: bin/cypress - checksum: 551e2ec372f56a39a22526575b39bf9c6a110e5648ac1bf1c76460dfaebc3ca57d5537e7c206316284fe796ec76fa18f0493f3e040c92bd39c3720c9136fd5e4 + checksum: 19144db1fe02d92270de71f69ece324affd2f60bafa2f7018440c00907f837b1f8556926206df8b6e7b1c9890d250435730656ccb4a5a31e7872b24dd79c0af8 languageName: node linkType: hard @@ -13718,7 +12830,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0, debug@npm:^2.6.9": +"debug@npm:2.6.9, debug@npm:^2.6.0, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -13739,7 +12851,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.0.0, debug@npm:^3.1.0, debug@npm:^3.2.7": +"debug@npm:^3.1.0, debug@npm:^3.2.7": version: 3.2.7 resolution: "debug@npm:3.2.7" dependencies: @@ -13748,7 +12860,7 @@ __metadata: languageName: node linkType: hard -"decamelize@npm:^1.1.2, decamelize@npm:^1.2.0": +"decamelize@npm:^1.2.0": version: 1.2.0 resolution: "decamelize@npm:1.2.0" checksum: ad8c51a7e7e0720c70ec2eeb1163b66da03e7616d7b98c9ef43cce2416395e84c1e9548dd94f5f6ffecfee9f8b94251fc57121a8b021f2ff2469b2bae247b8aa @@ -13806,6 +12918,32 @@ __metadata: languageName: node linkType: hard +"deep-equal@npm:^2.0.5": + version: 2.2.1 + resolution: "deep-equal@npm:2.2.1" + dependencies: + array-buffer-byte-length: ^1.0.0 + call-bind: ^1.0.2 + es-get-iterator: ^1.1.3 + get-intrinsic: ^1.2.0 + is-arguments: ^1.1.1 + is-array-buffer: ^3.0.2 + is-date-object: ^1.0.5 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.2 + isarray: ^2.0.5 + object-is: ^1.1.5 + object-keys: ^1.1.1 + object.assign: ^4.1.4 + regexp.prototype.flags: ^1.5.0 + side-channel: ^1.0.4 + which-boxed-primitive: ^1.0.2 + which-collection: ^1.0.1 + which-typed-array: ^1.1.9 + checksum: 561f0e001a07b2f1b80ff914d0b3d76964bbfc102f34c2128bc8039c0050e63b1a504a8911910e011d8cd1cd4b600a9686c049e327f4ef94420008efc42d25f4 + languageName: node + linkType: hard + "deep-extend@npm:^0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -13827,16 +12965,13 @@ __metadata: languageName: node linkType: hard -"default-browser-id@npm:^1.0.4": - version: 1.0.4 - resolution: "default-browser-id@npm:1.0.4" +"default-browser-id@npm:3.0.0": + version: 3.0.0 + resolution: "default-browser-id@npm:3.0.0" dependencies: - bplist-parser: ^0.1.0 - meow: ^3.1.0 - untildify: ^2.0.0 - bin: - default-browser-id: cli.js - checksum: c6576428ebdd304d209e09c40803c974de3236232fdfa564d82bd1e985246a0d0f0b344f2b207fcbf663b925c20d30ab4d77fbe2755d2be3a6073f12620b9056 + bplist-parser: ^0.2.0 + untildify: ^4.0.0 + checksum: 279c7ad492542e5556336b6c254a4eaf31b2c63a5433265655ae6e47301197b6cfb15c595a6fdc6463b2ff8e1a1a1ed3cba56038a60e1527ba4ab1628c6b9941 languageName: node linkType: hard @@ -13872,7 +13007,7 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.1.2, define-properties@npm:^1.1.3, define-properties@npm:^1.1.4": +"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4, define-properties@npm:^1.2.0": version: 1.2.0 resolution: "define-properties@npm:1.2.0" dependencies: @@ -13882,34 +13017,6 @@ __metadata: languageName: node linkType: hard -"define-property@npm:^0.2.5": - version: 0.2.5 - resolution: "define-property@npm:0.2.5" - dependencies: - is-descriptor: ^0.1.0 - checksum: 85af107072b04973b13f9e4128ab74ddfda48ec7ad2e54b193c0ffb57067c4ce5b7786a7b4ae1f24bd03e87c5d18766b094571810b314d7540f86d4354dbd394 - languageName: node - linkType: hard - -"define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "define-property@npm:1.0.0" - dependencies: - is-descriptor: ^1.0.0 - checksum: 5fbed11dace44dd22914035ba9ae83ad06008532ca814d7936a53a09e897838acdad5b108dd0688cc8d2a7cf0681acbe00ee4136cf36743f680d10517379350a - languageName: node - linkType: hard - -"define-property@npm:^2.0.2": - version: 2.0.2 - resolution: "define-property@npm:2.0.2" - dependencies: - is-descriptor: ^1.0.2 - isobject: ^3.0.1 - checksum: 3217ed53fc9eed06ba8da6f4d33e28c68a82e2f2a8ab4d562c4920d8169a166fe7271453675e6c69301466f36a65d7f47edf0cf7f474b9aa52a5ead9c1b13c99 - languageName: node - linkType: hard - "defined@npm:^1.0.0": version: 1.0.0 resolution: "defined@npm:1.0.0" @@ -13917,6 +13024,13 @@ __metadata: languageName: node linkType: hard +"defu@npm:^6.1.2": + version: 6.1.2 + resolution: "defu@npm:6.1.2" + checksum: 2ec0ff8414d5a1ab2b8c7e9a79bbad6d97d23ea7ebf5dcf80c3c7ffd9715c30f84a3cc47b917379ea756b3db0dc4701ce6400e493a1ae1688dffcd0f884233b2 + languageName: node + linkType: hard + "del@npm:^6.0.0": version: 6.1.1 resolution: "del@npm:6.1.1" @@ -13975,6 +13089,13 @@ __metadata: languageName: node linkType: hard +"dequal@npm:^2.0.2": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 + languageName: node + linkType: hard + "des.js@npm:^1.0.0": version: 1.0.1 resolution: "des.js@npm:1.0.1" @@ -14049,15 +13170,6 @@ __metadata: languageName: node linkType: hard -"detab@npm:2.0.4": - version: 2.0.4 - resolution: "detab@npm:2.0.4" - dependencies: - repeat-string: ^1.5.4 - checksum: 34b077521ecd4c6357d32ff7923be644d34aa6f6b7d717d40ec4a9168243eefaea2b512a75a460a6f70c31b0bbc31ff90f820a891803b4ddaf99e9d04d0d389d - languageName: node - linkType: hard - "detect-file@npm:^1.0.0": version: 1.0.0 resolution: "detect-file@npm:1.0.0" @@ -14072,6 +13184,13 @@ __metadata: languageName: node linkType: hard +"detect-indent@npm:^6.1.0": + version: 6.1.0 + resolution: "detect-indent@npm:6.1.0" + checksum: ab953a73c72dbd4e8fc68e4ed4bfd92c97eb6c43734af3900add963fd3a9316f3bc0578b018b24198d4c31a358571eff5f0656e81a1f3b9ad5c547d58b2d093d + languageName: node + linkType: hard + "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -14204,15 +13323,6 @@ __metadata: languageName: node linkType: hard -"dir-glob@npm:^2.2.2": - version: 2.2.2 - resolution: "dir-glob@npm:2.2.2" - dependencies: - path-type: ^3.0.0 - checksum: 3aa48714a9f7845ffc30ab03a5c674fe760477cc55e67b0847333371549227d93953e6627ec160f75140c5bea5c5f88d13c01de79bd1997a588efbcf06980842 - languageName: node - linkType: hard - "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -14368,13 +13478,6 @@ __metadata: languageName: node linkType: hard -"dom-walk@npm:^0.1.0": - version: 0.1.2 - resolution: "dom-walk@npm:0.1.2" - checksum: 19eb0ce9c6de39d5e231530685248545d9cd2bd97b2cb3486e0bfc0f2a393a9addddfd5557463a932b52fdfcf68ad2a619020cd2c74a5fe46fbecaa8e80872f3 - languageName: node - linkType: hard - "dom4@npm:^2.1.5": version: 2.1.5 resolution: "dom4@npm:2.1.5" @@ -14490,6 +13593,13 @@ __metadata: languageName: node linkType: hard +"dotenv-expand@npm:^10.0.0": + version: 10.0.0 + resolution: "dotenv-expand@npm:10.0.0" + checksum: 2a38b470efe0abcb1ac8490421a55e1d764dc9440fd220942bce40965074f3fb00b585f4346020cb0f0f219966ee6b4ee5023458b3e2953fe5b3214de1b314ee + languageName: node + linkType: hard + "dotenv-expand@npm:^5.1.0": version: 5.1.0 resolution: "dotenv-expand@npm:5.1.0" @@ -14504,7 +13614,14 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^8.0.0, dotenv@npm:^8.1.0": +"dotenv@npm:^16.0.0": + version: 16.3.1 + resolution: "dotenv@npm:16.3.1" + checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd + languageName: node + linkType: hard + +"dotenv@npm:^8.1.0": version: 8.6.0 resolution: "dotenv@npm:8.6.0" checksum: 38e902c80b0666ab59e9310a3d24ed237029a7ce34d976796349765ac96b8d769f6df19090f1f471b77a25ca391971efde8a1ea63bb83111bd8bec8e5cc9b2cd @@ -14543,6 +13660,18 @@ __metadata: languageName: node linkType: hard +"duplexify@npm:^3.5.0, duplexify@npm:^3.6.0": + version: 3.7.1 + resolution: "duplexify@npm:3.7.1" + dependencies: + end-of-stream: ^1.0.0 + inherits: ^2.0.1 + readable-stream: ^2.0.0 + stream-shift: ^1.0.0 + checksum: 3c2ed2223d956a5da713dae12ba8295acb61d9acd966ccbba938090d04f4574ca4dca75cca089b5077c2d7e66101f32e6ea9b36a78ca213eff574e7a8b8accf2 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -14560,6 +13689,16 @@ __metadata: languageName: node linkType: hard +"echarts@npm:^5.4.2": + version: 5.4.2 + resolution: "echarts@npm:5.4.2" + dependencies: + tslib: 2.3.0 + zrender: 5.4.3 + checksum: 933c28dada362314f7c7a5fd4243b44b24f75adb233f7c87541ac9a81734cb380a9683c3f56c8e559dacfddd363879e95a96f0047e33820123cd8f5b95b60f8f + languageName: node + linkType: hard + "editorconfig@npm:^0.15.3": version: 0.15.3 resolution: "editorconfig@npm:0.15.3" @@ -14691,7 +13830,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0": +"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.4 resolution: "end-of-stream@npm:1.4.4" dependencies: @@ -14808,6 +13947,15 @@ __metadata: languageName: node linkType: hard +"envinfo@npm:^7.7.3": + version: 7.10.0 + resolution: "envinfo@npm:7.10.0" + bin: + envinfo: dist/cli.js + checksum: 05e81a5768c42cbd5c580dc3f274db3401facadd53e9bd52e2aa49dfbb5d8b26f6181c25a6652d79618a6994185bd2b1c137673101690b147f758e4e71d42f7d + languageName: node + linkType: hard + "err-code@npm:^2.0.2": version: 2.0.3 resolution: "err-code@npm:2.0.3" @@ -14826,7 +13974,7 @@ __metadata: languageName: node linkType: hard -"error-ex@npm:^1.2.0, error-ex@npm:^1.3.1": +"error-ex@npm:^1.3.1": version: 1.3.2 resolution: "error-ex@npm:1.3.2" dependencies: @@ -14844,7 +13992,7 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.17.2, es-abstract@npm:^1.18.0-next.1, es-abstract@npm:^1.19.0, es-abstract@npm:^1.19.1, es-abstract@npm:^1.19.5, es-abstract@npm:^1.20.4": +"es-abstract@npm:^1.17.2, es-abstract@npm:^1.19.0, es-abstract@npm:^1.19.1, es-abstract@npm:^1.19.5, es-abstract@npm:^1.20.4": version: 1.21.1 resolution: "es-abstract@npm:1.21.1" dependencies: @@ -14892,7 +14040,7 @@ __metadata: languageName: node linkType: hard -"es-get-iterator@npm:^1.0.2": +"es-get-iterator@npm:^1.1.3": version: 1.1.3 resolution: "es-get-iterator@npm:1.1.3" dependencies: @@ -14947,13 +14095,6 @@ __metadata: languageName: node linkType: hard -"es5-shim@npm:^4.5.13": - version: 4.6.7 - resolution: "es5-shim@npm:4.6.7" - checksum: f2f60cf3d9c682106c51a70d27d41273d2edb3b90fa8795a2765be4a214574b71ddf9147a7972eb82998d94f96ca015d29f5915efd3af0a6c09673abd4299ee8 - languageName: node - linkType: hard - "es6-error@npm:^4.1.1": version: 4.1.1 resolution: "es6-error@npm:4.1.1" @@ -14961,10 +14102,105 @@ __metadata: languageName: node linkType: hard -"es6-shim@npm:^0.35.5": - version: 0.35.7 - resolution: "es6-shim@npm:0.35.7" - checksum: 3d5573d8d82e2639f1b05b28bc6799692cbf931cf8f8afbf5b26b3d36e4a4360ac0d3569eefe64320cea213106e3e14546b9e91ee33590c37dee4e654389ecac +"es6-object-assign@npm:^1.1.0": + version: 1.1.0 + resolution: "es6-object-assign@npm:1.1.0" + checksum: 8d4fdf63484d78b5c64cacc2c2e1165bc7b6a64b739d2a9db6a4dc8641d99cc9efb433cdd4dc3d3d6b00bfa6ce959694e4665e3255190339945c5f33b692b5d8 + languageName: node + linkType: hard + +"esbuild-plugin-alias@npm:^0.2.1": + version: 0.2.1 + resolution: "esbuild-plugin-alias@npm:0.2.1" + checksum: afe2d2c8b5f09d5321cb8d9c0825e8a9f6e03c2d50df92f953a291d4620cc29eddb3da9e33b238f6d8f77738e0277bdcb831f127399449fecf78fb84c04e5da9 + languageName: node + linkType: hard + +"esbuild-register@npm:^3.4.0": + version: 3.4.2 + resolution: "esbuild-register@npm:3.4.2" + dependencies: + debug: ^4.3.4 + peerDependencies: + esbuild: ">=0.12 <1" + checksum: f65d1ccb58b1ccbba376efb1fc023abe22731d9b79eead1b0120e57d4413318f063696257a5af637b527fa1d3f009095aa6edb1bf6ff69d637a9ab281fb727b3 + languageName: node + linkType: hard + +"esbuild@npm:^0.18.0": + version: 0.18.17 + resolution: "esbuild@npm:0.18.17" + dependencies: + "@esbuild/android-arm": 0.18.17 + "@esbuild/android-arm64": 0.18.17 + "@esbuild/android-x64": 0.18.17 + "@esbuild/darwin-arm64": 0.18.17 + "@esbuild/darwin-x64": 0.18.17 + "@esbuild/freebsd-arm64": 0.18.17 + "@esbuild/freebsd-x64": 0.18.17 + "@esbuild/linux-arm": 0.18.17 + "@esbuild/linux-arm64": 0.18.17 + "@esbuild/linux-ia32": 0.18.17 + "@esbuild/linux-loong64": 0.18.17 + "@esbuild/linux-mips64el": 0.18.17 + "@esbuild/linux-ppc64": 0.18.17 + "@esbuild/linux-riscv64": 0.18.17 + "@esbuild/linux-s390x": 0.18.17 + "@esbuild/linux-x64": 0.18.17 + "@esbuild/netbsd-x64": 0.18.17 + "@esbuild/openbsd-x64": 0.18.17 + "@esbuild/sunos-x64": 0.18.17 + "@esbuild/win32-arm64": 0.18.17 + "@esbuild/win32-ia32": 0.18.17 + "@esbuild/win32-x64": 0.18.17 + dependenciesMeta: + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: c6e1ffa776978a45697763a07ec9b16411db3d3b3997b2c4a0165a211727fce8b63b87165a28d8ef60d3a28b98197bbbc2833e51b89888a4437e0a483dffc8ff languageName: node linkType: hard @@ -15429,7 +14665,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.0, esprima@npm:^4.0.1": +"esprima@npm:^4.0.0, esprima@npm:^4.0.1, esprima@npm:~4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" bin: @@ -15556,13 +14792,6 @@ __metadata: languageName: node linkType: hard -"exec-sh@npm:^0.3.2": - version: 0.3.6 - resolution: "exec-sh@npm:0.3.6" - checksum: 0be4f06929c8e4834ea4812f29fe59e2dfcc1bc3fc4b4bb71acb38a500c3b394628a05ef7ba432520bc6c5ec4fadab00cc9c513c4ff6a32104965af302e998e0 - languageName: node - linkType: hard - "execa@npm:4.1.0": version: 4.1.0 resolution: "execa@npm:4.1.0" @@ -15659,21 +14888,6 @@ __metadata: languageName: node linkType: hard -"expand-brackets@npm:^2.1.4": - version: 2.1.4 - resolution: "expand-brackets@npm:2.1.4" - dependencies: - debug: ^2.3.3 - define-property: ^0.2.5 - extend-shallow: ^2.0.1 - posix-character-classes: ^0.1.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: 1781d422e7edfa20009e2abda673cadb040a6037f0bd30fcd7357304f4f0c284afd420d7622722ca4a016f39b6d091841ab57b401c1f7e2e5131ac65b9f14fa1 - languageName: node - linkType: hard - "expand-tilde@npm:^2.0.0, expand-tilde@npm:^2.0.2": version: 2.0.2 resolution: "expand-tilde@npm:2.0.2" @@ -15718,7 +14932,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.16.3, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.2": +"express@npm:^4.16.3, express@npm:^4.17.3, express@npm:^4.18.2": version: 4.18.2 resolution: "express@npm:4.18.2" dependencies: @@ -15757,25 +14971,6 @@ __metadata: languageName: node linkType: hard -"extend-shallow@npm:^2.0.1": - version: 2.0.1 - resolution: "extend-shallow@npm:2.0.1" - dependencies: - is-extendable: ^0.1.0 - checksum: 8fb58d9d7a511f4baf78d383e637bd7d2e80843bd9cd0853649108ea835208fb614da502a553acc30208e1325240bb7cc4a68473021612496bb89725483656d8 - languageName: node - linkType: hard - -"extend-shallow@npm:^3.0.0, extend-shallow@npm:^3.0.2": - version: 3.0.2 - resolution: "extend-shallow@npm:3.0.2" - dependencies: - assign-symbols: ^1.0.0 - is-extendable: ^1.0.1 - checksum: a920b0cd5838a9995ace31dfd11ab5e79bf6e295aa566910ce53dff19f4b1c0fda2ef21f26b28586c7a2450ca2b42d97bd8c0f5cec9351a819222bf861e02461 - languageName: node - linkType: hard - "extend@npm:^3.0.0, extend@npm:^3.0.2, extend@npm:~3.0.2": version: 3.0.2 resolution: "extend@npm:3.0.2" @@ -15794,22 +14989,6 @@ __metadata: languageName: node linkType: hard -"extglob@npm:^2.0.4": - version: 2.0.4 - resolution: "extglob@npm:2.0.4" - dependencies: - array-unique: ^0.3.2 - define-property: ^1.0.0 - expand-brackets: ^2.1.4 - extend-shallow: ^2.0.1 - fragment-cache: ^0.2.1 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: a41531b8934735b684cef5e8c5a01d0f298d7d384500ceca38793a9ce098125aab04ee73e2d75d5b2901bc5dddd2b64e1b5e3bf19139ea48bac52af4a92f1d00 - languageName: node - linkType: hard - "extract-zip@npm:2.0.1": version: 2.0.1 resolution: "extract-zip@npm:2.0.1" @@ -15827,6 +15006,20 @@ __metadata: languageName: node linkType: hard +"extract-zip@npm:^1.6.6": + version: 1.7.0 + resolution: "extract-zip@npm:1.7.0" + dependencies: + concat-stream: ^1.6.2 + debug: ^2.6.9 + mkdirp: ^0.5.4 + yauzl: ^2.10.0 + bin: + extract-zip: cli.js + checksum: 011bab660d738614555773d381a6ba4815d98c1cfcdcdf027e154ebcc9fc8c9ef637b3ea5c9b2144013100071ee41722ed041fc9aacc60f6198ef747cac0c073 + languageName: node + linkType: hard + "extsprintf@npm:1.3.0": version: 1.3.0 resolution: "extsprintf@npm:1.3.0" @@ -15865,20 +15058,6 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^2.2.6": - version: 2.2.7 - resolution: "fast-glob@npm:2.2.7" - dependencies: - "@mrmlnc/readdir-enhanced": ^2.2.1 - "@nodelib/fs.stat": ^1.1.2 - glob-parent: ^3.1.0 - is-glob: ^4.0.0 - merge2: ^1.2.3 - micromatch: ^3.1.10 - checksum: 304ccff1d437fcc44ae0168b0c3899054b92e0fd6af6ad7c3ccc82ab4ddd210b99c7c739d60ee3686da2aa165cd1a31810b31fd91f7c2a575d297342a9fc0534 - languageName: node - linkType: hard - "fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9": version: 3.2.11 resolution: "fast-glob@npm:3.2.11" @@ -16058,13 +15237,13 @@ __metadata: languageName: node linkType: hard -"file-system-cache@npm:^1.0.5": - version: 1.1.0 - resolution: "file-system-cache@npm:1.1.0" +"file-system-cache@npm:2.3.0": + version: 2.3.0 + resolution: "file-system-cache@npm:2.3.0" dependencies: - fs-extra: ^10.1.0 - ramda: ^0.28.0 - checksum: d60d7aadf2e9d1629c20dd423f9e1fc3a9719f80dc4e08017a1aa06a8f8d8f66cf140a63ab68a72f07edd9684786ce7409ef4177b43ed0209cd6bcdbb39dab00 + fs-extra: 11.1.1 + ramda: 0.29.0 + checksum: 74afa2870a062500643d41e02d1fbd47a3f30100f9e153dec5233d59f05545f4c8ada6085629d624e043479ac28c0cafc31824f7b49a3f997efab8cc5d05bfee languageName: node linkType: hard @@ -16091,18 +15270,6 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^4.0.0": - version: 4.0.0 - resolution: "fill-range@npm:4.0.0" - dependencies: - extend-shallow: ^2.0.1 - is-number: ^3.0.0 - repeat-string: ^1.6.1 - to-regex-range: ^2.1.0 - checksum: dbb5102467786ab42bc7a3ec7380ae5d6bfd1b5177b2216de89e4a541193f8ba599a6db84651bd2c58c8921db41b8cc3d699ea83b477342d3ce404020f73c298 - languageName: node - linkType: hard - "fill-range@npm:^7.0.1": version: 7.0.1 resolution: "fill-range@npm:7.0.1" @@ -16163,7 +15330,7 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^3.3.1, find-cache-dir@npm:^3.3.2": +"find-cache-dir@npm:^3.0.0, find-cache-dir@npm:^3.3.1, find-cache-dir@npm:^3.3.2": version: 3.3.2 resolution: "find-cache-dir@npm:3.3.2" dependencies: @@ -16174,6 +15341,16 @@ __metadata: languageName: node linkType: hard +"find-cache-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "find-cache-dir@npm:4.0.0" + dependencies: + common-path-prefix: ^3.0.0 + pkg-dir: ^7.0.0 + checksum: 52a456a80deeb27daa3af6e06059b63bdb9cc4af4d845fc6d6229887e505ba913cd56000349caa60bc3aa59dacdb5b4c37903d4ba34c75102d83cab330b70d2f + languageName: node + linkType: hard + "find-node-modules@npm:^2.1.3": version: 2.1.3 resolution: "find-node-modules@npm:2.1.3" @@ -16191,16 +15368,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^1.0.0": - version: 1.1.2 - resolution: "find-up@npm:1.1.2" - dependencies: - path-exists: ^2.0.0 - pinkie-promise: ^2.0.0 - checksum: a2cb9f4c9f06ee3a1e92ed71d5aed41ac8ae30aefa568132f6c556fac7678a5035126153b59eaec68da78ac409eef02503b2b059706bdbf232668d7245e3240a - languageName: node - linkType: hard - "find-up@npm:^2.1.0": version: 2.1.0 resolution: "find-up@npm:2.1.0" @@ -16239,6 +15406,16 @@ __metadata: languageName: node linkType: hard +"find-up@npm:^6.3.0": + version: 6.3.0 + resolution: "find-up@npm:6.3.0" + dependencies: + locate-path: ^7.1.0 + path-exists: ^5.0.0 + checksum: 9a21b7f9244a420e54c6df95b4f6fc3941efd3c3e5476f8274eb452f6a85706e7a6a90de71353ee4f091fcb4593271a6f92810a324ec542650398f928783c280 + languageName: node + linkType: hard + "findup-sync@npm:^4.0.0": version: 4.0.0 resolution: "findup-sync@npm:4.0.0" @@ -16300,6 +15477,13 @@ __metadata: languageName: node linkType: hard +"flow-parser@npm:0.*": + version: 0.213.1 + resolution: "flow-parser@npm:0.213.1" + checksum: bb953544fc7951e3c7074cfd08cd28e0f9988018560a6aec5598e8b4da9d5701a9f586a8947fc6cd8c9bed8f3cc21cd33e6dac778550e1155dc06d4253380010 + languageName: node + linkType: hard + "flux@npm:^4.0.1": version: 4.0.3 resolution: "flux@npm:4.0.3" @@ -16312,15 +15496,6 @@ __metadata: languageName: node linkType: hard -"focus-lock@npm:^0.8.0": - version: 0.8.1 - resolution: "focus-lock@npm:0.8.1" - dependencies: - tslib: ^1.9.3 - checksum: 3b25b06bb8e23a3a826a8eda89e547593a688486df531db92f6b767d96d397dc1efed4529ec3a44cb3ec1fbdd44abe50a30d0ce498f732501b36f5f18b619003 - languageName: node - linkType: hard - "focus-trap-react@npm:^8.9.2": version: 8.11.0 resolution: "focus-trap-react@npm:8.11.0" @@ -16362,7 +15537,7 @@ __metadata: languageName: node linkType: hard -"for-in@npm:^1.0.1, for-in@npm:^1.0.2": +"for-in@npm:^1.0.1": version: 1.0.2 resolution: "for-in@npm:1.0.2" checksum: 09f4ae93ce785d253ac963d94c7f3432d89398bf25ac7a24ed034ca393bf74380bdeccc40e0f2d721a895e54211b07c8fad7132e8157827f6f7f059b70b4043d @@ -16388,6 +15563,16 @@ __metadata: languageName: node linkType: hard +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: ^7.0.0 + signal-exit: ^4.0.1 + checksum: 139d270bc82dc9e6f8bc045fe2aae4001dc2472157044fdfad376d0a3457f77857fa883c1c8b21b491c6caade9a926a4bed3d3d2e8d3c9202b151a4cbbd0bcd5 + languageName: node + linkType: hard + "forever-agent@npm:~0.6.1": version: 0.6.1 resolution: "forever-agent@npm:0.6.1" @@ -16395,22 +15580,7 @@ __metadata: languageName: node linkType: hard -"fork-ts-checker-webpack-plugin@npm:^4.1.6": - version: 4.1.6 - resolution: "fork-ts-checker-webpack-plugin@npm:4.1.6" - dependencies: - "@babel/code-frame": ^7.5.5 - chalk: ^2.4.1 - micromatch: ^3.1.10 - minimatch: ^3.0.4 - semver: ^5.6.0 - tapable: ^1.0.0 - worker-rpc: ^0.1.0 - checksum: 4cc4fa7919dd9a0d765514d064c86e3a6f9cea8e700996b3e775cfcc0280f606a2dd16203d9b7e294b64e900795b0d80eb41fc8c192857d3350e407f14ef3eed - languageName: node - linkType: hard - -"fork-ts-checker-webpack-plugin@npm:^6.0.4, fork-ts-checker-webpack-plugin@npm:^6.5.0": +"fork-ts-checker-webpack-plugin@npm:^6.5.0": version: 6.5.3 resolution: "fork-ts-checker-webpack-plugin@npm:6.5.3" dependencies: @@ -16441,6 +15611,29 @@ __metadata: languageName: node linkType: hard +"fork-ts-checker-webpack-plugin@npm:^8.0.0": + version: 8.0.0 + resolution: "fork-ts-checker-webpack-plugin@npm:8.0.0" + dependencies: + "@babel/code-frame": ^7.16.7 + chalk: ^4.1.2 + chokidar: ^3.5.3 + cosmiconfig: ^7.0.1 + deepmerge: ^4.2.2 + fs-extra: ^10.0.0 + memfs: ^3.4.1 + minimatch: ^3.0.4 + node-abort-controller: ^3.0.1 + schema-utils: ^3.1.1 + semver: ^7.3.5 + tapable: ^2.2.1 + peerDependencies: + typescript: ">3.6.0" + webpack: ^5.11.0 + checksum: aad4cbc5b802e6281a2700a379837697c93ad95288468f9595219d91d9c26674736d37852bb4c4341e9122f26181e9e05fc1a362e8d029fdd88e99de7816037b + languageName: node + linkType: hard + "form-data@npm:^3.0.0": version: 3.0.1 resolution: "form-data@npm:3.0.1" @@ -16507,15 +15700,6 @@ __metadata: languageName: node linkType: hard -"fragment-cache@npm:^0.2.1": - version: 0.2.1 - resolution: "fragment-cache@npm:0.2.1" - dependencies: - map-cache: ^0.2.2 - checksum: 1cbbd0b0116b67d5790175de0038a11df23c1cd2e8dcdbade58ebba5594c2d641dade6b4f126d82a7b4a6ffc2ea12e3d387dbb64ea2ae97cf02847d436f60fdc - languageName: node - linkType: hard - "fresh@npm:0.5.2": version: 0.5.2 resolution: "fresh@npm:0.5.2" @@ -16523,7 +15707,25 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^10.0.0, fs-extra@npm:^10.0.1, fs-extra@npm:^10.1.0": +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 18f5b718371816155849475ac36c7d0b24d39a11d91348cfcb308b4494824413e03572c403c86d3a260e049465518c4f0d5bd00f0371cdfcad6d4f30a85b350d + languageName: node + linkType: hard + +"fs-extra@npm:11.1.1, fs-extra@npm:^11.1.0": + version: 11.1.1 + resolution: "fs-extra@npm:11.1.1" + dependencies: + graceful-fs: ^4.2.0 + jsonfile: ^6.0.1 + universalify: ^2.0.0 + checksum: fb883c68245b2d777fbc1f2082c9efb084eaa2bbf9fddaa366130d196c03608eebef7fb490541276429ee1ca99f317e2d73e96f5ca0999eefedf5a624ae1edfd + languageName: node + linkType: hard + +"fs-extra@npm:^10.0.0, fs-extra@npm:^10.0.1": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" dependencies: @@ -16566,10 +15768,10 @@ __metadata: languageName: node linkType: hard -"fs-monkey@npm:^1.0.3": - version: 1.0.3 - resolution: "fs-monkey@npm:1.0.3" - checksum: cf50804833f9b88a476911ae911fe50f61a98d986df52f890bd97e7262796d023698cb2309fa9b74fdd8974f04315b648748a0a8ee059e7d5257b293bfc409c0 +"fs-monkey@npm:^1.0.4": + version: 1.0.4 + resolution: "fs-monkey@npm:1.0.4" + checksum: 8b254c982905c0b7e028eab22b410dc35a5c0019c1c860456f5f54ae6a61666e1cb8c6b700d6c88cc873694c00953c935847b9959cc4dcf274aacb8673c1e8bf languageName: node linkType: hard @@ -16594,7 +15796,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.1.2, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": +"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" dependencies: @@ -16604,7 +15806,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@^2.1.2#~builtin, fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": +"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" dependencies: @@ -16627,7 +15829,7 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.0, function.prototype.name@npm:^1.1.5": +"function.prototype.name@npm:^1.1.5": version: 1.1.5 resolution: "function.prototype.name@npm:1.1.5" dependencies: @@ -16639,7 +15841,7 @@ __metadata: languageName: node linkType: hard -"functions-have-names@npm:^1.2.2": +"functions-have-names@npm:^1.2.2, functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" checksum: c3f1f5ba20f4e962efb71344ce0a40722163e85bee2101ce25f88214e78182d2d2476aa85ef37950c579eb6cf6ee811c17b3101bb84004bb75655f3e33f3fdb5 @@ -16697,23 +15899,6 @@ __metadata: languageName: node linkType: hard -"gauge@npm:^3.0.0": - version: 3.0.2 - resolution: "gauge@npm:3.0.2" - dependencies: - aproba: ^1.0.3 || ^2.0.0 - color-support: ^1.1.2 - console-control-strings: ^1.0.0 - has-unicode: ^2.0.1 - object-assign: ^4.1.1 - signal-exit: ^3.0.0 - string-width: ^4.2.3 - strip-ansi: ^6.0.1 - wide-align: ^1.1.2 - checksum: 81296c00c7410cdd48f997800155fbead4f32e4f82109be0719c63edc8560e6579946cc8abd04205297640691ec26d21b578837fd13a4e96288ab4b40b1dc3e9 - languageName: node - linkType: hard - "gauge@npm:^4.0.3": version: 4.0.4 resolution: "gauge@npm:4.0.4" @@ -16746,7 +15931,7 @@ __metadata: languageName: node linkType: hard -"gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": +"gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" checksum: a7437e58c6be12aa6c90f7730eac7fa9833dc78872b4ad2963d2031b00a3367a93f98aec75f9aaac7220848e4026d67a8655e870b24f20a543d103c0d65952ec @@ -16785,6 +15970,13 @@ __metadata: languageName: node linkType: hard +"get-npm-tarball-url@npm:^2.0.3": + version: 2.0.3 + resolution: "get-npm-tarball-url@npm:2.0.3" + checksum: 8ad48a6f1126697665e12ebf053e0d1c3b15b3c4f29ea6c458387ac68d044ea1c08f0f2eb5c0fe35447fdd2da4f2fb5c9882feb5a2ea195c773f94e762c9b886 + languageName: node + linkType: hard + "get-own-enumerable-property-symbols@npm:^3.0.0": version: 3.0.2 resolution: "get-own-enumerable-property-symbols@npm:3.0.2" @@ -16799,10 +15991,10 @@ __metadata: languageName: node linkType: hard -"get-stdin@npm:^4.0.1": - version: 4.0.1 - resolution: "get-stdin@npm:4.0.1" - checksum: 4f73d3fe0516bc1f3dc7764466a68ad7c2ba809397a02f56c2a598120e028430fcff137a648a01876b2adfb486b4bc164119f98f1f7d7c0abd63385bdaa0113f +"get-port@npm:^5.1.1": + version: 5.1.1 + resolution: "get-port@npm:5.1.1" + checksum: 0162663ffe5c09e748cd79d97b74cd70e5a5c84b760a475ce5767b357fb2a57cb821cee412d646aa8a156ed39b78aab88974eddaa9e5ee926173c036c0713787 languageName: node linkType: hard @@ -16848,13 +16040,6 @@ __metadata: languageName: node linkType: hard -"get-value@npm:^2.0.3, get-value@npm:^2.0.6": - version: 2.0.6 - resolution: "get-value@npm:2.0.6" - checksum: 5c3b99cb5398ea8016bf46ff17afc5d1d286874d2ad38ca5edb6e87d75c0965b0094cb9a9dddef2c59c23d250702323539a7fbdd870620db38c7e7d7ec87c1eb - languageName: node - linkType: hard - "getos@npm:^3.2.1": version: 3.2.1 resolution: "getos@npm:3.2.1" @@ -16873,6 +16058,23 @@ __metadata: languageName: node linkType: hard +"giget@npm:^1.0.0": + version: 1.1.2 + resolution: "giget@npm:1.1.2" + dependencies: + colorette: ^2.0.19 + defu: ^6.1.2 + https-proxy-agent: ^5.0.1 + mri: ^1.2.0 + node-fetch-native: ^1.0.2 + pathe: ^1.1.0 + tar: ^6.1.13 + bin: + giget: dist/cli.mjs + checksum: 76ad0f7e792ee95dd6c4e1096697fdcce61a2a3235a6c21761fc3e0d1053342074ce71c80059d6d4363fd34152e5d7b2e58221412f300c852ff7d4a12d0321fe + languageName: node + linkType: hard + "github-slugger@npm:^1.0.0": version: 1.5.0 resolution: "github-slugger@npm:1.5.0" @@ -16889,24 +16091,6 @@ __metadata: languageName: node linkType: hard -"glob-promise@npm:^3.4.0": - version: 3.4.0 - resolution: "glob-promise@npm:3.4.0" - dependencies: - "@types/glob": "*" - peerDependencies: - glob: "*" - checksum: 84a2c076e7581c9f8aa7a8a151ad5f9352c4118ba03c5673ecfcf540f4c53aa75f8d32fe493c2286d471dccd7a75932b9bfe97bf782564c1f4a50b9c7954e3b6 - languageName: node - linkType: hard - -"glob-to-regexp@npm:^0.3.0": - version: 0.3.0 - resolution: "glob-to-regexp@npm:0.3.0" - checksum: d34b3219d860042d508c4893b67617cd16e2668827e445ff39cff9f72ef70361d3dc24f429e003cdfb6607c75c9664b8eadc41d2eeb95690af0b0d3113c1b23b - languageName: node - linkType: hard - "glob-to-regexp@npm:^0.4.1": version: 0.4.1 resolution: "glob-to-regexp@npm:0.4.1" @@ -16914,6 +16098,21 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.0.0": + version: 10.3.3 + resolution: "glob@npm:10.3.3" + dependencies: + foreground-child: ^3.1.0 + jackspeak: ^2.0.3 + minimatch: ^9.0.1 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + path-scurry: ^1.10.1 + bin: + glob: dist/cjs/src/bin.js + checksum: 29190d3291f422da0cb40b77a72fc8d2c51a36524e99b8bf412548b7676a6627489528b57250429612b6eec2e6fe7826d328451d3e694a9d15e575389308ec53 + languageName: node + linkType: hard + "glob@npm:^7.1.0, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -16994,16 +16193,6 @@ __metadata: languageName: node linkType: hard -"global@npm:^4.4.0": - version: 4.4.0 - resolution: "global@npm:4.4.0" - dependencies: - min-document: ^2.19.0 - process: ^0.11.10 - checksum: 9c057557c8f5a5bcfbeb9378ba4fe2255d04679452be504608dd5f13b54edf79f7be1db1031ea06a4ec6edd3b9f5f17d2d172fb47e6c69dae57fd84b7e72b77f - languageName: node - linkType: hard - "globals@npm:^11.1.0, globals@npm:^11.12.0": version: 11.12.0 resolution: "globals@npm:11.12.0" @@ -17020,7 +16209,7 @@ __metadata: languageName: node linkType: hard -"globalthis@npm:^1.0.0, globalthis@npm:^1.0.3": +"globalthis@npm:^1.0.3": version: 1.0.3 resolution: "globalthis@npm:1.0.3" dependencies: @@ -17056,22 +16245,6 @@ __metadata: languageName: node linkType: hard -"globby@npm:^9.2.0": - version: 9.2.0 - resolution: "globby@npm:9.2.0" - dependencies: - "@types/glob": ^7.1.1 - array-union: ^1.0.2 - dir-glob: ^2.2.2 - fast-glob: ^2.2.6 - glob: ^7.1.3 - ignore: ^4.0.3 - pify: ^4.0.1 - slash: ^2.0.0 - checksum: 9b4cb70aa0b43bf89b18cf0e543695185e16d8dd99c17bdc6a1df0a9f88ff9dc8d2467aebace54c3842fc451a564882948c87a3b4fbdb1cacf3e05fd54b6ac5d - languageName: node - linkType: hard - "glur@npm:^1.1.2": version: 1.1.2 resolution: "glur@npm:1.1.2" @@ -17163,6 +16336,22 @@ __metadata: languageName: node linkType: hard +"gunzip-maybe@npm:^1.4.2": + version: 1.4.2 + resolution: "gunzip-maybe@npm:1.4.2" + dependencies: + browserify-zlib: ^0.1.4 + is-deflate: ^1.0.0 + is-gzip: ^1.0.0 + peek-stream: ^1.1.0 + pumpify: ^1.3.3 + through2: ^2.0.3 + bin: + gunzip-maybe: bin.js + checksum: bc4d4977c24a2860238df271de75d53dd72a359d19f1248d1c613807dc221d3b8ae09624e3085c8106663e3e1b59db62a85b261d1138c2cc24efad9df577d4e1 + languageName: node + linkType: hard + "gzip-size@npm:^5.0.0": version: 5.1.1 resolution: "gzip-size@npm:5.1.1" @@ -17244,15 +16433,6 @@ __metadata: languageName: node linkType: hard -"has-glob@npm:^1.0.0": - version: 1.0.0 - resolution: "has-glob@npm:1.0.0" - dependencies: - is-glob: ^3.0.0 - checksum: cafad93e599f49f676a9ab444ec90210fcda35ac14ad6c9bb96c08057ad18a1318f1116b053aa6bdc744f19252537006872d3fc76785e842bbe8cc4312447fc8 - languageName: node - linkType: hard - "has-property-descriptors@npm:^1.0.0": version: 1.0.0 resolution: "has-property-descriptors@npm:1.0.0" @@ -17292,45 +16472,6 @@ __metadata: languageName: node linkType: hard -"has-value@npm:^0.3.1": - version: 0.3.1 - resolution: "has-value@npm:0.3.1" - dependencies: - get-value: ^2.0.3 - has-values: ^0.1.4 - isobject: ^2.0.0 - checksum: 29e2a1e6571dad83451b769c7ce032fce6009f65bccace07c2962d3ad4d5530b6743d8f3229e4ecf3ea8e905d23a752c5f7089100c1f3162039fa6dc3976558f - languageName: node - linkType: hard - -"has-value@npm:^1.0.0": - version: 1.0.0 - resolution: "has-value@npm:1.0.0" - dependencies: - get-value: ^2.0.6 - has-values: ^1.0.0 - isobject: ^3.0.0 - checksum: b9421d354e44f03d3272ac39fd49f804f19bc1e4fa3ceef7745df43d6b402053f828445c03226b21d7d934a21ac9cf4bc569396dc312f496ddff873197bbd847 - languageName: node - linkType: hard - -"has-values@npm:^0.1.4": - version: 0.1.4 - resolution: "has-values@npm:0.1.4" - checksum: ab1c4bcaf811ccd1856c11cfe90e62fca9e2b026ebe474233a3d282d8d67e3b59ed85b622c7673bac3db198cb98bd1da2b39300a2f98e453729b115350af49bc - languageName: node - linkType: hard - -"has-values@npm:^1.0.0": - version: 1.0.0 - resolution: "has-values@npm:1.0.0" - dependencies: - is-number: ^3.0.0 - kind-of: ^4.0.0 - checksum: 77e6693f732b5e4cf6c38dfe85fdcefad0fab011af74995c3e83863fabf5e3a836f406d83565816baa0bc0a523c9410db8b990fe977074d61aeb6d8f4fcffa11 - languageName: node - linkType: hard - "has-yarn@npm:^2.1.0": version: 2.1.0 resolution: "has-yarn@npm:2.1.0" @@ -17368,35 +16509,6 @@ __metadata: languageName: node linkType: hard -"hast-to-hyperscript@npm:^9.0.0": - version: 9.0.1 - resolution: "hast-to-hyperscript@npm:9.0.1" - dependencies: - "@types/unist": ^2.0.3 - comma-separated-tokens: ^1.0.0 - property-information: ^5.3.0 - space-separated-tokens: ^1.0.0 - style-to-object: ^0.3.0 - unist-util-is: ^4.0.0 - web-namespaces: ^1.0.0 - checksum: de570d789853018fff2fd38fc096549b9814e366b298f60c90c159a57018230eefc44d46a246027b0e2426ed9e99f2e270050bc183d5bdfe4c9487c320b392cd - languageName: node - linkType: hard - -"hast-util-from-parse5@npm:^6.0.0": - version: 6.0.1 - resolution: "hast-util-from-parse5@npm:6.0.1" - dependencies: - "@types/parse5": ^5.0.0 - hastscript: ^6.0.0 - property-information: ^5.0.0 - vfile: ^4.0.0 - vfile-location: ^3.2.0 - web-namespaces: ^1.0.0 - checksum: 4daa78201468af7779161e7caa2513c329830778e0528481ab16b3e1bcef4b831f6285b526aacdddbee802f3bd9d64df55f80f010591ea1916da535e3a923b83 - languageName: node - linkType: hard - "hast-util-parse-selector@npm:^2.0.0": version: 2.2.5 resolution: "hast-util-parse-selector@npm:2.2.5" @@ -17404,37 +16516,6 @@ __metadata: languageName: node linkType: hard -"hast-util-raw@npm:6.0.1": - version: 6.0.1 - resolution: "hast-util-raw@npm:6.0.1" - dependencies: - "@types/hast": ^2.0.0 - hast-util-from-parse5: ^6.0.0 - hast-util-to-parse5: ^6.0.0 - html-void-elements: ^1.0.0 - parse5: ^6.0.0 - unist-util-position: ^3.0.0 - vfile: ^4.0.0 - web-namespaces: ^1.0.0 - xtend: ^4.0.0 - zwitch: ^1.0.0 - checksum: f6d960644f9fbbe0b92d0227b20a24d659cce021d5f9fd218e077154931b4524ee920217b7fd5a45ec2736ec1dee53de9209fe449f6f89454c01d225ff0e7851 - languageName: node - linkType: hard - -"hast-util-to-parse5@npm:^6.0.0": - version: 6.0.0 - resolution: "hast-util-to-parse5@npm:6.0.0" - dependencies: - hast-to-hyperscript: ^9.0.0 - property-information: ^5.0.0 - web-namespaces: ^1.0.0 - xtend: ^4.0.0 - zwitch: ^1.0.0 - checksum: 91a36244e37df1d63c8b7e865ab0c0a25bb7396155602be005cf71d95c348e709568f80e0f891681a3711d733ad896e70642dc41a05b574eddf2e07d285408a8 - languageName: node - linkType: hard - "hastscript@npm:^6.0.0": version: 6.0.0 resolution: "hastscript@npm:6.0.0" @@ -17587,23 +16668,6 @@ __metadata: languageName: node linkType: hard -"html-minifier-terser@npm:^5.0.1": - version: 5.1.1 - resolution: "html-minifier-terser@npm:5.1.1" - dependencies: - camel-case: ^4.1.1 - clean-css: ^4.2.3 - commander: ^4.1.1 - he: ^1.2.0 - param-case: ^3.0.3 - relateurl: ^0.2.7 - terser: ^4.6.3 - bin: - html-minifier-terser: cli.js - checksum: 75ff3ff886631b9ecb3035acb8e7dd98c599bb4d4618ad6f7e487ee9752987dddcf6848dc3c1ab1d7fc1ad4484337c2ce39c19eac17b0342b4b15e4294c8a904 - languageName: node - linkType: hard - "html-minifier-terser@npm:^6.0.2": version: 6.1.0 resolution: "html-minifier-terser@npm:6.1.0" @@ -17628,33 +16692,7 @@ __metadata: languageName: node linkType: hard -"html-void-elements@npm:^1.0.0": - version: 1.0.5 - resolution: "html-void-elements@npm:1.0.5" - checksum: 1a56f4f6cfbeb994c21701ff72b4b7f556fe784a70e5e554d1566ff775af83b91ea93f10664f039a67802d9f7b40d4a7f1ed20312bab47bd88d89bd792ea84ca - languageName: node - linkType: hard - -"html-webpack-plugin@npm:^4.0.0": - version: 4.5.2 - resolution: "html-webpack-plugin@npm:4.5.2" - dependencies: - "@types/html-minifier-terser": ^5.0.0 - "@types/tapable": ^1.0.5 - "@types/webpack": ^4.41.8 - html-minifier-terser: ^5.0.1 - loader-utils: ^1.2.3 - lodash: ^4.17.20 - pretty-error: ^2.1.1 - tapable: ^1.1.3 - util.promisify: 1.0.0 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 25ca0b341234501c64754ba8f9bb84f978e50f3f90affc199d18d04511cdc2c0c8ef8a975901a0fbcfe5bae32f80e8fd5ef52f1ce3672d3ff5307057ccb5a063 - languageName: node - linkType: hard - -"html-webpack-plugin@npm:^5.0.0, html-webpack-plugin@npm:^5.5.0": +"html-webpack-plugin@npm:^5.5.0": version: 5.5.0 resolution: "html-webpack-plugin@npm:5.5.0" dependencies: @@ -17845,13 +16883,23 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^5.0.0": - version: 5.0.0 - resolution: "https-proxy-agent@npm:5.0.0" +"https-proxy-agent@npm:^4.0.0": + version: 4.0.0 + resolution: "https-proxy-agent@npm:4.0.0" + dependencies: + agent-base: 5 + debug: 4 + checksum: 19471d5aae3e747b1c98b17556647e2a1362e68220c6b19585a8527498f32e62e03c41d2872d059d8720d56846bd7460a80ac06f876bccfa786468ff40dd5eef + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.0, https-proxy-agent@npm:^5.0.1": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" dependencies: agent-base: 6 debug: 4 - checksum: 165bfb090bd26d47693597661298006841ab733d0c7383a8cb2f17373387a94c903a3ac687090aa739de05e379ab6f868bae84ab4eac288ad85c328cd1ec9e53 + checksum: 571fccdf38184f05943e12d37d6ce38197becdd69e58d03f43637f7fa1269cf303a7d228aa27e5b27bbd3af8f09fd938e1c91dcfefff2df7ba77c20ed8dfc765 languageName: node linkType: hard @@ -17919,15 +16967,6 @@ __metadata: languageName: node linkType: hard -"icss-utils@npm:^4.0.0, icss-utils@npm:^4.1.1": - version: 4.1.1 - resolution: "icss-utils@npm:4.1.1" - dependencies: - postcss: ^7.0.14 - checksum: a4ca2c6b82cb3eb879d635bd4028d74bca174edc49ee48ef5f01988489747d340a389d5a0ac6f6887a5c24ab8fc4386c781daab32a7ade5344a2edff66207635 - languageName: node - linkType: hard - "icss-utils@npm:^5.0.0, icss-utils@npm:^5.1.0": version: 5.1.0 resolution: "icss-utils@npm:5.1.0" @@ -17960,13 +16999,6 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^4.0.3": - version: 4.0.6 - resolution: "ignore@npm:4.0.6" - checksum: 248f82e50a430906f9ee7f35e1158e3ec4c3971451dd9f99c9bc1548261b4db2b99709f60ac6c6cac9333494384176cc4cc9b07acbe42d52ac6a09cad734d800 - languageName: node - linkType: hard - "ignore@npm:^5.2.0": version: 5.2.0 resolution: "ignore@npm:5.2.0" @@ -18024,15 +17056,6 @@ __metadata: languageName: node linkType: hard -"indent-string@npm:^2.1.0": - version: 2.1.0 - resolution: "indent-string@npm:2.1.0" - dependencies: - repeating: ^2.0.0 - checksum: 2fe7124311435f4d7a98f0a314d8259a4ec47ecb221110a58e2e2073e5f75c8d2b4f775f2ed199598fbe20638917e57423096539455ca8bff8eab113c9bee12c - languageName: node - linkType: hard - "indent-string@npm:^4.0.0": version: 4.0.0 resolution: "indent-string@npm:4.0.0" @@ -18057,7 +17080,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.0, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3, inherits@npm:~2.0.4": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -18101,13 +17124,6 @@ __metadata: languageName: node linkType: hard -"inline-style-parser@npm:0.1.1": - version: 0.1.1 - resolution: "inline-style-parser@npm:0.1.1" - checksum: 5d545056a3e1f2bf864c928a886a0e1656a3517127d36917b973de581bd54adc91b4bf1febcb0da054f204b4934763f1a4e09308b4d55002327cf1d48ac5d966 - languageName: node - linkType: hard - "inquirer@npm:^7.3.3": version: 7.3.3 resolution: "inquirer@npm:7.3.3" @@ -18277,25 +17293,7 @@ __metadata: languageName: node linkType: hard -"is-accessor-descriptor@npm:^0.1.6": - version: 0.1.6 - resolution: "is-accessor-descriptor@npm:0.1.6" - dependencies: - kind-of: ^3.0.2 - checksum: 3d629a086a9585bc16a83a8e8a3416f400023301855cafb7ccc9a1d63145b7480f0ad28877dcc2cce09492c4ec1c39ef4c071996f24ee6ac626be4217b8ffc8a - languageName: node - linkType: hard - -"is-accessor-descriptor@npm:^1.0.0": - version: 1.0.0 - resolution: "is-accessor-descriptor@npm:1.0.0" - dependencies: - kind-of: ^6.0.0 - checksum: 8e475968e9b22f9849343c25854fa24492dbe8ba0dea1a818978f9f1b887339190b022c9300d08c47fe36f1b913d70ce8cbaca00369c55a56705fdb7caed37fe - languageName: node - linkType: hard - -"is-alphabetical@npm:1.0.4, is-alphabetical@npm:^1.0.0": +"is-alphabetical@npm:^1.0.0": version: 1.0.4 resolution: "is-alphabetical@npm:1.0.4" checksum: 6508cce44fd348f06705d377b260974f4ce68c74000e7da4045f0d919e568226dc3ce9685c5a2af272195384df6930f748ce9213fc9f399b5d31b362c66312cb @@ -18322,7 +17320,7 @@ __metadata: languageName: node linkType: hard -"is-array-buffer@npm:^3.0.1": +"is-array-buffer@npm:^3.0.1, is-array-buffer@npm:^3.0.2": version: 3.0.2 resolution: "is-array-buffer@npm:3.0.2" dependencies: @@ -18368,20 +17366,13 @@ __metadata: languageName: node linkType: hard -"is-buffer@npm:^1.1.0, is-buffer@npm:^1.1.5": +"is-buffer@npm:^1.1.0": version: 1.1.6 resolution: "is-buffer@npm:1.1.6" checksum: 4a186d995d8bbf9153b4bd9ff9fd04ae75068fe695d29025d25e592d9488911eeece84eefbd8fa41b8ddcc0711058a71d4c466dcf6f1f6e1d83830052d8ca707 languageName: node linkType: hard -"is-buffer@npm:^2.0.0": - version: 2.0.5 - resolution: "is-buffer@npm:2.0.5" - checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42 - languageName: node - linkType: hard - "is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" @@ -18420,28 +17411,12 @@ __metadata: languageName: node linkType: hard -"is-data-descriptor@npm:^0.1.4": - version: 0.1.4 - resolution: "is-data-descriptor@npm:0.1.4" +"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": + version: 1.0.5 + resolution: "is-date-object@npm:1.0.5" dependencies: - kind-of: ^3.0.2 - checksum: 5c622e078ba933a78338ae398a3d1fc5c23332b395312daf4f74bab4afb10d061cea74821add726cb4db8b946ba36217ee71a24fe71dd5bca4632edb7f6aad87 - languageName: node - linkType: hard - -"is-data-descriptor@npm:^1.0.0": - version: 1.0.0 - resolution: "is-data-descriptor@npm:1.0.0" - dependencies: - kind-of: ^6.0.0 - checksum: e705e6816241c013b05a65dc452244ee378d1c3e3842bd140beabe6e12c0d700ef23c91803f971aa7b091fb0573c5da8963af34a2b573337d87bc3e1f53a4e6d - languageName: node - linkType: hard - -"is-date-object@npm:^1.0.1": - version: 1.0.2 - resolution: "is-date-object@npm:1.0.2" - checksum: ac859426e5df031abd9d1eeed32a41cc0de06e47227bd972b8bc716460a9404654b3dba78f41e8171ccf535c4bfa6d72a8d1d15a0873f9646698af415e92c2fb + has-tostringtag: ^1.0.0 + checksum: baa9077cdf15eb7b58c79398604ca57379b2fc4cf9aa7a9b9e295278648f628c9b201400c01c5e0f7afae56507d741185730307cbe7cad3b9f90a77e5ee342fc languageName: node linkType: hard @@ -18452,25 +17427,10 @@ __metadata: languageName: node linkType: hard -"is-descriptor@npm:^0.1.0": - version: 0.1.6 - resolution: "is-descriptor@npm:0.1.6" - dependencies: - is-accessor-descriptor: ^0.1.6 - is-data-descriptor: ^0.1.4 - kind-of: ^5.0.0 - checksum: 0f780c1b46b465f71d970fd7754096ffdb7b69fd8797ca1f5069c163eaedcd6a20ec4a50af669075c9ebcfb5266d2e53c8b227e485eefdb0d1fee09aa1dd8ab6 - languageName: node - linkType: hard - -"is-descriptor@npm:^1.0.0, is-descriptor@npm:^1.0.2": - version: 1.0.2 - resolution: "is-descriptor@npm:1.0.2" - dependencies: - is-accessor-descriptor: ^1.0.0 - is-data-descriptor: ^1.0.0 - kind-of: ^6.0.2 - checksum: 2ed623560bee035fb67b23e32ce885700bef8abe3fbf8c909907d86507b91a2c89a9d3a4d835a4d7334dd5db0237a0aeae9ca109c1e4ef1c0e7b577c0846ab5a +"is-deflate@npm:^1.0.0": + version: 1.0.0 + resolution: "is-deflate@npm:1.0.0" + checksum: c2f9f2d3db79ac50c5586697d1e69a55282a2b0cc5e437b3c470dd47f24e40b6216dcd7e024511e21381607bf57afa019343e3bd0e08a119032818b596004262 languageName: node linkType: hard @@ -18483,46 +17443,13 @@ __metadata: languageName: node linkType: hard -"is-dom@npm:^1.0.0": - version: 1.1.0 - resolution: "is-dom@npm:1.1.0" - dependencies: - is-object: ^1.0.1 - is-window: ^1.0.2 - checksum: 72aff0a7366b801c9d598d49452ec06544b52c3da92a0c6c3cacace33bb0c3df5ba1b4e422ac39224773316a553699d5920a1eb136919319f57d00e6384eb41b - languageName: node - linkType: hard - -"is-extendable@npm:^0.1.0, is-extendable@npm:^0.1.1": - version: 0.1.1 - resolution: "is-extendable@npm:0.1.1" - checksum: 3875571d20a7563772ecc7a5f36cb03167e9be31ad259041b4a8f73f33f885441f778cee1f1fe0085eb4bc71679b9d8c923690003a36a6a5fdf8023e6e3f0672 - languageName: node - linkType: hard - -"is-extendable@npm:^1.0.1": - version: 1.0.1 - resolution: "is-extendable@npm:1.0.1" - dependencies: - is-plain-object: ^2.0.4 - checksum: db07bc1e9de6170de70eff7001943691f05b9d1547730b11be01c0ebfe67362912ba743cf4be6fd20a5e03b4180c685dad80b7c509fe717037e3eee30ad8e84f - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": +"is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 languageName: node linkType: hard -"is-finite@npm:^1.0.0": - version: 1.1.0 - resolution: "is-finite@npm:1.1.0" - checksum: 532b97ed3d03e04c6bd203984d9e4ba3c0c390efee492bad5d1d1cd1802a68ab27adbd3ef6382f6312bed6c8bb1bd3e325ea79a8dc8fe080ed7a06f5f97b93e7 - languageName: node - linkType: hard - "is-fullwidth-code-point@npm:^1.0.0": version: 1.0.0 resolution: "is-fullwidth-code-point@npm:1.0.0" @@ -18553,13 +17480,6 @@ __metadata: languageName: node linkType: hard -"is-function@npm:^1.0.2": - version: 1.0.2 - resolution: "is-function@npm:1.0.2" - checksum: 7d564562e07b4b51359547d3ccc10fb93bb392fd1b8177ae2601ee4982a0ece86d952323fc172a9000743a3971f09689495ab78a1d49a9b14fc97a7e28521dc0 - languageName: node - linkType: hard - "is-generator-fn@npm:^2.0.0": version: 2.1.0 resolution: "is-generator-fn@npm:2.1.0" @@ -18576,15 +17496,6 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^3.0.0": - version: 3.1.0 - resolution: "is-glob@npm:3.1.0" - dependencies: - is-extglob: ^2.1.0 - checksum: 9d483bca84f16f01230f7c7c8c63735248fe1064346f292e0f6f8c76475fd20c6f50fc19941af5bec35f85d6bf26f4b7768f39a48a5f5fdc72b408dc74e07afc - languageName: node - linkType: hard - "is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" @@ -18594,6 +17505,13 @@ __metadata: languageName: node linkType: hard +"is-gzip@npm:^1.0.0": + version: 1.0.0 + resolution: "is-gzip@npm:1.0.0" + checksum: 0d28931c1f445fa29c900cf9f48e06e9d1d477a3bf7bd7332e7ce68f1333ccd8cb381de2f0f62a9a262d9c0912608a9a71b4a40e788e201b3dbd67072bb20d86 + languageName: node + linkType: hard + "is-hexadecimal@npm:^1.0.0": version: 1.0.4 resolution: "is-hexadecimal@npm:1.0.4" @@ -18632,7 +17550,7 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.2": +"is-map@npm:^2.0.1, is-map@npm:^2.0.2": version: 2.0.2 resolution: "is-map@npm:2.0.2" checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 @@ -18646,6 +17564,16 @@ __metadata: languageName: node linkType: hard +"is-nan@npm:^1.2.1": + version: 1.3.2 + resolution: "is-nan@npm:1.3.2" + dependencies: + call-bind: ^1.0.0 + define-properties: ^1.1.3 + checksum: 5dfadcef6ad12d3029d43643d9800adbba21cf3ce2ec849f734b0e14ee8da4070d82b15fdb35138716d02587c6578225b9a22779cab34888a139cc43e4e3610a + languageName: node + linkType: hard + "is-negative-zero@npm:^2.0.2": version: 2.0.2 resolution: "is-negative-zero@npm:2.0.2" @@ -18669,15 +17597,6 @@ __metadata: languageName: node linkType: hard -"is-number@npm:^3.0.0": - version: 3.0.0 - resolution: "is-number@npm:3.0.0" - dependencies: - kind-of: ^3.0.2 - checksum: 0c62bf8e9d72c4dd203a74d8cfc751c746e75513380fef420cda8237e619a988ee43e678ddb23c87ac24d91ac0fe9f22e4ffb1301a50310c697e9d73ca3994e9 - languageName: node - linkType: hard - "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -18699,13 +17618,6 @@ __metadata: languageName: node linkType: hard -"is-object@npm:^1.0.1": - version: 1.0.2 - resolution: "is-object@npm:1.0.2" - checksum: 971219c4b1985b9751f65e4c8296d3104f0457b0e8a70849e848a4a2208bc47317d73b3b85d4a369619cb2df8284dc22584cb2695a7d99aca5e8d0aa64fc075a - languageName: node - linkType: hard - "is-path-cwd@npm:^2.2.0": version: 2.2.0 resolution: "is-path-cwd@npm:2.2.0" @@ -18727,13 +17639,6 @@ __metadata: languageName: node linkType: hard -"is-plain-obj@npm:^2.0.0": - version: 2.1.0 - resolution: "is-plain-obj@npm:2.1.0" - checksum: cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa - languageName: node - linkType: hard - "is-plain-obj@npm:^3.0.0": version: 3.0.0 resolution: "is-plain-obj@npm:3.0.0" @@ -18748,7 +17653,7 @@ __metadata: languageName: node linkType: hard -"is-plain-object@npm:^2.0.3, is-plain-object@npm:^2.0.4": +"is-plain-object@npm:^2.0.4": version: 2.0.4 resolution: "is-plain-object@npm:2.0.4" dependencies: @@ -18780,7 +17685,7 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.0.4, is-regex@npm:^1.1.2, is-regex@npm:^1.1.4": +"is-regex@npm:^1.0.4, is-regex@npm:^1.1.4": version: 1.1.4 resolution: "is-regex@npm:1.1.4" dependencies: @@ -18813,7 +17718,7 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.2": +"is-set@npm:^2.0.1, is-set@npm:^2.0.2": version: 2.0.2 resolution: "is-set@npm:2.0.2" checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 @@ -18918,10 +17823,10 @@ __metadata: languageName: node linkType: hard -"is-utf8@npm:^0.2.0": - version: 0.2.1 - resolution: "is-utf8@npm:0.2.1" - checksum: 167ccd2be869fc228cc62c1a28df4b78c6b5485d15a29027d3b5dceb09b383e86a3522008b56dcac14b592b22f0a224388718c2505027a994fd8471465de54b3 +"is-weakmap@npm:^2.0.1": + version: 2.0.1 + resolution: "is-weakmap@npm:2.0.1" + checksum: 1222bb7e90c32bdb949226e66d26cb7bce12e1e28e3e1b40bfa6b390ba3e08192a8664a703dff2a00a84825f4e022f9cd58c4599ff9981ab72b1d69479f4f7f6 languageName: node linkType: hard @@ -18934,35 +17839,24 @@ __metadata: languageName: node linkType: hard -"is-whitespace-character@npm:^1.0.0": - version: 1.0.4 - resolution: "is-whitespace-character@npm:1.0.4" - checksum: adab8ad9847ccfcb6f1b7000b8f622881b5ba2a09ce8be2794a6d2b10c3af325b469fc562c9fb889f468eed27be06e227ac609d0aa1e3a59b4dbcc88e2b0418e +"is-weakset@npm:^2.0.1": + version: 2.0.2 + resolution: "is-weakset@npm:2.0.2" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.1.1 + checksum: 5d8698d1fa599a0635d7ca85be9c26d547b317ed8fd83fc75f03efbe75d50001b5eececb1e9971de85fcde84f69ae6f8346bc92d20d55d46201d328e4c74a367 languageName: node linkType: hard -"is-window@npm:^1.0.2": - version: 1.0.2 - resolution: "is-window@npm:1.0.2" - checksum: aeaacd2ca816d38d4e2fba4670158fba2190061f28a61c5d84df7c479abf8897b8cb634d22cb76cdf7805035e95bebd430faaab6231ac2ebc814eae02d2c8fd4 - languageName: node - linkType: hard - -"is-windows@npm:^1.0.1, is-windows@npm:^1.0.2": +"is-windows@npm:^1.0.1": version: 1.0.2 resolution: "is-windows@npm:1.0.2" checksum: 438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7 languageName: node linkType: hard -"is-word-character@npm:^1.0.0": - version: 1.0.4 - resolution: "is-word-character@npm:1.0.4" - checksum: 1821d6c6abe5bc0b3abe3fdc565d66d7c8a74ea4e93bc77b4a47d26e2e2a306d6ab7d92b353b0d2b182869e3ecaa8f4a346c62d0e31d38ebc0ceaf7cae182c3f - languageName: node - linkType: hard - -"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": +"is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -18985,13 +17879,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:1.0.0, isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -18999,6 +17886,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + languageName: node + linkType: hard + "isbinaryfile@npm:^4.0.8": version: 4.0.10 resolution: "isbinaryfile@npm:4.0.10" @@ -19013,15 +17907,6 @@ __metadata: languageName: node linkType: hard -"isobject@npm:^2.0.0": - version: 2.1.0 - resolution: "isobject@npm:2.1.0" - dependencies: - isarray: 1.0.0 - checksum: 811c6f5a866877d31f0606a88af4a45f282544de886bf29f6a34c46616a1ae2ed17076cc6bf34c0128f33eecf7e1fcaa2c82cf3770560d3e26810894e96ae79f - languageName: node - linkType: hard - "isobject@npm:^3.0.0, isobject@npm:^3.0.1": version: 3.0.1 resolution: "isobject@npm:3.0.1" @@ -19029,23 +17914,6 @@ __metadata: languageName: node linkType: hard -"isobject@npm:^4.0.0": - version: 4.0.0 - resolution: "isobject@npm:4.0.0" - checksum: bbcb522e46d54fb22418ba49fb9a82057ffa201c8401fb6e018c042e2c98cf7d9c7b185aff88e035ec8adea0814506dc2aeff2d08891bbc158e1671a49e99c06 - languageName: node - linkType: hard - -"isomorphic-unfetch@npm:^3.1.0": - version: 3.1.0 - resolution: "isomorphic-unfetch@npm:3.1.0" - dependencies: - node-fetch: ^2.6.1 - unfetch: ^4.2.0 - checksum: 82b92fe4ec2823a81ab0fc0d11bd94d710e6f9a940d56b3cba31896d4345ec9ffc7949f4ff31ebcae84f6b95f7ebf3474c4c7452b834eb4078ea3f2c37e459c5 - languageName: node - linkType: hard - "isomorphic.js@npm:^0.2.4": version: 0.2.4 resolution: "isomorphic.js@npm:0.2.4" @@ -19112,23 +17980,6 @@ __metadata: languageName: node linkType: hard -"iterate-iterator@npm:^1.0.1": - version: 1.0.2 - resolution: "iterate-iterator@npm:1.0.2" - checksum: 97b3ed4f2bebe038be57d03277879e406b2c537ceeeab7f82d4167f9a3cff872cc2cc5da3dc9920ff544ca247329d2a4d44121bb8ef8d0807a72176bdbc17c84 - languageName: node - linkType: hard - -"iterate-value@npm:^1.0.2": - version: 1.0.2 - resolution: "iterate-value@npm:1.0.2" - dependencies: - es-get-iterator: ^1.0.2 - iterate-iterator: ^1.0.1 - checksum: 446a4181657df1872e5020713206806757157db6ab375dee05eb4565b66e1244d7a99cd36ce06862261ad4bd059e66ba8192f62b5d1ff41d788c3b61953af6c3 - languageName: node - linkType: hard - "iterm2-version@npm:^4.1.0": version: 4.2.0 resolution: "iterm2-version@npm:4.2.0" @@ -19139,6 +17990,19 @@ __metadata: languageName: node linkType: hard +"jackspeak@npm:^2.0.3": + version: 2.2.2 + resolution: "jackspeak@npm:2.2.2" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 7b1468dd910afc00642db87448f24b062346570b8b47531409aa9012bcb95fdf7ec2b1c48edbb8b57a938c08391f8cc01b5034fc335aa3a2e74dbcc0ee5c555a + languageName: node + linkType: hard + "jake@npm:^10.8.5": version: 10.8.5 resolution: "jake@npm:10.8.5" @@ -19493,31 +18357,6 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-haste-map@npm:26.6.2" - dependencies: - "@jest/types": ^26.6.2 - "@types/graceful-fs": ^4.1.2 - "@types/node": "*" - anymatch: ^3.0.3 - fb-watchman: ^2.0.0 - fsevents: ^2.1.2 - graceful-fs: ^4.2.4 - jest-regex-util: ^26.0.0 - jest-serializer: ^26.6.2 - jest-util: ^26.6.2 - jest-worker: ^26.6.2 - micromatch: ^4.0.2 - sane: ^4.0.3 - walker: ^1.0.7 - dependenciesMeta: - fsevents: - optional: true - checksum: 8ad5236d5646d2388d2bd58a57ea53698923434f43d59ea9ebdc58bce4d0b8544c8de2f7acaa9a6d73171f04460388b2b6d7d6b6c256aea4ebb8780140781596 - languageName: node - linkType: hard - "jest-haste-map@npm:^27.5.1": version: 27.5.1 resolution: "jest-haste-map@npm:27.5.1" @@ -19542,11 +18381,11 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^29.5.0": - version: 29.5.0 - resolution: "jest-haste-map@npm:29.5.0" +"jest-haste-map@npm:^29.5.0, jest-haste-map@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-haste-map@npm:29.6.2" dependencies: - "@jest/types": ^29.5.0 + "@jest/types": ^29.6.1 "@types/graceful-fs": ^4.1.3 "@types/node": "*" anymatch: ^3.0.3 @@ -19554,14 +18393,14 @@ __metadata: fsevents: ^2.3.2 graceful-fs: ^4.2.9 jest-regex-util: ^29.4.3 - jest-util: ^29.5.0 - jest-worker: ^29.5.0 + jest-util: ^29.6.2 + jest-worker: ^29.6.2 micromatch: ^4.0.4 walker: ^1.0.8 dependenciesMeta: fsevents: optional: true - checksum: 3828ff7783f168e34be2c63887f82a01634261f605dcae062d83f979a61c37739e21b9607ecb962256aea3fbe5a530a1acee062d0026fcb47c607c12796cf3b7 + checksum: 726233972030eb2e5bce6c9468e497310436b455c88b40e744bd053e20a6f3ff19aec340edcbd89537c629ed5cf8916506bc895d690cc39a0862c74dcd95b7b8 languageName: node linkType: hard @@ -19704,7 +18543,7 @@ __metadata: languageName: node linkType: hard -"jest-mock@npm:^27.0.6, jest-mock@npm:^27.5.1": +"jest-mock@npm:^27.5.1": version: 27.5.1 resolution: "jest-mock@npm:27.5.1" dependencies: @@ -19762,13 +18601,6 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^26.0.0": - version: 26.0.0 - resolution: "jest-regex-util@npm:26.0.0" - checksum: 930a00665e8dfbedc29140678b4a54f021b41b895cf35050f76f557c1da3ac48ff42dd7b18ba2ccba6f4e518c6445d6753730d03ec7049901b93992db1ef0483 - languageName: node - linkType: hard - "jest-regex-util@npm:^27.5.1": version: 27.5.1 resolution: "jest-regex-util@npm:27.5.1" @@ -19964,16 +18796,6 @@ __metadata: languageName: node linkType: hard -"jest-serializer@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-serializer@npm:26.6.2" - dependencies: - "@types/node": "*" - graceful-fs: ^4.2.4 - checksum: dbecfb0d01462fe486a0932cf1680cf6abb204c059db2a8f72c6c2a7c9842a82f6d256874112774cea700764ed8f38fc9e3db982456c138d87353e3390e746fe - languageName: node - linkType: hard - "jest-serializer@npm:^27.5.1": version: 27.5.1 resolution: "jest-serializer@npm:27.5.1" @@ -20056,20 +18878,6 @@ __metadata: languageName: node linkType: hard -"jest-util@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-util@npm:26.6.2" - dependencies: - "@jest/types": ^26.6.2 - "@types/node": "*" - chalk: ^4.0.0 - graceful-fs: ^4.2.4 - is-ci: ^2.0.0 - micromatch: ^4.0.2 - checksum: 3c6a5fba05c4c6892cd3a9f66196ea8867087b77a5aa1a3f6cd349c785c3f1ca24abfd454664983aed1a165cab7846688e44fe8630652d666ba326b08625bc3d - languageName: node - linkType: hard - "jest-util@npm:^27.0.0, jest-util@npm:^27.5.1": version: 27.5.1 resolution: "jest-util@npm:27.5.1" @@ -20098,17 +18906,17 @@ __metadata: languageName: node linkType: hard -"jest-util@npm:^29.0.0, jest-util@npm:^29.5.0": - version: 29.5.0 - resolution: "jest-util@npm:29.5.0" +"jest-util@npm:^29.0.0, jest-util@npm:^29.5.0, jest-util@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-util@npm:29.6.2" dependencies: - "@jest/types": ^29.5.0 + "@jest/types": ^29.6.1 "@types/node": "*" chalk: ^4.0.0 ci-info: ^3.2.0 graceful-fs: ^4.2.9 picomatch: ^2.2.3 - checksum: fd9212950d34d2ecad8c990dda0d8ea59a8a554b0c188b53ea5d6c4a0829a64f2e1d49e6e85e812014933d17426d7136da4785f9cf76fff1799de51b88bc85d3 + checksum: 8aedc0c80083d0cabd6c6c4f04dea1cbcac609fd7bc3b1fc05a3999291bd6e63dd52b0c806f9378d5cae28eff5a6191709a4987861001293f8d03e53984adca4 languageName: node linkType: hard @@ -20204,7 +19012,7 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^26.2.1, jest-worker@npm:^26.5.0, jest-worker@npm:^26.6.2": +"jest-worker@npm:^26.2.1": version: 26.6.2 resolution: "jest-worker@npm:26.6.2" dependencies: @@ -20226,15 +19034,15 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^29.5.0": - version: 29.5.0 - resolution: "jest-worker@npm:29.5.0" +"jest-worker@npm:^29.5.0, jest-worker@npm:^29.6.2": + version: 29.6.2 + resolution: "jest-worker@npm:29.6.2" dependencies: "@types/node": "*" - jest-util: ^29.5.0 + jest-util: ^29.6.2 merge-stream: ^2.0.0 supports-color: ^8.0.0 - checksum: 1151a1ae3602b1ea7c42a8f1efe2b5a7bf927039deaa0827bf978880169899b705744e288f80a63603fb3fc2985e0071234986af7dc2c21c7a64333d8777c7c9 + checksum: 11035564534bf181ead80b25be138c2d42372bd5626151a3e705200d47a74fd9da3ca79f8a7b15806cdc325ad73c3d21d23acceeed99d50941589ff02915ed38 languageName: node linkType: hard @@ -20344,13 +19152,6 @@ __metadata: languageName: node linkType: hard -"js-string-escape@npm:^1.0.1": - version: 1.0.1 - resolution: "js-string-escape@npm:1.0.1" - checksum: f11e0991bf57e0c183b55c547acec85bd2445f043efc9ea5aa68b41bd2a3e7d3ce94636cb233ae0d84064ba4c1a505d32e969813c5b13f81e7d4be12c59256fe - languageName: node - linkType: hard - "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -20388,6 +19189,37 @@ __metadata: languageName: node linkType: hard +"jscodeshift@npm:^0.14.0": + version: 0.14.0 + resolution: "jscodeshift@npm:0.14.0" + dependencies: + "@babel/core": ^7.13.16 + "@babel/parser": ^7.13.16 + "@babel/plugin-proposal-class-properties": ^7.13.0 + "@babel/plugin-proposal-nullish-coalescing-operator": ^7.13.8 + "@babel/plugin-proposal-optional-chaining": ^7.13.12 + "@babel/plugin-transform-modules-commonjs": ^7.13.8 + "@babel/preset-flow": ^7.13.13 + "@babel/preset-typescript": ^7.13.0 + "@babel/register": ^7.13.16 + babel-core: ^7.0.0-bridge.0 + chalk: ^4.1.2 + flow-parser: 0.* + graceful-fs: ^4.2.4 + micromatch: ^4.0.4 + neo-async: ^2.5.0 + node-dir: ^0.1.17 + recast: ^0.21.0 + temp: ^0.8.4 + write-file-atomic: ^2.3.0 + peerDependencies: + "@babel/preset-env": ^7.1.6 + bin: + jscodeshift: bin/jscodeshift.js + checksum: 54ea6d639455883336f80b38a70648821c88b7942315dc0fbab01bc34a9ad0f0f78e3bd69304b5ab167e4262d6ed7e6284c6d32525ab01c89d9118df89b3e2a0 + languageName: node + linkType: hard + "jsdom@npm:^16.6.0": version: 16.7.0 resolution: "jsdom@npm:16.7.0" @@ -20610,13 +19442,6 @@ __metadata: languageName: node linkType: hard -"junk@npm:^3.1.0": - version: 3.1.0 - resolution: "junk@npm:3.1.0" - checksum: 6c4d68e8f8bc25b546baed802cd0e7be6a971e92f1e885c92cbfe98946d5690b961a32f8e7909e77765d3204c3e556d13c17f73e31697ffae1db07a58b9e68c0 - languageName: node - linkType: hard - "kdbush@npm:^3.0.0": version: 3.0.0 resolution: "kdbush@npm:3.0.0" @@ -20633,32 +19458,7 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^3.0.2, kind-of@npm:^3.0.3, kind-of@npm:^3.2.0": - version: 3.2.2 - resolution: "kind-of@npm:3.2.2" - dependencies: - is-buffer: ^1.1.5 - checksum: e898df8ca2f31038f27d24f0b8080da7be274f986bc6ed176f37c77c454d76627619e1681f6f9d2e8d2fd7557a18ecc419a6bb54e422abcbb8da8f1a75e4b386 - languageName: node - linkType: hard - -"kind-of@npm:^4.0.0": - version: 4.0.0 - resolution: "kind-of@npm:4.0.0" - dependencies: - is-buffer: ^1.1.5 - checksum: 1b9e7624a8771b5a2489026e820f3bbbcc67893e1345804a56b23a91e9069965854d2a223a7c6ee563c45be9d8c6ff1ef87f28ed5f0d1a8d00d9dcbb067c529f - languageName: node - linkType: hard - -"kind-of@npm:^5.0.0": - version: 5.1.0 - resolution: "kind-of@npm:5.1.0" - checksum: f2a0102ae0cf19c4a953397e552571bad2b588b53282874f25fca7236396e650e2db50d41f9f516bd402536e4df968dbb51b8e69e4d5d4a7173def78448f7bab - languageName: node - linkType: hard - -"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2": +"kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" checksum: 3ab01e7b1d440b22fe4c31f23d8d38b4d9b91d9f291df683476576493d5dfd2e03848a8b05813dd0c3f0e835bc63f433007ddeceb71f05cb25c45ae1b19c6d3b @@ -20721,16 +19521,14 @@ __metadata: languageName: node linkType: hard -"lazy-universal-dotenv@npm:^3.0.1": - version: 3.0.1 - resolution: "lazy-universal-dotenv@npm:3.0.1" +"lazy-universal-dotenv@npm:^4.0.0": + version: 4.0.0 + resolution: "lazy-universal-dotenv@npm:4.0.0" dependencies: - "@babel/runtime": ^7.5.0 app-root-dir: ^1.0.2 - core-js: ^3.0.4 - dotenv: ^8.0.0 - dotenv-expand: ^5.1.0 - checksum: a80509d8cb40dafcfab5859335920754a21814320aa16115e58c0ae5ef3b1d8bd4daa96349ea548e2833f2f89269ddbb103ebd55be06cfdba00e0af6785b5ba7 + dotenv: ^16.0.0 + dotenv-expand: ^10.0.0 + checksum: 196e0d701100144fbfe078d604a477573413ebf38dfe8d543748605e6a7074978508a3bb9f8135acd319db4fa947eef78836497163617d15a22163c59a00996b languageName: node linkType: hard @@ -20899,19 +19697,6 @@ __metadata: languageName: node linkType: hard -"load-json-file@npm:^1.0.0": - version: 1.1.0 - resolution: "load-json-file@npm:1.1.0" - dependencies: - graceful-fs: ^4.1.2 - parse-json: ^2.2.0 - pify: ^2.0.0 - pinkie-promise: ^2.0.0 - strip-bom: ^2.0.0 - checksum: 0e4e4f380d897e13aa236246a917527ea5a14e4fc34d49e01ce4e7e2a1e08e2740ee463a03fb021c04f594f29a178f4adb994087549d7c1c5315fcd29bf9934b - languageName: node - linkType: hard - "load-script@npm:^1.0.0": version: 1.0.0 resolution: "load-script@npm:1.0.0" @@ -20984,6 +19769,15 @@ __metadata: languageName: node linkType: hard +"locate-path@npm:^7.1.0": + version: 7.2.0 + resolution: "locate-path@npm:7.2.0" + dependencies: + p-locate: ^6.0.0 + checksum: c1b653bdf29beaecb3d307dfb7c44d98a2a98a02ebe353c9ad055d1ac45d6ed4e1142563d222df9b9efebc2bcb7d4c792b507fad9e7150a04c29530b7db570f8 + languageName: node + linkType: hard + "lodash-es@npm:4.17.21": version: 4.17.21 resolution: "lodash-es@npm:4.17.21" @@ -21131,7 +19925,7 @@ __metadata: languageName: node linkType: hard -"lodash.uniq@npm:4.5.0, lodash.uniq@npm:^4.5.0": +"lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" checksum: a4779b57a8d0f3c441af13d9afe7ecff22dd1b8ce1129849f71d9bbc8e8ee4e46dfb4b7c28f7ad3d67481edd6e51126e4e2a6ee276e25906d10f7140187c392d @@ -21227,16 +20021,6 @@ __metadata: languageName: node linkType: hard -"loud-rejection@npm:^1.0.0": - version: 1.6.0 - resolution: "loud-rejection@npm:1.6.0" - dependencies: - currently-unhandled: ^0.4.1 - signal-exit: ^3.0.0 - checksum: 750e12defde34e8cbf263c2bff16f028a89b56e022ad6b368aa7c39495b5ac33f2349a8d00665a9b6d25c030b376396524d8a31eb0dde98aaa97956d7324f927 - languageName: node - linkType: hard - "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -21298,12 +20082,19 @@ __metadata: languageName: node linkType: hard -"lz-string@npm:^1.4.4": - version: 1.4.4 - resolution: "lz-string@npm:1.4.4" +"lru-cache@npm:^9.1.1 || ^10.0.0": + version: 10.0.0 + resolution: "lru-cache@npm:10.0.0" + checksum: 18f101675fe283bc09cda0ef1e3cc83781aeb8373b439f086f758d1d91b28730950db785999cd060d3c825a8571c03073e8c14512b6655af2188d623031baf50 + languageName: node + linkType: hard + +"lz-string@npm:^1.5.0": + version: 1.5.0 + resolution: "lz-string@npm:1.5.0" bin: lz-string: bin/bin.js - checksum: 54e31238a61a84d8f664d9860a9fba7310c5b97a52c444f80543069bc084815eff40b8d4474ae1d93992fdf6c252dca37cf27f6adbeb4dbc3df2f3ac773d0e61 + checksum: 1ee98b4580246fd90dd54da6e346fb1caefcf05f677c686d9af237a157fdea3fd7c83a4bc58f858cd5b10a34d27afe0fdcbd0505a47e0590726a873dc8b8f65d languageName: node linkType: hard @@ -21403,29 +20194,13 @@ __metadata: languageName: node linkType: hard -"map-age-cleaner@npm:^0.1.3": - version: 0.1.3 - resolution: "map-age-cleaner@npm:0.1.3" - dependencies: - p-defer: ^1.0.0 - checksum: cb2804a5bcb3cbdfe4b59066ea6d19f5e7c8c196cd55795ea4c28f792b192e4c442426ae52524e5e1acbccf393d3bddacefc3d41f803e66453f6c4eda3650bc1 - languageName: node - linkType: hard - -"map-cache@npm:^0.2.0, map-cache@npm:^0.2.2": +"map-cache@npm:^0.2.0": version: 0.2.2 resolution: "map-cache@npm:0.2.2" checksum: 3067cea54285c43848bb4539f978a15dedc63c03022abeec6ef05c8cb6829f920f13b94bcaf04142fc6a088318e564c4785704072910d120d55dbc2e0c421969 languageName: node linkType: hard -"map-obj@npm:^1.0.0, map-obj@npm:^1.0.1": - version: 1.0.1 - resolution: "map-obj@npm:1.0.1" - checksum: 9949e7baec2a336e63b8d4dc71018c117c3ce6e39d2451ccbfd3b8350c547c4f6af331a4cbe1c83193d7c6b786082b6256bde843db90cb7da2a21e8fcc28afed - languageName: node - linkType: hard - "map-or-similar@npm:^1.5.0": version: 1.5.0 resolution: "map-or-similar@npm:1.5.0" @@ -21433,19 +20208,12 @@ __metadata: languageName: node linkType: hard -"map-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "map-visit@npm:1.0.0" - dependencies: - object-visit: ^1.0.0 - checksum: c27045a5021c344fc19b9132eb30313e441863b2951029f8f8b66f79d3d8c1e7e5091578075a996f74e417479506fe9ede28c44ca7bc351a61c9d8073daec36a - languageName: node - linkType: hard - -"markdown-escapes@npm:^1.0.0": - version: 1.0.4 - resolution: "markdown-escapes@npm:1.0.4" - checksum: 6833a93d72d3f70a500658872312c6fa8015c20cc835a85ae6901fa232683fbc6ed7118ebe920fea7c80039a560f339c026597d96eee0e9de602a36921804997 +"markdown-to-jsx@npm:^7.1.8": + version: 7.2.1 + resolution: "markdown-to-jsx@npm:7.2.1" + peerDependencies: + react: ">= 0.14.0" + checksum: 0c8c715229044401ea48c2fc26c2554464100074959dafacdd9e4a0e849f0a190b02f39edb373bbdd95e38b8f910074b83b63d08752b8ae6be6ddcfb40ea50a0 languageName: node linkType: hard @@ -21485,15 +20253,6 @@ __metadata: languageName: node linkType: hard -"mdast-squeeze-paragraphs@npm:^4.0.0": - version: 4.0.0 - resolution: "mdast-squeeze-paragraphs@npm:4.0.0" - dependencies: - unist-util-remove: ^2.0.0 - checksum: dfe8ec8e8a62171f020e82b088cc35cb9da787736dc133a3b45ce8811782a93e69bf06d147072e281079f09fac67be8a36153ffffd9bfbf89ed284e4c4f56f75 - languageName: node - linkType: hard - "mdast-util-definitions@npm:^4.0.0": version: 4.0.0 resolution: "mdast-util-definitions@npm:4.0.0" @@ -21503,22 +20262,6 @@ __metadata: languageName: node linkType: hard -"mdast-util-to-hast@npm:10.0.1": - version: 10.0.1 - resolution: "mdast-util-to-hast@npm:10.0.1" - dependencies: - "@types/mdast": ^3.0.0 - "@types/unist": ^2.0.0 - mdast-util-definitions: ^4.0.0 - mdurl: ^1.0.0 - unist-builder: ^2.0.0 - unist-util-generated: ^1.0.0 - unist-util-position: ^3.0.0 - unist-util-visit: ^2.0.0 - checksum: e5f385757df7e9b37db4d6f326bf7b4fc1b40f9ad01fc335686578f44abe0ba46d3e60af4d5e5b763556d02e65069ef9a09c49db049b52659203a43e7fa9084d - languageName: node - linkType: hard - "mdast-util-to-string@npm:^1.0.0": version: 1.1.0 resolution: "mdast-util-to-string@npm:1.1.0" @@ -21540,13 +20283,6 @@ __metadata: languageName: node linkType: hard -"mdurl@npm:^1.0.0": - version: 1.0.1 - resolution: "mdurl@npm:1.0.1" - checksum: 71731ecba943926bfbf9f9b51e28b5945f9411c4eda80894221b47cc105afa43ba2da820732b436f0798fd3edbbffcd1fc1415843c41a87fea08a41cc1e3d02b - languageName: node - linkType: hard - "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" @@ -21554,22 +20290,12 @@ __metadata: languageName: node linkType: hard -"mem@npm:^8.1.1": - version: 8.1.1 - resolution: "mem@npm:8.1.1" +"memfs@npm:^3.1.2, memfs@npm:^3.4.1, memfs@npm:^3.4.12, memfs@npm:^3.4.3": + version: 3.5.3 + resolution: "memfs@npm:3.5.3" dependencies: - map-age-cleaner: ^0.1.3 - mimic-fn: ^3.1.0 - checksum: c41bc97f6f82b91899206058989e34bcb1543af40413c2ab59e5a8e97e4f8f2188d62e7bd95b2d575d5b0d823d5034a0f274a0676f6d11a0e0b973898b06c8b1 - languageName: node - linkType: hard - -"memfs@npm:^3.1.2, memfs@npm:^3.2.2, memfs@npm:^3.4.3": - version: 3.4.13 - resolution: "memfs@npm:3.4.13" - dependencies: - fs-monkey: ^1.0.3 - checksum: 3f9717d6f060919d53f211acb6096a0ea2f566a8cbcc4ef7e1f2561e31e33dc456053fdf951c90a49c8ec55402de7f01b006b81683ab7bd4bdbbd8c9b9cdae5f + fs-monkey: ^1.0.4 + checksum: 18dfdeacad7c8047b976a6ccd58bc98ba76e122ad3ca0e50a21837fe2075fc0d9aafc58ab9cf2576c2b6889da1dd2503083f2364191b695273f40969db2ecc44 languageName: node linkType: hard @@ -21606,34 +20332,6 @@ __metadata: languageName: node linkType: hard -"memory-fs@npm:^0.4.1": - version: 0.4.1 - resolution: "memory-fs@npm:0.4.1" - dependencies: - errno: ^0.1.3 - readable-stream: ^2.0.1 - checksum: 6db6c8682eff836664ca9b5b6052ae38d21713dda9d0ef4700fa5c0599a8bc16b2093bee75ac3dedbe59fb2222d368f25bafaa62ba143c41051359cbcb005044 - languageName: node - linkType: hard - -"meow@npm:^3.1.0": - version: 3.7.0 - resolution: "meow@npm:3.7.0" - dependencies: - camelcase-keys: ^2.0.0 - decamelize: ^1.1.2 - loud-rejection: ^1.0.0 - map-obj: ^1.0.1 - minimist: ^1.1.3 - normalize-package-data: ^2.3.4 - object-assign: ^4.0.1 - read-pkg-up: ^1.0.1 - redent: ^1.0.0 - trim-newlines: ^1.0.0 - checksum: 65a412e5d0d643615508007a9292799bb3e4e690597d54c9e98eb0ca3adb7b8ca8899f41ea7cb7d8277129cdcd9a1a60202b31f88e0034e6aaae02894d80999a - languageName: node - linkType: hard - "merge-descriptors@npm:1.0.1": version: 1.0.1 resolution: "merge-descriptors@npm:1.0.1" @@ -21648,7 +20346,7 @@ __metadata: languageName: node linkType: hard -"merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 resolution: "merge2@npm:1.4.1" checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 @@ -21676,34 +20374,6 @@ __metadata: languageName: node linkType: hard -"microevent.ts@npm:~0.1.1": - version: 0.1.1 - resolution: "microevent.ts@npm:0.1.1" - checksum: 7874fcdb3f0dfa4e996d3ea63b3b9882874ae7d22be28d51ae20da24c712e9e28e5011d988095c27dd2b32e37c0ad7425342a71b89adb8e808ec7194fadf4a7a - languageName: node - linkType: hard - -"micromatch@npm:^3.1.10, micromatch@npm:^3.1.4": - version: 3.1.10 - resolution: "micromatch@npm:3.1.10" - dependencies: - arr-diff: ^4.0.0 - array-unique: ^0.3.2 - braces: ^2.3.1 - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - extglob: ^2.0.4 - fragment-cache: ^0.2.1 - kind-of: ^6.0.2 - nanomatch: ^1.2.9 - object.pick: ^1.3.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.2 - checksum: ad226cba4daa95b4eaf47b2ca331c8d2e038d7b41ae7ed0697cde27f3f1d6142881ab03d4da51b65d9d315eceb5e4cdddb3fbb55f5f72cfa19cf3ea469d054dc - languageName: node - linkType: hard - "micromatch@npm:^4.0.0, micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": version: 4.0.5 resolution: "micromatch@npm:4.0.5" @@ -21742,7 +20412,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.30, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.25, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -21760,7 +20430,7 @@ __metadata: languageName: node linkType: hard -"mime@npm:2.6.0, mime@npm:^2.4.4": +"mime@npm:2.6.0, mime@npm:^2.0.3, mime@npm:^2.4.4": version: 2.6.0 resolution: "mime@npm:2.6.0" bin: @@ -21776,13 +20446,6 @@ __metadata: languageName: node linkType: hard -"mimic-fn@npm:^3.1.0": - version: 3.1.0 - resolution: "mimic-fn@npm:3.1.0" - checksum: f7b167f9115b8bbdf2c3ee55dce9149d14be9e54b237259c4bc1d8d0512ea60f25a1b323f814eb1fe8f5a541662804bcfcfff3202ca58df143edb986849d58db - languageName: node - linkType: hard - "mimic-fn@npm:^4.0.0": version: 4.0.0 resolution: "mimic-fn@npm:4.0.0" @@ -21804,15 +20467,6 @@ __metadata: languageName: node linkType: hard -"min-document@npm:^2.19.0": - version: 2.19.0 - resolution: "min-document@npm:2.19.0" - dependencies: - dom-walk: ^0.1.0 - checksum: da6437562ea2228041542a2384528e74e22d1daa1a4ec439c165abf0b9d8a63e17e3b8a6dc6e0c731845e85301198730426932a0e813d23f932ca668340c9623 - languageName: node - linkType: hard - "min-indent@npm:^1.0.0": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -21867,7 +20521,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.1.0, minimist@npm:^1.1.1, minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": +"minimist@npm:^1.1.0, minimist@npm:^1.1.1, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -21907,7 +20561,7 @@ __metadata: languageName: node linkType: hard -"minipass-pipeline@npm:^1.2.2, minipass-pipeline@npm:^1.2.4": +"minipass-pipeline@npm:^1.2.4": version: 1.2.4 resolution: "minipass-pipeline@npm:1.2.4" dependencies: @@ -21934,10 +20588,17 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^4.0.0": - version: 4.2.1 - resolution: "minipass@npm:4.2.1" - checksum: 727641018e2b2dcd8fb6239b9220b4f0ef1b43d279dcb7f53840f7c43d005a36f0cdcfe2ffbc18ce32fae2ea484d3e7d3cb29cbe99c9274b0365bbb74661266c +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0": + version: 7.0.2 + resolution: "minipass@npm:7.0.2" + checksum: 46776de732eb7cef2c7404a15fb28c41f5c54a22be50d47b03c605bf21f5c18d61a173c0a20b49a97e7a65f78d887245066410642551e45fffe04e9ac9e325bc languageName: node linkType: hard @@ -21951,16 +20612,6 @@ __metadata: languageName: node linkType: hard -"mixin-deep@npm:^1.2.0": - version: 1.3.2 - resolution: "mixin-deep@npm:1.3.2" - dependencies: - for-in: ^1.0.2 - is-extendable: ^1.0.1 - checksum: 820d5a51fcb7479f2926b97f2c3bb223546bc915e6b3a3eb5d906dda871bba569863595424a76682f2b15718252954644f3891437cb7e3f220949bed54b1750d - languageName: node - linkType: hard - "mkdirp-classic@npm:^0.5.2": version: 0.5.3 resolution: "mkdirp-classic@npm:0.5.3" @@ -21977,7 +20628,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.5, mkdirp@npm:~0.5.1": +"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.5, mkdirp@npm:~0.5.1": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -22100,6 +20751,13 @@ __metadata: languageName: node linkType: hard +"mri@npm:^1.2.0": + version: 1.2.0 + resolution: "mri@npm:1.2.0" + checksum: 83f515abbcff60150873e424894a2f65d68037e5a7fcde8a9e2b285ee9c13ac581b63cfc1e6826c4732de3aeb84902f7c1e16b7aff46cd3f897a0f757a894e85 + languageName: node + linkType: hard + "mrmime@npm:^1.0.0": version: 1.0.1 resolution: "mrmime@npm:1.0.1" @@ -22210,7 +20868,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.1, nanoid@npm:^3.3.6": +"nanoid@npm:^3.3.6": version: 3.3.6 resolution: "nanoid@npm:3.3.6" bin: @@ -22219,25 +20877,6 @@ __metadata: languageName: node linkType: hard -"nanomatch@npm:^1.2.9": - version: 1.2.13 - resolution: "nanomatch@npm:1.2.13" - dependencies: - arr-diff: ^4.0.0 - array-unique: ^0.3.2 - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - fragment-cache: ^0.2.1 - is-windows: ^1.0.2 - kind-of: ^6.0.2 - object.pick: ^1.3.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: 54d4166d6ef08db41252eb4e96d4109ebcb8029f0374f9db873bd91a1f896c32ec780d2a2ea65c0b2d7caf1f28d5e1ea33746a470f32146ac8bba821d80d38d8 - languageName: node - linkType: hard - "natural-compare-lite@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare-lite@npm:1.4.0" @@ -22276,20 +20915,13 @@ __metadata: languageName: node linkType: hard -"neo-async@npm:^2.6.0, neo-async@npm:^2.6.1, neo-async@npm:^2.6.2": +"neo-async@npm:^2.5.0, neo-async@npm:^2.6.0, neo-async@npm:^2.6.1, neo-async@npm:^2.6.2": version: 2.6.2 resolution: "neo-async@npm:2.6.2" checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 languageName: node linkType: hard -"nested-error-stacks@npm:^2.0.0, nested-error-stacks@npm:^2.1.0": - version: 2.1.1 - resolution: "nested-error-stacks@npm:2.1.1" - checksum: 5f452fad75db8480b4db584e1602894ff5977f8bf3d2822f7ba5cb7be80e89adf1fffa34dada3347ef313a4288850b4486eb0635b315c32bdfb505577e8880e3 - languageName: node - linkType: hard - "nice-try@npm:^1.0.4": version: 1.0.5 resolution: "nice-try@npm:1.0.5" @@ -22307,7 +20939,14 @@ __metadata: languageName: node linkType: hard -"node-dir@npm:^0.1.10": +"node-abort-controller@npm:^3.0.1": + version: 3.1.1 + resolution: "node-abort-controller@npm:3.1.1" + checksum: 2c340916af9710328b11c0828223fc65ba320e0d082214a211311bf64c2891028e42ef276b9799188c4ada9e6e1c54cf7a0b7c05dd9d59fcdc8cd633304c8047 + languageName: node + linkType: hard + +"node-dir@npm:^0.1.10, node-dir@npm:^0.1.17": version: 0.1.17 resolution: "node-dir@npm:0.1.17" dependencies: @@ -22316,6 +20955,13 @@ __metadata: languageName: node linkType: hard +"node-fetch-native@npm:^1.0.2": + version: 1.2.0 + resolution: "node-fetch-native@npm:1.2.0" + checksum: f18d775523fc25b9fbec05a1da99cbf40214045bcaca82c8fd949b99148890c3cead4ab1764e26a92af600d14884d846481bcebf82d56815210624f836051a10 + languageName: node + linkType: hard + "node-fetch@npm:2.6.7": version: 2.6.7 resolution: "node-fetch@npm:2.6.7" @@ -22421,7 +21067,7 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^2.3.2, normalize-package-data@npm:^2.3.4, normalize-package-data@npm:^2.5.0": +"normalize-package-data@npm:^2.5.0": version: 2.5.0 resolution: "normalize-package-data@npm:2.5.0" dependencies: @@ -22433,15 +21079,6 @@ __metadata: languageName: node linkType: hard -"normalize-path@npm:^2.1.1": - version: 2.1.1 - resolution: "normalize-path@npm:2.1.1" - dependencies: - remove-trailing-separator: ^1.0.1 - checksum: 7e9cbdcf7f5b8da7aa191fbfe33daf290cdcd8c038f422faf1b8a83c972bf7a6d94c5be34c4326cb00fb63bc0fd97d9fbcfaf2e5d6142332c2cd36d2e1b86cea - languageName: node - linkType: hard - "normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" @@ -22516,18 +21153,6 @@ __metadata: languageName: node linkType: hard -"npmlog@npm:^5.0.1": - version: 5.0.1 - resolution: "npmlog@npm:5.0.1" - dependencies: - are-we-there-yet: ^2.0.0 - console-control-strings: ^1.1.0 - gauge: ^3.0.0 - set-blocking: ^2.0.0 - checksum: 516b2663028761f062d13e8beb3f00069c5664925871a9b57989642ebe09f23ab02145bf3ab88da7866c4e112cafff72401f61a672c7c8a20edc585a7016ef5f - languageName: node - linkType: hard - "npmlog@npm:^6.0.0": version: 6.0.2 resolution: "npmlog@npm:6.0.2" @@ -22556,13 +21181,6 @@ __metadata: languageName: node linkType: hard -"num2fraction@npm:^1.2.2": - version: 1.2.2 - resolution: "num2fraction@npm:1.2.2" - checksum: 1da9c6797b505d3f5b17c7f694c4fa31565bdd5c0e5d669553253aed848a580804cd285280e8a73148bd9628839267daee4967f24b53d4e893e44b563e412635 - languageName: node - linkType: hard - "number-is-nan@npm:^1.0.0": version: 1.0.1 resolution: "number-is-nan@npm:1.0.1" @@ -22584,17 +21202,6 @@ __metadata: languageName: node linkType: hard -"object-copy@npm:^0.1.0": - version: 0.1.0 - resolution: "object-copy@npm:0.1.0" - dependencies: - copy-descriptor: ^0.1.0 - define-property: ^0.2.5 - kind-of: ^3.0.3 - checksum: a9e35f07e3a2c882a7e979090360d1a20ab51d1fa19dfdac3aa8873b328a7c4c7683946ee97c824ae40079d848d6740a3788fa14f2185155dab7ed970a72c783 - languageName: node - linkType: hard - "object-hash@npm:^3.0.0": version: 3.0.0 resolution: "object-hash@npm:3.0.0" @@ -22609,13 +21216,13 @@ __metadata: languageName: node linkType: hard -"object-is@npm:^1.0.1": - version: 1.1.3 - resolution: "object-is@npm:1.1.3" +"object-is@npm:^1.0.1, object-is@npm:^1.1.5": + version: 1.1.5 + resolution: "object-is@npm:1.1.5" dependencies: + call-bind: ^1.0.2 define-properties: ^1.1.3 - es-abstract: ^1.18.0-next.1 - checksum: 8b03d2706f489b4f86c1de803e16389bdf7facd6e715c044bd898376d370b98a47aafdf64c26be6c6151e57cf8b4e499210d2768935b24b369dac90ad2ce8a19 + checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe languageName: node linkType: hard @@ -22626,15 +21233,6 @@ __metadata: languageName: node linkType: hard -"object-visit@npm:^1.0.0": - version: 1.0.1 - resolution: "object-visit@npm:1.0.1" - dependencies: - isobject: ^3.0.0 - checksum: b0ee07f5bf3bb881b881ff53b467ebbde2b37ebb38649d6944a6cd7681b32eedd99da9bd1e01c55facf81f54ed06b13af61aba6ad87f0052982995e09333f790 - languageName: node - linkType: hard - "object.assign@npm:^4.1.2, object.assign@npm:^4.1.4": version: 4.1.4 resolution: "object.assign@npm:4.1.4" @@ -22659,7 +21257,7 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.0, object.entries@npm:^1.1.5": +"object.entries@npm:^1.1.5": version: 1.1.6 resolution: "object.entries@npm:1.1.6" dependencies: @@ -22670,7 +21268,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.0 || ^1.0.0, object.fromentries@npm:^2.0.5": +"object.fromentries@npm:^2.0.5": version: 2.0.6 resolution: "object.fromentries@npm:2.0.6" dependencies: @@ -22681,7 +21279,7 @@ __metadata: languageName: node linkType: hard -"object.getownpropertydescriptors@npm:^2.0.3, object.getownpropertydescriptors@npm:^2.1.0, object.getownpropertydescriptors@npm:^2.1.2": +"object.getownpropertydescriptors@npm:^2.1.0": version: 2.1.5 resolution: "object.getownpropertydescriptors@npm:2.1.5" dependencies: @@ -22799,24 +21397,14 @@ __metadata: languageName: node linkType: hard -"open@npm:^7.0.3": - version: 7.4.2 - resolution: "open@npm:7.4.2" - dependencies: - is-docker: ^2.0.0 - is-wsl: ^2.1.1 - checksum: 3333900ec0e420d64c23b831bc3467e57031461d843c801f569b2204a1acc3cd7b3ec3c7897afc9dde86491dfa289708eb92bba164093d8bd88fb2c231843c91 - languageName: node - linkType: hard - -"open@npm:^8.0.9, open@npm:^8.4.0": - version: 8.4.0 - resolution: "open@npm:8.4.0" +"open@npm:^8.0.4, open@npm:^8.0.9, open@npm:^8.4.0": + version: 8.4.2 + resolution: "open@npm:8.4.2" dependencies: define-lazy-prop: ^2.0.0 is-docker: ^2.1.1 is-wsl: ^2.2.0 - checksum: e9545bec64cdbf30a0c35c1bdc310344adf8428a117f7d8df3c0af0a0a24c513b304916a6d9b11db0190ff7225c2d578885080b761ed46a3d5f6f1eebb98b63c + checksum: 6388bfff21b40cb9bd8f913f9130d107f2ed4724ea81a8fd29798ee322b361ca31fa2cdfb491a5c31e43a3996cfe9566741238c7a741ada8d7af1cb78d85cf26 languageName: node linkType: hard @@ -22905,13 +21493,6 @@ __metadata: languageName: node linkType: hard -"os-homedir@npm:^1.0.0": - version: 1.0.2 - resolution: "os-homedir@npm:1.0.2" - checksum: af609f5a7ab72de2f6ca9be6d6b91a599777afc122ac5cad47e126c1f67c176fe9b52516b9eeca1ff6ca0ab8587fe66208bc85e40a3940125f03cdb91408e9d2 - languageName: node - linkType: hard - "os-tmpdir@npm:~1.0.2": version: 1.0.2 resolution: "os-tmpdir@npm:1.0.2" @@ -22935,15 +21516,6 @@ __metadata: languageName: node linkType: hard -"p-all@npm:^2.1.0": - version: 2.1.0 - resolution: "p-all@npm:2.1.0" - dependencies: - p-map: ^2.0.0 - checksum: 6c20134eb3f16dca270d04a40cd14d2d05012b5a5762ca4f89962ae03a5fc13e13b09f64626a780f10bbe4e204b9370f708c6d8c079296bd2512d7e15462c76f - languageName: node - linkType: hard - "p-cancelable@npm:^2.0.0": version: 2.1.1 resolution: "p-cancelable@npm:2.1.1" @@ -22951,31 +21523,6 @@ __metadata: languageName: node linkType: hard -"p-defer@npm:^1.0.0": - version: 1.0.0 - resolution: "p-defer@npm:1.0.0" - checksum: 4271b935c27987e7b6f229e5de4cdd335d808465604644cb7b4c4c95bef266735859a93b16415af8a41fd663ee9e3b97a1a2023ca9def613dba1bad2a0da0c7b - languageName: node - linkType: hard - -"p-event@npm:^4.1.0": - version: 4.2.0 - resolution: "p-event@npm:4.2.0" - dependencies: - p-timeout: ^3.1.0 - checksum: 8a3588f7a816a20726a3262dfeee70a631e3997e4773d23219176333eda55cce9a76219e3d2b441b331eb746e14fdb381eb2694ab9ff2fcf87c846462696fe89 - languageName: node - linkType: hard - -"p-filter@npm:^2.1.0": - version: 2.1.0 - resolution: "p-filter@npm:2.1.0" - dependencies: - p-map: ^2.0.0 - checksum: 76e552ca624ce2233448d68b19eec9de42b695208121998f7e011edce71d1079a83096ee6a2078fb2a59cfa8a5c999f046edf00ebf16a8e780022010b4693234 - languageName: node - linkType: hard - "p-finally@npm:^1.0.0": version: 1.0.0 resolution: "p-finally@npm:1.0.0" @@ -23010,6 +21557,15 @@ __metadata: languageName: node linkType: hard +"p-limit@npm:^4.0.0": + version: 4.0.0 + resolution: "p-limit@npm:4.0.0" + dependencies: + yocto-queue: ^1.0.0 + checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b + languageName: node + linkType: hard + "p-locate@npm:^2.0.0": version: 2.0.0 resolution: "p-locate@npm:2.0.0" @@ -23046,19 +21602,12 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^2.0.0": - version: 2.1.0 - resolution: "p-map@npm:2.1.0" - checksum: 9e3ad3c9f6d75a5b5661bcad78c91f3a63849189737cd75e4f1225bf9ac205194e5c44aac2ef6f09562b1facdb9bd1425584d7ac375bfaa17b3f1a142dab936d - languageName: node - linkType: hard - -"p-map@npm:^3.0.0": - version: 3.0.0 - resolution: "p-map@npm:3.0.0" +"p-locate@npm:^6.0.0": + version: 6.0.0 + resolution: "p-locate@npm:6.0.0" dependencies: - aggregate-error: ^3.0.0 - checksum: 49b0fcbc66b1ef9cd379de1b4da07fa7a9f84b41509ea3f461c31903623aaba8a529d22f835e0d77c7cb9fcc16e4fae71e308fd40179aea514ba68f27032b5d5 + p-limit: ^4.0.0 + checksum: 2bfe5234efa5e7a4e74b30a5479a193fdd9236f8f6b4d2f3f69e3d286d9a7d7ab0c118a2a50142efcf4e41625def635bd9332d6cbf9cc65d85eb0718c579ab38 languageName: node linkType: hard @@ -23081,15 +21630,6 @@ __metadata: languageName: node linkType: hard -"p-timeout@npm:^3.1.0": - version: 3.2.0 - resolution: "p-timeout@npm:3.2.0" - dependencies: - p-finally: ^1.0.0 - checksum: 3dd0eaa048780a6f23e5855df3dd45c7beacff1f820476c1d0d1bcd6648e3298752ba2c877aa1c92f6453c7dd23faaf13d9f5149fc14c0598a142e2c5e8d649c - languageName: node - linkType: hard - "p-try@npm:^1.0.0": version: 1.0.0 resolution: "p-try@npm:1.0.0" @@ -23123,6 +21663,13 @@ __metadata: languageName: node linkType: hard +"pako@npm:~0.2.0": + version: 0.2.9 + resolution: "pako@npm:0.2.9" + checksum: 055f9487cd57fbb78df84315873bbdd089ba286f3499daed47d2effdc6253e981f5db6898c23486de76d4a781559f890d643bd3a49f70f1b4a18019c98aa5125 + languageName: node + linkType: hard + "pako@npm:~1.0.2, pako@npm:~1.0.5": version: 1.0.11 resolution: "pako@npm:1.0.11" @@ -23130,7 +21677,7 @@ __metadata: languageName: node linkType: hard -"param-case@npm:^3.0.3, param-case@npm:^3.0.4": +"param-case@npm:^3.0.4": version: 3.0.4 resolution: "param-case@npm:3.0.4" dependencies: @@ -23196,15 +21743,6 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^2.2.0": - version: 2.2.0 - resolution: "parse-json@npm:2.2.0" - dependencies: - error-ex: ^1.2.0 - checksum: dda78a63e57a47b713a038630868538f718a7ca0cd172a36887b0392ccf544ed0374902eb28f8bf3409e8b71d62b79d17062f8543afccf2745f9b0b2d2bb80ca - languageName: node - linkType: hard - "parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" @@ -23224,7 +21762,7 @@ __metadata: languageName: node linkType: hard -"parse5@npm:6.0.1, parse5@npm:^6.0.0": +"parse5@npm:6.0.1": version: 6.0.1 resolution: "parse5@npm:6.0.1" checksum: 7d569a176c5460897f7c8f3377eff640d54132b9be51ae8a8fa4979af940830b2b0c296ce75e5bd8f4041520aadde13170dbdec44889975f906098ea0002f4bd @@ -23248,13 +21786,6 @@ __metadata: languageName: node linkType: hard -"pascalcase@npm:^0.1.1": - version: 0.1.1 - resolution: "pascalcase@npm:0.1.1" - checksum: f83681c3c8ff75fa473a2bb2b113289952f802ff895d435edd717e7cb898b0408cbdb247117a938edcbc5d141020909846cc2b92c47213d764e2a94d2ad2b925 - languageName: node - linkType: hard - "path-browserify@npm:^1.0.0, path-browserify@npm:^1.0.1": version: 1.0.1 resolution: "path-browserify@npm:1.0.1" @@ -23279,15 +21810,6 @@ __metadata: languageName: node linkType: hard -"path-exists@npm:^2.0.0": - version: 2.1.0 - resolution: "path-exists@npm:2.1.0" - dependencies: - pinkie-promise: ^2.0.0 - checksum: fdb734f1d00f225f7a0033ce6d73bff6a7f76ea08936abf0e5196fa6e54a645103538cd8aedcb90d6d8c3fa3705ded0c58a4da5948ae92aa8834892c1ab44a84 - languageName: node - linkType: hard - "path-exists@npm:^3.0.0": version: 3.0.0 resolution: "path-exists@npm:3.0.0" @@ -23302,6 +21824,13 @@ __metadata: languageName: node linkType: hard +"path-exists@npm:^5.0.0": + version: 5.0.0 + resolution: "path-exists@npm:5.0.0" + checksum: 8ca842868cab09423994596eb2c5ec2a971c17d1a3cb36dbf060592c730c725cd524b9067d7d2a1e031fef9ba7bd2ac6dc5ec9fb92aa693265f7be3987045254 + languageName: node + linkType: hard + "path-is-absolute@npm:^1.0.0, path-is-absolute@npm:^1.0.1": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -23360,6 +21889,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^1.10.1": + version: 1.10.1 + resolution: "path-scurry@npm:1.10.1" + dependencies: + lru-cache: ^9.1.1 || ^10.0.0 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + checksum: e2557cff3a8fb8bc07afdd6ab163a92587884f9969b05bbbaf6fe7379348bfb09af9ed292af12ed32398b15fb443e81692047b786d1eeb6d898a51eb17ed7d90 + languageName: node + linkType: hard + "path-to-regexp@npm:0.1.7": version: 0.1.7 resolution: "path-to-regexp@npm:0.1.7" @@ -23383,26 +21922,6 @@ __metadata: languageName: node linkType: hard -"path-type@npm:^1.0.0": - version: 1.1.0 - resolution: "path-type@npm:1.1.0" - dependencies: - graceful-fs: ^4.1.2 - pify: ^2.0.0 - pinkie-promise: ^2.0.0 - checksum: 59a4b2c0e566baf4db3021a1ed4ec09a8b36fca960a490b54a6bcefdb9987dafe772852982b6011cd09579478a96e57960a01f75fa78a794192853c9d468fc79 - languageName: node - linkType: hard - -"path-type@npm:^3.0.0": - version: 3.0.0 - resolution: "path-type@npm:3.0.0" - dependencies: - pify: ^3.0.0 - checksum: 735b35e256bad181f38fa021033b1c33cfbe62ead42bb2222b56c210e42938eecb272ae1949f3b6db4ac39597a61b44edd8384623ec4d79bfdc9a9c0f12537a6 - languageName: node - linkType: hard - "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -23410,6 +21929,13 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^1.1.0": + version: 1.1.1 + resolution: "pathe@npm:1.1.1" + checksum: 34ab3da2e5aa832ebc6a330ffe3f73d7ba8aec6e899b53b8ec4f4018de08e40742802deb12cf5add9c73b7bf719b62c0778246bd376ca62b0fb23e0dde44b759 + languageName: node + linkType: hard + "pbkdf2@npm:^3.0.3": version: 3.1.2 resolution: "pbkdf2@npm:3.1.2" @@ -23423,6 +21949,17 @@ __metadata: languageName: node linkType: hard +"peek-stream@npm:^1.1.0": + version: 1.1.3 + resolution: "peek-stream@npm:1.1.3" + dependencies: + buffer-from: ^1.0.0 + duplexify: ^3.5.0 + through2: ^2.0.3 + checksum: a0e09d6d1a8a01158a3334f20d6b1cdd91747eba24eb06a1d742eefb620385593121a76d4378cc81f77cdce6a66df0575a41041b1189c510254aec91878afc99 + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -23467,20 +22004,13 @@ __metadata: languageName: node linkType: hard -"pify@npm:^2.0.0, pify@npm:^2.2.0, pify@npm:^2.3.0": +"pify@npm:^2.2.0, pify@npm:^2.3.0": version: 2.3.0 resolution: "pify@npm:2.3.0" checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba languageName: node linkType: hard -"pify@npm:^3.0.0": - version: 3.0.0 - resolution: "pify@npm:3.0.0" - checksum: 6cdcbc3567d5c412450c53261a3f10991665d660961e06605decf4544a61a97a54fefe70a68d5c37080ff9d6f4cf51444c90198d1ba9f9309a6c0d6e9f5c4fde - languageName: node - linkType: hard - "pify@npm:^4.0.1": version: 4.0.1 resolution: "pify@npm:4.0.1" @@ -23488,23 +22018,7 @@ __metadata: languageName: node linkType: hard -"pinkie-promise@npm:^2.0.0": - version: 2.0.1 - resolution: "pinkie-promise@npm:2.0.1" - dependencies: - pinkie: ^2.0.0 - checksum: b53a4a2e73bf56b6f421eef711e7bdcb693d6abb474d57c5c413b809f654ba5ee750c6a96dd7225052d4b96c4d053cdcb34b708a86fceed4663303abee52fcca - languageName: node - linkType: hard - -"pinkie@npm:^2.0.0": - version: 2.0.4 - resolution: "pinkie@npm:2.0.4" - checksum: b12b10afea1177595aab036fc220785488f67b4b0fc49e7a27979472592e971614fa1c728e63ad3e7eb748b4ec3c3dbd780819331dad6f7d635c77c10537b9db - languageName: node - linkType: hard - -"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.5": +"pirates@npm:^4.0.4, pirates@npm:^4.0.5": version: 4.0.5 resolution: "pirates@npm:4.0.5" checksum: c9994e61b85260bec6c4fc0307016340d9b0c4f4b6550a957afaaff0c9b1ad58fbbea5cfcf083860a25cb27a375442e2b0edf52e2e1e40e69934e08dcc52d227 @@ -23549,6 +22063,15 @@ __metadata: languageName: node linkType: hard +"pkg-dir@npm:^7.0.0": + version: 7.0.0 + resolution: "pkg-dir@npm:7.0.0" + dependencies: + find-up: ^6.3.0 + checksum: 94298b20a446bfbbd66604474de8a0cdd3b8d251225170970f15d9646f633e056c80520dd5b4c1d1050c9fed8f6a9e5054b141c93806439452efe72e57562c03 + languageName: node + linkType: hard + "pkg-up@npm:^3.1.0": version: 3.1.0 resolution: "pkg-up@npm:3.1.0" @@ -23622,13 +22145,6 @@ __metadata: languageName: node linkType: hard -"pluralize@npm:^8.0.0": - version: 8.0.0 - resolution: "pluralize@npm:8.0.0" - checksum: 08931d4a6a4a5561a7f94f67a31c17e6632cb21e459ab3ff4f6f629d9a822984cf8afef2311d2005fbea5d7ef26016ebb090db008e2d8bce39d0a9a9d218736e - languageName: node - linkType: hard - "pngjs@npm:^3.4.0": version: 3.4.0 resolution: "pngjs@npm:3.4.0" @@ -23643,15 +22159,6 @@ __metadata: languageName: node linkType: hard -"pnp-webpack-plugin@npm:1.6.4": - version: 1.6.4 - resolution: "pnp-webpack-plugin@npm:1.6.4" - dependencies: - ts-pnp: ^1.1.6 - checksum: 0606a63db96400b07f182300168298da9518727a843f9e10cf5045d2a102a4be06bb18c73dc481281e3e0f1ed8d04ef0d285a342b6dcd0eff1340e28e5d2328d - languageName: node - linkType: hard - "pnp-webpack-plugin@npm:^1.7.0": version: 1.7.0 resolution: "pnp-webpack-plugin@npm:1.7.0" @@ -23677,13 +22184,6 @@ __metadata: languageName: node linkType: hard -"posix-character-classes@npm:^0.1.0": - version: 0.1.1 - resolution: "posix-character-classes@npm:0.1.1" - checksum: dedb99913c60625a16050cfed2fb5c017648fc075be41ac18474e1c6c3549ef4ada201c8bd9bd006d36827e289c571b6092e1ef6e756cdbab2fd7046b25c6442 - languageName: node - linkType: hard - "postcss-attribute-case-insensitive@npm:^5.0.0": version: 5.0.0 resolution: "postcss-attribute-case-insensitive@npm:5.0.0" @@ -23888,15 +22388,6 @@ __metadata: languageName: node linkType: hard -"postcss-flexbugs-fixes@npm:^4.2.1": - version: 4.2.1 - resolution: "postcss-flexbugs-fixes@npm:4.2.1" - dependencies: - postcss: ^7.0.26 - checksum: 51a626bc80dbe42fcc8b0895b4f23a558bb809ec52cdc05aa27fb24cdffd4c9dc53f25218085ddf407c53d76573bc6d7568219c912161609f02532a8f5f59b43 - languageName: node - linkType: hard - "postcss-flexbugs-fixes@npm:^5.0.2": version: 5.0.2 resolution: "postcss-flexbugs-fixes@npm:5.0.2" @@ -24038,22 +22529,6 @@ __metadata: languageName: node linkType: hard -"postcss-loader@npm:^4.2.0": - version: 4.3.0 - resolution: "postcss-loader@npm:4.3.0" - dependencies: - cosmiconfig: ^7.0.0 - klona: ^2.0.4 - loader-utils: ^2.0.0 - schema-utils: ^3.0.0 - semver: ^7.3.4 - peerDependencies: - postcss: ^7.0.0 || ^8.0.1 - webpack: ^4.0.0 || ^5.0.0 - checksum: b8ba29789d48512c7ce10e9391b1e1512a4b8f8b4063ebff0f9ebdd0a3a01e433ccfa0d2db6dbdd63b126acf7692330f0773bef75e78d53f38eba556ca5f2aee - languageName: node - linkType: hard - "postcss-loader@npm:^6.2.1": version: 6.2.1 resolution: "postcss-loader@npm:6.2.1" @@ -24160,15 +22635,6 @@ __metadata: languageName: node linkType: hard -"postcss-modules-extract-imports@npm:^2.0.0": - version: 2.0.0 - resolution: "postcss-modules-extract-imports@npm:2.0.0" - dependencies: - postcss: ^7.0.5 - checksum: 154790fe5954aaa12f300aa9aa782fae8b847138459c8f533ea6c8f29439dd66b4d9a49e0bf6f8388fa0df898cc03d61c84678e3b0d4b47cac5a4334a7151a9f - languageName: node - linkType: hard - "postcss-modules-extract-imports@npm:^3.0.0": version: 3.0.0 resolution: "postcss-modules-extract-imports@npm:3.0.0" @@ -24178,38 +22644,16 @@ __metadata: languageName: node linkType: hard -"postcss-modules-local-by-default@npm:^3.0.2": - version: 3.0.3 - resolution: "postcss-modules-local-by-default@npm:3.0.3" - dependencies: - icss-utils: ^4.1.1 - postcss: ^7.0.32 - postcss-selector-parser: ^6.0.2 - postcss-value-parser: ^4.1.0 - checksum: 0267633eaf80e72a3abf391b6e34c5b344a1bdfb1421543d3ed43fc757e053e0fcc1a2eb06d959a8f435776e8dc80288b59bfc34d61e5e021d47b747c417c5a1 - languageName: node - linkType: hard - -"postcss-modules-local-by-default@npm:^4.0.0": - version: 4.0.0 - resolution: "postcss-modules-local-by-default@npm:4.0.0" +"postcss-modules-local-by-default@npm:^4.0.3": + version: 4.0.3 + resolution: "postcss-modules-local-by-default@npm:4.0.3" dependencies: icss-utils: ^5.0.0 postcss-selector-parser: ^6.0.2 postcss-value-parser: ^4.1.0 peerDependencies: postcss: ^8.1.0 - checksum: 6cf570badc7bc26c265e073f3ff9596b69bb954bc6ac9c5c1b8cba2995b80834226b60e0a3cbb87d5f399dbb52e6466bba8aa1d244f6218f99d834aec431a69d - languageName: node - linkType: hard - -"postcss-modules-scope@npm:^2.2.0": - version: 2.2.0 - resolution: "postcss-modules-scope@npm:2.2.0" - dependencies: - postcss: ^7.0.6 - postcss-selector-parser: ^6.0.0 - checksum: c611181df924275ca1ffea261149c229488d6921054896879ca98feeb0913f9b00f4f160654beb2cb243a2989036c269baa96778eeacaaa399a4604b6e2fea17 + checksum: 2f8083687f3d6067885f8863dd32dbbb4f779cfcc7e52c17abede9311d84faf6d3ed8760e7c54c6380281732ae1f78e5e56a28baf3c271b33f450a11c9e30485 languageName: node linkType: hard @@ -24224,16 +22668,6 @@ __metadata: languageName: node linkType: hard -"postcss-modules-values@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-modules-values@npm:3.0.0" - dependencies: - icss-utils: ^4.0.0 - postcss: ^7.0.6 - checksum: f1aea0b9c6798b39ec02a6d2310924bb9bfbddb4579668c2d4e2205ca7a68c656b85d5720f9bba3629d611f36667fe04ab889ea3f9a6b569a0a0d57b4f2f4e99 - languageName: node - linkType: hard - "postcss-modules-values@npm:^4.0.0": version: 4.0.0 resolution: "postcss-modules-values@npm:4.0.0" @@ -24539,7 +22973,7 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.0, postcss-selector-parser@npm:^6.0.10, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.6, postcss-selector-parser@npm:^6.0.9": +"postcss-selector-parser@npm:^6.0.10, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.6, postcss-selector-parser@npm:^6.0.9": version: 6.0.11 resolution: "postcss-selector-parser@npm:6.0.11" dependencies: @@ -24579,7 +23013,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^7.0.14, postcss@npm:^7.0.26, postcss@npm:^7.0.32, postcss@npm:^7.0.35, postcss@npm:^7.0.36, postcss@npm:^7.0.5, postcss@npm:^7.0.6": +"postcss@npm:^7.0.35": version: 7.0.39 resolution: "postcss@npm:7.0.39" dependencies: @@ -24589,14 +23023,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.2.15, postcss@npm:^8.3.5, postcss@npm:^8.4.12, postcss@npm:^8.4.14, postcss@npm:^8.4.23, postcss@npm:^8.4.4, postcss@npm:^8.4.7": - version: 8.4.24 - resolution: "postcss@npm:8.4.24" +"postcss@npm:^8.3.5, postcss@npm:^8.4.12, postcss@npm:^8.4.14, postcss@npm:^8.4.21, postcss@npm:^8.4.23, postcss@npm:^8.4.4": + version: 8.4.27 + resolution: "postcss@npm:8.4.27" dependencies: nanoid: ^3.3.6 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: 814e2126dacfea313588eda09cc99a9b4c26ec55c059188aa7a916d20d26d483483106dc5ff9e560731b59f45c5bb91b945dfadc670aed875cc90ddbbf4e787d + checksum: 1cdd0c298849df6cd65f7e646a3ba36870a37b65f55fd59d1a165539c263e9b4872a402bf4ed1ca1bc31f58b68b2835545e33ea1a23b161a1f8aa6d5ded81e78 languageName: node linkType: hard @@ -24644,21 +23078,12 @@ __metadata: languageName: node linkType: hard -"prettier@npm:>=2.2.1 <=2.3.0": - version: 2.3.0 - resolution: "prettier@npm:2.3.0" +"prettier@npm:^2.6.2, prettier@npm:^2.8.0, prettier@npm:^2.8.6": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" bin: prettier: bin-prettier.js - checksum: e8851a45f60f2994775f96e07964646c299b8a8f9c64da4fbd8efafc20db3458bdcedac79aed34e1d5477540b3aa04f6499adc4979cb7937f8ebd058a767d8ff - languageName: node - linkType: hard - -"prettier@npm:^2.6.2, prettier@npm:^2.8.6": - version: 2.8.6 - resolution: "prettier@npm:2.8.6" - bin: - prettier: bin-prettier.js - checksum: 8ac94fa67aec0e65743ea15ebf954ef2f1e52638abd129dc04e8b49e8bb3224c0233c98df6b5c98efd31bd2a43866590486559438ee4ead09dc81be389068572 + checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8 languageName: node linkType: hard @@ -24669,16 +23094,6 @@ __metadata: languageName: node linkType: hard -"pretty-error@npm:^2.1.1": - version: 2.1.2 - resolution: "pretty-error@npm:2.1.2" - dependencies: - lodash: ^4.17.20 - renderkid: ^2.0.4 - checksum: 16775d06f9a695d17103414d610b1281f9535ee1f2da1ce1e1b9be79584a114aa7eac6dcdcc5ef151756d3c014dfd4ac1c7303ed8016d0cec12437cfdf4021c6 - languageName: node - linkType: hard - "pretty-error@npm:^4.0.0": version: 4.0.0 resolution: "pretty-error@npm:4.0.0" @@ -24763,7 +23178,7 @@ __metadata: languageName: node linkType: hard -"progress@npm:^2.0.3": +"progress@npm:^2.0.1, progress@npm:^2.0.3": version: 2.0.3 resolution: "progress@npm:2.0.3" checksum: f67403fe7b34912148d9252cb7481266a354bd99ce82c835f79070643bb3c6583d10dbcfda4d41e04bbc1d8437e9af0fb1e1f2135727878f5308682a579429b7 @@ -24794,31 +23209,6 @@ __metadata: languageName: node linkType: hard -"promise.allsettled@npm:^1.0.0": - version: 1.0.6 - resolution: "promise.allsettled@npm:1.0.6" - dependencies: - array.prototype.map: ^1.0.5 - call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - get-intrinsic: ^1.1.3 - iterate-value: ^1.0.2 - checksum: 5de80c33f41b23387be49229e47ade2fbeb86ad9b2066e5e093c21dbd5a3e7a8e4eb8e420cbf58386e2af976cc4677950092f855b677b16771191599f493d035 - languageName: node - linkType: hard - -"promise.prototype.finally@npm:^3.1.0": - version: 3.1.4 - resolution: "promise.prototype.finally@npm:3.1.4" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - checksum: 116556f16e5af74a1be0faf0b76e05fc6592bf74e66c6babbba7094f89887b771691f13236d2ffcf0f8d28ee1048808ccee8f70754c4cb5b3736314fbfadc32b - languageName: node - linkType: hard - "promise@npm:^7.1.1": version: 7.3.1 resolution: "promise@npm:7.3.1" @@ -24847,7 +23237,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.0.0, prop-types@npm:^15.5.0, prop-types@npm:^15.5.10, prop-types@npm:^15.5.4, prop-types@npm:^15.5.8, prop-types@npm:^15.6.0, prop-types@npm:^15.6.1, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.5.0, prop-types@npm:^15.5.10, prop-types@npm:^15.5.4, prop-types@npm:^15.5.8, prop-types@npm:^15.6.0, prop-types@npm:^15.6.1, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -24858,7 +23248,7 @@ __metadata: languageName: node linkType: hard -"property-information@npm:^5.0.0, property-information@npm:^5.3.0": +"property-information@npm:^5.0.0": version: 5.6.0 resolution: "property-information@npm:5.6.0" dependencies: @@ -24898,7 +23288,7 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:^1.1.0": +"proxy-from-env@npm:^1.0.0, proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 @@ -24949,6 +23339,16 @@ __metadata: languageName: node linkType: hard +"pump@npm:^2.0.0": + version: 2.0.1 + resolution: "pump@npm:2.0.1" + dependencies: + end-of-stream: ^1.1.0 + once: ^1.3.1 + checksum: e9f26a17be00810bff37ad0171edb35f58b242487b0444f92fb7d78bc7d61442fa9b9c5bd93a43fd8fd8ddd3cc75f1221f5e04c790f42907e5baab7cf5e2b931 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0" @@ -24959,14 +23359,18 @@ __metadata: languageName: node linkType: hard -"punycode@npm:1.3.2": - version: 1.3.2 - resolution: "punycode@npm:1.3.2" - checksum: b8807fd594b1db33335692d1f03e8beeddde6fda7fbb4a2e32925d88d20a3aa4cd8dcc0c109ccaccbd2ba761c208dfaaada83007087ea8bfb0129c9ef1b99ed6 +"pumpify@npm:^1.3.3": + version: 1.5.1 + resolution: "pumpify@npm:1.5.1" + dependencies: + duplexify: ^3.6.0 + inherits: ^2.0.3 + pump: ^2.0.0 + checksum: 26ca412ec8d665bd0d5e185c1b8f627728eff603440d75d22a58e421e3c66eaf86ec6fc6a6efc54808ecef65979279fa8e99b109a23ec1fa8d79f37e6978c9bd languageName: node linkType: hard -"punycode@npm:^1.3.2": +"punycode@npm:^1.3.2, punycode@npm:^1.4.1": version: 1.4.1 resolution: "punycode@npm:1.4.1" checksum: fa6e698cb53db45e4628559e557ddaf554103d2a96a1d62892c8f4032cd3bc8871796cae9eabc1bc700e2b6677611521ce5bb1d9a27700086039965d0cf34518 @@ -24989,6 +23393,24 @@ __metadata: languageName: node linkType: hard +"puppeteer-core@npm:^2.1.1": + version: 2.1.1 + resolution: "puppeteer-core@npm:2.1.1" + dependencies: + "@types/mime-types": ^2.1.0 + debug: ^4.1.0 + extract-zip: ^1.6.6 + https-proxy-agent: ^4.0.0 + mime: ^2.0.3 + mime-types: ^2.1.25 + progress: ^2.0.1 + proxy-from-env: ^1.0.0 + rimraf: ^2.6.1 + ws: ^6.1.0 + checksum: 2ddb597ef1b2d162b4aa49833b977734129edf7c8fa558fc38c59d273e79aa1bd079481c642de87f7163665f7f37aa52683da2716bafb7d3cab68c262c36ec28 + languageName: node + linkType: hard + "pure-color@npm:^1.2.0": version: 1.3.0 resolution: "pure-color@npm:1.3.0" @@ -25035,10 +23457,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:~6.5.2": - version: 6.5.3 - resolution: "qs@npm:6.5.3" - checksum: 6f20bf08cabd90c458e50855559539a28d00b2f2e7dddcb66082b16a43188418cb3cb77cbd09268bcef6022935650f0534357b8af9eeb29bf0f27ccb17655692 +"qs@npm:~6.10.3": + version: 6.10.4 + resolution: "qs@npm:6.10.4" + dependencies: + side-channel: ^1.0.4 + checksum: 31e4fedd759d01eae52dde6692abab175f9af3e639993c5caaa513a2a3607b34d8058d3ae52ceeccf37c3025f22ed5e90e9ddd6c2537e19c0562ddd10dc5b1eb languageName: node linkType: hard @@ -25049,13 +23473,6 @@ __metadata: languageName: node linkType: hard -"querystring@npm:0.2.0": - version: 0.2.0 - resolution: "querystring@npm:0.2.0" - checksum: 8258d6734f19be27e93f601758858c299bdebe71147909e367101ba459b95446fbe5b975bf9beb76390156a592b6f4ac3a68b6087cea165c259705b8b4e56a69 - languageName: node - linkType: hard - "queue-lit@npm:^1.5.0": version: 1.5.0 resolution: "queue-lit@npm:1.5.0" @@ -25100,6 +23517,13 @@ __metadata: languageName: node linkType: hard +"ramda@npm:0.29.0": + version: 0.29.0 + resolution: "ramda@npm:0.29.0" + checksum: 9ab26c06eb7545cbb7eebcf75526d6ee2fcaae19e338f165b2bf32772121e7b28192d6664d1ba222ff76188ba26ab307342d66e805dbb02c860560adc4d5dd57 + languageName: node + linkType: hard + "ramda@npm:^0.25.0": version: 0.25.0 resolution: "ramda@npm:0.25.0" @@ -25107,13 +23531,6 @@ __metadata: languageName: node linkType: hard -"ramda@npm:^0.28.0": - version: 0.28.0 - resolution: "ramda@npm:0.28.0" - checksum: 44ea6e5010bba70151b6a92d8114a91915e8b5a16105cce65fae58c9d7386b812c429645e35f21141d7087568550ce383bc10ee1a65cdec951f4b69ea457e6a4 - languageName: node - linkType: hard - "randexp@npm:0.4.6": version: 0.4.6 resolution: "randexp@npm:0.4.6" @@ -25396,16 +23813,6 @@ __metadata: languageName: node linkType: hard -"react-animate-height@npm:^3.0.5": - version: 3.1.1 - resolution: "react-animate-height@npm:3.1.1" - peerDependencies: - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 0f22eb1d9c2d2fd650a462da3db5aabcbde5f62a828053f953e17f7e65118c04acfb035408ce89ee48dc8289fcee8503c7a64e353e5e9568ea7659ab950497ec - languageName: node - linkType: hard - "react-app-polyfill@npm:^1.0.6": version: 1.0.6 resolution: "react-app-polyfill@npm:1.0.6" @@ -25483,6 +23890,16 @@ __metadata: languageName: node linkType: hard +"react-colorful@npm:^5.1.2": + version: 5.6.1 + resolution: "react-colorful@npm:5.6.1" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: e432b7cb0df57e8f0bcdc3b012d2e93fcbcb6092c9e0f85654788d5ebfc4442536d8cc35b2418061ba3c4afb8b7788cc101c606d86a1732407921de7a9244c8d + languageName: node + linkType: hard + "react-custom-scrollbars@npm:^4.2.1": version: 4.2.1 resolution: "react-custom-scrollbars@npm:4.2.1" @@ -25605,7 +24022,7 @@ __metadata: languageName: node linkType: hard -"react-docgen-typescript@npm:^2.1.1, react-docgen-typescript@npm:^2.2.2": +"react-docgen-typescript@npm:^2.2.2": version: 2.2.2 resolution: "react-docgen-typescript@npm:2.2.2" peerDependencies: @@ -25657,17 +24074,17 @@ __metadata: languageName: node linkType: hard -"react-element-to-jsx-string@npm:^14.3.4": - version: 14.3.4 - resolution: "react-element-to-jsx-string@npm:14.3.4" +"react-element-to-jsx-string@npm:^15.0.0": + version: 15.0.0 + resolution: "react-element-to-jsx-string@npm:15.0.0" dependencies: "@base2/pretty-print-object": 1.0.1 is-plain-object: 5.0.0 - react-is: 17.0.2 + react-is: 18.1.0 peerDependencies: - react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 - react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 - checksum: 42bcd4423f12e9ee21b2d3f0c2a28805ff4953bd82b6be4c1f5b5f9a371115aafa36a6f3d82726d43b4912179b79e99550c2b9a772c7fe6a5cd8f7e93ff34ceb + react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 + react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 + checksum: c3907cc4c1d3e9ecc8ca7727058ebcba6ec89848d9e07bfd2c77ee8f28f1ad99bf55e38359dec8a1125de83d41ac09a2874f53c41415edc86ffa9840fa1b7856 languageName: node linkType: hard @@ -25771,16 +24188,12 @@ __metadata: languageName: node linkType: hard -"react-inspector@npm:^5.1.0": - version: 5.1.1 - resolution: "react-inspector@npm:5.1.1" - dependencies: - "@babel/runtime": ^7.0.0 - is-dom: ^1.0.0 - prop-types: ^15.0.0 +"react-inspector@npm:^6.0.0": + version: 6.0.2 + resolution: "react-inspector@npm:6.0.2" peerDependencies: - react: ^16.8.4 || ^17.0.0 - checksum: ca9e4c1fedb94e4e956dd3142838c5a25a9d61375aee5e8a74dd623bae09a263098a93f220e8d84c7fd39e569e1fa4297d363ddbc91b15bca91baeb7281d7f4f + react: ^16.8.4 || ^17.0.0 || ^18.0.0 + checksum: dab7a7daf570c283fdc5d4e07ee8941ee8670af698ab5a27a704602b248e29ab911b117310d64c30a4af93931b2d6ee2a729369e3f5ab7f02df4651692e195a5 languageName: node linkType: hard @@ -25814,10 +24227,10 @@ __metadata: languageName: node linkType: hard -"react-is@npm:17.0.2, react-is@npm:^17.0.1": - version: 17.0.2 - resolution: "react-is@npm:17.0.2" - checksum: 9d6d111d8990dc98bc5402c1266a808b0459b5d54830bbea24c12d908b536df7883f268a7868cfaedde3dd9d4e0d574db456f84d2e6df9c4526f99bb4b5344d8 +"react-is@npm:18.1.0": + version: 18.1.0 + resolution: "react-is@npm:18.1.0" + checksum: d206a0fe6790851bff168727bfb896de02c5591695afb0c441163e8630136a3e13ee1a7ddd59fdccddcc93968b4721ae112c10f790b194b03b35a3dc13a355ef languageName: node linkType: hard @@ -25828,6 +24241,13 @@ __metadata: languageName: node linkType: hard +"react-is@npm:^17.0.1": + version: 17.0.2 + resolution: "react-is@npm:17.0.2" + checksum: 9d6d111d8990dc98bc5402c1266a808b0459b5d54830bbea24c12d908b536df7883f268a7868cfaedde3dd9d4e0d574db456f84d2e6df9c4526f99bb4b5344d8 + languageName: node + linkType: hard + "react-is@npm:^18.0.0": version: 18.2.0 resolution: "react-is@npm:18.2.0" @@ -25873,13 +24293,6 @@ __metadata: languageName: node linkType: hard -"react-merge-refs@npm:^1.0.0": - version: 1.1.0 - resolution: "react-merge-refs@npm:1.1.0" - checksum: 90884352999002d868ab9f1bcfe3222fb0f2178ed629f1da7e98e5a9b02a2c96b4aa72800db92aabd69d2483211b4be57a2088e89a11a0b660e7ada744d4ddf7 - languageName: node - linkType: hard - "react-modal@npm:^3.15.1": version: 3.15.1 resolution: "react-modal@npm:3.15.1" @@ -25944,20 +24357,6 @@ __metadata: languageName: node linkType: hard -"react-popper-tooltip@npm:^4.4.2": - version: 4.4.2 - resolution: "react-popper-tooltip@npm:4.4.2" - dependencies: - "@babel/runtime": ^7.18.3 - "@popperjs/core": ^2.11.5 - react-popper: ^2.3.0 - peerDependencies: - react: ">=16.6.0" - react-dom: ">=16.6.0" - checksum: 516988b9258f05fe8f48d702654d70c3701d9a730c10a07c2b5229193322b985478fad7033092c8f0449d83e77aa536d2993747609206208ed6f6b014b98acb0 - languageName: node - linkType: hard - "react-popper@npm:^1.3.7": version: 1.3.11 resolution: "react-popper@npm:1.3.11" @@ -26314,16 +24713,16 @@ __metadata: linkType: hard "react-test-renderer@npm:^16.11.0": - version: 16.13.1 - resolution: "react-test-renderer@npm:16.13.1" + version: 16.14.0 + resolution: "react-test-renderer@npm:16.14.0" dependencies: object-assign: ^4.1.1 prop-types: ^15.6.2 react-is: ^16.8.6 scheduler: ^0.19.1 peerDependencies: - react: ^16.13.1 - checksum: fd89dc26b58f774753e2f92833ed5f1dc6e6cd8dfe9ce3021730618ff9cfd9bbc409e0d7109dcb11a65a6aa8eee9c30aca0d91a177203969793bc411426fd35d + react: ^16.14.0 + checksum: 96eb8a2566e67ebd246ef6e1b36d8c8498c68ebfdb94ca8399c19b4e3b73368caf0ffbe44767593e3499f2f58b4b5e57ba0565a47628048d2ab01b23a422724e languageName: node linkType: hard @@ -26487,16 +24886,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^1.0.1": - version: 1.0.1 - resolution: "read-pkg-up@npm:1.0.1" - dependencies: - find-up: ^1.0.0 - read-pkg: ^1.0.0 - checksum: d18399a0f46e2da32beb2f041edd0cda49d2f2cc30195a05c759ef3ed9b5e6e19ba1ad1bae2362bdec8c6a9f2c3d18f4d5e8c369e808b03d498d5781cb9122c7 - languageName: node - linkType: hard - "read-pkg-up@npm:^7.0.1": version: 7.0.1 resolution: "read-pkg-up@npm:7.0.1" @@ -26508,17 +24897,6 @@ __metadata: languageName: node linkType: hard -"read-pkg@npm:^1.0.0": - version: 1.1.0 - resolution: "read-pkg@npm:1.1.0" - dependencies: - load-json-file: ^1.0.0 - normalize-package-data: ^2.3.2 - path-type: ^1.0.0 - checksum: a0f5d5e32227ec8e6a028dd5c5134eab229768dcb7a5d9a41a284ed28ad4b9284fecc47383dc1593b5694f4de603a7ffaee84b738956b9b77e0999567485a366 - languageName: node - linkType: hard - "read-pkg@npm:^5.2.0": version: 5.2.0 resolution: "read-pkg@npm:5.2.0" @@ -26543,7 +24921,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:3, readable-stream@npm:^3.0.6, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0": +"readable-stream@npm:3, readable-stream@npm:^3.0.6, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -26554,7 +24932,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.6, readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.6, readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -26578,6 +24956,31 @@ __metadata: languageName: node linkType: hard +"recast@npm:^0.21.0": + version: 0.21.5 + resolution: "recast@npm:0.21.5" + dependencies: + ast-types: 0.15.2 + esprima: ~4.0.0 + source-map: ~0.6.1 + tslib: ^2.0.1 + checksum: 03cc7f57562238ba258d468be67bf7446ce7a707bc87a087891dad15afead46c36e9aaeedf2130e2ab5a465244a9c62bfd4127849761cf8f4085abe2f3e5f485 + languageName: node + linkType: hard + +"recast@npm:^0.23.1": + version: 0.23.3 + resolution: "recast@npm:0.23.3" + dependencies: + assert: ^2.0.0 + ast-types: ^0.16.1 + esprima: ~4.0.0 + source-map: ~0.6.1 + tslib: ^2.0.1 + checksum: b1340ab0a3a8e4bf206c6c7d54168f7019ed4138a53bc746df230c01f1b6672ce9d25dceb34896b6683622d3eede4e1f18b7d0b672f5aab54ba7762de949e317 + languageName: node + linkType: hard + "rechoir@npm:^0.8.0": version: 0.8.0 resolution: "rechoir@npm:0.8.0" @@ -26596,16 +24999,6 @@ __metadata: languageName: node linkType: hard -"redent@npm:^1.0.0": - version: 1.0.0 - resolution: "redent@npm:1.0.0" - dependencies: - indent-string: ^2.1.0 - strip-indent: ^1.0.1 - checksum: 2bb8f76fda9c9f44e26620047b0ba9dd1834b0a80309d0badcc23fdcf7bb27a7ca74e66b683baa0d4b8cb5db787f11be086504036d63447976f409dd3e73fd7d - languageName: node - linkType: hard - "redent@npm:^3.0.0": version: 3.0.0 resolution: "redent@npm:3.0.0" @@ -26733,7 +25126,7 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.13.11, regenerator-runtime@npm:^0.13.2, regenerator-runtime@npm:^0.13.3, regenerator-runtime@npm:^0.13.4, regenerator-runtime@npm:^0.13.7, regenerator-runtime@npm:^0.13.9": +"regenerator-runtime@npm:^0.13.11, regenerator-runtime@npm:^0.13.3, regenerator-runtime@npm:^0.13.4, regenerator-runtime@npm:^0.13.9": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 @@ -26749,16 +25142,6 @@ __metadata: languageName: node linkType: hard -"regex-not@npm:^1.0.0, regex-not@npm:^1.0.2": - version: 1.0.2 - resolution: "regex-not@npm:1.0.2" - dependencies: - extend-shallow: ^3.0.2 - safe-regex: ^1.1.0 - checksum: 3081403de79559387a35ef9d033740e41818a559512668cef3d12da4e8a29ef34ee13c8ed1256b07e27ae392790172e8a15c8a06b72962fd4550476cde3d8f77 - languageName: node - linkType: hard - "regex-parser@npm:^2.2.11": version: 2.2.11 resolution: "regex-parser@npm:2.2.11" @@ -26766,14 +25149,14 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.2.0, regexp.prototype.flags@npm:^1.4.3": - version: 1.4.3 - resolution: "regexp.prototype.flags@npm:1.4.3" +"regexp.prototype.flags@npm:^1.2.0, regexp.prototype.flags@npm:^1.4.3, regexp.prototype.flags@npm:^1.5.0": + version: 1.5.0 + resolution: "regexp.prototype.flags@npm:1.5.0" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.3 - functions-have-names: ^1.2.2 - checksum: 51228bae732592adb3ededd5e15426be25f289e9c4ef15212f4da73f4ec3919b6140806374b8894036a86020d054a8d2657d3fee6bb9b4d35d8939c20030b7a6 + define-properties: ^1.2.0 + functions-have-names: ^1.2.3 + checksum: c541687cdbdfff1b9a07f6e44879f82c66bbf07665f9a7544c5fd16acdb3ec8d1436caab01662d2fbcad403f3499d49ab0b77fbc7ef29ef961d98cc4bc9755b4 languageName: node linkType: hard @@ -26840,53 +25223,6 @@ __metadata: languageName: node linkType: hard -"remark-footnotes@npm:2.0.0": - version: 2.0.0 - resolution: "remark-footnotes@npm:2.0.0" - checksum: f2f87ffd6fe25892373c7164d6584a7cb03ab0ea4f186af493a73df519e24b72998a556e7f16cb996f18426cdb80556b95ff252769e252cf3ccba0fd2ca20621 - languageName: node - linkType: hard - -"remark-mdx@npm:1.6.22": - version: 1.6.22 - resolution: "remark-mdx@npm:1.6.22" - dependencies: - "@babel/core": 7.12.9 - "@babel/helper-plugin-utils": 7.10.4 - "@babel/plugin-proposal-object-rest-spread": 7.12.1 - "@babel/plugin-syntax-jsx": 7.12.1 - "@mdx-js/util": 1.6.22 - is-alphabetical: 1.0.4 - remark-parse: 8.0.3 - unified: 9.2.0 - checksum: 45e62f8a821c37261f94448d54f295de1c5c393f762ff96cd4d4b730715037fafeb6c89ef94adf6a10a09edfa72104afe1431b93b5ae5e40ce2a7677e133c3d9 - languageName: node - linkType: hard - -"remark-parse@npm:8.0.3": - version: 8.0.3 - resolution: "remark-parse@npm:8.0.3" - dependencies: - ccount: ^1.0.0 - collapse-white-space: ^1.0.2 - is-alphabetical: ^1.0.0 - is-decimal: ^1.0.0 - is-whitespace-character: ^1.0.0 - is-word-character: ^1.0.0 - markdown-escapes: ^1.0.0 - parse-entities: ^2.0.0 - repeat-string: ^1.5.4 - state-toggle: ^1.0.0 - trim: 0.0.1 - trim-trailing-lines: ^1.0.0 - unherit: ^1.0.4 - unist-util-remove-position: ^2.0.0 - vfile-location: ^3.0.0 - xtend: ^4.0.1 - checksum: 2dfea250e7606ddfc9e223b9f41e0b115c5c701be4bd35181beaadd46ee59816bc00aadc6085a420f8df00b991ada73b590ea7fd34ace14557de4a0a41805be5 - languageName: node - linkType: hard - "remark-slug@npm:^6.0.0": version: 6.1.0 resolution: "remark-slug@npm:6.1.0" @@ -26898,15 +25234,6 @@ __metadata: languageName: node linkType: hard -"remark-squeeze-paragraphs@npm:4.0.0": - version: 4.0.0 - resolution: "remark-squeeze-paragraphs@npm:4.0.0" - dependencies: - mdast-squeeze-paragraphs: ^4.0.0 - checksum: 2071eb74d0ecfefb152c4932690a9fd950c3f9f798a676f1378a16db051da68fb20bf288688cc153ba5019dded35408ff45a31dfe9686eaa7a9f1df9edbb6c81 - languageName: node - linkType: hard - "remixicon-react@npm:^1.0.0": version: 1.0.0 resolution: "remixicon-react@npm:1.0.0" @@ -26916,26 +25243,6 @@ __metadata: languageName: node linkType: hard -"remove-trailing-separator@npm:^1.0.1": - version: 1.1.0 - resolution: "remove-trailing-separator@npm:1.1.0" - checksum: d3c20b5a2d987db13e1cca9385d56ecfa1641bae143b620835ac02a6b70ab88f68f117a0021838db826c57b31373d609d52e4f31aca75fc490c862732d595419 - languageName: node - linkType: hard - -"renderkid@npm:^2.0.4": - version: 2.0.7 - resolution: "renderkid@npm:2.0.7" - dependencies: - css-select: ^4.1.3 - dom-converter: ^0.2.0 - htmlparser2: ^6.1.0 - lodash: ^4.17.21 - strip-ansi: ^3.0.1 - checksum: d3d7562531fb8104154d4aa6aa977707783616318014088378a6c5bbc36318ada9289543d380ede707e531b7f5b96229e87d1b8944f675e5ec3686e62692c7c7 - languageName: node - linkType: hard - "renderkid@npm:^3.0.0": version: 3.0.0 resolution: "renderkid@npm:3.0.0" @@ -26949,29 +25256,6 @@ __metadata: languageName: node linkType: hard -"repeat-element@npm:^1.1.2": - version: 1.1.4 - resolution: "repeat-element@npm:1.1.4" - checksum: 1edd0301b7edad71808baad226f0890ba709443f03a698224c9ee4f2494c317892dc5211b2ba8cbea7194a9ddbcac01e283bd66de0467ab24ee1fc1a3711d8a9 - languageName: node - linkType: hard - -"repeat-string@npm:^1.5.4, repeat-string@npm:^1.6.1": - version: 1.6.1 - resolution: "repeat-string@npm:1.6.1" - checksum: 1b809fc6db97decdc68f5b12c4d1a671c8e3f65ec4a40c238bc5200e44e85bcc52a54f78268ab9c29fcf5fe4f1343e805420056d1f30fa9a9ee4c2d93e3cc6c0 - languageName: node - linkType: hard - -"repeating@npm:^2.0.0": - version: 2.0.1 - resolution: "repeating@npm:2.0.1" - dependencies: - is-finite: ^1.0.0 - checksum: d2db0b69c5cb0c14dd750036e0abcd6b3c3f7b2da3ee179786b755cf737ca15fa0fff417ca72de33d6966056f4695440e680a352401fc02c95ade59899afbdd0 - languageName: node - linkType: hard - "request-progress@npm:^3.0.0": version: 3.0.0 resolution: "request-progress@npm:3.0.0" @@ -27112,13 +25396,6 @@ __metadata: languageName: node linkType: hard -"resolve-url@npm:^0.2.1": - version: 0.2.1 - resolution: "resolve-url@npm:0.2.1" - checksum: 7b7035b9ed6e7bc7d289e90aef1eab5a43834539695dac6416ca6e91f1a94132ae4796bbd173cdacfdc2ade90b5f38a3fb6186bebc1b221cd157777a23b9ad14 - languageName: node - linkType: hard - "resolve.exports@npm:^1.1.0": version: 1.1.0 resolution: "resolve.exports@npm:1.1.0" @@ -27133,7 +25410,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.4, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0, resolve@npm:^1.3.2, resolve@npm:^1.4.0": +"resolve@npm:^1.1.4, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0, resolve@npm:^1.4.0": version: 1.22.3 resolution: "resolve@npm:1.22.3" dependencies: @@ -27156,7 +25433,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.4#~builtin, resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.13.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@^1.3.2#~builtin, resolve@patch:resolve@^1.4.0#~builtin": +"resolve@patch:resolve@^1.1.4#~builtin, resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.13.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@^1.4.0#~builtin": version: 1.22.3 resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin::version=1.22.3&hash=c3c19d" dependencies: @@ -27243,7 +25520,7 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^2.6.2": +"rimraf@npm:^2.6.1, rimraf@npm:^2.6.2": version: 2.7.1 resolution: "rimraf@npm:2.7.1" dependencies: @@ -27265,6 +25542,17 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:~2.6.2": + version: 2.6.3 + resolution: "rimraf@npm:2.6.3" + dependencies: + glob: ^7.1.3 + bin: + rimraf: ./bin.js + checksum: 3ea587b981a19016297edb96d1ffe48af7e6af69660e3b371dbfc73722a73a0b0e9be5c88089fbeeb866c389c1098e07f64929c7414290504b855f54f901ab10 + languageName: node + linkType: hard + "ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": version: 2.0.2 resolution: "ripemd160@npm:2.0.2" @@ -27340,13 +25628,6 @@ __metadata: languageName: node linkType: hard -"rsvp@npm:^4.8.4": - version: 4.8.5 - resolution: "rsvp@npm:4.8.5" - checksum: 2d8ef30d8febdf05bdf856ccca38001ae3647e41835ca196bc1225333f79b94ae44def733121ca549ccc36209c9b689f6586905e2a043873262609744da8efc1 - languageName: node - linkType: hard - "run-async@npm:^2.4.0": version: 2.4.1 resolution: "run-async@npm:2.4.1" @@ -27413,15 +25694,6 @@ __metadata: languageName: node linkType: hard -"safe-regex@npm:^1.1.0": - version: 1.1.0 - resolution: "safe-regex@npm:1.1.0" - dependencies: - ret: ~0.1.10 - checksum: 9a8bba57c87a841f7997b3b951e8e403b1128c1a4fd1182f40cc1a20e2d490593d7c2a21030fadfea320c8e859219019e136f678c6689ed5960b391b822f01d5 - languageName: node - linkType: hard - "safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -27429,25 +25701,6 @@ __metadata: languageName: node linkType: hard -"sane@npm:^4.0.3": - version: 4.1.0 - resolution: "sane@npm:4.1.0" - dependencies: - "@cnakazawa/watch": ^1.0.3 - anymatch: ^2.0.0 - capture-exit: ^2.0.0 - exec-sh: ^0.3.2 - execa: ^1.0.0 - fb-watchman: ^2.0.0 - micromatch: ^3.1.4 - minimist: ^1.1.1 - walker: ~1.0.5 - bin: - sane: ./src/cli.js - checksum: 97716502d456c0d38670a902a4ea943d196dcdf998d1e40532d8f3e24e25d7eddfd4c3579025a1eee8eac09a48dfd05fba61a2156c56704e7feaa450eb249f7c - languageName: node - linkType: hard - "sanitize.css@npm:*": version: 13.0.0 resolution: "sanitize.css@npm:13.0.0" @@ -27534,7 +25787,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^2.6.5, schema-utils@npm:^2.7.0": +"schema-utils@npm:^2.6.5": version: 2.7.1 resolution: "schema-utils@npm:2.7.1" dependencies: @@ -27602,7 +25855,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0, semver@npm:^5.6.0": version: 5.7.1 resolution: "semver@npm:5.7.1" bin: @@ -27611,23 +25864,32 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.x, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8": - version: 7.3.8 - resolution: "semver@npm:7.3.8" +"semver@npm:7.x, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3": + version: 7.5.4 + resolution: "semver@npm:7.5.4" dependencies: lru-cache: ^6.0.0 bin: semver: bin/semver.js - checksum: ba9c7cbbf2b7884696523450a61fee1a09930d888b7a8d7579025ad93d459b2d1949ee5bbfeb188b2be5f4ac163544c5e98491ad6152df34154feebc2cc337c1 + checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.1.1, semver@npm:^6.1.2, semver@npm:^6.2.0, semver@npm:^6.3.0": - version: 6.3.0 - resolution: "semver@npm:6.3.0" +"semver@npm:^6.0.0, semver@npm:^6.1.1, semver@npm:^6.1.2, semver@npm:^6.2.0, semver@npm:^6.3.0, semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" bin: - semver: ./bin/semver.js - checksum: 1b26ecf6db9e8292dd90df4e781d91875c0dcc1b1909e70f5d12959a23c7eebb8f01ea581c00783bbee72ceeaad9505797c381756326073850dc36ed284b21b9 + semver: bin/semver.js + checksum: ae47d06de28836adb9d3e25f22a92943477371292d9b665fb023fae278d345d508ca1958232af086d85e0155aee22e313e100971898bbb8d5d89b8b1d4054ca2 + languageName: node + linkType: hard + +"semver@npm:~7.0.0": + version: 7.0.0 + resolution: "semver@npm:7.0.0" + bin: + semver: bin/semver.js + checksum: 272c11bf8d083274ef79fe40a81c55c184dff84dd58e3c325299d0927ba48cece1f020793d138382b85f89bab5002a35a5ba59a3a68a7eebbb597eb733838778 languageName: node linkType: hard @@ -27672,21 +25934,12 @@ __metadata: languageName: node linkType: hard -"serialize-javascript@npm:^5.0.1": - version: 5.0.1 - resolution: "serialize-javascript@npm:5.0.1" +"serialize-javascript@npm:^6.0.0, serialize-javascript@npm:^6.0.1": + version: 6.0.1 + resolution: "serialize-javascript@npm:6.0.1" dependencies: randombytes: ^2.1.0 - checksum: bb45a427690c3d2711e28499de0fbf25036af1e23c63c6a9237ed0aa572fd0941fcdefe50a2dccf26d9df8c8b86ae38659e19d8ba7afd3fbc1f1c7539a2a48d2 - languageName: node - linkType: hard - -"serialize-javascript@npm:^6.0.0": - version: 6.0.0 - resolution: "serialize-javascript@npm:6.0.0" - dependencies: - randombytes: ^2.1.0 - checksum: 56f90b562a1bdc92e55afb3e657c6397c01a902c588c0fe3d4c490efdcc97dcd2a3074ba12df9e94630f33a5ce5b76a74784a7041294628a6f4306e0ec84bf93 + checksum: 3c4f4cb61d0893b988415bdb67243637333f3f574e9e9cc9a006a2ced0b390b0b3b44aef8d51c951272a9002ec50885eefdc0298891bc27eb2fe7510ea87dc4f languageName: node linkType: hard @@ -27744,18 +25997,6 @@ __metadata: languageName: node linkType: hard -"set-value@npm:^2.0.0, set-value@npm:^2.0.1": - version: 2.0.1 - resolution: "set-value@npm:2.0.1" - dependencies: - extend-shallow: ^2.0.1 - is-extendable: ^0.1.1 - is-plain-object: ^2.0.3 - split-string: ^3.0.1 - checksum: 09a4bc72c94641aeae950eb60dc2755943b863780fcc32e441eda964b64df5e3f50603d5ebdd33394ede722528bd55ed43aae26e9df469b4d32e2292b427b601 - languageName: node - linkType: hard - "setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" @@ -27906,6 +26147,13 @@ __metadata: languageName: node linkType: hard +"signal-exit@npm:^4.0.1": + version: 4.0.2 + resolution: "signal-exit@npm:4.0.2" + checksum: 41f5928431cc6e91087bf0343db786a6313dd7c6fd7e551dbc141c95bb5fb26663444fd9df8ea47c5d7fc202f60aa7468c3162a9365cbb0615fc5e1b1328fe31 + languageName: node + linkType: hard + "simple-concat@npm:^1.0.0": version: 1.0.1 resolution: "simple-concat@npm:1.0.1" @@ -27913,6 +26161,15 @@ __metadata: languageName: node linkType: hard +"simple-update-notifier@npm:^1.0.0": + version: 1.1.0 + resolution: "simple-update-notifier@npm:1.1.0" + dependencies: + semver: ~7.0.0 + checksum: 1012e9b6c504e559a948078177b3eedbb9d7e4d15878e2bda56314d08db609ca5da485be4ac9f838759faae8057935ee0246fcdf63f1233c86bd9fecb2a5544b + languageName: node + linkType: hard + "simplebar-react@npm:^2.4.3": version: 2.4.3 resolution: "simplebar-react@npm:2.4.3" @@ -28035,42 +26292,6 @@ __metadata: languageName: node linkType: hard -"snapdragon-node@npm:^2.0.1": - version: 2.1.1 - resolution: "snapdragon-node@npm:2.1.1" - dependencies: - define-property: ^1.0.0 - isobject: ^3.0.0 - snapdragon-util: ^3.0.1 - checksum: 9bb57d759f9e2a27935dbab0e4a790137adebace832b393e350a8bf5db461ee9206bb642d4fe47568ee0b44080479c8b4a9ad0ebe3712422d77edf9992a672fd - languageName: node - linkType: hard - -"snapdragon-util@npm:^3.0.1": - version: 3.0.1 - resolution: "snapdragon-util@npm:3.0.1" - dependencies: - kind-of: ^3.2.0 - checksum: 684997dbe37ec995c03fd3f412fba2b711fc34cb4010452b7eb668be72e8811a86a12938b511e8b19baf853b325178c56d8b78d655305e5cfb0bb8b21677e7b7 - languageName: node - linkType: hard - -"snapdragon@npm:^0.8.1": - version: 0.8.2 - resolution: "snapdragon@npm:0.8.2" - dependencies: - base: ^0.11.1 - debug: ^2.2.0 - define-property: ^0.2.5 - extend-shallow: ^2.0.1 - map-cache: ^0.2.2 - source-map: ^0.5.6 - source-map-resolve: ^0.5.0 - use: ^3.1.0 - checksum: a197f242a8f48b11036563065b2487e9b7068f50a20dd81d9161eca6af422174fc158b8beeadbe59ce5ef172aa5718143312b3aebaae551c124b7824387c8312 - languageName: node - linkType: hard - "socket.io-adapter@npm:^2.4.0, socket.io-adapter@npm:~2.5.2": version: 2.5.2 resolution: "socket.io-adapter@npm:2.5.2" @@ -28184,19 +26405,6 @@ __metadata: languageName: node linkType: hard -"source-map-resolve@npm:^0.5.0": - version: 0.5.3 - resolution: "source-map-resolve@npm:0.5.3" - dependencies: - atob: ^2.1.2 - decode-uri-component: ^0.2.0 - resolve-url: ^0.2.1 - source-map-url: ^0.4.0 - urix: ^0.1.0 - checksum: c73fa44ac00783f025f6ad9e038ab1a2e007cd6a6b86f47fe717c3d0765b4a08d264f6966f3bd7cd9dbcd69e4832783d5472e43247775b2a550d6f2155d24bae - languageName: node - linkType: hard - "source-map-resolve@npm:^0.6.0": version: 0.6.0 resolution: "source-map-resolve@npm:0.6.0" @@ -28217,7 +26425,7 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:^0.5.16, source-map-support@npm:^0.5.19, source-map-support@npm:^0.5.6, source-map-support@npm:^0.5.9, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.20": +"source-map-support@npm:^0.5.16, source-map-support@npm:^0.5.19, source-map-support@npm:^0.5.6, source-map-support@npm:^0.5.9, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -28227,13 +26435,6 @@ __metadata: languageName: node linkType: hard -"source-map-url@npm:^0.4.0": - version: 0.4.1 - resolution: "source-map-url@npm:0.4.1" - checksum: 64c5c2c77aff815a6e61a4120c309ae4cac01298d9bcbb3deb1b46a4dd4c46d4a1eaeda79ec9f684766ae80e8dc86367b89326ce9dd2b89947bd9291fc1ac08c - languageName: node - linkType: hard - "source-map@npm:0.6.1, source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -28241,7 +26442,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.0, source-map@npm:^0.5.6, source-map@npm:^0.5.7, source-map@npm:~0.5.3": +"source-map@npm:^0.5.7, source-map@npm:~0.5.3": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d @@ -28346,15 +26547,6 @@ __metadata: languageName: node linkType: hard -"split-string@npm:^3.0.1, split-string@npm:^3.0.2": - version: 3.1.0 - resolution: "split-string@npm:3.1.0" - dependencies: - extend-shallow: ^3.0.0 - checksum: ae5af5c91bdc3633628821bde92fdf9492fa0e8a63cf6a0376ed6afde93c701422a1610916f59be61972717070119e848d10dfbbd5024b7729d6a71972d2a84c - languageName: node - linkType: hard - "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -28402,15 +26594,6 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^8.0.1": - version: 8.0.1 - resolution: "ssri@npm:8.0.1" - dependencies: - minipass: ^3.1.1 - checksum: bc447f5af814fa9713aa201ec2522208ae0f4d8f3bda7a1f445a797c7b929a02720436ff7c478fb5edc4045adb02b1b88d2341b436a80798734e2494f1067b36 - languageName: node - linkType: hard - "ssri@npm:^9.0.0": version: 9.0.1 resolution: "ssri@npm:9.0.1" @@ -28443,23 +26626,6 @@ __metadata: languageName: node linkType: hard -"state-toggle@npm:^1.0.0": - version: 1.0.3 - resolution: "state-toggle@npm:1.0.3" - checksum: 17398af928413e8d8b866cf0c81fd1b1348bb7d65d8983126ff6ff2317a80d6ee023484fba0c54d8169f5aa544f125434a650ae3a71eddc935cae307d4692b4f - languageName: node - linkType: hard - -"static-extend@npm:^0.1.1": - version: 0.1.2 - resolution: "static-extend@npm:0.1.2" - dependencies: - define-property: ^0.2.5 - object-copy: ^0.1.0 - checksum: 8657485b831f79e388a437260baf22784540417a9b29e11572c87735df24c22b84eda42107403a64b30861b2faf13df9f7fc5525d51f9d1d2303aba5cbf4e12c - languageName: node - linkType: hard - "statuses@npm:2.0.1, statuses@npm:^2.0.0": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -28483,53 +26649,22 @@ __metadata: languageName: node linkType: hard -"store2@npm:^2.12.0": +"store2@npm:^2.14.2": version: 2.14.2 resolution: "store2@npm:2.14.2" checksum: 6f270fc5bab99b63f45fcc7bd8b99c2714b4adf880f557ed7ffb5ed3987131251165bccde425a00928aaf044870aee79ddeef548576d093c68703ed2edec45d7 languageName: node linkType: hard -"storybook-addon-pseudo-states@npm:^1.15.2": - version: 1.15.2 - resolution: "storybook-addon-pseudo-states@npm:1.15.2" - peerDependencies: - "@storybook/addons": ^6.5.0 - "@storybook/api": ^6.5.0 - "@storybook/components": ^6.5.0 - "@storybook/core-events": ^6.5.0 - "@storybook/theming": ^6.5.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - checksum: 64d0fb698054961c1999585549631521ba0de63a01dd5bb27dcc0f519fa26d7ccaaad020feecb867a1087368b18505a060d9c229d43000ba8ba9f299079b1d38 - languageName: node - linkType: hard - -"storybook-color-picker@npm:^3.1.0": - version: 3.1.0 - resolution: "storybook-color-picker@npm:3.1.0" +"storybook@npm:^7.1.1": + version: 7.1.1 + resolution: "storybook@npm:7.1.1" dependencies: - "@emotion/react": ^11.10.5 - "@fortawesome/fontawesome-svg-core": ^6.2.1 - "@fortawesome/free-solid-svg-icons": ^6.2.1 - "@fortawesome/react-fontawesome": ^0.2.0 - "@storybook/addons": ^6.5.13 - "@storybook/api": ^6.5.13 - "@storybook/components": ^6.5.13 - "@storybook/theming": ^6.5.13 - chroma-js: ^2.1.2 - copy-to-clipboard: ^3.3.3 - pluralize: ^8.0.0 - react: ^17.0.2 - react-animate-height: ^3.0.5 - react-dom: ^17.0.2 - react-popper-tooltip: ^4.4.2 - checksum: 32122b2f6a86ffd81e56fbd0891b8fccf4fc9d5b90da482993b4991c40cf760e8194d8ab3a16ba506ff292cf6aef0750f416ae7583d4c3055a46871c826c84ec + "@storybook/cli": 7.1.1 + bin: + sb: ./index.js + storybook: ./index.js + checksum: df6fd3a75c93cc9e98ac3d383c58a7162f1a2b94436c4f072e359417305ae0b973cc3870872f313f39c9639c024f8897edbaa7aa35eff3d63a0e3066f200332a languageName: node linkType: hard @@ -28575,6 +26710,13 @@ __metadata: languageName: node linkType: hard +"stream-shift@npm:^1.0.0": + version: 1.0.1 + resolution: "stream-shift@npm:1.0.1" + checksum: 59b82b44b29ec3699b5519a49b3cedcc6db58c72fb40c04e005525dfdcab1c75c4e0c180b923c380f204bed78211b9bad8faecc7b93dece4d004c3f6ec75737b + languageName: node + linkType: hard + "stream-splicer@npm:^2.0.0": version: 2.0.1 resolution: "stream-splicer@npm:2.0.1" @@ -28649,6 +26791,17 @@ __metadata: languageName: node linkType: hard +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: ^8.0.0 + is-fullwidth-code-point: ^3.0.0 + strip-ansi: ^6.0.1 + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + "string-width@npm:^1.0.1": version: 1.0.2 resolution: "string-width@npm:1.0.2" @@ -28660,17 +26813,6 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": - version: 4.2.3 - resolution: "string-width@npm:4.2.3" - dependencies: - emoji-regex: ^8.0.0 - is-fullwidth-code-point: ^3.0.0 - strip-ansi: ^6.0.1 - checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb - languageName: node - linkType: hard - "string-width@npm:^3.0.0, string-width@npm:^3.1.0": version: 3.1.0 resolution: "string-width@npm:3.1.0" @@ -28682,7 +26824,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^5.0.0": +"string-width@npm:^5.0.0, string-width@npm:^5.0.1, string-width@npm:^5.1.2": version: 5.1.2 resolution: "string-width@npm:5.1.2" dependencies: @@ -28700,7 +26842,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.0 || ^3.0.1, string.prototype.matchall@npm:^4.0.6, string.prototype.matchall@npm:^4.0.7": +"string.prototype.matchall@npm:^4.0.6, string.prototype.matchall@npm:^4.0.7": version: 4.0.8 resolution: "string.prototype.matchall@npm:4.0.8" dependencies: @@ -28716,28 +26858,6 @@ __metadata: languageName: node linkType: hard -"string.prototype.padend@npm:^3.0.0": - version: 3.1.4 - resolution: "string.prototype.padend@npm:3.1.4" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - checksum: 76e07238fe31dc12177428f0436b7ed6985f6a7ba97470fd53e4f0a6d9860bfee127d81957f3073cc879b434233df143825d140581e1340278053ad993c92f6c - languageName: node - linkType: hard - -"string.prototype.padstart@npm:^3.0.0": - version: 3.1.4 - resolution: "string.prototype.padstart@npm:3.1.4" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - checksum: a8517d83fd4fc5832b85cd9621188156094392494983fa41f6e6e727ab6af20f6bf8b2aac43b97ffad94e21fa52f1bb21342e2f87b79965707fe174cff5b8b2b - languageName: node - linkType: hard - "string.prototype.trimend@npm:^1.0.6": version: 1.0.6 resolution: "string.prototype.trimend@npm:1.0.6" @@ -28796,6 +26916,15 @@ __metadata: languageName: node linkType: hard +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: ^5.0.1 + checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + languageName: node + linkType: hard + "strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1": version: 3.0.1 resolution: "strip-ansi@npm:3.0.1" @@ -28814,15 +26943,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": - version: 6.0.1 - resolution: "strip-ansi@npm:6.0.1" - dependencies: - ansi-regex: ^5.0.1 - checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c - languageName: node - linkType: hard - "strip-ansi@npm:^7.0.1": version: 7.0.1 resolution: "strip-ansi@npm:7.0.1" @@ -28832,15 +26952,6 @@ __metadata: languageName: node linkType: hard -"strip-bom@npm:^2.0.0": - version: 2.0.0 - resolution: "strip-bom@npm:2.0.0" - dependencies: - is-utf8: ^0.2.0 - checksum: 08efb746bc67b10814cd03d79eb31bac633393a782e3f35efbc1b61b5165d3806d03332a97f362822cf0d4dd14ba2e12707fcff44fe1c870c48a063a0c9e4944 - languageName: node - linkType: hard - "strip-bom@npm:^3.0.0": version: 3.0.0 resolution: "strip-bom@npm:3.0.0" @@ -28883,17 +26994,6 @@ __metadata: languageName: node linkType: hard -"strip-indent@npm:^1.0.1": - version: 1.0.1 - resolution: "strip-indent@npm:1.0.1" - dependencies: - get-stdin: ^4.0.1 - bin: - strip-indent: cli.js - checksum: 81ad9a0b8a558bdbd05b66c6c437b9ab364aa2b5479ed89969ca7908e680e21b043d40229558c434b22b3d640622e39b66288e0456d601981ac9289de9700fbd - languageName: node - linkType: hard - "strip-indent@npm:^3.0.0": version: 3.0.0 resolution: "strip-indent@npm:3.0.0" @@ -28912,7 +27012,7 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": +"strip-json-comments@npm:^3.0.1, strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 @@ -28926,30 +27026,6 @@ __metadata: languageName: node linkType: hard -"style-loader@npm:^1.3.0": - version: 1.3.0 - resolution: "style-loader@npm:1.3.0" - dependencies: - loader-utils: ^2.0.0 - schema-utils: ^2.7.0 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 1be9e8705307f5b8eb89e80f3703fa27296dccec349d790eace7aabe212f08c7c8f3ea6b6cb97bc53e82fbebfb9aa0689259671a8315f4655e24a850781e062a - languageName: node - linkType: hard - -"style-loader@npm:^2.0.0": - version: 2.0.0 - resolution: "style-loader@npm:2.0.0" - dependencies: - loader-utils: ^2.0.0 - schema-utils: ^3.0.0 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 21425246a5a8f14d1625a657a3a56f8a323193fa341a71af818a2ed2a429efa2385a328b4381cf2f12c2d0e6380801eb9e0427ed9c3a10ff95c86e383184d632 - languageName: node - linkType: hard - "style-loader@npm:^3.3.1": version: 3.3.1 resolution: "style-loader@npm:3.3.1" @@ -28959,15 +27035,6 @@ __metadata: languageName: node linkType: hard -"style-to-object@npm:0.3.0, style-to-object@npm:^0.3.0": - version: 0.3.0 - resolution: "style-to-object@npm:0.3.0" - dependencies: - inline-style-parser: 0.1.1 - checksum: 4d7084015207f2a606dfc10c29cb5ba569f2fe8005551df7396110dd694d6ff650f2debafa95bd5d147dfb4ca50f57868e2a7f91bf5d11ef734fe7ccbd7abf59 - languageName: node - linkType: hard - "styled-components@npm:6.0.2": version: 6.0.2 resolution: "styled-components@npm:6.0.2" @@ -29036,13 +27103,6 @@ __metadata: languageName: node linkType: hard -"stylis@npm:4.1.3": - version: 4.1.3 - resolution: "stylis@npm:4.1.3" - checksum: d04dbffcb9bf2c5ca8d8dc09534203c75df3bf711d33973ea22038a99cc475412a350b661ebd99cbc01daa50d7eedcf0d130d121800eb7318759a197023442a6 - languageName: node - linkType: hard - "stylis@npm:^4.3.0": version: 4.3.0 resolution: "stylis@npm:4.3.0" @@ -29194,6 +27254,16 @@ __metadata: languageName: node linkType: hard +"swc-loader@npm:^0.2.3": + version: 0.2.3 + resolution: "swc-loader@npm:0.2.3" + peerDependencies: + "@swc/core": ^1.2.147 + webpack: ">=2" + checksum: 010d84d399525c0185d36d62c86c55ae017e7a90046bc8a39be4b7e07526924037868049f6037bc966da98151cb2600934b96a66279b742d3c413a718b427251 + languageName: node + linkType: hard + "symbol-observable@npm:^1.2.0": version: 1.2.0 resolution: "symbol-observable@npm:1.2.0" @@ -29208,18 +27278,6 @@ __metadata: languageName: node linkType: hard -"symbol.prototype.description@npm:^1.0.0": - version: 1.0.5 - resolution: "symbol.prototype.description@npm:1.0.5" - dependencies: - call-bind: ^1.0.2 - get-symbol-description: ^1.0.0 - has-symbols: ^1.0.2 - object.getownpropertydescriptors: ^2.1.2 - checksum: 2bf20a5fbc74bdda7133e0915b978bf50bf5e2a48dd2174885ba6cd623d001ca18f7dbb1e01a3f3ea3a34f05030175ebee3dcb357f099a61af6e964f3281e9b9 - languageName: node - linkType: hard - "synchronous-promise@npm:^2.0.15": version: 2.0.17 resolution: "synchronous-promise@npm:2.0.17" @@ -29284,31 +27342,56 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^1.0.0, tapable@npm:^1.1.3": +"tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" checksum: 53ff4e7c3900051c38cc4faab428ebfd7e6ad0841af5a7ac6d5f3045c5b50e88497bfa8295b4b3fbcadd94993c9e358868b78b9fb249a76cb8b018ac8dccafd7 languageName: node linkType: hard -"tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0": +"tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": version: 2.2.1 resolution: "tapable@npm:2.2.1" checksum: 3b7a1b4d86fa940aad46d9e73d1e8739335efd4c48322cb37d073eb6f80f5281889bf0320c6d8ffcfa1a0dd5bfdbd0f9d037e252ef972aca595330538aac4d51 languageName: node linkType: hard -"tar@npm:^6.0.2, tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.1.13 - resolution: "tar@npm:6.1.13" +"tar-fs@npm:^2.1.1": + version: 2.1.1 + resolution: "tar-fs@npm:2.1.1" + dependencies: + chownr: ^1.1.1 + mkdirp-classic: ^0.5.2 + pump: ^3.0.0 + tar-stream: ^2.1.4 + checksum: f5b9a70059f5b2969e65f037b4e4da2daf0fa762d3d232ffd96e819e3f94665dbbbe62f76f084f1acb4dbdcce16c6e4dac08d12ffc6d24b8d76720f4d9cf032d + languageName: node + linkType: hard + +"tar-stream@npm:^2.1.4": + version: 2.2.0 + resolution: "tar-stream@npm:2.2.0" + dependencies: + bl: ^4.0.3 + end-of-stream: ^1.4.1 + fs-constants: ^1.0.0 + inherits: ^2.0.3 + readable-stream: ^3.1.1 + checksum: 699831a8b97666ef50021c767f84924cfee21c142c2eb0e79c63254e140e6408d6d55a065a2992548e72b06de39237ef2b802b99e3ece93ca3904a37622a66f3 + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.13, tar@npm:^6.1.2": + version: 6.1.15 + resolution: "tar@npm:6.1.15" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 - minipass: ^4.0.0 + minipass: ^5.0.0 minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: 8a278bed123aa9f53549b256a36b719e317c8b96fe86a63406f3c62887f78267cea9b22dc6f7007009738509800d4a4dccc444abd71d762287c90f35b002eb1c + checksum: f23832fceeba7578bf31907aac744ae21e74a66f4a17a9e94507acf460e48f6db598c7023882db33bab75b80e027c21f276d405e4a0322d58f51c7088d428268 languageName: node linkType: hard @@ -29328,19 +27411,12 @@ __metadata: languageName: node linkType: hard -"telejson@npm:^6.0.8": - version: 6.0.8 - resolution: "telejson@npm:6.0.8" +"telejson@npm:^7.0.3": + version: 7.1.0 + resolution: "telejson@npm:7.1.0" dependencies: - "@types/is-function": ^1.0.0 - global: ^4.4.0 - is-function: ^1.0.2 - is-regex: ^1.1.2 - is-symbol: ^1.0.3 - isobject: ^4.0.0 - lodash: ^4.17.21 memoizerific: ^1.11.3 - checksum: 7411a5e78a35720bd0654a544409d3ce467b1dbb2073c73f36476b4c0905d97dbf539d6cbae737bb1fd8c872c2058f2a5450163a15117ed3fa031b2a2b8b33f6 + checksum: 8000e43dc862a87ab1ca342a2635641923d55c2585f85ea8c7c60293681d6f920e8b9570cc12d90ecef286f065c176da5f769f42f4828ba18a626627bed1ac07 languageName: node linkType: hard @@ -29351,6 +27427,15 @@ __metadata: languageName: node linkType: hard +"temp@npm:^0.8.4": + version: 0.8.4 + resolution: "temp@npm:0.8.4" + dependencies: + rimraf: ~2.6.2 + checksum: f35bed78565355dfdf95f730b7b489728bd6b7e35071bcc6497af7c827fb6c111fbe9063afc7b8cbc19522a072c278679f9a0ee81e684aa2c8617cc0f2e9c191 + languageName: node + linkType: hard + "tempy@npm:^0.6.0": version: 0.6.0 resolution: "tempy@npm:0.6.0" @@ -29363,6 +27448,19 @@ __metadata: languageName: node linkType: hard +"tempy@npm:^1.0.1": + version: 1.0.1 + resolution: "tempy@npm:1.0.1" + dependencies: + del: ^6.0.0 + is-stream: ^2.0.0 + temp-dir: ^2.0.0 + type-fest: ^0.16.0 + unique-string: ^2.0.0 + checksum: e77ca4440af18e42dc64d8903b7ed0be673455b76680ff94a7d7c6ee7c16f7604bdcdee3c39436342b1082c23eda010dbe48f6094e836e0bd53c8b1aa63e5b95 + languageName: node + linkType: hard + "term-img@npm:^4.0.0": version: 4.1.0 resolution: "term-img@npm:4.1.0" @@ -29398,34 +27496,15 @@ __metadata: languageName: node linkType: hard -"terser-webpack-plugin@npm:^4.2.3": - version: 4.2.3 - resolution: "terser-webpack-plugin@npm:4.2.3" +"terser-webpack-plugin@npm:^5.1.3, terser-webpack-plugin@npm:^5.2.5, terser-webpack-plugin@npm:^5.3.1": + version: 5.3.9 + resolution: "terser-webpack-plugin@npm:5.3.9" dependencies: - cacache: ^15.0.5 - find-cache-dir: ^3.3.1 - jest-worker: ^26.5.0 - p-limit: ^3.0.2 - schema-utils: ^3.0.0 - serialize-javascript: ^5.0.1 - source-map: ^0.6.1 - terser: ^5.3.4 - webpack-sources: ^1.4.3 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: ec1b3a85e2645c57e359d5e4831f3e1d78eca2a0c94b156db70eb846ae35b5e6e98ad8784b12e153fc273e57445ce69d017075bbe9fc42868a258ef121f11537 - languageName: node - linkType: hard - -"terser-webpack-plugin@npm:^5.0.3, terser-webpack-plugin@npm:^5.1.3, terser-webpack-plugin@npm:^5.2.5": - version: 5.3.6 - resolution: "terser-webpack-plugin@npm:5.3.6" - dependencies: - "@jridgewell/trace-mapping": ^0.3.14 + "@jridgewell/trace-mapping": ^0.3.17 jest-worker: ^27.4.5 schema-utils: ^3.1.1 - serialize-javascript: ^6.0.0 - terser: ^5.14.1 + serialize-javascript: ^6.0.1 + terser: ^5.16.8 peerDependencies: webpack: ^5.1.0 peerDependenciesMeta: @@ -29435,34 +27514,21 @@ __metadata: optional: true uglify-js: optional: true - checksum: 8f3448d7fdb0434ce6a0c09d95c462bfd2f4a5a430233d854163337f734a7f5c07c74513d16081e06d4ca33d366d5b1a36f5444219bc41a7403afd6162107bad + checksum: 41705713d6f9cb83287936b21e27c658891c78c4392159f5148b5623f0e8c48559869779619b058382a4c9758e7820ea034695e57dc7c474b4962b79f553bc5f languageName: node linkType: hard -"terser@npm:^4.6.3": - version: 4.8.1 - resolution: "terser@npm:4.8.1" +"terser@npm:^5.0.0, terser@npm:^5.10.0, terser@npm:^5.16.8": + version: 5.19.2 + resolution: "terser@npm:5.19.2" dependencies: - commander: ^2.20.0 - source-map: ~0.6.1 - source-map-support: ~0.5.12 - bin: - terser: bin/terser - checksum: b342819bf7e82283059aaa3f22bb74deb1862d07573ba5a8947882190ad525fd9b44a15074986be083fd379c58b9a879457a330b66dcdb77b485c44267f9a55a - languageName: node - linkType: hard - -"terser@npm:^5.0.0, terser@npm:^5.10.0, terser@npm:^5.14.1, terser@npm:^5.3.4": - version: 5.16.5 - resolution: "terser@npm:5.16.5" - dependencies: - "@jridgewell/source-map": ^0.3.2 - acorn: ^8.5.0 + "@jridgewell/source-map": ^0.3.3 + acorn: ^8.8.2 commander: ^2.20.0 source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: f2c1a087fac7f4ff04b1b4e79bffc52e2fc0b068b98912bfcc0b341184c284c30c19ed73f76ac92b225b71668f7f8fc586d99a7e50a29cdc1c916cb1265522ec + checksum: e059177775b4d4f4cff219ad89293175aefbd1b081252270444dc83e42a2c5f07824eb2a85eae6e22ef6eb7ef04b21af36dd7d1dd7cfb93912310e57d416a205 languageName: node linkType: hard @@ -29498,7 +27564,7 @@ __metadata: languageName: node linkType: hard -"through2@npm:^2.0.0": +"through2@npm:^2.0.0, through2@npm:^2.0.3": version: 2.0.5 resolution: "through2@npm:2.0.5" dependencies: @@ -29540,10 +27606,10 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.0.2, tiny-invariant@npm:^1.0.6": - version: 1.1.0 - resolution: "tiny-invariant@npm:1.1.0" - checksum: 27d29bbb9e1d1d86e25766711c28ad91af6d67c87d561167077ac7fbce5212b97bbfe875e70bc369808e075748c825864c9b61f0e9f8652275ec86bcf4dcc924 +"tiny-invariant@npm:^1.0.2, tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.1": + version: 1.3.1 + resolution: "tiny-invariant@npm:1.3.1" + checksum: 872dbd1ff20a21303a2fd20ce3a15602cfa7fcf9b228bd694a52e2938224313b5385a1078cb667ed7375d1612194feaca81c4ecbe93121ca1baebe344de4f84c languageName: node linkType: hard @@ -29639,25 +27705,6 @@ __metadata: languageName: node linkType: hard -"to-object-path@npm:^0.3.0": - version: 0.3.0 - resolution: "to-object-path@npm:0.3.0" - dependencies: - kind-of: ^3.0.2 - checksum: 9425effee5b43e61d720940fa2b889623f77473d459c2ce3d4a580a4405df4403eec7be6b857455908070566352f9e2417304641ed158dda6f6a365fe3e66d70 - languageName: node - linkType: hard - -"to-regex-range@npm:^2.1.0": - version: 2.1.1 - resolution: "to-regex-range@npm:2.1.1" - dependencies: - is-number: ^3.0.0 - repeat-string: ^1.6.1 - checksum: 46093cc14be2da905cc931e442d280b2e544e2bfdb9a24b3cf821be8d342f804785e5736c108d5be026021a05d7b38144980a61917eee3c88de0a5e710e10320 - languageName: node - linkType: hard - "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -29667,18 +27714,6 @@ __metadata: languageName: node linkType: hard -"to-regex@npm:^3.0.1, to-regex@npm:^3.0.2": - version: 3.0.2 - resolution: "to-regex@npm:3.0.2" - dependencies: - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - regex-not: ^1.0.2 - safe-regex: ^1.1.0 - checksum: 4ed4a619059b64e204aad84e4e5f3ea82d97410988bcece7cf6cbfdbf193d11bff48cf53842d88b8bb00b1bfc0d048f61f20f0709e6f393fd8fe0122662d9db4 - languageName: node - linkType: hard - "to-space-case@npm:^1.0.0": version: 1.0.0 resolution: "to-space-case@npm:1.0.0" @@ -29688,6 +27723,13 @@ __metadata: languageName: node linkType: hard +"tocbot@npm:^4.20.1": + version: 4.21.0 + resolution: "tocbot@npm:4.21.0" + checksum: 473686301b14f3ad275f5e39a0cbd1e7a4cb5856a98653d916ec4fb09fb6e6cd913f000bc8299fdd42511001d0b53bfce2d041ed949de2a13e4f3daa88931f56 + languageName: node + linkType: hard + "toggle-selection@npm:^1.0.6": version: 1.0.6 resolution: "toggle-selection@npm:1.0.6" @@ -29771,34 +27813,6 @@ __metadata: languageName: node linkType: hard -"trim-newlines@npm:3.0.1": - version: 3.0.1 - resolution: "trim-newlines@npm:3.0.1" - checksum: b530f3fadf78e570cf3c761fb74fef655beff6b0f84b29209bac6c9622db75ad1417f4a7b5d54c96605dcd72734ad44526fef9f396807b90839449eb543c6206 - languageName: node - linkType: hard - -"trim-trailing-lines@npm:^1.0.0": - version: 1.1.4 - resolution: "trim-trailing-lines@npm:1.1.4" - checksum: 5d39d21c0d4b258667012fcd784f73129e148ea1c213b1851d8904f80499fc91df6710c94c7dd49a486a32da2b9cb86020dda79f285a9a2586cfa622f80490c2 - languageName: node - linkType: hard - -"trim@npm:0.0.3": - version: 0.0.3 - resolution: "trim@npm:0.0.3" - checksum: 9a059ba56d5e22c9e571798a7c63640cb25478c495d8a9d001f6352927207c6bd224018751a0c5145fbedc943ee2ebab1d7cc2e8ccba3121a51a7d3428dd879c - languageName: node - linkType: hard - -"trough@npm:^1.0.0": - version: 1.0.5 - resolution: "trough@npm:1.0.5" - checksum: d6c8564903ed00e5258bab92134b020724dbbe83148dc72e4bf6306c03ed8843efa1bcc773fa62410dd89161ecb067432dd5916501793508a9506cacbc408e25 - languageName: node - linkType: hard - "tryer@npm:^1.0.1": version: 1.0.1 resolution: "tryer@npm:1.0.1" @@ -30042,7 +28056,14 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": +"tslib@npm:2.3.0": + version: 2.3.0 + resolution: "tslib@npm:2.3.0" + checksum: 8869694c26e4a7b56d449662fd54a4f9ba872c889d991202c74462bd99f10e61d5bd63199566c4284c0f742277736292a969642cc7b590f98727a7cae9529122 + languageName: node + linkType: hard + +"tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd @@ -30164,6 +28185,20 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^2.19.0": + version: 2.19.0 + resolution: "type-fest@npm:2.19.0" + checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278 + languageName: node + linkType: hard + +"type-fest@npm:^3.11.0": + version: 3.13.1 + resolution: "type-fest@npm:3.13.1" + checksum: c06b0901d54391dc46de3802375f5579868949d71f93b425ce564e19a428a0d411ae8d8cb0e300d330071d86152c3ea86e744c3f2860a42a79585b6ec2fdae8e + languageName: node + linkType: hard + "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -30355,23 +28390,6 @@ __metadata: languageName: node linkType: hard -"unfetch@npm:^4.2.0": - version: 4.2.0 - resolution: "unfetch@npm:4.2.0" - checksum: 6a4b2557e1d921eaa80c4425ce27a404945ec26491ed06e62598f333996a91a44c7908cb26dc7c2746d735762b13276cf4aa41829b4c8f438dde63add3045d7a - languageName: node - linkType: hard - -"unherit@npm:^1.0.4": - version: 1.1.3 - resolution: "unherit@npm:1.1.3" - dependencies: - inherits: ^2.0.0 - xtend: ^4.0.0 - checksum: fd7922f84fc0bfb7c4df6d1f5a50b5b94a0218e3cda98a54dbbd209226ddd4072d742d3df44d0e295ab08d5ccfd304a1e193dfe31a86d2a91b7cb9fdac093194 - languageName: node - linkType: hard - "unicode-canonical-property-names-ecmascript@npm:^2.0.0": version: 2.0.0 resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.0" @@ -30403,41 +28421,6 @@ __metadata: languageName: node linkType: hard -"unified@npm:9.2.0": - version: 9.2.0 - resolution: "unified@npm:9.2.0" - dependencies: - bail: ^1.0.0 - extend: ^3.0.0 - is-buffer: ^2.0.0 - is-plain-obj: ^2.0.0 - trough: ^1.0.0 - vfile: ^4.0.0 - checksum: 0cac4ae119893fbd49d309b4db48595e4d4e9f0a2dc1dde4d0074059f9a46012a2905f37c1346715e583f30c970bc8078db8462675411d39ff5036ae18b4fb8a - languageName: node - linkType: hard - -"union-value@npm:^1.0.0": - version: 1.0.1 - resolution: "union-value@npm:1.0.1" - dependencies: - arr-union: ^3.1.0 - get-value: ^2.0.6 - is-extendable: ^0.1.1 - set-value: ^2.0.1 - checksum: a3464097d3f27f6aa90cf103ed9387541bccfc006517559381a10e0dffa62f465a9d9a09c9b9c3d26d0f4cbe61d4d010e2fbd710fd4bf1267a768ba8a774b0ba - languageName: node - linkType: hard - -"unique-filename@npm:^1.1.1": - version: 1.1.1 - resolution: "unique-filename@npm:1.1.1" - dependencies: - unique-slug: ^2.0.0 - checksum: cf4998c9228cc7647ba7814e255dec51be43673903897b1786eff2ac2d670f54d4d733357eb08dea969aa5e6875d0e1bd391d668fbdb5a179744e7c7551a6f80 - languageName: node - linkType: hard - "unique-filename@npm:^2.0.0": version: 2.0.1 resolution: "unique-filename@npm:2.0.1" @@ -30447,15 +28430,6 @@ __metadata: languageName: node linkType: hard -"unique-slug@npm:^2.0.0": - version: 2.0.2 - resolution: "unique-slug@npm:2.0.2" - dependencies: - imurmurhash: ^0.1.4 - checksum: 5b6876a645da08d505dedb970d1571f6cebdf87044cb6b740c8dbb24f0d6e1dc8bdbf46825fd09f994d7cf50760e6f6e063cfa197d51c5902c00a861702eb75a - languageName: node - linkType: hard - "unique-slug@npm:^3.0.0": version: 3.0.0 resolution: "unique-slug@npm:3.0.0" @@ -30474,20 +28448,6 @@ __metadata: languageName: node linkType: hard -"unist-builder@npm:2.0.3, unist-builder@npm:^2.0.0": - version: 2.0.3 - resolution: "unist-builder@npm:2.0.3" - checksum: e946fdf77dbfc320feaece137ce4959ae2da6614abd1623bd39512dc741a9d5f313eb2ba79f8887d941365dccddec7fef4e953827475e392bf49b45336f597f6 - languageName: node - linkType: hard - -"unist-util-generated@npm:^1.0.0": - version: 1.1.6 - resolution: "unist-util-generated@npm:1.1.6" - checksum: 86239ff88a08800d52198f2f0e15911f05bab2dad17cef95550f7c2728f15ebb0344694fcc3101d05762d88adaf86cb85aa7a3300fedabd0b6d7d00b41cdcb7f - languageName: node - linkType: hard - "unist-util-is@npm:^4.0.0": version: 4.1.0 resolution: "unist-util-is@npm:4.1.0" @@ -30495,40 +28455,6 @@ __metadata: languageName: node linkType: hard -"unist-util-position@npm:^3.0.0": - version: 3.1.0 - resolution: "unist-util-position@npm:3.1.0" - checksum: 10b3952e32a1ffabbecad41c3946237f7059f5bb6436796da05531a285f50b97e4f37cfc2f7164676d041063f40fe1ad92fbb8ca38d3ae8747328ebe738d738f - languageName: node - linkType: hard - -"unist-util-remove-position@npm:^2.0.0": - version: 2.0.1 - resolution: "unist-util-remove-position@npm:2.0.1" - dependencies: - unist-util-visit: ^2.0.0 - checksum: 4149294969f1a78a367b5d03eb0a138aa8320a39e1b15686647a2bec5945af3df27f2936a1e9752ecbb4a82dc23bd86f7e5a0ee048e5eeaedc2deb9237872795 - languageName: node - linkType: hard - -"unist-util-remove@npm:^2.0.0": - version: 2.1.0 - resolution: "unist-util-remove@npm:2.1.0" - dependencies: - unist-util-is: ^4.0.0 - checksum: 99e54f3ea0523f8cf957579a6e84e5b58427bffab929cc7f6aa5119581f929db683dd4691ea5483df0c272f486dda9dbd04f4ab74dca6cae1f3ebe8e4261a4d9 - languageName: node - linkType: hard - -"unist-util-stringify-position@npm:^2.0.0": - version: 2.0.3 - resolution: "unist-util-stringify-position@npm:2.0.3" - dependencies: - "@types/unist": ^2.0.2 - checksum: f755cadc959f9074fe999578a1a242761296705a7fe87f333a37c00044de74ab4b184b3812989a57d4cd12211f0b14ad397b327c3a594c7af84361b1c25a7f09 - languageName: node - linkType: hard - "unist-util-visit-parents@npm:^3.0.0": version: 3.1.1 resolution: "unist-util-visit-parents@npm:3.1.1" @@ -30539,7 +28465,7 @@ __metadata: languageName: node linkType: hard -"unist-util-visit@npm:2.0.3, unist-util-visit@npm:^2.0.0": +"unist-util-visit@npm:^2.0.0": version: 2.0.3 resolution: "unist-util-visit@npm:2.0.3" dependencies: @@ -30571,6 +28497,18 @@ __metadata: languageName: node linkType: hard +"unplugin@npm:^1.3.1": + version: 1.4.0 + resolution: "unplugin@npm:1.4.0" + dependencies: + acorn: ^8.9.0 + chokidar: ^3.5.3 + webpack-sources: ^3.2.3 + webpack-virtual-modules: ^0.5.0 + checksum: 49f586b07988397aa130b44710e8017a0472e825d08a218557031f08d694788b3ee61d686e67af153cb39b73132e2616c2f135222b83ff8aa2f7a89027f74600 + languageName: node + linkType: hard + "unquote@npm:~1.1.1": version: 1.1.1 resolution: "unquote@npm:1.1.1" @@ -30578,25 +28516,6 @@ __metadata: languageName: node linkType: hard -"unset-value@npm:^1.0.0": - version: 1.0.0 - resolution: "unset-value@npm:1.0.0" - dependencies: - has-value: ^0.3.1 - isobject: ^3.0.0 - checksum: 5990ecf660672be2781fc9fb322543c4aa592b68ed9a3312fa4df0e9ba709d42e823af090fc8f95775b4cd2c9a5169f7388f0cec39238b6d0d55a69fc2ab6b29 - languageName: node - linkType: hard - -"untildify@npm:^2.0.0": - version: 2.1.0 - resolution: "untildify@npm:2.1.0" - dependencies: - os-homedir: ^1.0.0 - checksum: 071b394053fc94747d9df8c7f7ca50af41355c1207c8a0bf9f35f52b0d9ad5142a1920b018bc2b6ff04340a4f9c599ad50c9b8f4ff2c689ae52b1463ebbda94e - languageName: node - linkType: hard - "untildify@npm:^4.0.0": version: 4.0.0 resolution: "untildify@npm:4.0.0" @@ -30660,30 +28579,6 @@ __metadata: languageName: node linkType: hard -"urix@npm:^0.1.0": - version: 0.1.0 - resolution: "urix@npm:0.1.0" - checksum: 4c076ecfbf3411e888547fe844e52378ab5ada2d2f27625139011eada79925e77f7fbf0e4016d45e6a9e9adb6b7e64981bd49b22700c7c401c5fc15f423303b3 - languageName: node - linkType: hard - -"url-loader@npm:^4.1.1": - version: 4.1.1 - resolution: "url-loader@npm:4.1.1" - dependencies: - loader-utils: ^2.0.0 - mime-types: ^2.1.27 - schema-utils: ^3.0.0 - peerDependencies: - file-loader: "*" - webpack: ^4.0.0 || ^5.0.0 - peerDependenciesMeta: - file-loader: - optional: true - checksum: c1122a992c6cff70a7e56dfc2b7474534d48eb40b2cc75467cde0c6972e7597faf8e43acb4f45f93c2473645dfd803bcbc20960b57544dd1e4c96e77f72ba6fd - languageName: node - linkType: hard - "url-search-params-polyfill@npm:^8.0.0": version: 8.1.0 resolution: "url-search-params-polyfill@npm:8.1.0" @@ -30691,13 +28586,13 @@ __metadata: languageName: node linkType: hard -"url@npm:~0.11.0": - version: 0.11.0 - resolution: "url@npm:0.11.0" +"url@npm:^0.11.0, url@npm:~0.11.0": + version: 0.11.1 + resolution: "url@npm:0.11.1" dependencies: - punycode: 1.3.2 - querystring: 0.2.0 - checksum: 50d100d3dd2d98b9fe3ada48cadb0b08aa6be6d3ac64112b867b56b19be4bfcba03c2a9a0d7922bfd7ac17d4834e88537749fe182430dfd9b68e520175900d90 + punycode: ^1.4.1 + qs: ^6.11.0 + checksum: a7de4b37bbcbe60ef199acda4ce437ef843c0ef3a4b34ec3e3d97e0446a5f50dc7bfeafbe33ad118cf4e5aa04805e1328f0d0126e254f2b77bb8498fa395c596 languageName: node linkType: hard @@ -30760,6 +28655,18 @@ __metadata: languageName: node linkType: hard +"use-resize-observer@npm:^9.1.0": + version: 9.1.0 + resolution: "use-resize-observer@npm:9.1.0" + dependencies: + "@juggle/resize-observer": ^3.3.1 + peerDependencies: + react: 16.8.0 - 18 + react-dom: 16.8.0 - 18 + checksum: 92be0ac34a3b3cf884cd55847c90792b5b44833dc258e96d650152815ad246afe45825aa223332203004d836535a927ab74f18dc0313229e2c7c69510eddf382 + languageName: node + linkType: hard + "use-sidecar@npm:^1.1.2": version: 1.1.2 resolution: "use-sidecar@npm:1.1.2" @@ -30776,13 +28683,6 @@ __metadata: languageName: node linkType: hard -"use@npm:^3.1.0": - version: 3.1.1 - resolution: "use@npm:3.1.1" - checksum: 08a130289f5238fcbf8f59a18951286a6e660d17acccc9d58d9b69dfa0ee19aa038e8f95721b00b432c36d1629a9e32a464bf2e7e0ae6a244c42ddb30bdd8b33 - languageName: node - linkType: hard - "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -30790,16 +28690,6 @@ __metadata: languageName: node linkType: hard -"util.promisify@npm:1.0.0": - version: 1.0.0 - resolution: "util.promisify@npm:1.0.0" - dependencies: - define-properties: ^1.1.2 - object.getownpropertydescriptors: ^2.0.3 - checksum: 482e857d676adee506c5c3a10212fd6a06a51d827a9b6d5396a8e593db53b4bb7064f77c5071357d8cd76072542de5cc1c08bc6d7c10cf43fa22dc3bc67556f1 - languageName: node - linkType: hard - "util.promisify@npm:~1.0.0": version: 1.0.1 resolution: "util.promisify@npm:1.0.1" @@ -30821,16 +28711,7 @@ __metadata: languageName: node linkType: hard -"util@npm:~0.10.1": - version: 0.10.4 - resolution: "util@npm:0.10.4" - dependencies: - inherits: 2.0.3 - checksum: 913f9a90d05a60e91f91af01b8bd37e06bca4cc02d7b49e01089f9d5b78be2fffd61fb1a41b517de7238c5fc7337fa939c62d1fb4eb82e014894c7bee6637aaf - languageName: node - linkType: hard - -"util@npm:~0.12.0": +"util@npm:^0.12.0, util@npm:^0.12.4, util@npm:~0.12.0": version: 0.12.5 resolution: "util@npm:0.12.5" dependencies: @@ -30843,6 +28724,15 @@ __metadata: languageName: node linkType: hard +"util@npm:~0.10.1": + version: 0.10.4 + resolution: "util@npm:0.10.4" + dependencies: + inherits: 2.0.3 + checksum: 913f9a90d05a60e91f91af01b8bd37e06bca4cc02d7b49e01089f9d5b78be2fffd61fb1a41b517de7238c5fc7337fa939c62d1fb4eb82e014894c7bee6637aaf + languageName: node + linkType: hard + "utila@npm:~0.4": version: 0.4.0 resolution: "utila@npm:0.4.0" @@ -30857,14 +28747,7 @@ __metadata: languageName: node linkType: hard -"uuid-browser@npm:^3.1.0": - version: 3.1.0 - resolution: "uuid-browser@npm:3.1.0" - checksum: 951ec47593865c7cc746df671f7b0f0ff48fcab583fcdaeab6c517a5222af0f5e144a6fcea5fa9620a5b3be047e2f9412a80267ea5c45050e07d51774197d49e - languageName: node - linkType: hard - -"uuid@npm:^3.2.1, uuid@npm:^3.3.2": +"uuid@npm:^3.2.1": version: 3.4.0 resolution: "uuid@npm:3.4.0" bin: @@ -30969,35 +28852,6 @@ __metadata: languageName: node linkType: hard -"vfile-location@npm:^3.0.0, vfile-location@npm:^3.2.0": - version: 3.2.0 - resolution: "vfile-location@npm:3.2.0" - checksum: 9bb3df6d0be31b5dd2d8da0170c27b7045c64493a8ba7b6ff7af8596c524fc8896924b8dd85ae12d201eead2709217a0fbc44927b7264f4bbf0aa8027a78be9c - languageName: node - linkType: hard - -"vfile-message@npm:^2.0.0": - version: 2.0.4 - resolution: "vfile-message@npm:2.0.4" - dependencies: - "@types/unist": ^2.0.0 - unist-util-stringify-position: ^2.0.0 - checksum: 1bade499790f46ca5aba04bdce07a1e37c2636a8872e05cf32c26becc912826710b7eb063d30c5754fdfaeedc8a7658e78df10b3bc535c844890ec8a184f5643 - languageName: node - linkType: hard - -"vfile@npm:^4.0.0": - version: 4.2.1 - resolution: "vfile@npm:4.2.1" - dependencies: - "@types/unist": ^2.0.0 - is-buffer: ^2.0.0 - unist-util-stringify-position: ^2.0.0 - vfile-message: ^2.0.0 - checksum: ee5726e10d170472cde778fc22e0f7499caa096eb85babea5d0ce0941455b721037ee1c9e6ae506ca2803250acd313d0f464328ead0b55cfe7cb6315f1b462d6 - languageName: node - linkType: hard - "vm-browserify@npm:^1.0.0": version: 1.1.2 resolution: "vm-browserify@npm:1.1.2" @@ -31045,7 +28899,7 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.7, walker@npm:^1.0.8, walker@npm:~1.0.5": +"walker@npm:^1.0.7, walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" dependencies: @@ -31108,13 +28962,6 @@ __metadata: languageName: node linkType: hard -"web-namespaces@npm:^1.0.0": - version: 1.1.4 - resolution: "web-namespaces@npm:1.1.4" - checksum: 5149842ccbfbc56fe4f8758957b3f8c8616a281874a5bb84aa1b305e4436a9bad853d21c629a7b8f174902449e1489c7a6c724fccf60965077c5636bd8aed42b - languageName: node - linkType: hard - "webfontloader@npm:^1.6.28": version: 1.6.28 resolution: "webfontloader@npm:1.6.28" @@ -31173,37 +29020,6 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:^3.7.3": - version: 3.7.3 - resolution: "webpack-dev-middleware@npm:3.7.3" - dependencies: - memory-fs: ^0.4.1 - mime: ^2.4.4 - mkdirp: ^0.5.1 - range-parser: ^1.2.1 - webpack-log: ^2.0.0 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: faa3cdd7b82d23c35b8f45903556eadd92b0795c76f3e08e234d53f7bab3de13331096a71968e7e9905770ae5de7a4f75ddf09f66d1e0bbabfecbb30db0f71e3 - languageName: node - linkType: hard - -"webpack-dev-middleware@npm:^4.1.0": - version: 4.3.0 - resolution: "webpack-dev-middleware@npm:4.3.0" - dependencies: - colorette: ^1.2.2 - mem: ^8.1.1 - memfs: ^3.2.2 - mime-types: ^2.1.30 - range-parser: ^1.2.1 - schema-utils: ^3.0.0 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 113389f9aa488312758b329f9fdd34ff646a50822c197d0e1dc7ce171b1d826a607c92702a60439fead24e495d5b2c9959d90948fc272f7472a301d37cec1e8d - languageName: node - linkType: hard - "webpack-dev-middleware@npm:^5.3.1": version: 5.3.3 resolution: "webpack-dev-middleware@npm:5.3.3" @@ -31219,6 +29035,24 @@ __metadata: languageName: node linkType: hard +"webpack-dev-middleware@npm:^6.1.1": + version: 6.1.1 + resolution: "webpack-dev-middleware@npm:6.1.1" + dependencies: + colorette: ^2.0.10 + memfs: ^3.4.12 + mime-types: ^2.1.31 + range-parser: ^1.2.1 + schema-utils: ^4.0.0 + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + checksum: 3bced6ef644b20f2e76df9db1c5209f4a73761d7d307fe29ae20bc00397d4f9727af2607f98794c6c7c57d5c1a48bfa12690168b08f5d46820b07aab2c63640c + languageName: node + linkType: hard + "webpack-dev-server@npm:^4.6.0": version: 4.9.3 resolution: "webpack-dev-server@npm:4.9.3" @@ -31263,15 +29097,6 @@ __metadata: languageName: node linkType: hard -"webpack-filter-warnings-plugin@npm:^1.2.1": - version: 1.2.1 - resolution: "webpack-filter-warnings-plugin@npm:1.2.1" - peerDependencies: - webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 - checksum: 91d853596ddb81b6c4673e03f55ab18f7f652ef7a278533623910d53b59df1c661b7f2cb2ef859eabc5fd615daa5be3f9f4c00a59ab33192b93f1be7c8908ace - languageName: node - linkType: hard - "webpack-hot-middleware@npm:^2.25.1": version: 2.25.3 resolution: "webpack-hot-middleware@npm:2.25.3" @@ -31283,16 +29108,6 @@ __metadata: languageName: node linkType: hard -"webpack-log@npm:^2.0.0": - version: 2.0.0 - resolution: "webpack-log@npm:2.0.0" - dependencies: - ansi-colors: ^3.0.0 - uuid: ^3.3.2 - checksum: 4757179310995e20633ec2d77a8c1ac11e4135c84745f57148692f8195f1c0f8ec122c77d0dc16fc484b7d301df6674f36c9fc6b1ff06b5cf142abaaf5d24f4f - languageName: node - linkType: hard - "webpack-manifest-plugin@npm:^4.0.2": version: 4.1.1 resolution: "webpack-manifest-plugin@npm:4.1.1" @@ -31353,19 +29168,10 @@ __metadata: languageName: node linkType: hard -"webpack-virtual-modules@npm:^0.2.2": - version: 0.2.2 - resolution: "webpack-virtual-modules@npm:0.2.2" - dependencies: - debug: ^3.0.0 - checksum: 38706eb5ffd7a5120a731c2d35d4de5714cb16dcc87076276d7b130e3221d2665f5c30696bfde5edfddc6b7ae40d772096a0019202260a9d4e19df43b7cf9c95 - languageName: node - linkType: hard - -"webpack-virtual-modules@npm:^0.4.1": - version: 0.4.6 - resolution: "webpack-virtual-modules@npm:0.4.6" - checksum: cb056ba8c50b35436ae43149554b051b80065b0cf79f2d528ca692ddf344a422ac71c415adb9da83dc3acc6e7e58f518388cc1cd11cb4fa29dc04f2c4494afe3 +"webpack-virtual-modules@npm:^0.5.0": + version: 0.5.0 + resolution: "webpack-virtual-modules@npm:0.5.0" + checksum: 22b59257b55c89d11ae295b588b683ee9fdf3aeb591bc7b6f88ac1d69cb63f4fcb507666ea986866dfae161a1fa534ad6fb4e2ea91bbcd0a6d454368d7d4c64b languageName: node linkType: hard @@ -31492,6 +29298,18 @@ __metadata: languageName: node linkType: hard +"which-collection@npm:^1.0.1": + version: 1.0.1 + resolution: "which-collection@npm:1.0.1" + dependencies: + is-map: ^2.0.1 + is-set: ^2.0.1 + is-weakmap: ^2.0.1 + is-weakset: ^2.0.1 + checksum: c815bbd163107ef9cb84f135e6f34453eaf4cca994e7ba85ddb0d27cea724c623fae2a473ceccfd5549c53cc65a5d82692de418166df3f858e1e5dc60818581c + languageName: node + linkType: hard + "which-module@npm:^2.0.0": version: 2.0.0 resolution: "which-module@npm:2.0.0" @@ -31535,7 +29353,7 @@ __metadata: languageName: node linkType: hard -"wide-align@npm:^1.1.0, wide-align@npm:^1.1.2, wide-align@npm:^1.1.5": +"wide-align@npm:^1.1.0, wide-align@npm:^1.1.5": version: 1.1.5 resolution: "wide-align@npm:1.1.5" dependencies: @@ -31786,12 +29604,14 @@ __metadata: languageName: node linkType: hard -"worker-rpc@npm:^0.1.0": - version: 0.1.1 - resolution: "worker-rpc@npm:0.1.1" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" dependencies: - microevent.ts: ~0.1.1 - checksum: 8f8607506172f44c05490f3ccf13e5c1f430eeb9b6116a405919c186b8b17add13bbb22467a0dbcd18ec7fcb080709a15738182e0003c5fbe2144721ea00f357 + ansi-styles: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b languageName: node linkType: hard @@ -31817,14 +29637,14 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^7.0.0": - version: 7.0.0 - resolution: "wrap-ansi@npm:7.0.0" +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" dependencies: - ansi-styles: ^4.0.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + ansi-styles: ^6.1.0 + string-width: ^5.0.1 + strip-ansi: ^7.0.1 + checksum: 371733296dc2d616900ce15a0049dca0ef67597d6394c57347ba334393599e800bab03c41d4d45221b6bc967b8c453ec3ae4749eff3894202d16800fdfe0e238 languageName: node linkType: hard @@ -31835,7 +29655,7 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^2.4.2": +"write-file-atomic@npm:^2.3.0, write-file-atomic@npm:^2.4.2": version: 2.4.3 resolution: "write-file-atomic@npm:2.4.3" dependencies: @@ -31962,20 +29782,6 @@ __metadata: languageName: node linkType: hard -"x-default-browser@npm:^0.4.0": - version: 0.4.0 - resolution: "x-default-browser@npm:0.4.0" - dependencies: - default-browser-id: ^1.0.4 - dependenciesMeta: - default-browser-id: - optional: true - bin: - x-default-browser: bin/x-default-browser.js - checksum: 9649fe6b4b91de93d5a48a5042b55a6e15c87d2514bc4f2e12582f8b25c1a6810fafc6f4c454fb531540e431e32a0a26ac130e418c0ce5c6ca892fb01945ea9e - languageName: node - linkType: hard - "xdg-basedir@npm:^4.0.0": version: 4.0.0 resolution: "xdg-basedir@npm:4.0.0" @@ -32218,6 +30024,13 @@ __metadata: languageName: node linkType: hard +"yocto-queue@npm:^1.0.0": + version: 1.0.0 + resolution: "yocto-queue@npm:1.0.0" + checksum: 2cac84540f65c64ccc1683c267edce396b26b1e931aa429660aefac8fbe0188167b7aee815a3c22fa59a28a58d898d1a2b1825048f834d8d629f4c2a5d443801 + languageName: node + linkType: hard + "zipcelx@npm:^1.6.2": version: 1.6.2 resolution: "zipcelx@npm:1.6.2" @@ -32229,9 +30042,11 @@ __metadata: languageName: node linkType: hard -"zwitch@npm:^1.0.0": - version: 1.0.5 - resolution: "zwitch@npm:1.0.5" - checksum: 28a1bebacab3bc60150b6b0a2ba1db2ad033f068e81f05e4892ec0ea13ae63f5d140a1d692062ac0657840c8da076f35b94433b5f1c329d7803b247de80f064a +"zrender@npm:5.4.3": + version: 5.4.3 + resolution: "zrender@npm:5.4.3" + dependencies: + tslib: 2.3.0 + checksum: ae89584fbe4256217e500a74183fd5870a2bed7e7b3234cd78fcbc0a1a82da8449596b2019105927069531b567ecf94425fb171abd6cedcbf517e52fdf438722 languageName: node linkType: hard diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java index 7619733a5a..66dcdad5c3 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/helpers/FileUtilsImpl.java @@ -44,6 +44,8 @@ import java.nio.file.DirectoryNotEmptyException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; import java.time.Instant; import java.util.Arrays; import java.util.HashMap; @@ -436,6 +438,7 @@ public class FileUtilsImpl implements FileInterface { Files.createDirectories(path.getParent()); return writeToFile(sourceEntity, path, gson); } catch (IOException e) { + log.error("Error while writing resource to file {} with {}", path, e.getMessage()); log.debug(e.getMessage()); } return false; @@ -502,7 +505,7 @@ public class FileUtilsImpl implements FileInterface { Path metadataPath = path.resolve(CommonConstants.METADATA + CommonConstants.JSON_EXTENSION); return writeToFile(sourceEntity, metadataPath, gson); } catch (IOException e) { - log.debug(e.getMessage()); + log.error("Error while reading file {} with message {} with cause", path, e.getMessage(), e.getCause()); } return false; } @@ -537,7 +540,7 @@ public class FileUtilsImpl implements FileInterface { pathLocal.getFileName().toString())) .forEach(this::deleteFile); } catch (IOException e) { - log.debug("Error while scanning directory: {}, with error {}", resourceDirectory, e); + log.error("Error while scanning directory: {}, with error {}", resourceDirectory, e.getMessage()); } } } @@ -558,7 +561,7 @@ public class FileUtilsImpl implements FileInterface { && !validResources.contains(path.getFileName().toString())) .forEach(this::deleteDirectory); } catch (IOException e) { - log.debug("Error while scanning directory: {}, with error {}", resourceDirectory, e); + log.error("Error while scanning directory {} with error {}", resourceDirectory, e.getMessage()); } } } @@ -585,9 +588,9 @@ public class FileUtilsImpl implements FileInterface { try { Files.deleteIfExists(filePath); } catch (DirectoryNotEmptyException e) { - log.error("Unable to delete non-empty directory at {}", filePath); + log.error("Unable to delete non-empty directory at {} with cause", filePath, e.getMessage()); } catch (IOException e) { - log.error("Unable to delete file, {}", e.getMessage()); + log.error("Unable to delete file {} with {}", filePath, e.getMessage()); } } @@ -706,7 +709,7 @@ public class FileUtilsImpl implements FileInterface { try (JsonReader reader = new JsonReader(new FileReader(filePath.toFile()))) { file = gson.fromJson(reader, Object.class); } catch (Exception e) { - log.debug(e.getMessage()); + log.error("Error while reading file {} with message {} with cause", filePath, e.getMessage(), e.getCause()); return null; } return file; @@ -726,7 +729,11 @@ public class FileUtilsImpl implements FileInterface { try (JsonReader reader = new JsonReader(new FileReader(file))) { resource.put(file.getName() + keySuffix, gson.fromJson(reader, Object.class)); } catch (Exception e) { - log.debug(e.getMessage()); + log.error( + "Error while reading file {} with message {} with cause", + file.toPath(), + e.getMessage(), + e.getCause()); } }); } @@ -743,7 +750,7 @@ public class FileUtilsImpl implements FileInterface { try { data = FileUtils.readFileToString(filePath.toFile(), "UTF-8"); } catch (IOException e) { - log.error(" Error while reading the file from git repo {0} ", e.getMessage()); + log.error("Error while reading the file from git repo {} ", e.getMessage()); } return data; } @@ -1067,4 +1074,27 @@ public class FileUtilsImpl implements FileInterface { JSONArray layouts = pageJSON.getJSONObject("unpublishedPage").getJSONArray("layouts"); return layouts.getJSONObject(0).getJSONObject("dsl"); } + + @Override + public Mono deleteIndexLockFile(Path path, int validTimeInSeconds) { + // Check the time created of the index.lock file + // If the File is stale for more than validTime, then delete the file + try { + BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); + FileTime fileTime = attr.creationTime(); + Instant now = Instant.now(); + Instant validCreateTime = now.minusSeconds(validTimeInSeconds); + if (fileTime.toInstant().isBefore(validCreateTime)) { + // Add base repo path + path = Paths.get(path + ".lock"); + deleteFile(path); + return Mono.just(now.minusMillis(fileTime.toMillis()).getEpochSecond()); + } else { + return Mono.just(0L); + } + } catch (IOException ex) { + log.error("Error reading index.lock file: {}", ex.getMessage()); + return Mono.just(0L); + } + } } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java index f1c136cc40..b5b006f413 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/AnalyticsEvents.java @@ -82,7 +82,9 @@ public enum AnalyticsEvents { DS_TEST_EVENT("Test_Datasource_Clicked"), DS_TEST_EVENT_SUCCESS("Test_Datasource_Success"), - DS_TEST_EVENT_FAILED("Test_Datasource_Failed"); + DS_TEST_EVENT_FAILED("Test_Datasource_Failed"), + + GIT_STALE_FILE_LOCK_DELETED; private final String eventName; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java index 14c2d734f9..b9622daf20 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java @@ -73,4 +73,6 @@ public interface FileInterface { * @return success if the clone repo doesnt contain any files */ Mono checkIfDirectoryIsEmpty(Path baseRepoSuffix) throws IOException; + + Mono deleteIndexLockFile(Path path, int validTimeInSeconds); } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/DataTypeServiceUtils.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/DataTypeServiceUtils.java index e41018f88d..86718af27d 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/DataTypeServiceUtils.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/helpers/DataTypeServiceUtils.java @@ -1,6 +1,20 @@ package com.appsmith.external.helpers; -import com.appsmith.external.datatypes.*; +import com.appsmith.external.datatypes.AppsmithType; +import com.appsmith.external.datatypes.ArrayType; +import com.appsmith.external.datatypes.BigDecimalType; +import com.appsmith.external.datatypes.BooleanType; +import com.appsmith.external.datatypes.ClientDataType; +import com.appsmith.external.datatypes.DateType; +import com.appsmith.external.datatypes.DoubleType; +import com.appsmith.external.datatypes.FallbackType; +import com.appsmith.external.datatypes.IntegerType; +import com.appsmith.external.datatypes.JsonObjectType; +import com.appsmith.external.datatypes.LongType; +import com.appsmith.external.datatypes.NullType; +import com.appsmith.external.datatypes.StringType; +import com.appsmith.external.datatypes.TimeType; +import com.appsmith.external.datatypes.TimestampType; import java.util.HashMap; import java.util.List; diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/test/java/com/external/plugins/AmazonS3PluginTest.java b/app/server/appsmith-plugins/amazons3Plugin/src/test/java/com/external/plugins/AmazonS3PluginTest.java index a04e5b241d..784b67059c 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/test/java/com/external/plugins/AmazonS3PluginTest.java +++ b/app/server/appsmith-plugins/amazons3Plugin/src/test/java/com/external/plugins/AmazonS3PluginTest.java @@ -45,7 +45,12 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import static com.appsmith.external.constants.ActionConstants.ACTION_CONFIGURATION_PATH; @@ -88,7 +93,11 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; @Slf4j public class AmazonS3PluginTest { diff --git a/app/server/appsmith-plugins/elasticSearchPlugin/src/test/java/com/external/plugins/ElasticSearchPluginTest.java b/app/server/appsmith-plugins/elasticSearchPlugin/src/test/java/com/external/plugins/ElasticSearchPluginTest.java index d0cbba2e57..0ceda55bb9 100755 --- a/app/server/appsmith-plugins/elasticSearchPlugin/src/test/java/com/external/plugins/ElasticSearchPluginTest.java +++ b/app/server/appsmith-plugins/elasticSearchPlugin/src/test/java/com/external/plugins/ElasticSearchPluginTest.java @@ -30,7 +30,12 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import static com.appsmith.external.constants.ActionConstants.ACTION_CONFIGURATION_BODY; diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/GoogleSheetsMethodStrategy.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/GoogleSheetsMethodStrategy.java index 6908f4d006..87cbf3e203 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/GoogleSheetsMethodStrategy.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/GoogleSheetsMethodStrategy.java @@ -65,6 +65,8 @@ public class GoogleSheetsMethodStrategy { return new FileInfoMethod(objectMapper); case MethodIdentifiers.TRIGGER_COLUMNS_SELECTOR: return new GetStructureMethod(objectMapper); + case MethodIdentifiers.TRIGGER_SHEET_DATA: + return new RowsGetMethod(objectMapper); default: throw Exceptions.propagate(new AppsmithPluginException( AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodConfig.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodConfig.java index e3edd66e78..92807f509c 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodConfig.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodConfig.java @@ -25,6 +25,7 @@ import static com.appsmith.external.helpers.PluginUtils.getTrimmedStringDataValu import static com.appsmith.external.helpers.PluginUtils.getValueSafelyFromFormDataAsString; import static com.appsmith.external.helpers.PluginUtils.parseWhereClause; import static com.appsmith.external.helpers.PluginUtils.validDataConfigurationPresentInFormData; +import static com.external.constants.FieldName.QUERY_FORMAT; import static com.external.constants.FieldName.SHEET_NAME; import static com.external.constants.FieldName.SHEET_URL; import static com.external.constants.FieldName.TABLE_HEADER_INDEX; @@ -100,6 +101,8 @@ public class MethodConfig { public MethodConfig(TriggerRequestDTO triggerRequestDTO) { final Map parameters = triggerRequestDTO.getParameters(); switch (parameters.size()) { + case 4: + this.queryFormat = getValueSafelyFromFormDataAsString(parameters, QUERY_FORMAT); case 3: case 2: this.tableHeaderIndex = getValueSafelyFromFormDataAsString(parameters, TABLE_HEADER_INDEX); diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodIdentifiers.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodIdentifiers.java index 81bfd607b6..6291d81bde 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodIdentifiers.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/MethodIdentifiers.java @@ -20,4 +20,5 @@ public class MethodIdentifiers { public static final String TRIGGER_SPREADSHEET_SELECTOR = "SPREADSHEET_SELECTOR"; public static final String TRIGGER_SHEET_SELECTOR = "SHEET_SELECTOR"; public static final String TRIGGER_COLUMNS_SELECTOR = "COLUMNS_SELECTOR"; + public static final String TRIGGER_SHEET_DATA = "SHEET_DATA"; } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/RowsGetMethod.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/RowsGetMethod.java index 49fdc3e19b..bf007ac06b 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/RowsGetMethod.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/RowsGetMethod.java @@ -29,7 +29,7 @@ import java.util.regex.Pattern; * API reference: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get */ @Slf4j -public class RowsGetMethod implements ExecutionMethod, TemplateMethod { +public class RowsGetMethod implements ExecutionMethod, TemplateMethod, TriggerMethod { ObjectMapper objectMapper; FilterDataService filterDataService; @@ -193,6 +193,22 @@ public class RowsGetMethod implements ExecutionMethod, TemplateMethod { return preFilteringResponse; } + @Override + public boolean validateTriggerMethodRequest(MethodConfig methodConfig) { + return this.validateExecutionMethodRequest(methodConfig); + } + + @Override + public WebClient.RequestHeadersSpec getTriggerClient(WebClient webClient, MethodConfig methodConfig) { + return this.getExecutionClient(webClient, methodConfig); + } + + @Override + public JsonNode transformTriggerResponse( + JsonNode response, MethodConfig methodConfig, Set userAuthorizedSheetIds) { + return this.transformExecutionResponse(response, methodConfig, userAuthorizedSheetIds); + } + private Set sanitizeHeaders(ArrayNode headers, int valueSize) { final Set headerSet = new LinkedHashSet<>(); int headerSize = headers.size(); diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/test/java/com/external/config/RowsGetMethodTest.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/test/java/com/external/config/RowsGetMethodTest.java index 716afcd65a..58542eec50 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/test/java/com/external/config/RowsGetMethodTest.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/test/java/com/external/config/RowsGetMethodTest.java @@ -1,6 +1,7 @@ package com.external.config; import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; +import com.appsmith.external.models.TriggerRequestDTO; import com.external.constants.ErrorMessages; import com.external.constants.FieldName; import com.fasterxml.jackson.core.JsonProcessingException; @@ -8,10 +9,12 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import java.util.HashMap; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; public class RowsGetMethodTest { @@ -168,4 +171,76 @@ public class RowsGetMethodTest { assertEquals(3, result.size()); assertEquals(0, result.get(0).get(FieldName.ROW_INDEX).asInt()); } + + @Test + public void testValidateExecutionMethodRequest_noSpreadsheetId_returnsException() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + RowsGetMethod rowsGetMethod = new RowsGetMethod(objectMapper); + TriggerRequestDTO triggerRequest = new TriggerRequestDTO(); + Map params = new HashMap(); + + triggerRequest.setParameters(params); + + MethodConfig methodConfig = new MethodConfig(triggerRequest); + final AppsmithPluginException exception = assertThrows( + AppsmithPluginException.class, () -> rowsGetMethod.validateExecutionMethodRequest(methodConfig)); + + assertEquals("Missing required field 'Spreadsheet Url'", exception.getMessage()); + } + + @Test + public void testValidateExecutionMethodRequest_noSheetName_returnsException() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + RowsGetMethod rowsGetMethod = new RowsGetMethod(objectMapper); + TriggerRequestDTO triggerRequest = new TriggerRequestDTO(); + Map params = new HashMap(); + params.put("sheetUrl", "https://docs.google.com/spreadsheets/d/spreadsheetId/"); + + triggerRequest.setParameters(params); + + MethodConfig methodConfig = new MethodConfig(triggerRequest); + final AppsmithPluginException exception = assertThrows( + AppsmithPluginException.class, () -> rowsGetMethod.validateExecutionMethodRequest(methodConfig)); + + assertEquals("Missing required field 'Spreadsheet Name'", exception.getMessage()); + } + + @Test + public void testValidateExecutionMethodRequest_noTableHeaderIndex_returnsException() + throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + RowsGetMethod rowsGetMethod = new RowsGetMethod(objectMapper); + TriggerRequestDTO triggerRequest = new TriggerRequestDTO(); + Map params = new HashMap(); + params.put("sheetUrl", "https://docs.google.com/spreadsheets/d/spreadsheetId/"); + params.put("queryFormat", "ROWS"); + params.put("sheetName", "sample_sheet_name"); + + triggerRequest.setParameters(params); + + MethodConfig methodConfig = new MethodConfig(triggerRequest); + final AppsmithPluginException exception = assertThrows( + AppsmithPluginException.class, () -> rowsGetMethod.validateExecutionMethodRequest(methodConfig)); + + assertEquals( + "Unexpected value for table header index. Please use a number starting from 1", exception.getMessage()); + } + + @Test + public void testValidateExecutionMethodRequest_allParamsPresent_returnsTrue() throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + RowsGetMethod rowsGetMethod = new RowsGetMethod(objectMapper); + TriggerRequestDTO triggerRequest = new TriggerRequestDTO(); + Map params = new HashMap(); + params.put("sheetUrl", "https://docs.google.com/spreadsheets/d/spreadsheetId/"); + params.put("queryFormat", "ROWS"); + params.put("sheetName", "sample_sheet_name"); + params.put("tableHeaderIndex", 1); + + triggerRequest.setParameters(params); + + MethodConfig methodConfig = new MethodConfig(triggerRequest); + Boolean actualResult = rowsGetMethod.validateExecutionMethodRequest(methodConfig); + assertEquals(true, actualResult); + } } diff --git a/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginErrorsTest.java b/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginErrorsTest.java index 3b399f06e4..341b84ce7c 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginErrorsTest.java +++ b/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginErrorsTest.java @@ -29,7 +29,12 @@ import org.testcontainers.junit.jupiter.Testcontainers; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import static com.appsmith.external.constants.DisplayDataType.JSON; diff --git a/app/server/appsmith-plugins/mssqlPlugin/src/test/java/com/external/plugins/MssqlPluginTest.java b/app/server/appsmith-plugins/mssqlPlugin/src/test/java/com/external/plugins/MssqlPluginTest.java index 0929cc3302..3d1a415556 100755 --- a/app/server/appsmith-plugins/mssqlPlugin/src/test/java/com/external/plugins/MssqlPluginTest.java +++ b/app/server/appsmith-plugins/mssqlPlugin/src/test/java/com/external/plugins/MssqlPluginTest.java @@ -47,7 +47,11 @@ import static com.appsmith.external.constants.ActionConstants.ACTION_CONFIGURATI import static com.external.plugins.MssqlTestDBContainerManager.createDatasourceConfiguration; import static com.external.plugins.MssqlTestDBContainerManager.mssqlPluginExecutor; import static com.external.plugins.MssqlTestDBContainerManager.runSQLQueryOnMssqlTestDB; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers public class MssqlPluginTest { diff --git a/app/server/appsmith-plugins/mysqlPlugin/src/main/java/com/external/plugins/MySqlPlugin.java b/app/server/appsmith-plugins/mysqlPlugin/src/main/java/com/external/plugins/MySqlPlugin.java index 034b138829..9d5c17f3cf 100644 --- a/app/server/appsmith-plugins/mysqlPlugin/src/main/java/com/external/plugins/MySqlPlugin.java +++ b/app/server/appsmith-plugins/mysqlPlugin/src/main/java/com/external/plugins/MySqlPlugin.java @@ -28,7 +28,16 @@ import com.external.utils.MySqlDatasourceUtils; import com.external.utils.MySqlErrorUtils; import com.external.utils.QueryUtils; import io.r2dbc.pool.ConnectionPool; -import io.r2dbc.spi.*; +import io.r2dbc.spi.Connection; +import io.r2dbc.spi.R2dbcBadGrammarException; +import io.r2dbc.spi.R2dbcException; +import io.r2dbc.spi.R2dbcNonTransientResourceException; +import io.r2dbc.spi.R2dbcPermissionDeniedException; +import io.r2dbc.spi.Result; +import io.r2dbc.spi.Row; +import io.r2dbc.spi.RowMetadata; +import io.r2dbc.spi.Statement; +import io.r2dbc.spi.ValidationDepth; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.ObjectUtils; import org.mariadb.r2dbc.message.server.ColumnDefinitionPacket; diff --git a/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java b/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java index 38860c177e..8c22dfc76e 100644 --- a/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java +++ b/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java @@ -24,7 +24,11 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import redis.clients.jedis.JedisPool; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import static com.appsmith.external.constants.ActionConstants.ACTION_CONFIGURATION_BODY; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudServicesConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudServicesConfig.java index b8dad4dc56..ac19520cd0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudServicesConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CloudServicesConfig.java @@ -1,18 +1,24 @@ package com.appsmith.server.configurations; import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @Configuration @Getter public class CloudServicesConfig { - @Value("${appsmith.cloud_services.base_url}") - String baseUrl; + private String baseUrl; @Value("${appsmith.cloud_services.username}") private String username; @Value("${appsmith.cloud_services.password}") private String password; + + @Autowired + public void setBaseUrl(@Value("${appsmith.cloud_services.base_url:}") String value) { + baseUrl = StringUtils.isEmpty(value) ? "https://cs.appsmith.com" : value; + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java index 188cb67176..aabde2c75d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java @@ -29,7 +29,7 @@ public class InstanceConfig implements ApplicationListener registrationAndRtsCheckMono = configService .getByName(Appsmith.APPSMITH_REGISTERED) .filter(config -> Boolean.TRUE.equals(config.getConfig().get("value"))) - .switchIfEmpty(instanceConfigHelper.registerInstance()) + .switchIfEmpty(Mono.defer(() -> instanceConfigHelper.registerInstance())) .onErrorResume(errorSignal -> { log.debug("Instance registration failed with error: \n{}", errorSignal.getMessage()); return Mono.empty(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java index 6935a2c13c..dd12055d08 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java @@ -8,14 +8,17 @@ import com.fasterxml.jackson.databind.json.JsonMapper; import io.lettuce.core.resource.ClientResources; import io.micrometer.observation.ObservationRegistry; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; import org.springframework.data.redis.connection.RedisClusterConfiguration; +import org.springframework.data.redis.connection.RedisConfiguration; import org.springframework.data.redis.connection.RedisNode; -import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; import org.springframework.data.redis.connection.lettuce.observability.MicrometerTracingAdapter; @@ -67,22 +70,35 @@ public class RedisConfig { switch (scheme) { case "redis" -> { - return new LettuceConnectionFactory(redisUri.getHost(), redisUri.getPort()); + final RedisStandaloneConfiguration config = + new RedisStandaloneConfiguration(redisUri.getHost(), redisUri.getPort()); + fillAuthentication(redisUri, config); + return new LettuceConnectionFactory(config); } case "redis-cluster" -> { // For ElastiCache Redis with cluster mode enabled, with the configuration endpoint. - final LettuceClientConfiguration config = - LettucePoolingClientConfiguration.builder().build(); final RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(); + fillAuthentication(redisUri, clusterConfig); clusterConfig.addClusterNode(new RedisNode(redisUri.getHost(), redisUri.getPort())); - return new LettuceConnectionFactory(clusterConfig, config); + return new LettuceConnectionFactory( + clusterConfig, + LettucePoolingClientConfiguration.builder().build()); } default -> throw new InvalidRedisURIException("Invalid redis scheme: " + scheme); } } + private void fillAuthentication(URI redisUri, RedisConfiguration.WithAuthentication config) { + final String userInfo = redisUri.getUserInfo(); + if (StringUtils.isNotEmpty(userInfo)) { + final String[] parts = userInfo.split(":", 2); + config.setUsername(parts[0]); + config.setPassword(RedisPassword.of(parts.length > 1 ? parts[1] : null)); + } + } + @Bean public RedisSerializer springSessionDefaultRedisSerializer() { return new JSONSessionRedisSerializer(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SharedConfigImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SharedConfigImpl.java index cfd8b8f4d0..602bbd0466 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SharedConfigImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SharedConfigImpl.java @@ -1,12 +1,14 @@ package com.appsmith.server.configurations; import com.appsmith.external.services.SharedConfig; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @Slf4j @Configuration +@RequiredArgsConstructor public class SharedConfigImpl implements SharedConfig { @Value("${appsmith.codec.max-in-memory-size:10}") @@ -15,8 +17,7 @@ public class SharedConfigImpl implements SharedConfig { @Value("${appsmith.plugin.response.size.max:5}") private float maxPluginResponseSize = 5; - @Value("${appsmith.cloud_services.base_url}") - private String cloudServicesBaseUrl; + private final CloudServicesConfig cloudServicesConfig; @Override public int getCodecSize() { @@ -30,6 +31,6 @@ public class SharedConfigImpl implements SharedConfig { @Override public String getRemoteExecutionUrl() { - return cloudServicesBaseUrl + "/api/v1/actions/execute"; + return cloudServicesConfig.getBaseUrl() + "/api/v1/actions/execute"; } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java index 06f7b1e179..857a94b71a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java @@ -9,6 +9,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import java.time.Instant; import java.util.Collection; import java.util.Set; @@ -28,6 +29,8 @@ public class UserSessionDTO { private String name; + private Long createdAt; + private LoginSource source; private UserState state; @@ -70,6 +73,10 @@ public class UserSessionDTO { session.email = user.getEmail(); session.hashedEmail = user.getHashedEmail(); session.name = user.getName(); + // user.getCreatedAt() is null for anonymous user + if (user.getCreatedAt() != null) { + session.createdAt = user.getCreatedAt().getEpochSecond(); + } session.source = user.getSource(); session.state = user.getState(); session.isEnabled = user.isEnabled(); @@ -106,6 +113,10 @@ public class UserSessionDTO { user.setEmail(email); user.setHashedEmail(hashedEmail); user.setName(name); + // createdAt is null for anonymous user + if (createdAt != null) { + user.setCreatedAt(Instant.ofEpochSecond(createdAt)); + } user.setSource(source); user.setState(state); user.setIsEnabled(isEnabled); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/FeaturesRequestDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/FeaturesRequestDTO.java new file mode 100644 index 0000000000..4e71526909 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/FeaturesRequestDTO.java @@ -0,0 +1,12 @@ +package com.appsmith.server.dtos.ce; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class FeaturesRequestDTO { + private String instanceId; + private String tenantId; + private String appsmithVersion; +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/FeaturesResponseDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/FeaturesResponseDTO.java new file mode 100644 index 0000000000..242d9834e9 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/FeaturesResponseDTO.java @@ -0,0 +1,12 @@ +package com.appsmith.server.dtos.ce; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; + +@Getter +@Setter +public class FeaturesResponseDTO { + private Map features; +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java index 83f6449858..bff6b5b389 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java @@ -731,7 +731,7 @@ public enum AppsmithError { ErrorType.GIT_CONFIGURATION_ERROR, null), GIT_GENERIC_ERROR( - 504, + 400, AppsmithErrorCode.GIT_GENERIC_ERROR.getCode(), "Git command execution error: {0}", AppsmithErrorAction.DEFAULT, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java index 7b6068a4e6..832144592c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java @@ -1,18 +1,25 @@ package com.appsmith.server.exceptions; +import com.appsmith.external.constants.AnalyticsEvents; import com.appsmith.external.exceptions.AppsmithErrorAction; import com.appsmith.external.exceptions.BaseException; import com.appsmith.external.exceptions.ErrorDTO; import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; +import com.appsmith.server.constants.FieldName; import com.appsmith.server.dtos.ResponseDTO; import com.appsmith.server.exceptions.util.DuplicateKeyExceptionUtils; import com.appsmith.server.filters.MDCFilter; +import com.appsmith.server.helpers.GitFileUtils; import com.appsmith.server.helpers.RedisUtils; +import com.appsmith.server.services.AnalyticsService; +import com.appsmith.server.services.SessionUserService; import io.micrometer.core.instrument.util.StringUtils; import io.sentry.Sentry; import io.sentry.SentryLevel; import io.sentry.protocol.User; import lombok.extern.slf4j.Slf4j; +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.errors.LockFailedException; import org.springframework.core.io.buffer.DataBufferLimitException; import org.springframework.http.HttpStatus; import org.springframework.security.access.AccessDeniedException; @@ -25,8 +32,10 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebInputException; import reactor.core.publisher.Mono; +import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; @@ -40,8 +49,21 @@ public class GlobalExceptionHandler { private final RedisUtils redisUtils; - public GlobalExceptionHandler(RedisUtils redisUtils) { + private final AnalyticsService analyticsService; + + private final GitFileUtils fileUtils; + + private final SessionUserService sessionUserService; + + public GlobalExceptionHandler( + RedisUtils redisUtils, + AnalyticsService analyticsService, + GitFileUtils fileUtils, + SessionUserService sessionUserService) { this.redisUtils = redisUtils; + this.analyticsService = analyticsService; + this.fileUtils = fileUtils; + this.sessionUserService = sessionUserService; } private void doLog(Throwable error) { @@ -283,9 +305,67 @@ public class GlobalExceptionHandler { return getResponseDTOMono(urlPath, response); } + @ExceptionHandler + @ResponseBody + public Mono> catchJGitInternalException(JGitInternalException e, ServerWebExchange exchange) { + AppsmithError appsmithError = AppsmithError.GIT_FILE_IN_USE; + exchange.getResponse().setStatusCode(HttpStatus.resolve(appsmithError.getHttpErrorCode())); + doLog(e); + String urlPath = exchange.getRequest().getPath().toString(); + if (e.getCause() instanceof LockFailedException) { + LockFailedException lockFailedException = (LockFailedException) e.getCause(); + return deleteLockFileAndSendAnalytics(lockFailedException.getFile(), urlPath) + .flatMap(status -> getResponseDTOGitException(urlPath)); + } + return getResponseDTOGitException(urlPath); + } + + @ExceptionHandler + @ResponseBody + public Mono> catchLockFailedException(LockFailedException e, ServerWebExchange exchange) { + AppsmithError appsmithError = AppsmithError.GIT_FILE_IN_USE; + exchange.getResponse().setStatusCode(HttpStatus.resolve(appsmithError.getHttpErrorCode())); + doLog(e); + String urlPath = exchange.getRequest().getPath().toString(); + return deleteLockFileAndSendAnalytics(e.getFile(), urlPath) + .flatMap(status -> getResponseDTOGitException(urlPath)); + } + + private Mono deleteLockFileAndSendAnalytics(File file, String urlPath) { + return fileUtils.deleteIndexLockFile(Path.of(file.getPath())).flatMap(fileTime -> { + Map analyticsProps = new HashMap<>(); + if (urlPath.contains("/git") && urlPath.contains("/app")) { + String appId = getAppIdFromUrlPath(urlPath); + analyticsProps.put(FieldName.APPLICATION_ID, appId); + } + if (!fileTime.equals(0L)) { + return sessionUserService + .getCurrentUser() + .flatMap(user -> analyticsService.sendEvent( + AnalyticsEvents.GIT_STALE_FILE_LOCK_DELETED.toString(), + user.getUsername(), + analyticsProps)) + .thenReturn(true); + } + return Mono.just(false); + }); + } + + private Mono> getResponseDTOGitException(String urlPath) { + AppsmithError appsmithError = AppsmithError.INTERNAL_SERVER_ERROR; + ResponseDTO response = new ResponseDTO<>( + appsmithError.getHttpErrorCode(), + new ErrorDTO( + appsmithError.getAppErrorCode(), + appsmithError.getErrorType(), + appsmithError.getMessage(), + appsmithError.getTitle())); + return getResponseDTOMono(urlPath, response); + } + private Mono> getResponseDTOMono(String urlPath, ResponseDTO response) { if (urlPath.contains("/git") && urlPath.contains("/app")) { - String appId = urlPath.substring(urlPath.lastIndexOf('/') + 1); + String appId = getAppIdFromUrlPath(urlPath); if (StringUtils.isEmpty(appId)) { return Mono.just(response); } @@ -293,4 +373,8 @@ public class GlobalExceptionHandler { } return Mono.just(response); } + + private String getAppIdFromUrlPath(String urlPath) { + return urlPath.substring(urlPath.lastIndexOf('/') + 1); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/featureflags/CachedFeatures.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/featureflags/CachedFeatures.java new file mode 100644 index 0000000000..ed663ae159 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/featureflags/CachedFeatures.java @@ -0,0 +1,17 @@ +package com.appsmith.server.featureflags; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.Instant; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CachedFeatures implements Serializable { + Map features; + Instant refreshedAt; +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitFileUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitFileUtils.java index 5e04820e24..cdf438f409 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitFileUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitFileUtils.java @@ -32,6 +32,7 @@ import net.minidev.json.parser.ParseException; import org.apache.commons.collections.PredicateUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.jgit.api.errors.GitAPIException; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Component; import reactor.core.Exceptions; @@ -73,6 +74,10 @@ public class GitFileUtils { private final Gson gson; + // Number of seconds after lock file is stale + @Value("${appsmith.index.lock.file.time}") + public static final int INDEX_LOCK_FILE_STALE_TIME = 900; + // Only include the application helper fields in metadata object private static final Set blockedMetadataFields = Set.of( EXPORTED_APPLICATION, @@ -571,4 +576,8 @@ public class GitFileUtils { return applicationJson; } + + public Mono deleteIndexLockFile(Path path) { + return fileUtils.deleteIndexLockFile(path, INDEX_LOCK_FILE_STALE_TIME); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ImportExportUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ImportExportUtils.java index 23f1b591e4..6de6563aa9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ImportExportUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ImportExportUtils.java @@ -103,4 +103,16 @@ public class ImportExportUtils { copyNestedNonNullProperties(importedApplication, existingApplication); } + + /** + * This method sets the published mode properties in the imported application. + * When a user imports an application from the git repository, since the git only stores the unpublished version, + * the current deployed version in the newly imported app is not updated. This function sets the initial deployed + * version to the same as the edit mode one. + * @param importedApplication + */ + public static void setPublishedApplicationProperties(Application importedApplication) { + importedApplication.setPublishedApplicationDetail(importedApplication.getUnpublishedApplicationDetail()); + importedApplication.setPublishedAppLayout(importedApplication.getUnpublishedAppLayout()); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/RedisUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/RedisUtils.java index 5cd268f882..dca07fd712 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/RedisUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/RedisUtils.java @@ -1,7 +1,5 @@ package com.appsmith.server.helpers; -import com.appsmith.server.exceptions.AppsmithError; -import com.appsmith.server.exceptions.AppsmithException; import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.ReactiveRedisOperations; import org.springframework.stereotype.Component; @@ -19,12 +17,14 @@ public class RedisUtils { private static final Duration FILE_LOCK_TIME_LIMIT = Duration.ofSeconds(20); public Mono addFileLock(String key) { - return redisOperations.hasKey(key).flatMap(isKeyPresent -> { + // TODO Remove this once we are sure that the file lock is working as expected. + return Mono.just(true); + /*return redisOperations.hasKey(key).flatMap(isKeyPresent -> { if (Boolean.TRUE.equals(isKeyPresent)) { return Mono.error(new AppsmithException(AppsmithError.GIT_FILE_IN_USE)); } return redisOperations.opsForValue().set(key, REDIS_FILE_LOCK_VALUE, FILE_LOCK_TIME_LIMIT); - }); + });*/ } public Mono releaseFileLock(String key) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java index 71383553ec..678353ffa8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java @@ -46,8 +46,6 @@ public class InstanceConfigHelperCEImpl implements InstanceConfigHelperCE { @Override public Mono registerInstance() { - log.debug("Triggering registration of this instance..."); - final String baseUrl = cloudServicesConfig.getBaseUrl(); if (baseUrl == null || StringUtils.isEmpty(baseUrl)) { return Mono.error(new AppsmithException( @@ -56,11 +54,15 @@ public class InstanceConfigHelperCEImpl implements InstanceConfigHelperCE { return configService .getInstanceId() - .flatMap(instanceId -> WebClientUtils.create(baseUrl + "/api/v1/installations") - .post() - .body(BodyInserters.fromValue(Map.of("key", instanceId))) - .headers(httpHeaders -> httpHeaders.set(HttpHeaders.CONTENT_TYPE, "application/json")) - .exchange()) + .flatMap(instanceId -> { + log.debug("Triggering registration of this instance..."); + + return WebClientUtils.create(baseUrl + "/api/v1/installations") + .post() + .body(BodyInserters.fromValue(Map.of("key", instanceId))) + .headers(httpHeaders -> httpHeaders.set(HttpHeaders.CONTENT_TYPE, "application/json")) + .exchange(); + }) .flatMap(clientResponse -> clientResponse.toEntity(new ParameterizedTypeReference>() {})) .flatMap(responseEntity -> { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java index 7c9c0403f3..7faa2ea2af 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java @@ -53,6 +53,7 @@ import com.appsmith.server.dtos.Permission; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.TextUtils; +import com.appsmith.server.migrations.solutions.UpdateSuperUserMigrationHelper; import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.repositories.NewPageRepository; import com.appsmith.server.repositories.UserRepository; @@ -107,12 +108,9 @@ import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullP import static com.appsmith.server.acl.AclPermission.ASSIGN_PERMISSION_GROUPS; import static com.appsmith.server.acl.AclPermission.MANAGE_INSTANCE_CONFIGURATION; import static com.appsmith.server.acl.AclPermission.MANAGE_INSTANCE_ENV; -import static com.appsmith.server.acl.AclPermission.MANAGE_USERS; import static com.appsmith.server.acl.AclPermission.READ_INSTANCE_CONFIGURATION; import static com.appsmith.server.acl.AclPermission.READ_PERMISSION_GROUP_MEMBERS; import static com.appsmith.server.acl.AclPermission.READ_THEMES; -import static com.appsmith.server.acl.AclPermission.READ_USERS; -import static com.appsmith.server.acl.AclPermission.RESET_PASSWORD_USERS; import static com.appsmith.server.acl.AppsmithRole.TENANT_ADMIN; import static com.appsmith.server.constants.EnvVariables.APPSMITH_ADMIN_EMAILS; import static com.appsmith.server.constants.FieldName.DEFAULT_PERMISSION_GROUP; @@ -139,6 +137,8 @@ public class DatabaseChangelog2 { private static final Pattern sheetRangePattern = Pattern.compile("https://docs.google.com/spreadsheets/d/([^/]+)/?[^\"]*"); + private final UpdateSuperUserMigrationHelper updateSuperUserMigrationHelper = new UpdateSuperUserMigrationHelper(); + @ChangeSet(order = "001", id = "fix-plugin-title-casing", author = "") public void fixPluginTitleCasing(MongoTemplate mongoTemplate) { mongoTemplate.updateFirst( @@ -2545,7 +2545,11 @@ public class DatabaseChangelog2 { * @param cacheableRepositoryHelper */ @ChangeSet(order = "10000", id = "update-super-users", author = "", runAlways = true) - public void updateSuperUsers(MongoTemplate mongoTemplate, CacheableRepositoryHelper cacheableRepositoryHelper) { + public void updateSuperUsers( + MongoTemplate mongoTemplate, + CacheableRepositoryHelper cacheableRepositoryHelper, + PolicySolution policySolution, + PolicyGenerator policyGenerator) { // Read the admin emails from the environment and update the super users accordingly String adminEmailsStr = System.getenv(String.valueOf(APPSMITH_ADMIN_EMAILS)); @@ -2581,7 +2585,8 @@ public class DatabaseChangelog2 { if (user == null) { log.info("Creating super user with username {}", email); - user = createNewUser(email, tenant.getId(), mongoTemplate); + user = updateSuperUserMigrationHelper.createNewUser( + email, tenant, instanceAdminPG, mongoTemplate, policySolution, policyGenerator); } return user.getId(); @@ -2596,43 +2601,6 @@ public class DatabaseChangelog2 { mongoTemplate.updateFirst(permissionGroupQuery, update, PermissionGroup.class); } - private User createNewUser(String email, String tenantId, MongoTemplate mongoTemplate) { - User user = new User(); - user.setEmail(email); - user.setIsEnabled(false); - user.setTenantId(tenantId); - user.setCreatedAt(Instant.now()); - user = mongoTemplate.save(user); - - // Assign the user to the default permissions - PermissionGroup userManagementPermissionGroup = new PermissionGroup(); - userManagementPermissionGroup.setName(user.getUsername() + FieldName.SUFFIX_USER_MANAGEMENT_ROLE); - // Add CRUD permissions for user to the group - userManagementPermissionGroup.setPermissions(Set.of(new Permission(user.getId(), MANAGE_USERS))); - - // Assign the permission group to the user - userManagementPermissionGroup.setAssignedToUserIds(Set.of(user.getId())); - - PermissionGroup savedPermissionGroup = mongoTemplate.save(userManagementPermissionGroup); - - Policy readUserPolicy = Policy.builder() - .permission(READ_USERS.getValue()) - .permissionGroups(Set.of(savedPermissionGroup.getId())) - .build(); - Policy manageUserPolicy = Policy.builder() - .permission(MANAGE_USERS.getValue()) - .permissionGroups(Set.of(savedPermissionGroup.getId())) - .build(); - Policy resetPwdPolicy = Policy.builder() - .permission(RESET_PASSWORD_USERS.getValue()) - .permissionGroups(Set.of(savedPermissionGroup.getId())) - .build(); - - user.setPolicies(Set.of(readUserPolicy, manageUserPolicy, resetPwdPolicy)); - - return mongoTemplate.save(user); - } - @ChangeSet(order = "034", id = "update-bad-theme-state", author = "") public void updateBadThemeState( MongoTemplate mongoTemplate, 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 d68ff6ca42..8cb96a5efd 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 @@ -3,7 +3,11 @@ package com.appsmith.server.migrations; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.InvisibleActionFields; import com.appsmith.server.constants.ResourceModes; -import com.appsmith.server.domains.*; +import com.appsmith.server.domains.ApplicationPage; +import com.appsmith.server.domains.NewAction; +import com.appsmith.server.domains.Plugin; +import com.appsmith.server.domains.QUser; +import com.appsmith.server.domains.User; import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.helpers.CollectionUtils; import com.appsmith.server.repositories.CacheableRepositoryHelper; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration003PermissionGroupDefaultWorkspaceIdMigration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004PermissionGroupDefaultWorkspaceIdMigration.java similarity index 93% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration003PermissionGroupDefaultWorkspaceIdMigration.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004PermissionGroupDefaultWorkspaceIdMigration.java index 150e4f725d..677cf0a4f4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration003PermissionGroupDefaultWorkspaceIdMigration.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004PermissionGroupDefaultWorkspaceIdMigration.java @@ -16,11 +16,11 @@ import static com.appsmith.server.repositories.BaseAppsmithRepositoryImpl.fieldN import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; -@ChangeUnit(order = "003", id = "migrate-default-workspace-id-to-default-domain-id") -public class Migration003PermissionGroupDefaultWorkspaceIdMigration { +@ChangeUnit(order = "004", id = "migrate-default-workspace-id-to-default-domain-id") +public class Migration004PermissionGroupDefaultWorkspaceIdMigration { private final MongoTemplate mongoTemplate; - public Migration003PermissionGroupDefaultWorkspaceIdMigration(MongoTemplate mongoTemplate) { + public Migration004PermissionGroupDefaultWorkspaceIdMigration(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004CreateIndexForApplicationSnapshotMigration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration005CreateIndexForApplicationSnapshotMigration.java similarity index 87% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004CreateIndexForApplicationSnapshotMigration.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration005CreateIndexForApplicationSnapshotMigration.java index 356cb1bc9f..02eca7bc18 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004CreateIndexForApplicationSnapshotMigration.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration005CreateIndexForApplicationSnapshotMigration.java @@ -12,11 +12,11 @@ import static com.appsmith.server.migrations.DatabaseChangelog1.ensureIndexes; import static com.appsmith.server.migrations.DatabaseChangelog1.makeIndex; import static com.appsmith.server.repositories.ce.BaseAppsmithRepositoryCEImpl.fieldName; -@ChangeUnit(order = "004", id = "create-index-for-application-snapshot-collection") -public class Migration004CreateIndexForApplicationSnapshotMigration { +@ChangeUnit(order = "005", id = "create-index-for-application-snapshot-collection") +public class Migration005CreateIndexForApplicationSnapshotMigration { private final MongoTemplate mongoTemplate; - public Migration004CreateIndexForApplicationSnapshotMigration(MongoTemplate mongoTemplate) { + public Migration005CreateIndexForApplicationSnapshotMigration(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004ResetOnPageLoadEdgesInLayouts.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration006ResetOnPageLoadEdgesInLayouts.java similarity index 89% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004ResetOnPageLoadEdgesInLayouts.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration006ResetOnPageLoadEdgesInLayouts.java index 1249fbf1bf..75ff97f304 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration004ResetOnPageLoadEdgesInLayouts.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration006ResetOnPageLoadEdgesInLayouts.java @@ -18,11 +18,11 @@ import org.springframework.data.mongodb.core.query.UpdateDefinition; * and this is essentially redundant information. * This migration gets rid of the edges property from the layout in all existing pages. */ -@ChangeUnit(order = "004", id = "reset-on-page-load-edges-in-layouts") -public class Migration004ResetOnPageLoadEdgesInLayouts { +@ChangeUnit(order = "006", id = "reset-on-page-load-edges-in-layouts") +public class Migration006ResetOnPageLoadEdgesInLayouts { private final MongoTemplate mongoTemplate; - public Migration004ResetOnPageLoadEdgesInLayouts(MongoTemplate mongoTemplate) { + public Migration006ResetOnPageLoadEdgesInLayouts(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration005OptOutUnsupportedPluginsForAirGap.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007OptOutUnsupportedPluginsForAirGap.java similarity index 93% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration005OptOutUnsupportedPluginsForAirGap.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007OptOutUnsupportedPluginsForAirGap.java index b1f8012250..0720aed5d7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration005OptOutUnsupportedPluginsForAirGap.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007OptOutUnsupportedPluginsForAirGap.java @@ -18,12 +18,12 @@ import static com.appsmith.external.constants.PluginConstants.PackageName.RAPID_ import static com.appsmith.external.constants.PluginConstants.PackageName.REDSHIFT_PLUGIN; import static com.appsmith.external.constants.PluginConstants.PackageName.SAAS_PLUGIN; -@ChangeUnit(order = "005", id = "opt-out-unsupported-plugins-airgap-instance", author = " ") -public class Migration005OptOutUnsupportedPluginsForAirGap { +@ChangeUnit(order = "007", id = "opt-out-unsupported-plugins-airgap-instance", author = " ") +public class Migration007OptOutUnsupportedPluginsForAirGap { private final MongoTemplate mongoTemplate; - public Migration005OptOutUnsupportedPluginsForAirGap(MongoTemplate mongoTemplate) { + public Migration007OptOutUnsupportedPluginsForAirGap(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration006SupportNonHostedPluginsForAirgap.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration008SupportNonHostedPluginsForAirgap.java similarity index 92% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration006SupportNonHostedPluginsForAirgap.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration008SupportNonHostedPluginsForAirgap.java index d4d9f6cec6..82acd7e8e4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration006SupportNonHostedPluginsForAirgap.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration008SupportNonHostedPluginsForAirgap.java @@ -18,11 +18,11 @@ import static com.appsmith.external.constants.PluginConstants.PackageName.DYNAMO import static com.appsmith.external.constants.PluginConstants.PackageName.FIRESTORE_PLUGIN; import static com.appsmith.external.constants.PluginConstants.PackageName.REDSHIFT_PLUGIN; -@ChangeUnit(order = "006", id = "support-non-self-hosted-plugins-for-airgap", author = " ") -public class Migration006SupportNonHostedPluginsForAirgap { +@ChangeUnit(order = "008", id = "support-non-self-hosted-plugins-for-airgap", author = " ") +public class Migration008SupportNonHostedPluginsForAirgap { private final MongoTemplate mongoTemplate; - public Migration006SupportNonHostedPluginsForAirgap(MongoTemplate mongoTemplate) { + public Migration008SupportNonHostedPluginsForAirgap(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007UpdateOracleLogoToSVG.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration009UpdateOracleLogoToSVG.java similarity index 84% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007UpdateOracleLogoToSVG.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration009UpdateOracleLogoToSVG.java index 1cce9894aa..60ae0be418 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007UpdateOracleLogoToSVG.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration009UpdateOracleLogoToSVG.java @@ -9,11 +9,11 @@ import org.springframework.data.mongodb.core.MongoTemplate; import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; -@ChangeUnit(order = "007", id = "update-oracle-logo-to-svg", author = " ") -public class Migration007UpdateOracleLogoToSVG { +@ChangeUnit(order = "009", id = "update-oracle-logo-to-svg", author = " ") +public class Migration009UpdateOracleLogoToSVG { private final MongoTemplate mongoTemplate; - public Migration007UpdateOracleLogoToSVG(MongoTemplate mongoTemplate) { + public Migration009UpdateOracleLogoToSVG(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007UpdatePluginDocsLink.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010UpdatePluginDocsLink.java similarity index 94% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007UpdatePluginDocsLink.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010UpdatePluginDocsLink.java index f8298976a0..9cfe5f87e3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration007UpdatePluginDocsLink.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010UpdatePluginDocsLink.java @@ -10,11 +10,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -@ChangeUnit(order = "007", id = "update-plugins-docs-link", author = " ") -public class Migration007UpdatePluginDocsLink { +@ChangeUnit(order = "010", id = "update-plugins-docs-link", author = " ") +public class Migration010UpdatePluginDocsLink { private final MongoTemplate mongoTemplate; - public Migration007UpdatePluginDocsLink(MongoTemplate mongoTemplate) { + public Migration010UpdatePluginDocsLink(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration008CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration011CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId.java similarity index 92% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration008CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration011CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId.java index 89cf0df358..27b81dabaf 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration008CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration011CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId.java @@ -13,8 +13,8 @@ import static com.appsmith.server.migrations.DatabaseChangelog1.ensureIndexes; import static com.appsmith.server.migrations.DatabaseChangelog1.makeIndex; import static com.appsmith.server.repositories.ce.BaseAppsmithRepositoryCEImpl.fieldName; -@ChangeUnit(order = "008", id = "create-index-default-domain-id-default-domain-type", author = " ") -public class Migration008CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId { +@ChangeUnit(order = "011", id = "create-index-default-domain-id-default-domain-type", author = " ") +public class Migration011CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId { private final MongoTemplate mongoTemplate; @@ -25,7 +25,7 @@ public class Migration008CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDef public static final String newPermissionGroupIndexNameDefaultDomainIdDefaultDomainType = "permission_group_domainId_domainType_deleted"; - public Migration008CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId( + public Migration011CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId( MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration009RemoveStructureFromWithinDatasource.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration012RemoveStructureFromWithinDatasource.java similarity index 91% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration009RemoveStructureFromWithinDatasource.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration012RemoveStructureFromWithinDatasource.java index 622cc42e8c..04e42e6b3c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration009RemoveStructureFromWithinDatasource.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration012RemoveStructureFromWithinDatasource.java @@ -14,14 +14,14 @@ import org.springframework.data.mongodb.core.query.Update; import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; -@ChangeUnit(order = "009", id = "remove-structure-from-within-datasource-modified") -public class Migration009RemoveStructureFromWithinDatasource { +@ChangeUnit(order = "012", id = "remove-structure-from-within-datasource-modified") +public class Migration012RemoveStructureFromWithinDatasource { private final MongoOperations mongoOperations; private final MongoTemplate mongoTemplate; - public Migration009RemoveStructureFromWithinDatasource( + public Migration012RemoveStructureFromWithinDatasource( MongoOperations mongoOperations, MongoTemplate mongoTemplate) { this.mongoOperations = mongoOperations; this.mongoTemplate = mongoTemplate; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010AddEmailBodyTypeToSMTPPlugin.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration013AddEmailBodyTypeToSMTPPlugin.java similarity index 93% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010AddEmailBodyTypeToSMTPPlugin.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration013AddEmailBodyTypeToSMTPPlugin.java index 1b79c5050d..e95d790d6b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010AddEmailBodyTypeToSMTPPlugin.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration013AddEmailBodyTypeToSMTPPlugin.java @@ -13,12 +13,12 @@ import static com.appsmith.server.migrations.MigrationHelperMethods.getQueryToFe import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; -@ChangeUnit(order = "010", id = "add-smtp-email-body-type", author = " ") -public class Migration010AddEmailBodyTypeToSMTPPlugin { +@ChangeUnit(order = "013", id = "add-smtp-email-body-type", author = " ") +public class Migration013AddEmailBodyTypeToSMTPPlugin { private final MongoTemplate mongoTemplate; - public Migration010AddEmailBodyTypeToSMTPPlugin(MongoTemplate mongoTemplate) { + public Migration013AddEmailBodyTypeToSMTPPlugin(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010AddIndexToDatasourceStorage.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration014AddIndexToDatasourceStorage.java similarity index 86% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010AddIndexToDatasourceStorage.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration014AddIndexToDatasourceStorage.java index 8e4ac5fe15..e4bed2de11 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration010AddIndexToDatasourceStorage.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration014AddIndexToDatasourceStorage.java @@ -10,12 +10,12 @@ import org.springframework.data.mongodb.core.index.Index; import static com.appsmith.server.migrations.DatabaseChangelog1.ensureIndexes; import static com.appsmith.server.migrations.DatabaseChangelog1.makeIndex; -@ChangeUnit(order = "010", id = "index-for-datasource-storage") -public class Migration010AddIndexToDatasourceStorage { +@ChangeUnit(order = "014", id = "index-for-datasource-storage") +public class Migration014AddIndexToDatasourceStorage { private final MongoTemplate mongoTemplate; - public Migration010AddIndexToDatasourceStorage(MongoTemplate mongoTemplate) { + public Migration014AddIndexToDatasourceStorage(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration011AddPluginTypeIndexToNewActionCollection.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration015AddPluginTypeIndexToNewActionCollection.java similarity index 88% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration011AddPluginTypeIndexToNewActionCollection.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration015AddPluginTypeIndexToNewActionCollection.java index d5b34e6f37..acaca03ca1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration011AddPluginTypeIndexToNewActionCollection.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration015AddPluginTypeIndexToNewActionCollection.java @@ -12,11 +12,11 @@ import static com.appsmith.server.migrations.DatabaseChangelog1.ensureIndexes; import static com.appsmith.server.migrations.DatabaseChangelog1.makeIndex; import static com.appsmith.server.repositories.ce.BaseAppsmithRepositoryCEImpl.fieldName; -@ChangeUnit(order = "011", id = "app-id-plugin-type-index-for-new-action", author = " ") -public class Migration011AddPluginTypeIndexToNewActionCollection { +@ChangeUnit(order = "015", id = "app-id-plugin-type-index-for-new-action", author = " ") +public class Migration015AddPluginTypeIndexToNewActionCollection { private final MongoTemplate mongoTemplate; - public Migration011AddPluginTypeIndexToNewActionCollection(MongoTemplate mongoTemplate) { + public Migration015AddPluginTypeIndexToNewActionCollection(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration012RenameIndexesWithLongNames.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration016RenameIndexesWithLongNames.java similarity index 97% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration012RenameIndexesWithLongNames.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration016RenameIndexesWithLongNames.java index e68060dfc7..2a580b1e2f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration012RenameIndexesWithLongNames.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration016RenameIndexesWithLongNames.java @@ -24,9 +24,9 @@ import static com.appsmith.server.migrations.DatabaseChangelog1.ensureIndexes; import static com.appsmith.server.migrations.DatabaseChangelog1.makeIndex; import static com.appsmith.server.repositories.ce.BaseAppsmithRepositoryCEImpl.fieldName; -@ChangeUnit(order = "012", id = "rename-indexes-with-long-names") +@ChangeUnit(order = "016", id = "rename-indexes-with-long-names") @RequiredArgsConstructor -public class Migration012RenameIndexesWithLongNames { +public class Migration016RenameIndexesWithLongNames { private final MongoTemplate mongoTemplate; @@ -125,7 +125,7 @@ public class Migration012RenameIndexesWithLongNames { fieldName(QPermissionGroup.permissionGroup.deleted), fieldName(QPermissionGroup.permissionGroup.deletedAt)) .named( - Migration008CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId + Migration011CreateIndexDefaultDomainIdDefaultDomainTypeDropIndexDefaultWorkspaceId .newPermissionGroupIndexNameDefaultDomainIdDefaultDomainType); ensureIndexes(mongoTemplate, PermissionGroup.class, newIndexDefaultDomainIdDefaultDomainTypeDeletedDeletedAt); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration013UnsetEncryptionVersion2Fields.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration017UnsetEncryptionVersion2Fields.java similarity index 96% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration013UnsetEncryptionVersion2Fields.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration017UnsetEncryptionVersion2Fields.java index 56d549b501..fc7667db0d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration013UnsetEncryptionVersion2Fields.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration017UnsetEncryptionVersion2Fields.java @@ -26,8 +26,8 @@ import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; @Slf4j -@ChangeUnit(order = "013", id = "unset-not-encrypted-encryption-version-2-fields", author = " ") -public class Migration013UnsetEncryptionVersion2Fields { +@ChangeUnit(order = "017", id = "unset-not-encrypted-encryption-version-2-fields", author = " ") +public class Migration017UnsetEncryptionVersion2Fields { private final MongoTemplate mongoTemplate; private static final int ENCRYPTION_VERSION = 2; @@ -52,7 +52,7 @@ public class Migration013UnsetEncryptionVersion2Fields { private static final String TOKEN_RESPONSE_QUALIFIED_NAME = AUTHENTICATION_RESPONSE_QUALIFIED_NAME + DELIMITER + TOKEN_RESPONSE; - public Migration013UnsetEncryptionVersion2Fields(MongoTemplate mongoTemplate) { + public Migration017UnsetEncryptionVersion2Fields(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration014UpdateOraclePluginDocumentationLink.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration018UpdateOraclePluginDocumentationLink.java similarity index 84% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration014UpdateOraclePluginDocumentationLink.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration018UpdateOraclePluginDocumentationLink.java index c4583d833e..df9bcd3877 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration014UpdateOraclePluginDocumentationLink.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration018UpdateOraclePluginDocumentationLink.java @@ -9,11 +9,11 @@ import org.springframework.data.mongodb.core.MongoTemplate; import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; -@ChangeUnit(order = "014", id = "update-oracle-doc-link", author = " ") -public class Migration014UpdateOraclePluginDocumentationLink { +@ChangeUnit(order = "018", id = "update-oracle-doc-link", author = " ") +public class Migration018UpdateOraclePluginDocumentationLink { private final MongoTemplate mongoTemplate; - public Migration014UpdateOraclePluginDocumentationLink(MongoTemplate mongoTemplate) { + public Migration018UpdateOraclePluginDocumentationLink(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration015RemoveNullEnvIdDatasourceStrucutureDocuments.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration019RemoveNullEnvIdDatasourceStructureDocuments.java similarity index 84% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration015RemoveNullEnvIdDatasourceStrucutureDocuments.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration019RemoveNullEnvIdDatasourceStructureDocuments.java index 09f380b57c..810b58573b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration015RemoveNullEnvIdDatasourceStrucutureDocuments.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration019RemoveNullEnvIdDatasourceStructureDocuments.java @@ -11,13 +11,13 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @Slf4j -@ChangeUnit(order = "015", id = "delete-null-envId-key-document", author = " ") -public class Migration015RemoveNullEnvIdDatasourceStrucutureDocuments { +@ChangeUnit(order = "019", id = "delete-null-envId-key-document", author = " ") +public class Migration019RemoveNullEnvIdDatasourceStructureDocuments { private final MongoTemplate mongoTemplate; private static final String environmentId = FieldName.ENVIRONMENT_ID; - public Migration015RemoveNullEnvIdDatasourceStrucutureDocuments(MongoTemplate mongoTemplate) { + public Migration019RemoveNullEnvIdDatasourceStructureDocuments(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration109TransferToDatasourceStorage.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration020TransferToDatasourceStorage.java similarity index 98% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration109TransferToDatasourceStorage.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration020TransferToDatasourceStorage.java index c849a6c9b0..1cd6882270 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration109TransferToDatasourceStorage.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration020TransferToDatasourceStorage.java @@ -34,7 +34,7 @@ import static org.springframework.data.mongodb.core.query.Query.query; // 107-ee, // as this migration has EE overrides for default environmentId, and for getting the environments on existing // workspaces, 107-ee needs to run -public class Migration109TransferToDatasourceStorage { +public class Migration020TransferToDatasourceStorage { private final MongoTemplate mongoTemplate; private final String migrationFlag = "hasDatasourceStorage"; @@ -46,7 +46,7 @@ public class Migration109TransferToDatasourceStorage { private final DatasourceStorageMigrationSolution solution = new DatasourceStorageMigrationSolution(); - public Migration109TransferToDatasourceStorage(MongoTemplate mongoTemplate) { + public Migration020TransferToDatasourceStorage(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration016MoveGoogleMapsKeyToTenantConfiguration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration021MoveGoogleMapsKeyToTenantConfiguration.java similarity index 94% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration016MoveGoogleMapsKeyToTenantConfiguration.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration021MoveGoogleMapsKeyToTenantConfiguration.java index 72277065bb..478c8d2ba6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration016MoveGoogleMapsKeyToTenantConfiguration.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration021MoveGoogleMapsKeyToTenantConfiguration.java @@ -21,8 +21,8 @@ import static org.springframework.data.mongodb.core.query.Criteria.where; @Slf4j @RequiredArgsConstructor -@ChangeUnit(order = "016", id = "move-google-maps-key-to-tenant-configuration") -public class Migration016MoveGoogleMapsKeyToTenantConfiguration { +@ChangeUnit(order = "021", id = "move-google-maps-key-to-tenant-configuration") +public class Migration021MoveGoogleMapsKeyToTenantConfiguration { private final MongoTemplate mongoTemplate; private final CommonConfig commonConfig; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/UpdateSuperUserMigrationHelper.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/UpdateSuperUserMigrationHelper.java new file mode 100644 index 0000000000..7c7f557153 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/UpdateSuperUserMigrationHelper.java @@ -0,0 +1,7 @@ +package com.appsmith.server.migrations.solutions; + +import com.appsmith.server.migrations.solutions.ce.UpdateSuperUserMigrationHelperCE; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class UpdateSuperUserMigrationHelper extends UpdateSuperUserMigrationHelperCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/ce/UpdateSuperUserMigrationHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/ce/UpdateSuperUserMigrationHelperCE.java new file mode 100644 index 0000000000..0140775476 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/ce/UpdateSuperUserMigrationHelperCE.java @@ -0,0 +1,77 @@ +package com.appsmith.server.migrations.solutions.ce; + +import com.appsmith.external.models.Policy; +import com.appsmith.server.acl.PolicyGenerator; +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.domains.PermissionGroup; +import com.appsmith.server.domains.Tenant; +import com.appsmith.server.domains.User; +import com.appsmith.server.dtos.Permission; +import com.appsmith.server.solutions.PolicySolution; +import org.springframework.data.mongodb.core.MongoTemplate; + +import java.time.Instant; +import java.util.HashSet; +import java.util.Set; + +import static com.appsmith.server.acl.AclPermission.MANAGE_USERS; +import static com.appsmith.server.acl.AclPermission.READ_USERS; +import static com.appsmith.server.acl.AclPermission.RESET_PASSWORD_USERS; + +public class UpdateSuperUserMigrationHelperCE { + protected Set generateUserPolicy( + User user, + PermissionGroup userManagementRole, + PermissionGroup instanceAdminRole, + Tenant tenant, + PolicySolution policySolution, + PolicyGenerator policyGenerator) { + Policy readUserPolicy = Policy.builder() + .permission(READ_USERS.getValue()) + .permissionGroups(Set.of(userManagementRole.getId())) + .build(); + Policy manageUserPolicy = Policy.builder() + .permission(MANAGE_USERS.getValue()) + .permissionGroups(Set.of(userManagementRole.getId())) + .build(); + Policy resetPwdPolicy = Policy.builder() + .permission(RESET_PASSWORD_USERS.getValue()) + .permissionGroups(Set.of(userManagementRole.getId())) + .build(); + + return new HashSet<>(Set.of(readUserPolicy, manageUserPolicy, resetPwdPolicy)); + } + + public User createNewUser( + String email, + Tenant tenant, + PermissionGroup instanceAdminRole, + MongoTemplate mongoTemplate, + PolicySolution policySolution, + PolicyGenerator policyGenerator) { + User user = new User(); + user.setEmail(email); + user.setIsEnabled(false); + user.setTenantId(tenant.getId()); + user.setCreatedAt(Instant.now()); + user = mongoTemplate.save(user); + + // Assign the user to the default permissions + PermissionGroup userManagementPermissionGroup = new PermissionGroup(); + userManagementPermissionGroup.setName(user.getUsername() + FieldName.SUFFIX_USER_MANAGEMENT_ROLE); + // Add CRUD permissions for user to the group + userManagementPermissionGroup.setPermissions(Set.of(new Permission(user.getId(), MANAGE_USERS))); + + // Assign the permission group to the user + userManagementPermissionGroup.setAssignedToUserIds(Set.of(user.getId())); + + PermissionGroup savedPermissionGroup = mongoTemplate.save(userManagementPermissionGroup); + + Set userPolicies = this.generateUserPolicy( + user, savedPermissionGroup, instanceAdminRole, tenant, policySolution, policyGenerator); + + user.setPolicies(userPolicies); + + return mongoTemplate.save(user); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java index adb3052186..a7606e9d8b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java @@ -3,6 +3,7 @@ package com.appsmith.server.services; import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.configurations.CommonConfig; import com.appsmith.server.services.ce.CacheableFeatureFlagHelperCEImpl; +import com.appsmith.server.solutions.ReleaseNotesService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -15,7 +16,14 @@ public class CacheableFeatureFlagHelperImpl extends CacheableFeatureFlagHelperCE ConfigService configService, CloudServicesConfig cloudServicesConfig, CommonConfig commonConfig, - UserIdentifierService userIdentifierService) { - super(tenantService, configService, cloudServicesConfig, commonConfig, userIdentifierService); + UserIdentifierService userIdentifierService, + ReleaseNotesService releaseNotesService) { + super( + tenantService, + configService, + cloudServicesConfig, + commonConfig, + userIdentifierService, + releaseNotesService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java index c6015953a6..20f563654f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java @@ -1,6 +1,9 @@ package com.appsmith.server.services.ce; import com.appsmith.server.domains.User; +import com.appsmith.server.dtos.ce.FeaturesRequestDTO; +import com.appsmith.server.dtos.ce.FeaturesResponseDTO; +import com.appsmith.server.featureflags.CachedFeatures; import com.appsmith.server.featureflags.CachedFlags; import reactor.core.publisher.Mono; @@ -9,4 +12,39 @@ public interface CacheableFeatureFlagHelperCE { Mono fetchUserCachedFlags(String userIdentifier, User user); Mono evictUserCachedFlags(String userIdentifier); + + /** + * To fetch the tenant current features via cache + * @param tenantId Id of the tenant + * @return Mono of CachedFeatures + */ + Mono fetchCachedTenantCurrentFeatures(String tenantId); + + /** + * To evict the tenant current features cache + * @param tenantId Id of the tenant + * @return Mono of Void + */ + Mono evictCachedTenantCurrentFeatures(String tenantId); + + /** + * To fetch the tenant new features via cache + * @param tenantId Id of the tenant + * @return Mono of CachedFeatures + */ + Mono fetchCachedTenantNewFeatures(String tenantId); + + /** + * To evict the tenant new features cache + * @param tenantId Id of the tenant + * @return Mono of Void + */ + Mono evictCachedTenantNewFeatures(String tenantId); + + /** + * To get all tenant features from Cloud Services + * @param featuresRequestDTO FeaturesRequestDTO + * @return Mono of Map + */ + Mono getRemoteFeaturesForTenant(FeaturesRequestDTO featuresRequestDTO); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java index 2f88032405..a3ebf29fc0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java @@ -6,13 +6,17 @@ import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.configurations.CommonConfig; import com.appsmith.server.domains.User; import com.appsmith.server.dtos.ResponseDTO; +import com.appsmith.server.dtos.ce.FeaturesRequestDTO; +import com.appsmith.server.dtos.ce.FeaturesResponseDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; +import com.appsmith.server.featureflags.CachedFeatures; import com.appsmith.server.featureflags.CachedFlags; import com.appsmith.server.featureflags.FeatureFlagIdentityTraits; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserIdentifierService; +import com.appsmith.server.solutions.ReleaseNotesService; import com.appsmith.util.WebClientUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.core.ParameterizedTypeReference; @@ -35,18 +39,21 @@ public class CacheableFeatureFlagHelperCEImpl implements CacheableFeatureFlagHel private final CommonConfig commonConfig; private final UserIdentifierService userIdentifierService; + private final ReleaseNotesService releaseNotesService; public CacheableFeatureFlagHelperCEImpl( TenantService tenantService, ConfigService configService, CloudServicesConfig cloudServicesConfig, CommonConfig commonConfig, - UserIdentifierService userIdentifierService) { + UserIdentifierService userIdentifierService, + ReleaseNotesService releaseNotesService) { this.tenantService = tenantService; this.configService = configService; this.cloudServicesConfig = cloudServicesConfig; this.commonConfig = commonConfig; this.userIdentifierService = userIdentifierService; + this.releaseNotesService = releaseNotesService; } @Cache(cacheName = "featureFlag", key = "{#userIdentifier}") @@ -73,7 +80,10 @@ public class CacheableFeatureFlagHelperCEImpl implements CacheableFeatureFlagHel userTraits.put("instanceId", instanceId); userTraits.put("tenantId", user.getTenantId()); userTraits.put("isTelemetryOn", !commonConfig.isTelemetryDisabled()); - userTraits.put("createdAt", user.getCreatedAt()); + // for anonymous user, user.getCreatedAt() is null + if (user.getCreatedAt() != null) { + userTraits.put("createdAt", user.getCreatedAt().getEpochSecond()); + } userTraits.put("defaultTraitsUpdatedAt", Instant.now().getEpochSecond()); userTraits.put("type", "user"); return userTraits; @@ -131,4 +141,102 @@ public class CacheableFeatureFlagHelperCEImpl implements CacheableFeatureFlagHel return Mono.just(Map.of()); }); } + + /** + * To fetch the tenant current features via cache + * @param tenantId Id of the tenant + * @return Mono of CachedFeatures + */ + @Cache(cacheName = "tenantCurrentFeatures", key = "{#tenantId}") + public Mono fetchCachedTenantCurrentFeatures(String tenantId) { + // TODO: Add logic to fetch default or current features from persistent storage + // TODO: Store the current features to DB for safe storage + // TODO: Update cache and persistent storage with newFeatures when migration is applied + return Mono.empty(); + } + + /** + * To evict the tenant current features cache + * @param tenantId Id of the tenant + * @return Mono of Void + */ + @CacheEvict(cacheName = "tenantCurrentFeatures", key = "{#tenantId}") + public Mono evictCachedTenantCurrentFeatures(String tenantId) { + return Mono.empty(); + } + + /** + * To fetch the tenant new features via cache + * @param tenantId Id of the tenant + * @return Mono of CachedFeatures + */ + @Cache(cacheName = "tenantNewFeatures", key = "{#tenantId}") + public Mono fetchCachedTenantNewFeatures(String tenantId) { + return this.forceAllRemoteFeaturesForTenant(tenantId).flatMap(flags -> { + CachedFeatures cachedFeatures = new CachedFeatures(); + cachedFeatures.setRefreshedAt(Instant.now()); + cachedFeatures.setFeatures(flags); + return Mono.just(cachedFeatures); + }); + } + + /** + * To evict the tenant new features cache + * @param tenantId Id of the tenant + * @return Mono of Void + */ + @CacheEvict(cacheName = "tenantNewFeatures", key = "{#tenantId}") + public Mono evictCachedTenantNewFeatures(String tenantId) { + return Mono.empty(); + } + + /** + * To force fetch all tenant features from Cloud Services + * @param tenantId Id of the tenant + * @return Mono of Map + */ + private Mono> forceAllRemoteFeaturesForTenant(String tenantId) { + Mono instanceIdMono = configService.getInstanceId(); + String appsmithVersion = releaseNotesService.getRunningVersion(); + return instanceIdMono + .map(instanceId -> { + FeaturesRequestDTO featuresRequestDTO = new FeaturesRequestDTO(); + featuresRequestDTO.setTenantId(tenantId); + featuresRequestDTO.setInstanceId(instanceId); + featuresRequestDTO.setAppsmithVersion(appsmithVersion); + + return featuresRequestDTO; + }) + .flatMap(this::getRemoteFeaturesForTenant) + .map(featuresMap -> featuresMap.getFeatures()); + } + + /** + * To get all tenant features from Cloud Services + * @param featuresRequestDTO FeaturesRequestDTO + * @return Mono of Map + */ + public Mono getRemoteFeaturesForTenant(FeaturesRequestDTO featuresRequestDTO) { + return WebClientUtils.create(cloudServicesConfig.getBaseUrl()) + .post() + .uri("/api/v1/business-features") + .body(BodyInserters.fromValue(featuresRequestDTO)) + .exchangeToMono(clientResponse -> { + if (clientResponse.statusCode().is2xxSuccessful()) { + return clientResponse.bodyToMono( + new ParameterizedTypeReference>() {}); + } else { + return clientResponse.createError(); + } + }) + .map(ResponseDTO::getData) + .onErrorMap( + // Only map errors if we haven't already wrapped them into an AppsmithException + e -> !(e instanceof AppsmithException), + e -> new AppsmithException(AppsmithError.CLOUD_SERVICES_ERROR, e.getMessage())) + .onErrorResume(error -> { + log.debug("Received error from CS while fetching features: {}", error.getMessage()); + return Mono.just(new FeaturesResponseDTO()); + }); + } } 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 7f7d4eb1e9..b146c343e5 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 @@ -20,19 +20,16 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; -import org.apache.http.NameValuePair; -import org.apache.http.client.utils.URLEncodedUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; import java.net.MalformedURLException; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; import java.util.List; import java.util.Map; @@ -500,19 +497,12 @@ public class CurlImporterServiceCEImpl extends BaseApiImporter implements CurlIm log.debug("cURL import URL: '{}', path: '{}' baseUrl: '{}'", url, path, base); // Extract query params. - URI uri = url.toURI(); - List params = URLEncodedUtils.parse(uri, StandardCharsets.UTF_8); final ActionConfiguration actionConfiguration = action.getActionConfiguration(); - List queryParameters = actionConfiguration.getQueryParameters(); - - if (queryParameters == null) { - queryParameters = new ArrayList<>(); - actionConfiguration.setQueryParameters(queryParameters); - } - - for (NameValuePair param : params) { - queryParameters.add(new Property(param.getName(), param.getValue())); - } + List queryParameters = actionConfiguration.getQueryParameters() == null + ? new ArrayList<>() + : actionConfiguration.getQueryParameters(); + queryParameters.addAll(getQueryParams(url)); + actionConfiguration.setQueryParameters(queryParameters); // Set the URL without the query params & the path. action.getDatasource().getDatasourceConfiguration().setUrl(base); @@ -521,6 +511,26 @@ public class CurlImporterServiceCEImpl extends BaseApiImporter implements CurlIm actionConfiguration.setPath(path); } + private List getQueryParams(URL url) { + List queryParamsList = new ArrayList<>(); + String queryParamsString = url.getQuery(); + + /** + * Attempt to extract query params only if the query params string is non-empty, and it has at least one key + * value pair. + */ + if (!isBlank(queryParamsString) && queryParamsString.contains("=")) { + Arrays.stream(queryParamsString.split("&")).forEach(queryParam -> { + String[] paramMap = queryParam.split("=", 2); + if (paramMap.length > 1) { + queryParamsList.add(new Property(paramMap[0], paramMap[1])); + } + }); + } + + return queryParamsList; + } + private String getPort(URL url) { if (url.getPort() != -1) { return ":" + url.getPort(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java index fe4a1d038a..58948f53ba 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java @@ -35,4 +35,16 @@ public interface FeatureFlagServiceCE { * @return Mono> */ Mono> getAllFeatureFlagsForUser(); + + /** + * To get all features of the tenant from Cloud Services and store them locally + * @return Mono of Void + */ + Mono getAllRemoteFeaturesForTenant(); + + /** + * To get all features of the current tenant. + * @return Mono of Map + */ + Mono> getCurrentTenantFeatures(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java index 7b59581222..1c8364c1ae 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java @@ -36,6 +36,8 @@ public class FeatureFlagServiceCEImpl implements FeatureFlagServiceCE { private final long featureFlagCacheTimeMin = 120; + private final long tenantFeaturesCacheTimeMin = 120; + private final UserIdentifierService userIdentifierService; private final CacheableFeatureFlagHelper cacheableFeatureFlagHelper; @@ -132,4 +134,41 @@ public class FeatureFlagServiceCEImpl implements FeatureFlagServiceCE { }); }); } + + /** + * To get all features of the tenant from Cloud Services and store them locally + * @return Mono of Void + */ + public Mono getAllRemoteFeaturesForTenant() { + return tenantService + .getDefaultTenantId() + .flatMap(defaultTenantId -> { + return cacheableFeatureFlagHelper + .fetchCachedTenantNewFeatures(defaultTenantId) + .map(cachedFeatures -> { + if (cachedFeatures.getRefreshedAt().until(Instant.now(), ChronoUnit.MINUTES) + < this.tenantFeaturesCacheTimeMin) { + return cachedFeatures; + } else { + return cacheableFeatureFlagHelper + .evictCachedTenantNewFeatures(defaultTenantId) + .then(cacheableFeatureFlagHelper.fetchCachedTenantNewFeatures( + defaultTenantId)); + } + }); + }) + .then(); + } + + /** + * To get all features of the current tenant. + * @return Mono of Map + */ + public Mono> getCurrentTenantFeatures() { + return tenantService + .getDefaultTenantId() + // TODO: Update to call fetchCachedTenantCurrentFeatures once default value storing is complete + .flatMap(defaultTenantId -> cacheableFeatureFlagHelper.fetchCachedTenantNewFeatures(defaultTenantId)) + .map(cachedFeatures -> cachedFeatures.getFeatures()); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java index 6ac3fec055..c7e956d900 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java @@ -147,6 +147,9 @@ public class GitServiceCEImpl implements GitServiceCE { private static final Duration RETRY_DELAY = Duration.ofSeconds(1); private static final Integer MAX_RETRIES = 20; + // @Value("${appsmith.index.lock.file.time:900}") + private int MAX_STALE_TIME = 900; // Default value is 15 minutes + @Override public Mono updateGitMetadata(String applicationId, GitApplicationMetadata gitApplicationMetadata) { @@ -512,7 +515,6 @@ public class GitServiceCEImpl implements GitServiceCE { childApplication.getWorkspaceId(), gitData.getDefaultApplicationId(), gitData.getRepoName()); - Mono repoPathMono; try { repoPathMono = executionTimeLogging.measureTask( @@ -609,7 +611,7 @@ public class GitServiceCEImpl implements GitServiceCE { // Push flow result.append(".\nPush Result : "); return executionTimeLogging - .measureTask("pushApplication", pushApplication(childApplication.getId(), false)) + .measureTask("pushApplication", pushApplication(childApplication.getId(), false, false)) .map(pushResult -> result.append(pushResult).toString()) .zipWith(Mono.just(childApplication)); } @@ -1016,7 +1018,7 @@ public class GitServiceCEImpl implements GitServiceCE { } return applicationService .findBranchedApplicationId(branchName, defaultApplicationId, applicationPermission.getEditPermission()) - .flatMap(applicationId -> pushApplication(applicationId, true)); + .flatMap(applicationId -> pushApplication(applicationId, true, true)); } /** @@ -1025,7 +1027,7 @@ public class GitServiceCEImpl implements GitServiceCE { * @param applicationId application which needs to be pushed to remote repo * @return Success message */ - private Mono pushApplication(String applicationId, boolean doPublish) { + private Mono pushApplication(String applicationId, boolean doPublish, boolean isFileLock) { Mono pushStatusMono = publishAndOrGetApplication(applicationId, doPublish) .flatMap(application -> { @@ -1044,6 +1046,14 @@ public class GitServiceCEImpl implements GitServiceCE { return application; }); }) + .flatMap(application -> { + if (Boolean.TRUE.equals(isFileLock)) { + return addFileLock( + application.getGitApplicationMetadata().getDefaultApplicationId()) + .map(status -> application); + } + return Mono.just(application); + }) .flatMap(application -> { GitApplicationMetadata gitData = application.getGitApplicationMetadata(); @@ -1128,6 +1138,16 @@ public class GitServiceCEImpl implements GitServiceCE { return Mono.just(pushResult).zipWith(Mono.just(tuple.getT2())); }) // Add BE analytics + .flatMap(tuple -> { + String pushStatus = tuple.getT1(); + Application application = tuple.getT2(); + if (Boolean.TRUE.equals(isFileLock)) { + return releaseFileLock( + application.getGitApplicationMetadata().getDefaultApplicationId()) + .map(status -> tuple); + } + return Mono.zip(Mono.just(pushStatus), Mono.just(application)); + }) .flatMap(tuple -> { String pushStatus = tuple.getT1(); Application application = tuple.getT2(); @@ -1437,12 +1457,12 @@ public class GitServiceCEImpl implements GitServiceCE { } private Mono checkoutRemoteBranch(String defaultApplicationId, String branchName) { - Mono checkoutRemoteBranchMono = getApplicationById(defaultApplicationId) + Mono checkoutRemoteBranchMono = addFileLock(defaultApplicationId) + .flatMap(status -> getApplicationById(defaultApplicationId)) .flatMap(application -> { GitApplicationMetadata gitApplicationMetadata = application.getGitApplicationMetadata(); String repoName = gitApplicationMetadata.getRepoName(); Path repoPath = Paths.get(application.getWorkspaceId(), defaultApplicationId, repoName); - return gitExecutor .fetchRemote( repoPath, @@ -1529,7 +1549,9 @@ public class GitServiceCEImpl implements GitServiceCE { Boolean.TRUE.equals(application1 .getGitApplicationMetadata() .getIsRepoPrivate()))) - .map(responseUtils::updateApplicationWithDefaultResources); + .map(responseUtils::updateApplicationWithDefaultResources) + .flatMap(application1 -> + releaseFileLock(defaultApplicationId).then(Mono.just(application1))); }); return Mono.create( @@ -1606,7 +1628,9 @@ public class GitServiceCEImpl implements GitServiceCE { @Override public Mono> listBranchForApplication( String defaultApplicationId, Boolean pruneBranches, String currentBranch) { + // File lock Mono> branchMono = getApplicationById(defaultApplicationId) + .flatMap(application -> addFileLock(defaultApplicationId).map(status -> application)) .flatMap(application -> { GitApplicationMetadata gitApplicationMetadata = application.getGitApplicationMetadata(); if (gitApplicationMetadata == null || gitApplicationMetadata.getDefaultApplicationId() == null) { @@ -1653,6 +1677,7 @@ public class GitServiceCEImpl implements GitServiceCE { AppsmithError.GIT_ACTION_FAILED, "branch --list", error.getMessage())); }); }) + .flatMap(objects -> releaseFileLock(defaultApplicationId).thenReturn(objects)) .flatMap(tuple -> { List gitBranchListDTOS = tuple.getT1(); Application application = tuple.getT2(); @@ -1757,22 +1782,45 @@ public class GitServiceCEImpl implements GitServiceCE { return executionTimeLogging.measureTask( "checkoutBranch", checkoutBranch(defaultApplicationId, finalBranchName)); }) - .zipWhen(application -> executionTimeLogging.measureTask( - "getStatus->exportApplicationById", - importExportApplicationService.exportApplicationById( - application.getId(), SerialiseApplicationObjective.VERSION_CONTROL))); + .zipWhen(application -> { + Path repoSuffix = Paths.get( + application.getWorkspaceId(), + gitApplicationMetadata.getDefaultApplicationId(), + gitApplicationMetadata.getRepoName()); + GitAuth gitAuth = gitApplicationMetadata.getGitAuth(); + + // Create a Mono to fetch the status from remote + Mono fetchRemoteMono = executionTimeLogging.measureTask( + "getStatus->gitExecutor.fetchRemote", + gitExecutor + .fetchRemote( + repoSuffix, + gitAuth.getPublicKey(), + gitAuth.getPrivateKey(), + false, + branchName, + false) + .onErrorResume(error -> Mono.error(new AppsmithException( + AppsmithError.GIT_GENERIC_ERROR, error.getMessage())))); + + Mono exportAppMono = executionTimeLogging.measureTask( + "getStatus->exportApplicationById", + importExportApplicationService.exportApplicationById( + application.getId(), SerialiseApplicationObjective.VERSION_CONTROL)); + + return Mono.zip(exportAppMono, fetchRemoteMono) // zip will run them in parallel + .elapsed() + .map(objects -> { + log.debug("Time to fetch remote and export app: {} ms", objects.getT1()); + // we need the applicationJson only + return objects.getT2().getT1(); + }); + }); if (Boolean.TRUE.equals(isFileLock)) { // Add file lock for the status API call to avoid sending wrong info on the status return executionTimeLogging - .measureTask( - "addFileLock", - redisUtils.addFileLock(gitApplicationMetadata.getDefaultApplicationId())) - .retryWhen(Retry.fixedDelay(MAX_RETRIES, RETRY_DELAY) - .jitter(0.75) - .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { - throw new AppsmithException(AppsmithError.GIT_FILE_IN_USE); - })) + .measureTask("addFileLock", addFileLock(defaultApplicationId)) .then(Mono.zip(Mono.just(gitApplicationMetadata), applicationJsonTuple)); } return Mono.zip(Mono.just(gitApplicationMetadata), applicationJsonTuple); @@ -1793,7 +1841,8 @@ public class GitServiceCEImpl implements GitServiceCE { fileUtils.saveApplicationToLocalRepo( repoSuffix, applicationJson, finalBranchName)), Mono.just(gitData.getGitAuth()), - Mono.just(repoSuffix)); + Mono.just(repoSuffix), + Mono.just(application)); } catch (IOException | GitAPIException e) { return Mono.error( new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "status", e.getMessage())); @@ -1805,18 +1854,9 @@ public class GitServiceCEImpl implements GitServiceCE { gitExecutor .getStatus(tuple.getT1(), finalBranchName) .cache()); + try { - return executionTimeLogging - .measureTask( - "getStatus->gitExecutor.fetchRemote", - gitExecutor.fetchRemote( - tuple.getT1(), - tuple.getT2().getPublicKey(), - tuple.getT2().getPrivateKey(), - true, - branchName, - false)) - .then(branchedStatusMono) + return branchedStatusMono // Remove any files which are copied by hard resetting the repo .then(executionTimeLogging.measureTask( "getStatus->gitExecutor.resetToLastCommit", @@ -1834,6 +1874,7 @@ public class GitServiceCEImpl implements GitServiceCE { .onErrorResume(error -> Mono.error(new AppsmithException( AppsmithError.GIT_ACTION_FAILED, "status", error.getMessage()))); } catch (GitAPIException | IOException e) { + log.error("error occurred", e); return Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR, e.getMessage())); } }); @@ -2036,13 +2077,8 @@ public class GitServiceCEImpl implements GitServiceCE { gitApplicationMetadata.getRepoName()); // 1. Hydrate from db to file system for both branch Applications - return redisUtils - .addFileLock(gitApplicationMetadata.getDefaultApplicationId()) - .retryWhen(Retry.fixedDelay(MAX_RETRIES, RETRY_DELAY) - .jitter(0.75) - .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { - throw new AppsmithException(AppsmithError.GIT_FILE_IN_USE); - })) + // Update function call + return addFileLock(defaultApplicationId) .flatMap(status -> this.getStatus(defaultApplicationId, sourceBranch, false)) .flatMap(srcBranchStatus -> { if (!Integer.valueOf(0).equals(srcBranchStatus.getBehindCount())) { @@ -2504,6 +2540,7 @@ public class GitServiceCEImpl implements GitServiceCE { @Override public Mono deleteBranch(String defaultApplicationId, String branchName) { Mono deleteBranchMono = getApplicationById(defaultApplicationId) + .flatMap(application -> addFileLock(defaultApplicationId).map(status -> application)) .flatMap(application -> { GitApplicationMetadata gitApplicationMetadata = application.getGitApplicationMetadata(); Path repoPath = Paths.get( @@ -2525,6 +2562,8 @@ public class GitServiceCEImpl implements GitServiceCE { return Mono.error(new AppsmithException( AppsmithError.GIT_ACTION_FAILED, "delete branch", throwable.getMessage())); }) + .flatMap(isBranchDeleted -> + releaseFileLock(defaultApplicationId).map(status -> isBranchDeleted)) .flatMap(isBranchDeleted -> { if (Boolean.FALSE.equals(isBranchDeleted)) { return Mono.error(new AppsmithException( @@ -2577,7 +2616,6 @@ public class GitServiceCEImpl implements GitServiceCE { .findByBranchNameAndDefaultApplicationId( branchName, defaultApplicationId, applicationPermission.getEditPermission()) .cache(); - Mono defaultApplicationMono = this.getApplicationById(defaultApplicationId); Mono discardChangeMono; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCEImpl.java index 79dc02bcca..3369013cc4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCEImpl.java @@ -120,6 +120,12 @@ public class TenantServiceCEImpl extends BaseService { + if (tenant.getTenantConfiguration() == null) { + tenant.setTenantConfiguration(new TenantConfiguration()); + } + return tenant; + }) .flatMap(tenant -> repository.setUserPermissionsInObject(tenant).switchIfEmpty(Mono.just(tenant))); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java index fcc8a81501..73ec4a11e0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java @@ -303,7 +303,14 @@ public class UserDataServiceCEImpl extends BaseService> getFeatureFlagsForCurrentUser() { - return featureFlagService.getAllFeatureFlagsForUser(); + return Mono.zip(featureFlagService.getAllFeatureFlagsForUser(), featureFlagService.getCurrentTenantFeatures()) + .map(tuple -> { + Map featureFlags = tuple.getT1(); + Map features = tuple.getT2(); + featureFlags.putAll(features); + + return featureFlags; + }); } /** diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTask.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTask.java new file mode 100644 index 0000000000..5a9d50f221 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTask.java @@ -0,0 +1,5 @@ +package com.appsmith.server.solutions; + +import com.appsmith.server.solutions.ce.ScheduledTaskCE; + +public interface ScheduledTask extends ScheduledTaskCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTaskImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTaskImpl.java new file mode 100644 index 0000000000..408275d9e6 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTaskImpl.java @@ -0,0 +1,10 @@ +package com.appsmith.server.solutions; + +import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.solutions.ce.ScheduledTaskCEImpl; + +public class ScheduledTaskImpl extends ScheduledTaskCEImpl implements ScheduledTask { + public ScheduledTaskImpl(FeatureFlagService featureFlagService) { + super(featureFlagService); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java index c82de2ce9d..91659a0aca 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java @@ -113,6 +113,7 @@ import static com.appsmith.server.constants.ResourceModes.EDIT; import static com.appsmith.server.constants.ResourceModes.VIEW; import static com.appsmith.server.helpers.ImportExportUtils.sanitizeDatasourceInActionDTO; import static com.appsmith.server.helpers.ImportExportUtils.setPropertiesToExistingApplication; +import static com.appsmith.server.helpers.ImportExportUtils.setPublishedApplicationProperties; import static java.lang.Boolean.TRUE; @Slf4j @@ -1200,6 +1201,13 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica unpublishedPages.addAll(existingApplication.getPages()); return Mono.just(existingApplication); } + // This method sets the published mode properties in the imported + // application.When a user imports an application from the git repo, + // since the git only stores the unpublished version, the current + // deployed version in the newly imported app is not updated. + // This function sets the initial deployed version to the same as the + // edit mode one. + setPublishedApplicationProperties(importedApplication); setPropertiesToExistingApplication( importedApplication, existingApplication); // We are expecting the changes present in DB are committed to git diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCE.java new file mode 100644 index 0000000000..c4c5a1f0e3 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCE.java @@ -0,0 +1,5 @@ +package com.appsmith.server.solutions.ce; + +public interface ScheduledTaskCE { + void fetchFeatures(); +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCEImpl.java new file mode 100644 index 0000000000..d135746d70 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCEImpl.java @@ -0,0 +1,25 @@ +package com.appsmith.server.solutions.ce; + +import com.appsmith.server.services.FeatureFlagService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import reactor.core.scheduler.Schedulers; + +@RequiredArgsConstructor +@Slf4j +@Component +public class ScheduledTaskCEImpl implements ScheduledTaskCE { + private final FeatureFlagService featureFlagService; + + @Scheduled(initialDelay = 10 * 1000 /* ten seconds */, fixedRate = 2 * 60 * 60 * 1000 /* two hours */) + public void fetchFeatures() { + log.info("Fetching features for default tenant"); + featureFlagService + .getAllRemoteFeaturesForTenant() + .doOnError(error -> log.error("Error while fetching features from Cloud Services {0}", error)) + .subscribeOn(Schedulers.boundedElastic()) + .subscribe(); + } +} diff --git a/app/server/appsmith-server/src/main/resources/application.properties b/app/server/appsmith-server/src/main/resources/application.properties index 46ff8eb983..240dbc38d3 100644 --- a/app/server/appsmith-server/src/main/resources/application.properties +++ b/app/server/appsmith-server/src/main/resources/application.properties @@ -76,7 +76,7 @@ admin.emails = ${APPSMITH_ADMIN_EMAILS:} emails.welcome.enabled = ${APPSMITH_EMAILS_WELCOME_ENABLED:true} # Appsmith Cloud Services -appsmith.cloud_services.base_url = ${APPSMITH_CLOUD_SERVICES_BASE_URL:https://cs.appsmith.com} +appsmith.cloud_services.base_url = ${APPSMITH_CLOUD_SERVICES_BASE_URL:} appsmith.cloud_services.username = ${APPSMITH_CLOUD_SERVICES_USERNAME:} appsmith.cloud_services.password = ${APPSMITH_CLOUD_SERVICES_PASSWORD:} github_repo = ${APPSMITH_GITHUB_REPO:} @@ -112,3 +112,6 @@ appsmith.admin.envfile=${APPSMITH_ENVFILE_PATH:/appsmith-stacks/configuration/do appsmith.rts.port=${APPSMITH_RTS_PORT:8091} appsmith.internal.password=${APPSMITH_INTERNAL_PASSWORD:} + +# GIT stale index.lock file valid time +appsmith.index.lock.file.time=${APPSMITH_INDEX_LOCK_FILE_TIME:900} diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/ApplicationControllerTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/ApplicationControllerTest.java index e4b5f063e1..890159b2bb 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/ApplicationControllerTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/ApplicationControllerTest.java @@ -5,10 +5,13 @@ import com.appsmith.server.configurations.SecurityTestConfig; import com.appsmith.server.constants.Url; import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.exceptions.AppsmithErrorCode; +import com.appsmith.server.helpers.GitFileUtils; import com.appsmith.server.helpers.RedisUtils; +import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.ApplicationPageService; import com.appsmith.server.services.ApplicationService; import com.appsmith.server.services.ApplicationSnapshotService; +import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.ThemeService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.solutions.ApplicationFetcher; @@ -63,6 +66,15 @@ public class ApplicationControllerTest { @Autowired private WebTestClient webTestClient; + @MockBean + AnalyticsService analyticsService; + + @MockBean + GitFileUtils gitFileUtils; + + @MockBean + SessionUserService sessionUserService; + private String getFileName(int length) { StringBuilder fileName = new StringBuilder(); for (int count = 0; count < length; count++) { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java index 779ecdab4f..69303feb60 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java @@ -1046,4 +1046,25 @@ public class CurlImporterServiceTest { assert (map.containsKey(API_CONTENT_TYPE)); assert (map.get(API_CONTENT_TYPE).equals(contentType)); } + + @Test + @WithUserDetails(value = "api_user") + public void testImportActionOnURLWithCurlyBraces() { + String curlCommandWithUrlContainingCurlyBraces = + "curl -X GET https://mock-api.appsmith.com/{id}/users?name=test"; + ActionDTO actionDTO = curlImporterService.curlToAction(curlCommandWithUrlContainingCurlyBraces); + + assertThat(actionDTO).isNotNull(); + assertThat(actionDTO.getDatasource()).isNotNull(); + assertThat(actionDTO.getDatasource().getDatasourceConfiguration()).isNotNull(); + assertThat(actionDTO.getDatasource().getDatasourceConfiguration().getUrl()) + .isEqualTo("https://mock-api.appsmith.com"); + + final ActionConfiguration actionConfiguration = actionDTO.getActionConfiguration(); + assertThat(actionConfiguration.getPath()).isEqualTo("/{id}/users"); + assertThat(actionConfiguration.getQueryParameters().size()).isEqualTo(1); + assertThat(actionConfiguration.getQueryParameters().get(0).getKey()).isEqualTo("name"); + assertThat(actionConfiguration.getQueryParameters().get(0).getValue()).isEqualTo("test"); + assertThat(actionConfiguration.getHttpMethod()).isEqualTo(HttpMethod.GET); + } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/FeatureFlagServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/FeatureFlagServiceTest.java index 1d0b93d415..6c5c2bdde5 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/FeatureFlagServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/FeatureFlagServiceTest.java @@ -1,6 +1,8 @@ package com.appsmith.server.services; import com.appsmith.server.domains.User; +import com.appsmith.server.dtos.ce.FeaturesResponseDTO; +import com.appsmith.server.featureflags.CachedFeatures; import com.appsmith.server.featureflags.CachedFlags; import com.appsmith.server.featureflags.FeatureFlagEnum; import lombok.extern.slf4j.Slf4j; @@ -11,6 +13,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.security.test.context.support.WithUserDetails; @@ -19,9 +22,15 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; @ExtendWith(SpringExtension.class) @SpringBootTest @@ -31,7 +40,7 @@ public class FeatureFlagServiceTest { @Autowired FeatureFlagService featureFlagService; - @Autowired + @SpyBean CacheableFeatureFlagHelper cacheableFeatureFlagHelper; @Autowired @@ -115,6 +124,41 @@ public class FeatureFlagServiceTest { .verifyComplete(); } + @Test + public void getFeatures_withTenantIdentifier_redisKeyExists() { + Map flags = new HashMap<>(); + flags.put(UUID.randomUUID().toString(), true); + flags.put(UUID.randomUUID().toString(), false); + FeaturesResponseDTO featuresResponseDTO = new FeaturesResponseDTO(); + featuresResponseDTO.setFeatures(flags); + + doReturn(Mono.just(featuresResponseDTO)) + .when(cacheableFeatureFlagHelper) + .getRemoteFeaturesForTenant(any()); + + String tenantIdentifier = UUID.randomUUID().toString(); + Mono cachedFeaturesMono = + cacheableFeatureFlagHelper.fetchCachedTenantNewFeatures(tenantIdentifier); + Mono hasKeyMono = reactiveRedisTemplate.hasKey("tenantNewFeatures:" + tenantIdentifier); + StepVerifier.create(cachedFeaturesMono.then(hasKeyMono)) + .assertNext(isKeyPresent -> { + assertTrue(isKeyPresent); + }) + .verifyComplete(); + } + + @Test + public void evictFeatures_withTenantIdentifier_redisKeyDoesNotExist() { + String tenantIdentifier = UUID.randomUUID().toString(); + Mono evictCache = cacheableFeatureFlagHelper.evictCachedTenantNewFeatures(tenantIdentifier); + Mono hasKeyMono = reactiveRedisTemplate.hasKey("tenantNewFeatures:" + tenantIdentifier); + StepVerifier.create(evictCache.then(hasKeyMono)) + .assertNext(isKeyPresent -> { + assertFalse(isKeyPresent); + }) + .verifyComplete(); + } + @TestConfiguration static class TestFeatureFlagConfig { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java index 8c51f66c2d..3eb0b16ba6 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java @@ -1609,7 +1609,7 @@ public class GitServiceTest { Mockito.any(Path.class), Mockito.anyString(), Mockito.anyString(), - eq(true), + eq(false), Mockito.anyString(), Mockito.anyBoolean())) .thenReturn(Mono.just("fetched")); @@ -1642,6 +1642,14 @@ public class GitServiceTest { Mockito.when(gitFileUtils.reconstructApplicationJsonFromGitRepo( Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())) .thenReturn(Mono.just(new ApplicationJson())); + Mockito.when(gitExecutor.fetchRemote( + Mockito.any(Path.class), + Mockito.anyString(), + Mockito.anyString(), + eq(false), + Mockito.anyString(), + Mockito.anyBoolean())) + .thenReturn(Mono.just("fetched")); Mockito.when(gitExecutor.pullApplication( Mockito.any(Path.class), Mockito.anyString(), diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java index 124145cf1f..5f9e9dda05 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ImportExportApplicationServiceTests.java @@ -3053,6 +3053,108 @@ public class ImportExportApplicationServiceTests { .verifyComplete(); } + @Test + @WithUserDetails(value = "api_user") + public void + importApplicationInWorkspaceFromGit_WithNavSettingsInEditMode_ImportedAppHasNavSettingsInEditAndViewMode() { + Workspace newWorkspace = new Workspace(); + newWorkspace.setName("import-with-navSettings-in-editMode"); + + Application testApplication = new Application(); + testApplication.setName( + "importApplicationInWorkspaceFromGit_WithNavSettingsInEditMode_ImportedAppHasNavSettingsInEditAndViewMode"); + Application.NavigationSetting appNavigationSetting = new Application.NavigationSetting(); + appNavigationSetting.setOrientation("top"); + testApplication.setUnpublishedApplicationDetail(new ApplicationDetail()); + testApplication.getUnpublishedApplicationDetail().setNavigationSetting(appNavigationSetting); + testApplication.setGitApplicationMetadata(new GitApplicationMetadata()); + GitApplicationMetadata gitData = new GitApplicationMetadata(); + gitData.setBranchName("testBranch"); + testApplication.setGitApplicationMetadata(gitData); + Application savedApplication = applicationPageService + .createApplication(testApplication, workspaceId) + .flatMap(application1 -> { + application1.getGitApplicationMetadata().setDefaultApplicationId(application1.getId()); + return applicationService.save(application1); + }) + .block(); + + Mono result = importExportApplicationService + .exportApplicationById(savedApplication.getId(), SerialiseApplicationObjective.VERSION_CONTROL) + .flatMap(applicationJson -> { + // setting published mode resource as null, similar to the app json exported to git repo + applicationJson.getExportedApplication().setPublishedApplicationDetail(null); + return importExportApplicationService.importApplicationInWorkspaceFromGit( + workspaceId, applicationJson, savedApplication.getId(), gitData.getBranchName()); + }); + + StepVerifier.create(result) + .assertNext(importedApp -> { + assertThat(importedApp.getUnpublishedApplicationDetail()).isNotNull(); + assertThat(importedApp.getPublishedApplicationDetail()).isNotNull(); + assertThat(importedApp.getUnpublishedApplicationDetail().getNavigationSetting()) + .isNotNull(); + assertEquals( + importedApp + .getUnpublishedApplicationDetail() + .getNavigationSetting() + .getOrientation(), + "top"); + assertThat(importedApp.getPublishedApplicationDetail().getNavigationSetting()) + .isNotNull(); + assertEquals( + importedApp + .getPublishedApplicationDetail() + .getNavigationSetting() + .getOrientation(), + "top"); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails(value = "api_user") + public void importApplicationInWorkspaceFromGit_WithAppLayoutInEditMode_ImportedAppHasAppLayoutInEditAndViewMode() { + Workspace newWorkspace = new Workspace(); + newWorkspace.setName("import-with-appLayout-in-editMode"); + + Application testApplication = new Application(); + testApplication.setName( + "importApplicationInWorkspaceFromGit_WithAppLayoutInEditMode_ImportedAppHasAppLayoutInEditAndViewMode"); + testApplication.setUnpublishedAppLayout(new Application.AppLayout(Application.AppLayout.Type.DESKTOP)); + testApplication.setGitApplicationMetadata(new GitApplicationMetadata()); + GitApplicationMetadata gitData = new GitApplicationMetadata(); + gitData.setBranchName("testBranch"); + testApplication.setGitApplicationMetadata(gitData); + Application savedApplication = applicationPageService + .createApplication(testApplication, workspaceId) + .flatMap(application1 -> { + application1.getGitApplicationMetadata().setDefaultApplicationId(application1.getId()); + return applicationService.save(application1); + }) + .block(); + + Mono result = importExportApplicationService + .exportApplicationById(savedApplication.getId(), SerialiseApplicationObjective.VERSION_CONTROL) + .flatMap(applicationJson -> { + // setting published mode resource as null, similar to the app json exported to git repo + applicationJson.getExportedApplication().setPublishedAppLayout(null); + return importExportApplicationService.importApplicationInWorkspaceFromGit( + workspaceId, applicationJson, savedApplication.getId(), gitData.getBranchName()); + }); + + StepVerifier.create(result) + .assertNext(importedApp -> { + assertThat(importedApp.getUnpublishedAppLayout()).isNotNull(); + assertThat(importedApp.getPublishedAppLayout()).isNotNull(); + assertThat(importedApp.getUnpublishedAppLayout().getType()) + .isEqualTo(Application.AppLayout.Type.DESKTOP); + assertThat(importedApp.getPublishedAppLayout().getType()) + .isEqualTo(Application.AppLayout.Type.DESKTOP); + }) + .verifyComplete(); + } + @Test @WithUserDetails(value = "api_user") public void diff --git a/app/server/pom.xml b/app/server/pom.xml index 0d8fae3311..c691140772 100644 --- a/app/server/pom.xml +++ b/app/server/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.0.6 + 3.0.9 @@ -45,7 +45,7 @@ 2.0 true 2.36.0 - 3.0.6 + 3.0.9 1.17.3 diff --git a/contributions/ServerSetup.md b/contributions/ServerSetup.md index 743c931bc7..635bbec044 100644 --- a/contributions/ServerSetup.md +++ b/contributions/ServerSetup.md @@ -24,7 +24,7 @@ Running the Appsmith Docker image as a container will grant you a running Appsmi 2. Change your directory to `deploy/docker` ```console - cd app/server + cd deploy/docker ``` 3. Start diff --git a/deploy/docker/templates/nginx/nginx-app-http.conf.template.sh b/deploy/docker/templates/nginx/nginx-app-http.conf.template.sh index 07c8a8f295..680ea258fe 100644 --- a/deploy/docker/templates/nginx/nginx-app-http.conf.template.sh +++ b/deploy/docker/templates/nginx/nginx-app-http.conf.template.sh @@ -19,6 +19,11 @@ map \$http_x_forwarded_host \$origin_host { '' \$host; } +map \$http_forwarded \$final_forwarded { + default '\$http_forwarded, host=\$host;proto=\$scheme'; + '' ''; +} + # redirect log to stdout for supervisor to capture access_log /dev/stdout; @@ -67,7 +72,8 @@ server { } proxy_set_header X-Forwarded-Proto \$origin_scheme; - proxy_set_header X-Forwarded-Host \$origin_host; + proxy_set_header X-Forwarded-Host \$origin_host; + proxy_set_header Forwarded \$final_forwarded; location / { try_files /loading.html \$uri /index.html =404; diff --git a/deploy/docker/templates/nginx/nginx-app-https.conf.template.sh b/deploy/docker/templates/nginx/nginx-app-https.conf.template.sh index e61b2df1d3..74e4364bdf 100644 --- a/deploy/docker/templates/nginx/nginx-app-https.conf.template.sh +++ b/deploy/docker/templates/nginx/nginx-app-https.conf.template.sh @@ -25,6 +25,11 @@ map \$http_x_forwarded_host \$origin_host { '' \$host; } +map \$http_forwarded \$final_forwarded { + default '\$http_forwarded, host=\$host;proto=\$scheme'; + '' ''; +} + # redirect log to stdout for supervisor to capture access_log /dev/stdout; @@ -70,6 +75,7 @@ server { proxy_set_header X-Forwarded-Proto \$origin_scheme; proxy_set_header X-Forwarded-Host \$origin_host; + proxy_set_header Forwarded \$final_forwarded; client_max_body_size 150m; diff --git a/deploy/helm/templates/configMap.yaml b/deploy/helm/templates/configMap.yaml index 4a53bbe25b..96a64b5af9 100644 --- a/deploy/helm/templates/configMap.yaml +++ b/deploy/helm/templates/configMap.yaml @@ -3,6 +3,7 @@ {{- $mongoUser := .Values.mongodb.auth.rootUser -}} {{- $mongoPassword := .Values.mongodb.auth.rootPassword -}} {{- $mongoServicename := .Values.mongodb.service.nameOverride -}} +{{- $releaseName := .Release.Name -}} apiVersion: v1 kind: ConfigMap metadata: @@ -19,7 +20,7 @@ data: {{- end }} {{- if and (eq "APPSMITH_REDIS_URL" $key) ( not $value) }} {{- if $.Values.redis.enabled }} - {{ $key }}: redis://{{ $name }}-redis-master.{{ $nameSpace }}.svc.cluster.local:6379 + {{ $key }}: redis://{{ $releaseName }}-redis-master.{{ $nameSpace }}.svc.cluster.local:6379 {{- end }} {{- end }} {{- if $value }} diff --git a/deploy/helm/templates/statefulset.yaml b/deploy/helm/templates/statefulset.yaml index 9e6ad7f0d6..43625df91b 100644 --- a/deploy/helm/templates/statefulset.yaml +++ b/deploy/helm/templates/statefulset.yaml @@ -51,7 +51,7 @@ spec: {{- else }} image: "docker.io/library/redis:6.2-alpine" {{- end }} - command: ['sh', '-c', "until redis-cli -h {{ include "appsmith.fullname" . }}-redis-master.{{.Release.Namespace}}.svc.cluster.local ping ; do echo waiting for redis; sleep 2; done"] + command: ['sh', '-c', "until redis-cli -h {{.Release.Name}}-redis-master.{{.Release.Namespace}}.svc.cluster.local ping ; do echo waiting for redis; sleep 2; done"] {{- end }} {{- if .Values.mongodb.enabled }} - name: mongo-init-container diff --git a/scripts/build_dp_from_branch.sh b/scripts/build_dp_from_branch.sh new file mode 100755 index 0000000000..69ae7011d8 --- /dev/null +++ b/scripts/build_dp_from_branch.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# Params are in environment variables as PARAM_{SLUG}, e.g. PARAM_USER_ID + +# Configure the AWS & kubectl environment + +mkdir ~/.aws; touch ~/.aws/config + + +echo "[default] +[profile eksci] +role_arn= $AWS_ROLE_ARN +output = json +region=ap-south-1 +source_profile = default" > ~/.aws/config + +export region=ap-south-1 +export cluster_name=uat-cluster + +echo "Region: $region" +echo "Cluster name: $cluster_name" +echo "Sub Domain Name: $SUB_DOMAIN_NAME" + +sts_output=$(aws sts assume-role --role-arn env.AWS_ROLE_ARN --role-session-name ekscisession) +export AWS_ACCESS_KEY_ID=$(echo $sts_output | jq -r '.Credentials''.AccessKeyId');\ +export AWS_SECRET_ACCESS_KEY=$(echo $sts_output | jq -r '.Credentials''.SecretAccessKey');\ +export AWS_SESSION_TOKEN=$(echo $sts_output | jq -r '.Credentials''.SessionToken'); + +export NAMESPACE="$SUB_DOMAIN_NAME" +export CHARTNAME="$SUB_DOMAIN_NAME" +export SECRET="$SUB_DOMAIN_NAME" +export DBNAME="$SUB_DOMAIN_NAME" +export DOMAINNAME="$SUB_DOMAIN_NAME".dp.appsmith.com +export HELMCHART="appsmith" +export HELMCHART_URL="http://helm.appsmith.com" +export HELMCHART_VERSION="2.0.2" + +aws eks update-kubeconfig --region $region --name $cluster_name --profile eksci + +echo "Set the default namespace" +kubectl config set-context --current --namespace=default + +echo "Getting the pods" +kubectl get pods + +if [[ -n "${RECREATE-}" ]] +then + kubectl delete ns $NAMESPACE || true + mongosh "mongodb+srv://$DB_USERNAME:$DB_PASSWORD@$DB_URL/$DBNAME?retryWrites=true&minPoolSize=1&maxPoolSize=10&maxIdleTimeMS=900000&authSource=admin" --eval 'db.dropDatabase()' +fi + +echo "Use kubernetes secret to Pull Image" +kubectl create ns $NAMESPACE || true + +kubectl create secret docker-registry $SECRET \ + --docker-server=https://index.docker.io/v1/ \ + --docker-username=$DOCKER_HUB_USERNAME \ + --docker-password=$DOCKER_HUB_ACCESS_TOKEN -n $NAMESPACE + +echo "Add appsmith-ce to helm repo" +AWS_REGION=ap-south-1 helm repo add $HELMCHART $HELMCHART_URL + +echo "Deploy appsmith helm chart" +helm upgrade -i $CHARTNAME appsmith/appsmith -n $NAMESPACE \ + --create-namespace --recreate-pods --set image.repository=$DOCKER_HUB_ORGANIZATION/appsmith-dp --set image.tag=$IMAGE_HASH \ + --set image.pullSecrets=$SECRET --set redis.enabled=false --set mongodb.enabled=false --set ingress.enabled=true \ + --set "ingress.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-ssl-cert=$AWS_RELEASE_CERT" \ + --set "ingress.hosts[0].host=$DOMAINNAME, ingress.hosts[0].paths[0].path=/, ingress.hosts[0].paths[0].pathType=Prefix" \ + --set ingress.className="nginx" --set applicationConfig.APPSMITH_CLOUD_SERVICES_BASE_URL="https://release-cs.appsmith.com" \ + --set image.pullPolicy="Always" --set autoupdate.enabled="true" --set persistence.size=2Gi \ + --set applicationConfig.APPSMITH_SENTRY_DSN="https://abf15a075d1347969df44c746cca7eaa@o296332.ingest.sentry.io/1546547" \ + --set applicationConfig.APPSMITH_SENTRY_ENVIRONMENT="$NAMESPACE" \ + --set applicationConfig.APPSMITH_MONGODB_URI="mongodb+srv://$DB_USERNAME:$DB_PASSWORD@$DB_URL/$DBNAME?retryWrites=true&minPoolSize=1&maxPoolSize=10&maxIdleTimeMS=900000&authSource=admin" \ + --version $HELMCHART_VERSION