Merge pull request #32850 from appsmithorg/release
Daily promotion 22/04
2
.github/config.json
vendored
11
.github/pull_request_template.md
vendored
|
|
@ -1,9 +1,10 @@
|
|||
## Description
|
||||
> [!TIP]
|
||||
> _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content team)._
|
||||
> _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._
|
||||
>
|
||||
> _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._
|
||||
|
||||
|
||||
Fixes #`Issue Number`
|
||||
_or_
|
||||
Fixes `Issue URL`
|
||||
|
|
@ -19,4 +20,10 @@ Fixes `Issue URL`
|
|||
> [!CAUTION]
|
||||
> If you modify the content in this section, you are likely to disrupt the CI result for your PR.
|
||||
|
||||
<!-- end of auto-generated comment: Cypress test results -->
|
||||
<!-- end of auto-generated comment: Cypress test results -->
|
||||
|
||||
|
||||
## Communication
|
||||
Should the DevRel and Marketing teams inform users about this change?
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
|
|
|
|||
2
.github/workflows/build-chromatic.yml
vendored
|
|
@ -50,4 +50,4 @@ jobs:
|
|||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
workingDir: ./app/client/packages/storybook
|
||||
exitOnceUploaded: true
|
||||
buildScriptName: "build"
|
||||
buildScriptName: "build-storybook"
|
||||
|
|
|
|||
2
.github/workflows/build-storybook.yml
vendored
|
|
@ -48,4 +48,4 @@ jobs:
|
|||
projectToken: ${{ secrets.STORYBOOK_PROJECT_TOKEN }}
|
||||
workingDir: ./app/client/packages/storybook
|
||||
exitOnceUploaded: true
|
||||
buildScriptName: "build"
|
||||
buildScriptName: "build-storybook"
|
||||
|
|
|
|||
2
.github/workflows/ci-debugging.yml
vendored
|
|
@ -71,7 +71,7 @@ jobs:
|
|||
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 --privileged --pid=host --ipc=host --volume /:/host -v ~/git-server/keys:/git-server/keys \
|
||||
-p 5432:5432 -p 28017:27017 -p 25:25 -p 4200:4200 -p 5000:5000 -p 3001:3000 --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
|
||||
cd cicontainerlocal
|
||||
docker run -d --name appsmith -p 80:80 \
|
||||
|
|
|
|||
2
.github/workflows/ci-test-custom-script.yml
vendored
|
|
@ -147,7 +147,7 @@ jobs:
|
|||
mkdir -p ~/git-server/repos
|
||||
ted_tag="${{inputs.ted_tag}}"
|
||||
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 -p 8001:8000 --privileged --pid=host --ipc=host --volume /:/host -v ~/git-server/keys:/git-server/keys \
|
||||
-p 5432:5432 -p 28017:27017 -p 25:25 -p 4200:4200 -p 5000:5000 -p 3001:3000 -p 6001:6001 -p 8001:8000 --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:${ted_tag:-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\
|
||||
|
|
|
|||
2
.github/workflows/ci-test-limited.yml
vendored
|
|
@ -167,7 +167,7 @@ jobs:
|
|||
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 -p 8001:8000 --privileged --pid=host --ipc=host --volume /:/host -v ~/git-server/keys:/git-server/keys \
|
||||
-p 5432:5432 -p 28017:27017 -p 25:25 -p 4200:4200 -p 5000:5000 -p 3001:3000 -p 6001:6001 -p 8001:8000 --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\
|
||||
|
|
|
|||
3
.github/workflows/pr-automation.yml
vendored
|
|
@ -22,8 +22,9 @@ jobs:
|
|||
|
||||
# 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@v4
|
||||
with:
|
||||
repository: appsmithorg/appsmith
|
||||
|
||||
# Checks for ok-to-test label presence in PR
|
||||
- name: Check label
|
||||
|
|
|
|||
68
CODEOWNERS
|
|
@ -30,9 +30,9 @@ app/client/src/widgets/anvil/* @appsmithorg/anvil-team
|
|||
# App viewers pod
|
||||
app/client/src/widgets/* @appsmithorg/app-viewers
|
||||
app/client/src/components/propertyControls/* @appsmithorg/app-viewers
|
||||
app/client/src/sagas/OneClickBindingSaga.ts @sbalaji1192
|
||||
app/client/src/WidgetQueryGenerators/* @sbalaji1192
|
||||
app/client/src/components/editorComponents/WidgetQueryGeneratorForm/* @sbalaji1192
|
||||
app/client/src/sagas/OneClickBindingSaga.ts @appsmithorg/app-viewers
|
||||
app/client/src/WidgetQueryGenerators/* @appsmithorg/app-viewers
|
||||
app/client/src/components/editorComponents/WidgetQueryGeneratorForm/* @appsmithorg/app-viewers
|
||||
app/client/src/pages/AppViewer/* @appsmithorg/app-viewers
|
||||
|
||||
# New Developers Pod
|
||||
|
|
@ -101,19 +101,16 @@ app/client/src/widgets/MetaHOC.tsx @appsmithorg/ui-builders
|
|||
app/client/src/widgets/withWidgetProps.tsx @appsmithorg/ui-builders
|
||||
|
||||
# Git Pod
|
||||
app/server/appsmith-git/* @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCEImpl.java @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ImportExportApplicationServiceCE.java @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCE.java @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitCloudServicesUtils.java @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitDeployKeyGenerator.java @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitFileUtils.java @AnaghHegde
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitUtils.java @AnaghHegde
|
||||
app/client/src/pages/Editor/gitSync/* @brayn003
|
||||
app/server/appsmith-git/ @appsmithorg/git-be-reviewers
|
||||
app/server/**/git/** @appsmithorg/git-be-reviewers
|
||||
app/server/**/import/** @appsmithorg/git-be-reviewers
|
||||
app/server/**/export/** @appsmithorg/git-be-reviewers
|
||||
app/server/**/*Git*.java @appsmithorg/git-be-reviewers
|
||||
app/server/**/*Import*.java @appsmithorg/git-be-reviewers
|
||||
app/server/**/*Export*.java @appsmithorg/git-be-reviewers
|
||||
|
||||
# DSL Package
|
||||
app/client/packages/dsl/* @brayn003
|
||||
app/client/src/pages/Editor/gitSync/ @appsmithorg/git-fe-reviewers
|
||||
app/client/packages/dsl/ @appsmithorg/git-fe-reviewers
|
||||
|
||||
# Data Platform
|
||||
|
||||
|
|
@ -149,41 +146,12 @@ app/client/src/transformers/RestAPIDatasourceFormTransformer.ts @ayushpahwa
|
|||
|
||||
|
||||
# Followed Globstar paths in combination with wildcard paths. Reference https://docs.gitlab.com/ee/user/project/codeowners/reference.html#globstar-paths
|
||||
# Data Platform server - Interfaces
|
||||
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/**/Action* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/**/Datasource* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-interfaces/src/main/java/com/appsmith/external/**/OAuth2* @nidhi-nair @sondermanish
|
||||
|
||||
# Data Platform server - Controllers
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/**/Action* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/**/Datasource* @nidhi-nair @sondermanish
|
||||
|
||||
# Data Platform server - Domains
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/domains/**/Action* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/domains/**/Datasource* @nidhi-nair @sondermanish
|
||||
|
||||
# Data Platform server - DTOs
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/**/Action* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/**/Datasource* @nidhi-nair @sondermanish
|
||||
|
||||
# Data Platform server - Repositories
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/**/*Action* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/**/*Datasource* @nidhi-nair @sondermanish
|
||||
|
||||
# Data Platform server - Services
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/services/**/*Action* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/services/**/*Datasource* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/services/**/*Authentication* @nidhi-nair @sondermanish
|
||||
|
||||
# Data Platform server - Solutions
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/**/*Action* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/**/*Datasource* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/**/*Authentication* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/**/*Environment* @nidhi-nair @sondermanish
|
||||
|
||||
# Data Platform server - Misc
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/**/Datasource* @nidhi-nair @sondermanish
|
||||
app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError* @nidhi-nair @sondermanish
|
||||
# Data Platform Pod
|
||||
app/server/**/*Action* @nidhi-nair @sondermanish
|
||||
app/server/**/*Datasource* @nidhi-nair @sondermanish
|
||||
app/server/**/*OAuth2* @nidhi-nair @sondermanish
|
||||
app/server/**/*Authentication* @nidhi-nair @sondermanish
|
||||
app/server/**/*Environment* @nidhi-nair @sondermanish
|
||||
|
||||
# Team Managers pod
|
||||
app/client/src/pages/Settings/**/* @ankitakinger
|
||||
|
|
|
|||
4
app/client/.gitignore
vendored
|
|
@ -46,14 +46,12 @@ results/
|
|||
/docker/nginx.conf
|
||||
/docker/nginx-root.conf
|
||||
|
||||
storybook-static/*
|
||||
build-storybook.log
|
||||
|
||||
.eslintcache
|
||||
.vscode
|
||||
TODO
|
||||
|
||||
/nginx
|
||||
/caddy
|
||||
|
||||
/public/static/wds/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import EditorNavigation, {
|
||||
EntityType,
|
||||
PageLeftPane,
|
||||
} from "../../../../support/Pages/EditorNavigation";
|
||||
import PageList from "../../../../support/Pages/PageList";
|
||||
|
||||
const widgetsPage = require("../../../../locators/Widgets.json");
|
||||
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||
|
|
@ -32,7 +32,7 @@ describe(
|
|||
it("1. Create MyPage and valdiate if its successfully created", function () {
|
||||
cy.Createpage(pageid);
|
||||
agHelper.AddDsl("displayWidgetDsl");
|
||||
PageLeftPane.assertPresence(pageid);
|
||||
PageList.assertPresence(pageid);
|
||||
//Table Widget Functionality with multiple page
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
EditorNavigation.SelectEntityByName("Table1", EntityType.Widget, {}, [
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {
|
|||
agHelper,
|
||||
appSettings,
|
||||
dataSources,
|
||||
debuggerHelper,
|
||||
deployMode,
|
||||
entityExplorer,
|
||||
entityItems,
|
||||
|
|
@ -118,7 +119,15 @@ describe(
|
|||
after(
|
||||
"Verify Deletion of the datasource after all created queries are deleted",
|
||||
() => {
|
||||
deployMode.NavigateBacktoEditor("ran successfully"); //runAstros triggered on PageLaoad of Edit page!
|
||||
deployMode.NavigateBacktoEditor();
|
||||
|
||||
//verify runAstros triggered on PageLaoad of Edit page!
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.ClickLogsTab();
|
||||
debuggerHelper.DebuggerLogsFilter("JSObject1.runAstros");
|
||||
debuggerHelper.DoesConsoleLogExist("JS Function executed successfully");
|
||||
debuggerHelper.CloseBottomBar();
|
||||
|
||||
PageLeftPane.switchSegment(PagePaneSegment.JS);
|
||||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "JSObject1",
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ describe(
|
|||
_.propPane.NavigateBackToPropertyPane();
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "Menu Item 1");
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "Menu Item");
|
||||
_.propPane.AssertIfPropertyIsVisible("icon");
|
||||
_.debuggerHelper.CloseBottomBar();
|
||||
EditorNavigation.SelectEntityByName("ButtonGroup1", EntityType.Widget);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import EditorNavigation, {
|
|||
|
||||
import * as _ from "../../../../support/Objects/ObjectsCore";
|
||||
import PageList from "../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../support/Pages/AssertHelper";
|
||||
|
||||
describe(
|
||||
"Hide / Show page test functionality",
|
||||
|
|
@ -17,6 +18,7 @@ describe(
|
|||
_.entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page2",
|
||||
action: "Hide",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
PageLeftPane.switchToAddNew();
|
||||
cy.ClearSearch();
|
||||
|
|
@ -27,6 +29,7 @@ describe(
|
|||
_.entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page2",
|
||||
action: "Show",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
cy.ClearSearch();
|
||||
_.deployMode.DeployApp();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import EditorNavigation, {
|
|||
PagePaneSegment,
|
||||
} from "../../../../support/Pages/EditorNavigation";
|
||||
import PageList from "../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../support/Pages/AssertHelper";
|
||||
|
||||
describe(
|
||||
"Validate basic operations on Entity explorer JSEditor structure",
|
||||
|
|
@ -49,13 +50,14 @@ describe(
|
|||
it("2. Validate Move JSObject", function () {
|
||||
const newPageId = "Page2";
|
||||
PageList.AddNewPage();
|
||||
PageLeftPane.assertPresence(newPageId);
|
||||
PageList.assertPresence(newPageId);
|
||||
EditorNavigation.SelectEntityByName(pageId, EntityType.Page);
|
||||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "RenamedJSObjectCopy",
|
||||
action: "Move to page",
|
||||
subAction: newPageId,
|
||||
toastToValidate: "moved to page",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
EditorNavigation.SelectEntityByName(newPageId, EntityType.Page);
|
||||
PageLeftPane.switchSegment(PagePaneSegment.JS);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
entityExplorer,
|
||||
} from "../../../../support/Objects/ObjectsCore";
|
||||
import PageList from "../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../support/Pages/AssertHelper";
|
||||
|
||||
describe("Page Load tests", { tags: ["@tag.IDE"] }, () => {
|
||||
afterEach(() => {
|
||||
|
|
@ -86,6 +87,7 @@ describe("Page Load tests", { tags: ["@tag.IDE"] }, () => {
|
|||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page1",
|
||||
action: "Hide",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
deployMode.DeployApp();
|
||||
// Assert active page DSL
|
||||
|
|
|
|||
|
|
@ -97,11 +97,10 @@ describe("Git discard changes:", { tags: ["@tag.Git"] }, function () {
|
|||
it("4. Delete page2 and trigger discard flow, page2 should be available again", () => {
|
||||
PageList.DeletePage(page2);
|
||||
// verify page is deleted
|
||||
//entityExplorer.ExpandCollapseEntity("Pages");
|
||||
PageLeftPane.assertAbsence(page2);
|
||||
PageList.assertAbsence(page2);
|
||||
gitSync.DiscardChanges();
|
||||
// verify page2 is recovered back
|
||||
PageLeftPane.assertPresence(page2);
|
||||
PageList.assertPresence(page2);
|
||||
EditorNavigation.SelectEntityByName(page2, EntityType.Page);
|
||||
cy.wait("@getPage");
|
||||
// verify data binding on page2
|
||||
|
|
@ -161,14 +160,13 @@ describe("Git discard changes:", { tags: ["@tag.Git"] }, function () {
|
|||
// discard changes
|
||||
gitSync.DiscardChanges();
|
||||
// verify page3 is removed
|
||||
PageList.ShowList();
|
||||
PageLeftPane.assertAbsence(page3);
|
||||
PageList.assertAbsence(page3);
|
||||
});
|
||||
|
||||
it(`8. Add new page i.e page3, discard changes should not throw error: "resource not found"`, () => {
|
||||
cy.Createpage(page3);
|
||||
gitSync.DiscardChanges();
|
||||
PageLeftPane.assertAbsence(page3);
|
||||
PageList.assertAbsence(page3);
|
||||
});
|
||||
|
||||
it("9. On discard failure an error message should be show and user should be able to discard again", () => {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import EditorNavigation, {
|
|||
PagePaneSegment,
|
||||
} from "../../../../../support/Pages/EditorNavigation";
|
||||
import PageList from "../../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../../support/Pages/AssertHelper";
|
||||
|
||||
const pagename = "ChildPage";
|
||||
const tempBranch = "feat/tempBranch";
|
||||
|
|
@ -98,6 +99,7 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page1",
|
||||
action: "Clone",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
cy.wait("@clonePage").should(
|
||||
"have.nested.property",
|
||||
|
|
@ -151,6 +153,7 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page1",
|
||||
action: "Clone",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
cy.wait("@clonePage").should(
|
||||
"have.nested.property",
|
||||
|
|
@ -180,6 +183,7 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page1",
|
||||
action: "Clone",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
cy.wait("@clonePage").should(
|
||||
"have.nested.property",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import {
|
|||
assertHelper,
|
||||
} from "../../../../../support/Objects/ObjectsCore";
|
||||
import PageList from "../../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../../support/Pages/AssertHelper";
|
||||
|
||||
const newPage = "ApiCalls_1";
|
||||
const pageName = "crudpage_1";
|
||||
|
|
@ -102,7 +103,12 @@ describe("Git sync apps", { tags: ["@tag.Git"] }, function () {
|
|||
expect(cellData).to.be.equal("New Config");
|
||||
});
|
||||
// rename page to crud_page
|
||||
entityExplorer.RenameEntityFromExplorer("Page1", pageName);
|
||||
entityExplorer.RenameEntityFromExplorer(
|
||||
"Page1",
|
||||
pageName,
|
||||
false,
|
||||
EntityItems.Page,
|
||||
);
|
||||
EditorNavigation.SelectEntityByName(pageName, EntityType.Page);
|
||||
// create a clone of page
|
||||
cy.get(`.t--entity-item:contains(${pageName})`).within(() => {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import EditorNavigation, {
|
|||
PagePaneSegment,
|
||||
} from "../../../../../support/Pages/EditorNavigation";
|
||||
import PageList from "../../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../../support/Pages/AssertHelper";
|
||||
|
||||
let parentBranchKey = "ParentBranch",
|
||||
childBranchKey = "ChildBranch",
|
||||
|
|
@ -67,7 +68,12 @@ describe("Git sync:", { tags: ["@tag.Git"] }, function () {
|
|||
});
|
||||
|
||||
PageList.AddNewPage();
|
||||
entityExplorer.RenameEntityFromExplorer("Page2", "ParentPage1", true);
|
||||
entityExplorer.RenameEntityFromExplorer(
|
||||
"Page2",
|
||||
"ParentPage1",
|
||||
false,
|
||||
EntityItems.Page,
|
||||
);
|
||||
dataSources.NavigateToDSCreateNew();
|
||||
apiPage.CreateApi("ParentApi1");
|
||||
jsEditor.CreateJSObject();
|
||||
|
|
@ -80,7 +86,12 @@ describe("Git sync:", { tags: ["@tag.Git"] }, function () {
|
|||
childBranchKey = branName;
|
||||
});
|
||||
PageList.AddNewPage();
|
||||
entityExplorer.RenameEntityFromExplorer("Page2", "ChildPage1", true);
|
||||
entityExplorer.RenameEntityFromExplorer(
|
||||
"Page2",
|
||||
"ChildPage1",
|
||||
false,
|
||||
EntityItems.Page,
|
||||
);
|
||||
dataSources.NavigateToDSCreateNew();
|
||||
apiPage.CreateApi("ChildApi1");
|
||||
jsEditor.CreateJSObject();
|
||||
|
|
@ -92,14 +103,10 @@ describe("Git sync:", { tags: ["@tag.Git"] }, function () {
|
|||
// A switch here should not show a 404 page
|
||||
cy.switchGitBranch(parentBranchKey);
|
||||
// When entity not found, takes them to the home page
|
||||
cy.get(`.t--entity.page`)
|
||||
.contains("Page1")
|
||||
.closest(".t--entity")
|
||||
.should("be.visible")
|
||||
.should("have.class", "activePage");
|
||||
PageList.VerifyIsCurrentPage("Page1");
|
||||
|
||||
EditorNavigation.SelectEntityByName("ParentPage1", EntityType.Page);
|
||||
PageLeftPane.assertAbsence("ChildPage1");
|
||||
PageList.assertAbsence("ChildPage1");
|
||||
PageLeftPane.switchSegment(PagePaneSegment.Queries);
|
||||
PageLeftPane.assertAbsence("ChildApi1");
|
||||
PageLeftPane.switchSegment(PagePaneSegment.JS);
|
||||
|
|
@ -113,7 +120,8 @@ describe("Git sync:", { tags: ["@tag.Git"] }, function () {
|
|||
entityExplorer.RenameEntityFromExplorer(
|
||||
"ParentPage1",
|
||||
"ParentPageRenamed",
|
||||
true,
|
||||
false,
|
||||
EntityItems.Page,
|
||||
);
|
||||
agHelper.RemoveUIElement("Tooltip", "Add a new query/JS Object");
|
||||
PageLeftPane.switchSegment(PagePaneSegment.Queries);
|
||||
|
|
@ -121,8 +129,7 @@ describe("Git sync:", { tags: ["@tag.Git"] }, function () {
|
|||
|
||||
cy.switchGitBranch(parentBranchKey);
|
||||
|
||||
PageList.ShowList();
|
||||
PageLeftPane.assertAbsence("ParentPageRenamed");
|
||||
PageList.assertAbsence("ParentPageRenamed");
|
||||
PageLeftPane.switchSegment(PagePaneSegment.Queries);
|
||||
PageLeftPane.assertAbsence("ParentApiRenamed");
|
||||
});
|
||||
|
|
@ -219,11 +226,7 @@ describe("Git sync:", { tags: ["@tag.Git"] }, function () {
|
|||
cy.get(gitSyncLocators.branchListItem).contains("master").click();
|
||||
cy.wait(4000);
|
||||
PageLeftPane.switchSegment(PagePaneSegment.UI);
|
||||
cy.get(`.t--entity.page`)
|
||||
.contains("Page1")
|
||||
.closest(".t--entity")
|
||||
.should("be.visible")
|
||||
.should("have.class", "activePage");
|
||||
PageList.VerifyIsCurrentPage("Page1");
|
||||
cy.get(".t--canvas-artboard").should("be.visible");
|
||||
});
|
||||
agHelper.RefreshPage();
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import EditorNavigation, {
|
|||
EntityType,
|
||||
} from "../../../../../support/Pages/EditorNavigation";
|
||||
import PageList from "../../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../../support/Pages/AssertHelper";
|
||||
|
||||
let parentBranchKey = "ParentBranch",
|
||||
childBranchKey = "ChildBranch";
|
||||
|
|
@ -58,6 +59,7 @@ describe("Git sync:", { tags: ["@tag.Git"] }, function () {
|
|||
|
||||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page2",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ describe("Editor Segment Context Switch", { tags: ["@tag.IDE"] }, function () {
|
|||
it("will select an item when switched to it", () => {
|
||||
// Check JS item is selected
|
||||
PageLeftPane.switchSegment(PagePaneSegment.JS);
|
||||
PageLeftPane.selectedItem().should("be.visible");
|
||||
PageLeftPane.selectedItem("not.exist");
|
||||
|
||||
// Check Query item is selected
|
||||
PageLeftPane.switchSegment(PagePaneSegment.Queries);
|
||||
PageLeftPane.selectedItem().should("be.visible");
|
||||
PageLeftPane.selectedItem("not.exist");
|
||||
|
||||
// Check UI item is selected
|
||||
PageLeftPane.switchSegment(PagePaneSegment.UI);
|
||||
|
|
|
|||
|
|
@ -67,8 +67,13 @@ describe("Linting", { tags: ["@tag.JS"] }, () => {
|
|||
AppSidebar.navigate(AppSidebarButton.Editor);
|
||||
});
|
||||
|
||||
it("1. TC 1927 - Shows correct lint error when Api is deleted or created", () => {
|
||||
it("1. TC 1927 - Show correct lint errors", () => {
|
||||
// For browser APIs it should give linting error
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
propPane.EnterJSContext("onClick", `{{window}}`);
|
||||
agHelper.AssertElementExist(locators._lintErrorElement);
|
||||
|
||||
// Shows correct lint error when Api is deleted or created
|
||||
propPane.EnterJSContext(
|
||||
"onClick",
|
||||
`{{function(){
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import EditorNavigation, {
|
|||
EntityType,
|
||||
} from "../../../../support/Pages/EditorNavigation";
|
||||
import PageList from "../../../../support/Pages/PageList";
|
||||
import { EntityItems } from "../../../../support/Pages/AssertHelper";
|
||||
|
||||
describe(
|
||||
"Handle Cases while conversion",
|
||||
|
|
@ -37,6 +38,7 @@ describe(
|
|||
|
||||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "Page2",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
locators,
|
||||
propPane,
|
||||
} from "../../../../support/Objects/ObjectsCore";
|
||||
import { EntityItems } from "../../../../support/Pages/AssertHelper";
|
||||
|
||||
describe("Slug URLs", () => {
|
||||
let applicationName;
|
||||
|
|
@ -41,7 +42,12 @@ describe("Slug URLs", () => {
|
|||
expect(pathname).to.be.equal(`/app/${appName}/page1-${pageId}/edit`);
|
||||
});
|
||||
});
|
||||
entityExplorer.RenameEntityFromExplorer("Page1", "Renamed");
|
||||
entityExplorer.RenameEntityFromExplorer(
|
||||
"Page1",
|
||||
"Renamed",
|
||||
false,
|
||||
EntityItems.Page,
|
||||
);
|
||||
assertHelper.AssertNetworkStatus("updatePage");
|
||||
// cy.location("pathname").then((pathname) => {
|
||||
cy.url().then((url) => {
|
||||
|
|
|
|||
|
|
@ -5,12 +5,15 @@ import EditorNavigation, {
|
|||
const omnibar = require("../../../../locators/Omnibar.json");
|
||||
import {
|
||||
agHelper,
|
||||
entityExplorer,
|
||||
assertHelper,
|
||||
deployMode,
|
||||
draggableWidgets,
|
||||
} from "../../../../support/Objects/ObjectsCore";
|
||||
|
||||
import {
|
||||
createMessage,
|
||||
NAV_DESCRIPTION,
|
||||
ACTION_OPERATION_DESCRIPTION,
|
||||
} from "../../../../../src/ce/constants/messages";
|
||||
|
||||
describe("Omnibar functionality test cases", () => {
|
||||
const apiName = "Omnibar1";
|
||||
const jsObjectName = "Omnibar2";
|
||||
|
|
@ -19,17 +22,7 @@ describe("Omnibar functionality test cases", () => {
|
|||
agHelper.AddDsl("omnibarDsl");
|
||||
});
|
||||
|
||||
it("1. Bug #15104 Docs tab opens after clicking on learn more link from property pane", function () {
|
||||
cy.dragAndDropToCanvas(draggableWidgets.AUDIO, { x: 300, y: 500 });
|
||||
agHelper.Sleep(2000);
|
||||
deployMode.StubWindowNAssert(
|
||||
'//span[text()="Learn more"]',
|
||||
"connect-to-a-database",
|
||||
"getConsolidatedData",
|
||||
);
|
||||
});
|
||||
|
||||
it("2.Verify omnibar is present across all pages and validate its fields", function () {
|
||||
it("1.Verify omnibar is present across all pages and validate its fields", function () {
|
||||
cy.get(omnibar.globalSearch)
|
||||
.trigger("mouseover")
|
||||
.should("have.css", "background-color", "rgb(255, 255, 255)");
|
||||
|
|
@ -39,19 +32,16 @@ describe("Omnibar functionality test cases", () => {
|
|||
.eq(0)
|
||||
.should("have.text", "Navigate")
|
||||
.next()
|
||||
.should(
|
||||
"have.text",
|
||||
"Navigate to any page, widget or file across this project.",
|
||||
);
|
||||
.should("have.text", createMessage(NAV_DESCRIPTION));
|
||||
cy.get(omnibar.categoryTitle)
|
||||
.eq(1)
|
||||
.should("have.text", "Create new")
|
||||
.next()
|
||||
.should("have.text", "Create a new query, API or JS Object");
|
||||
.should("have.text", createMessage(ACTION_OPERATION_DESCRIPTION));
|
||||
cy.get("body").type("{esc}");
|
||||
});
|
||||
|
||||
it("3. Verify Create new section and its data, also create a new api, new js object and new cURL import from omnibar ", function () {
|
||||
it("2. Verify Create new section and its data, also create a new api, new js object and new cURL import from omnibar ", function () {
|
||||
cy.intercept("POST", "/api/v1/actions").as("createNewApi");
|
||||
cy.intercept("POST", "/api/v1/collections/actions").as(
|
||||
"createNewJSCollection",
|
||||
|
|
@ -90,7 +80,7 @@ describe("Omnibar functionality test cases", () => {
|
|||
});
|
||||
|
||||
it(
|
||||
"4. On an invalid search, discord link should be displayed and on clicking that link, should open discord in new tab",
|
||||
"3. On an invalid search, discord link should be displayed and on clicking that link, should open discord in new tab",
|
||||
{ tags: ["@tag.excludeForAirgap"] },
|
||||
function () {
|
||||
// typing a random string in search bar
|
||||
|
|
@ -101,30 +91,11 @@ describe("Omnibar functionality test cases", () => {
|
|||
cy.get(omnibar.globalSearchInput).should("have.value", "vnjkv");
|
||||
// discord link should be visible
|
||||
cy.get(omnibar.discordLink).should("be.visible");
|
||||
// cy.window().then((win) => {
|
||||
// cy.stub(win, "open", (url) => {
|
||||
// win.location.href = "https://discord.com/invite/rBTTVJp";
|
||||
// }).as("discordLink");
|
||||
// });
|
||||
// cy.url().then(($urlBeforeDiscord) => {
|
||||
// // clicking on discord link should open discord
|
||||
// agHelper.GetNClick(omnibar.discordLink, 0, false, 4000);
|
||||
// cy.get("@discordLink").should("be.called");
|
||||
// cy.wait(2000);
|
||||
// //cy.go(-1);
|
||||
// cy.visit($urlBeforeDiscord);
|
||||
// cy.wait(4000); //for page to load
|
||||
// });
|
||||
|
||||
deployMode.StubWindowNAssert(
|
||||
omnibar.discordLink,
|
||||
"https://discord.com/invite/rBTTVJp",
|
||||
"getConsolidatedData",
|
||||
);
|
||||
cy.get(".no-data-title").should("be.visible");
|
||||
},
|
||||
);
|
||||
|
||||
it("5. Verify Navigate section shows recently opened widgets and datasources", function () {
|
||||
it("4. Verify Navigate section shows recently opened widgets and datasources", function () {
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
cy.get(omnibar.globalSearch).click({ force: true });
|
||||
cy.get(omnibar.categoryTitle).contains("Navigate").click();
|
||||
|
|
@ -147,12 +118,6 @@ describe("Omnibar functionality test cases", () => {
|
|||
.next()
|
||||
.should("have.text", "Page1");
|
||||
|
||||
cy.xpath(omnibar.recentlyopenItem)
|
||||
.eq(3)
|
||||
.should("have.text", "Audio1")
|
||||
.next()
|
||||
.should("have.text", "Page1");
|
||||
|
||||
cy.xpath(omnibar.recentlyopenItem).eq(4).should("have.text", "Page1");
|
||||
cy.xpath(omnibar.recentlyopenItem).eq(3).should("have.text", "Page1");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ describe("Page Settings", { tags: ["@tag.Settings"] }, () => {
|
|||
});
|
||||
_.appSettings.ClosePane();
|
||||
|
||||
//Page name doesn't allow special character
|
||||
// Page name doesn't allow slashes and colons
|
||||
_.appSettings.OpenAppSettings();
|
||||
_.appSettings.GoToPageSettings("Page3");
|
||||
_.pageSettings.UpdatePageNameAndVerifyTextValue("Page3!@#", "Page3 ");
|
||||
_.pageSettings.UpdatePageNameAndVerifyTextValue("Page3/\\:", "Page3");
|
||||
_.appSettings.ClosePane();
|
||||
|
||||
// Page name doesn't allow empty
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ describe(
|
|||
);
|
||||
cy.wait(1000);
|
||||
cy.get(template.templateDialogBox).should("be.visible");
|
||||
cy.xpath("//h1[text()='Slack Bot']").scrollIntoView().wait(500).click();
|
||||
cy.get(template.templateCard).first().click();
|
||||
cy.get(template.templateViewForkButton).first().click();
|
||||
cy.waitUntil(() => cy.xpath("//span[text()='Setting up the template']"), {
|
||||
errorMsg: "Setting Templates did not finish even after 75 seconds",
|
||||
timeout: 950000,
|
||||
timeout: 75000,
|
||||
interval: 5000,
|
||||
}).then(($ele) => {
|
||||
cy.wrap($ele).should("have.length", 0);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import homePage from "../../../../locators/HomePage";
|
||||
import * as _ from "../../../../support/Objects/ObjectsCore";
|
||||
import {
|
||||
createMessage,
|
||||
LOGIN_PAGE_TITLE,
|
||||
} from "../../../../../src/ce/constants/messages";
|
||||
|
||||
describe("Visual regression tests", { tags: ["@tag.Visual"] }, () => {
|
||||
// for any changes in UI, update the screenshot in snapshot folder, to do so:
|
||||
|
|
@ -47,7 +51,7 @@ describe("Visual regression tests", { tags: ["@tag.Visual"] }, () => {
|
|||
cy.get(homePage.signOutIcon).click();
|
||||
cy.wait(500);
|
||||
// validating all the fields on login page
|
||||
cy.xpath("//h1").should("have.text", "Sign in");
|
||||
cy.xpath("//h1").should("have.text", createMessage(LOGIN_PAGE_TITLE));
|
||||
cy.get(".bp3-label").first().should("have.text", "Email ");
|
||||
cy.get(".bp3-label").last().should("have.text", "Password ");
|
||||
cy.xpath('//span[text()="Sign in"]').should("be.visible");
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ describe(
|
|||
|
||||
// Check camera resource is properly released on navigating away
|
||||
PageList.AddNewPage();
|
||||
EditorNavigation.SelectEntityByName("Page2", EntityType.Widget);
|
||||
EditorNavigation.SelectEntityByName("Page2", EntityType.Page);
|
||||
agHelper.AssertElementAbsence(widgetLocators.cameraVideo);
|
||||
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Widget);
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
agHelper.AssertElementVisibility(widgetLocators.cameraVideo);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -94,9 +94,7 @@ describe(
|
|||
'SELECT * FROM public."country" LIMIT 10;',
|
||||
);
|
||||
// Going to HomePage where the button widget is located and opeing it's property pane.
|
||||
cy.get("[data-guided-tour-id='explorer-entity-Page1']").click({
|
||||
force: true,
|
||||
});
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
PageLeftPane.switchSegment(PagePaneSegment.UI);
|
||||
cy.openPropertyPane("selectwidget");
|
||||
cy.reload();
|
||||
|
|
|
|||
|
|
@ -38,22 +38,23 @@ describe(
|
|||
() => {
|
||||
before(() => {
|
||||
agHelper.AddDsl("Listv2/ListV2WithNullPrimaryKey");
|
||||
agHelper.Sleep(3000); //for List to load for CI flakyness
|
||||
});
|
||||
|
||||
it("1. Widgets get displayed when PrimaryKey doesn't exist - SSP", () => {
|
||||
apiPage.CreateAndFillApi(
|
||||
"https://api.punkapi.com/v2/beers?page={{List1.pageNo}}&per_page={{List1.pageSize}}",
|
||||
"http://host.docker.internal:5001/v1/dynamicrecords/getrecordsArray",
|
||||
"",
|
||||
);
|
||||
agHelper.VerifyEvaluatedValue(
|
||||
"https://api.punkapi.com/v2/beers?page=1&per_page=2",
|
||||
);
|
||||
apiPage.RunAPI(false);
|
||||
EditorNavigation.SelectEntityByName("List1", EntityType.Widget);
|
||||
propPane.SelectPropertiesDropDown("Data Identifier", "value");
|
||||
agHelper.AssertElementAbsence(propPane._dropdownControlError);
|
||||
|
||||
EditorNavigation.SelectEntityByName("Text2", EntityType.Widget, {}, [
|
||||
"List1",
|
||||
"Container1",
|
||||
]);
|
||||
|
||||
propPane.UpdatePropertyFieldValue("Text", "{{currentIndex}}");
|
||||
agHelper.AssertText(propPane._widgetToVerifyText("Text2"), "text", "0");
|
||||
table.NavigateToPageUsingButton_List("next", 2);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@ describe(
|
|||
" " +
|
||||
locators._widgetInDeployed(draggableWidgets.TABLE),
|
||||
);
|
||||
|
||||
deployMode.NavigateBacktoEditor();
|
||||
|
||||
//Fixed height
|
||||
|
|
@ -135,10 +134,6 @@ describe(
|
|||
deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.BUTTON));
|
||||
agHelper.ClickButton("Submit");
|
||||
agHelper.AssertElementVisibility(locators._modal);
|
||||
|
||||
//Verify that a fixed canvas size is visible when height is selected as Fixed
|
||||
agHelper.AssertProperty(locators._modal, "offsetHeight", 1094);
|
||||
agHelper.AssertProperty(locators._modal, "offsetWidth", 456);
|
||||
agHelper.AssertElementVisibility(
|
||||
locators._modal +
|
||||
" " +
|
||||
|
|
|
|||
|
|
@ -97,8 +97,7 @@ describe(
|
|||
// Check if the cursor is at the end when input Type is HTML
|
||||
setRTEContent(testString);
|
||||
testCursorPoistion(testStringLen, tinyMceId);
|
||||
setRTEContent("{selectAll}");
|
||||
setRTEContent("{backspace}");
|
||||
setRTEContent("{selectAll}{del}");
|
||||
|
||||
// Changing the input type to markdown and again testing the cursor position
|
||||
cy.openPropertyPane("richtexteditorwidget");
|
||||
|
|
|
|||
|
|
@ -46,13 +46,16 @@ describe("Rest Bugs tests", { tags: ["@tag.Datasource"] }, function () {
|
|||
agHelper.PressEscape();
|
||||
|
||||
//Api 3
|
||||
apiPage.CreateAndFillApi("http://numbersapi.com/random/math", "NumberFact");
|
||||
apiPage.CreateAndFillApi(
|
||||
"http://host.docker.internal:8000/a.txt",
|
||||
"SampleText",
|
||||
);
|
||||
agHelper.PressEscape();
|
||||
|
||||
//Api 4
|
||||
apiPage.CreateAndFillApi(
|
||||
"https://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita",
|
||||
"CocktailDB",
|
||||
"http://host.docker.internal:5001/v1/dynamicrecords/getrecordsArray",
|
||||
"dynamicRecords",
|
||||
);
|
||||
agHelper.PressEscape();
|
||||
|
||||
|
|
|
|||
|
|
@ -367,12 +367,12 @@ describe("JS Function Execution", { tags: ["@tag.JS"] }, function () {
|
|||
isMarkedAsync ? "async" : ""
|
||||
} ()=>"${functionName}",`
|
||||
: i === functionsLength - 1
|
||||
? `
|
||||
? `
|
||||
${functionName}: ${
|
||||
isMarkedAsync ? "async" : ""
|
||||
} ()=>"${functionName}",
|
||||
}`
|
||||
: `
|
||||
: `
|
||||
${functionName}: ${
|
||||
isMarkedAsync ? "async" : ""
|
||||
} ()=> "${functionName}",`;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
agHelper,
|
||||
dataSources,
|
||||
debuggerHelper,
|
||||
deployMode,
|
||||
entityExplorer,
|
||||
homePage,
|
||||
|
|
@ -70,44 +71,14 @@ describe(
|
|||
//homePage.DeleteWorkspace("JSOnLoadTest");
|
||||
});
|
||||
|
||||
it("6. Tc #1910 - Verify the Number of confirmation models of JS Object on page load", () => {
|
||||
it("6. Tc #1910 - Verify that JSObject functions set to run on pageLoad are executed on page refresh", () => {
|
||||
homePage.CreateAppInWorkspace("JSOnLoadTest");
|
||||
entityExplorer.DragDropWidgetNVerify("buttonwidget", 100, 100);
|
||||
dataSources.CreateDataSource("Postgres");
|
||||
cy.get("@dsName").then((dsName) => {
|
||||
datasourceName = dsName;
|
||||
dataSources.CreateQueryAfterDSSaved(
|
||||
`SELECT * FROM public."astronauts" LIMIT 1;`,
|
||||
"getastronauts",
|
||||
);
|
||||
dataSources.CreateQueryFromOverlay(
|
||||
datasourceName,
|
||||
`SELECT * FROM public."category" LIMIT 1;`,
|
||||
"getcategory",
|
||||
);
|
||||
dataSources.CreateQueryFromOverlay(
|
||||
datasourceName,
|
||||
`SELECT * FROM public."city" LIMIT 1;`,
|
||||
"getcity",
|
||||
);
|
||||
dataSources.CreateQueryFromOverlay(
|
||||
datasourceName,
|
||||
`SELECT * FROM public."film" LIMIT 1;`,
|
||||
"getfilm",
|
||||
);
|
||||
dataSources.CreateQueryFromOverlay(
|
||||
datasourceName,
|
||||
`SELECT * FROM public."hogwartsstudents" LIMIT 1;`,
|
||||
"gethogwartsstudents",
|
||||
);
|
||||
});
|
||||
|
||||
jsEditor.CreateJSObject(
|
||||
`export default {
|
||||
astros: () => {
|
||||
return getastronauts.run(); },
|
||||
return "test" },
|
||||
city: () => {
|
||||
return getcity.run()
|
||||
return "test2"
|
||||
}
|
||||
}`,
|
||||
{
|
||||
|
|
@ -119,57 +90,14 @@ describe(
|
|||
);
|
||||
|
||||
jsEditor.EnableDisableAsyncFuncSettings("astros", true);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("city", true);
|
||||
|
||||
jsEditor.CreateJSObject(
|
||||
`export default {
|
||||
cat: () => {
|
||||
return getcategory.run(); },
|
||||
hogwartsstudents: () => {
|
||||
return gethogwartsstudents.run();
|
||||
}
|
||||
}`,
|
||||
{
|
||||
paste: true,
|
||||
completeReplace: true,
|
||||
toRun: false,
|
||||
shouldCreateNewJSObj: true,
|
||||
},
|
||||
);
|
||||
|
||||
jsEditor.EnableDisableAsyncFuncSettings("cat", true);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("hogwartsstudents", true);
|
||||
|
||||
jsEditor.CreateJSObject(
|
||||
`export default {
|
||||
film: async () => {
|
||||
return getfilm.run();
|
||||
}
|
||||
}`,
|
||||
{
|
||||
paste: true,
|
||||
completeReplace: true,
|
||||
toRun: false,
|
||||
shouldCreateNewJSObj: true,
|
||||
},
|
||||
);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("film", true);
|
||||
});
|
||||
|
||||
it("7. Tc #1909 - Verify the sequence of of JS Object on page load", () => {
|
||||
EditorNavigation.SelectEntityByName("JSObject1", EntityType.JSObject);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("astros", true);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("city", true);
|
||||
EditorNavigation.SelectEntityByName("JSObject2", EntityType.JSObject);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("cat", true);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("hogwartsstudents", true);
|
||||
EditorNavigation.SelectEntityByName("JSObject3", EntityType.JSObject);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("film", true);
|
||||
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
agHelper.RefreshPage();
|
||||
|
||||
agHelper.ValidateToastMessage("ran successfully", 0, 5);
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.ClickLogsTab();
|
||||
debuggerHelper.DebuggerLogsFilter("JSObject1.astros");
|
||||
debuggerHelper.DoesConsoleLogExist("JS Function executed successfully");
|
||||
});
|
||||
|
||||
function AssertJSOnPageLoad(
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ describe(
|
|||
entityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: "ListingAndReviews",
|
||||
action: "Delete",
|
||||
entityType: entityItems.Datasource,
|
||||
entityType: entityItems.Page,
|
||||
});
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import EditorNavigation, {
|
||||
EntityType,
|
||||
} from "../../../support/Pages/EditorNavigation";
|
||||
import EditorNavigation from "../../../support/Pages/EditorNavigation";
|
||||
|
||||
const datasource = require("../../../locators/DatasourcesEditor.json");
|
||||
const queryLocators = require("../../../locators/QueryEditor.json");
|
||||
|
|
@ -57,7 +55,7 @@ describe(
|
|||
.eq(6)
|
||||
.type("{{FilePicker.files}}", { parseSpecialCharSequences: false });
|
||||
agHelper.ClickOutside(); //to close the evaluated pop-up
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
EditorNavigation.ShowCanvas();
|
||||
cy.wait(2000);
|
||||
});
|
||||
|
||||
|
|
@ -96,8 +94,7 @@ describe(
|
|||
});
|
||||
|
||||
it("3. On canvas, fill to email, from email, subject, body, attachment and run query", function () {
|
||||
EditorNavigation.SelectEntityByName("smtpquery", EntityType.Query);
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
EditorNavigation.ShowCanvas();
|
||||
const noise = Math.random().toString(36).substring(0, 7);
|
||||
const fromEmail = `smtp.datasource.tester.${noise}@appsmith.com`;
|
||||
cy.wait(2000);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
"topRow": 4,
|
||||
"bottomRow": 36,
|
||||
"parentRowSpace": 10,
|
||||
"source": "https://www.example.com",
|
||||
"source": "http://host.docker.internal:8000/a.txt",
|
||||
"type": "IFRAME_WIDGET",
|
||||
"hideCard": false,
|
||||
"borderOpacity": 100,
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
"topRow": 6.0,
|
||||
"bottomRow": 38.0,
|
||||
"parentRowSpace": 10.0,
|
||||
"source": "https://www.example.com",
|
||||
"source": "http://host.docker.internal:8000/a.txt",
|
||||
"type": "IFRAME_WIDGET",
|
||||
"hideCard": false,
|
||||
"borderOpacity": 100.0,
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"image": "https://source.unsplash.com/mGFHA_0TWnA/2048x620",
|
||||
"image": "http://host.docker.internal:8000/photo-1492529029602-33e53698f407.jpeg",
|
||||
"widgetName": "Image1",
|
||||
"rightColumn": 64,
|
||||
"widgetId": "ah4cbb9o2e",
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"image": "https://source.unsplash.com/mGFHA_0TWnA/2048x620",
|
||||
"image": "http://host.docker.internal:8000/photo-1503469432756-4aae2e18d881.jpeg",
|
||||
"widgetName": "Image1",
|
||||
"rightColumn": 64,
|
||||
"widgetId": "ah4cbb9o2e",
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
|
@ -289,8 +289,8 @@ export class AggregateHelper {
|
|||
return exists === "noVerify"
|
||||
? locator // Return the locator without verification if exists is "noVerify"
|
||||
: exists === "exist"
|
||||
? locator.should("have.length.at.least", 1)
|
||||
: locator.should("have.length", 0);
|
||||
? locator.should("have.length.at.least", 1)
|
||||
: locator.should("have.length", 0);
|
||||
}
|
||||
|
||||
public GetNAssertElementText(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { ObjectsRegistry } from "../Objects/Registry";
|
||||
import type { EntityItemsType } from "./AssertHelper";
|
||||
import { EntityItems } from "./AssertHelper";
|
||||
import EditorNavigation, {
|
||||
EntityType,
|
||||
|
|
@ -38,8 +39,7 @@ interface EntityActionParams {
|
|||
| "Export"
|
||||
| "Import";
|
||||
subAction?: string;
|
||||
//@ts-expect-error: type mismatch
|
||||
entityType?: EntityItems;
|
||||
entityType?: EntityItemsType;
|
||||
toAssertAction?: boolean;
|
||||
toastToValidate?: string;
|
||||
}
|
||||
|
|
@ -82,6 +82,9 @@ export class EntityExplorer {
|
|||
}: EntityActionParams) {
|
||||
AppSidebar.navigate(AppSidebarButton.Editor);
|
||||
this.agHelper.Sleep();
|
||||
if (entityType === EntityItems.Page) {
|
||||
PageList.ShowList();
|
||||
}
|
||||
cy.xpath(this._contextMenu(entityNameinLeftSidebar))
|
||||
.scrollIntoView()
|
||||
.last()
|
||||
|
|
@ -98,6 +101,9 @@ export class EntityExplorer {
|
|||
toastToValidate: toastToValidate,
|
||||
});
|
||||
}
|
||||
if (entityType === EntityItems.Page) {
|
||||
PageList.HideList();
|
||||
}
|
||||
}
|
||||
|
||||
public DeleteWidgetFromEntityExplorer(widgetNameinLeftSidebar: string) {
|
||||
|
|
@ -168,10 +174,10 @@ export class EntityExplorer {
|
|||
dropTargetId
|
||||
? dropTargetId + this.locator._dropHere
|
||||
: parentWidgetType
|
||||
? this.locator._widgetInCanvas(parentWidgetType) +
|
||||
" " +
|
||||
this.locator._dropHere
|
||||
: this.locator._dropHere,
|
||||
? this.locator._widgetInCanvas(parentWidgetType) +
|
||||
" " +
|
||||
this.locator._dropHere
|
||||
: this.locator._dropHere,
|
||||
)
|
||||
.first()
|
||||
.trigger("mousemove", x, y, {
|
||||
|
|
@ -256,13 +262,17 @@ export class EntityExplorer {
|
|||
entityName: string,
|
||||
renameVal: string,
|
||||
viaMenu = false,
|
||||
entityType?: EntityItemsType,
|
||||
) {
|
||||
AppSidebar.navigate(AppSidebarButton.Editor);
|
||||
PageList.ShowList();
|
||||
if (entityType === EntityItems.Page && !viaMenu) {
|
||||
PageList.ShowList();
|
||||
}
|
||||
if (viaMenu)
|
||||
this.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: entityName,
|
||||
action: "Edit name",
|
||||
entityType,
|
||||
});
|
||||
else cy.xpath(PageLeftPane.listItemSelector(entityName)).dblclick();
|
||||
cy.xpath(this.locator._entityNameEditing(entityName))
|
||||
|
|
@ -271,6 +281,10 @@ export class EntityExplorer {
|
|||
.type("{enter}")
|
||||
.wait(300);
|
||||
this.agHelper.Sleep(); //allowing time for name change to reflect in EntityExplorer
|
||||
PageLeftPane.assertPresence(renameVal);
|
||||
if (entityType === EntityItems.Page) {
|
||||
PageList.assertPresence(renameVal);
|
||||
} else {
|
||||
PageLeftPane.assertPresence(renameVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,8 +344,7 @@ export class GitSync {
|
|||
"Unable to import application in workspace",
|
||||
),
|
||||
);
|
||||
this.agHelper.AssertElementExist(this.locator._btnSpinner);
|
||||
this.agHelper.AssertElementAbsence(this.locator._btnSpinner, 70000); //Since page taking more time to laod in some cases
|
||||
this.agHelper.WaitUntilEleAppear(this._branchName(branch + uid));
|
||||
this.agHelper.AssertElementVisibility(this._branchName(branch + uid));
|
||||
this.assertHelper.AssertNetworkStatus("getBranch");
|
||||
cy.wrap(branch + uid).as("gitbranchName");
|
||||
|
|
|
|||
|
|
@ -91,9 +91,12 @@ export class LeftPane {
|
|||
}
|
||||
});
|
||||
}
|
||||
public selectedItem(): Cypress.Chainable {
|
||||
public selectedItem(
|
||||
exists?: "exist" | "not.exist" | "noVerify",
|
||||
): Cypress.Chainable {
|
||||
return ObjectsRegistry.AggregateHelper.GetElement(
|
||||
this.locators.activeItemSelector,
|
||||
exists,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ import EditorNavigation, {
|
|||
AppSidebarButton,
|
||||
EntityType,
|
||||
} from "./EditorNavigation";
|
||||
import { EntityItems } from "./AssertHelper";
|
||||
|
||||
class PageList {
|
||||
private locators = {
|
||||
pageListItem: (pageName: string) =>
|
||||
`.t--entity.page:contains('${pageName}')`,
|
||||
newButton: ".pages .t--entity-add-btn",
|
||||
newPageOption: (option: string) => `//span[text()='${option}']/parent::div`,
|
||||
newPageOption: ".ads-v2-menu__menu-item-children",
|
||||
switcher: `.t--pages-switcher`,
|
||||
};
|
||||
|
||||
|
|
@ -23,9 +24,9 @@ class PageList {
|
|||
AppSidebar.navigate(AppSidebarButton.Editor);
|
||||
this.ShowList();
|
||||
ObjectsRegistry.AggregateHelper.GetNClick(this.locators.newButton);
|
||||
ObjectsRegistry.AggregateHelper.GetNClick(
|
||||
this.locators.newPageOption(option),
|
||||
);
|
||||
cy.get(this.locators.newPageOption)
|
||||
.contains(option, { matchCase: false })
|
||||
.click({ force: true });
|
||||
if (option === "New blank page") {
|
||||
ObjectsRegistry.AssertHelper.AssertNetworkStatus("@createPage", 201);
|
||||
|
||||
|
|
@ -40,37 +41,54 @@ class PageList {
|
|||
ObjectsRegistry.AggregateHelper.GetElement(
|
||||
this.locators.pageListItem(pageName),
|
||||
).should("have.class", "activePage");
|
||||
this.HideList();
|
||||
}
|
||||
|
||||
public SelectedPageItem(): Cypress.Chainable {
|
||||
this.ShowList();
|
||||
return cy.get(".t--entity.page > .active");
|
||||
this.HideList();
|
||||
}
|
||||
|
||||
public ClonePage(pageName = "Page1") {
|
||||
AppSidebar.navigate(AppSidebarButton.Editor);
|
||||
this.ShowList();
|
||||
EditorNavigation.SelectEntityByName(pageName, EntityType.Page);
|
||||
ObjectsRegistry.EntityExplorer.ActionContextMenuByEntityName({
|
||||
entityNameinLeftSidebar: pageName,
|
||||
action: "Clone",
|
||||
entityType: EntityItems.Page,
|
||||
});
|
||||
ObjectsRegistry.AssertHelper.AssertNetworkStatus("@clonePage", 201);
|
||||
}
|
||||
|
||||
public ShowList() {
|
||||
cy.get(this.locators.switcher).then(($switcher) => {
|
||||
const isActive: string | undefined = $switcher.attr("data-active");
|
||||
if (isActive === "false") {
|
||||
const isActive: string | undefined = $switcher
|
||||
.parent()
|
||||
.attr("data-state");
|
||||
if (isActive === "closed") {
|
||||
cy.get(this.locators.switcher).click();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HideList() {
|
||||
cy.get(this.locators.switcher).then(($switcher) => {
|
||||
const isActive: string | undefined = $switcher
|
||||
.parent()
|
||||
.attr("data-state");
|
||||
if (isActive === "open") {
|
||||
cy.get(this.locators.switcher).click({ force: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
assertPresence(pageName: string) {
|
||||
this.ShowList();
|
||||
ObjectsRegistry.AggregateHelper.AssertElementVisibility(
|
||||
this.locators.pageListItem(pageName),
|
||||
);
|
||||
this.HideList();
|
||||
}
|
||||
|
||||
assertAbsence(pageName: string) {
|
||||
|
|
@ -78,6 +96,7 @@ class PageList {
|
|||
ObjectsRegistry.AggregateHelper.AssertElementAbsence(
|
||||
this.locators.pageListItem(pageName),
|
||||
);
|
||||
this.HideList();
|
||||
}
|
||||
|
||||
DeletePage(name: string) {
|
||||
|
|
@ -91,6 +110,7 @@ class PageList {
|
|||
cy.wait("@deletePage")
|
||||
.its("response.body.responseMeta.status")
|
||||
.should("eq", 200);
|
||||
this.HideList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ export class PropertyPane {
|
|||
|
||||
_dataIcon = (icon: string) => `[data-icon="${icon}"]`;
|
||||
_iconDropdown = "[data-test-id='virtuoso-scroller']";
|
||||
_dropdownControlError = "[data-testid='t---dropdown-control-error']";
|
||||
|
||||
public OpenJsonFormFieldSettings(fieldName: string) {
|
||||
this.agHelper.GetNClick(this._jsonFieldEdit(fieldName));
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ const dynamicInputLocators = require("../locators/DynamicInput.json");
|
|||
const viewWidgetsPage = require("../locators/ViewWidgets.json");
|
||||
import { ObjectsRegistry } from "../support/Objects/Registry";
|
||||
import { TABLE_COLUMN_ORDER_KEY } from "./Constants";
|
||||
import { EntityItems } from "./Pages/AssertHelper";
|
||||
|
||||
let pageidcopy = " ";
|
||||
|
||||
|
|
@ -934,7 +935,12 @@ Cypress.Commands.add("Createpage", (pageName, navigateToCanvasPage = true) => {
|
|||
PageList.AddNewPage().then((oldPageName) => {
|
||||
if (pageName) {
|
||||
cy.wait(2000);
|
||||
ee.RenameEntityFromExplorer(oldPageName, pageName, true);
|
||||
ee.RenameEntityFromExplorer(
|
||||
oldPageName,
|
||||
pageName,
|
||||
false,
|
||||
EntityItems.Page,
|
||||
);
|
||||
}
|
||||
cy.get("#loading").should("not.exist");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -59,8 +59,12 @@ module.exports = {
|
|||
"@tag.PropertyPane",
|
||||
"@tag.Workspace",
|
||||
"@tag.Sanity",
|
||||
"@tag.Templates",
|
||||
"@tag.Auditlogs",
|
||||
"@tag.AccessControl",
|
||||
"@tag.LicenseAndBilling",
|
||||
"@tag.Authentication",
|
||||
"@tag.Provisioning",
|
||||
"@tag.Templates",
|
||||
"@tag.MainContainer",
|
||||
"@tag.Visual",
|
||||
"@tag.Module",
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@
|
|||
"d3-geo": "^3.1.0",
|
||||
"dayjs": "^1.10.6",
|
||||
"deep-diff": "^1.0.2",
|
||||
"design-system": "npm:@appsmithorg/design-system@2.1.37",
|
||||
"design-system": "npm:@appsmithorg/design-system@2.1.38",
|
||||
"design-system-old": "npm:@appsmithorg/design-system-old@1.1.16",
|
||||
"downloadjs": "^1.4.7",
|
||||
"echarts": "^5.4.2",
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
import { Button } from "@design-system/headless";
|
||||
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
|
||||
|
||||
<Meta
|
||||
title="Design-system/Headless/Button"
|
||||
component={Button}
|
||||
args={{
|
||||
children: "Button",
|
||||
}}
|
||||
/>
|
||||
|
||||
export const Template = (args) => <Button {...args} />;
|
||||
|
||||
# Button
|
||||
|
||||
A button is a clickable element that is used to trigger an action.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Button">{Template.bind({})}</Story>
|
||||
</Canvas>
|
||||
|
||||
<ArgsTable story="Button" of={Button} />
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { Button } from "@design-system/headless";
|
||||
|
||||
const meta: Meta<typeof Button> = {
|
||||
component: Button,
|
||||
title: "Design-system/headless/Button",
|
||||
render: () => <Button>Button</Button>,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Button>;
|
||||
|
||||
export const Main: Story = {};
|
||||
|
|
@ -76,8 +76,8 @@ const _Checkbox = (props: CheckboxProps, ref: CheckboxRef) => {
|
|||
const dataState = isIndeterminate
|
||||
? "indeterminate"
|
||||
: Boolean(inputProps.checked)
|
||||
? "checked"
|
||||
: "unchecked";
|
||||
? "checked"
|
||||
: "unchecked";
|
||||
|
||||
return (
|
||||
<label
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { Checkbox, CheckboxGroup } from "@design-system/headless";
|
||||
|
||||
const meta: Meta<typeof CheckboxGroup> = {
|
||||
component: CheckboxGroup,
|
||||
title: "Design-system/headless/CheckboxGroup",
|
||||
subcomponents: {
|
||||
Checkbox,
|
||||
},
|
||||
render: (args) => (
|
||||
<CheckboxGroup {...args}>
|
||||
<Checkbox value="value-1">Value 1</Checkbox>
|
||||
<Checkbox value="value-2">Value 2</Checkbox>
|
||||
</CheckboxGroup>
|
||||
),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Checkbox>;
|
||||
|
||||
export const Main: Story = {};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import { CheckboxGroup, Checkbox } from "@design-system/headless";
|
||||
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
|
||||
|
||||
<Meta
|
||||
title="Design-system/Headless/CheckboxGroup"
|
||||
component={CheckboxGroup}
|
||||
args={{
|
||||
label: "Checkbox group",
|
||||
children: (
|
||||
<>
|
||||
<Checkbox value="option 1">Option 1</Checkbox>
|
||||
<Checkbox value="option 2">Option 2</Checkbox>
|
||||
</>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
export const Template = (args) => <CheckboxGroup {...args} />;
|
||||
|
||||
# CheckboxGroup
|
||||
|
||||
A Checkbox group is a group of radio buttons that are related to each other in some way. For example, they may all represent a single question on a survey. The Checkbox group component is a headless component that provides the logic and accessibility implementation for a group of radio buttons.
|
||||
|
||||
Note: The `<input="checkbox" />` is visually hidden. Use the `<span data-icon />` to render a custom looking checkbox.
|
||||
|
||||
<Canvas>
|
||||
<Story name="CheckboxGroup">{Template.bind({})}</Story>
|
||||
</Canvas>
|
||||
|
||||
<ArgsTable story="CheckboxGroup" of={CheckboxGroup} />
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
import { Menu, Button, MenuList, Item } from "@design-system/headless";
|
||||
import { Canvas, Meta, Story, ArgsTable, Source } from "@storybook/addon-docs";
|
||||
|
||||
<Meta title="Design-system/Headless/Menu" component={Menu} />
|
||||
|
||||
export const Template = (args) => {
|
||||
return (
|
||||
<Menu {...args}>
|
||||
<Button>Menu trigger</Button>
|
||||
<MenuList>
|
||||
<Item>Cut</Item>
|
||||
<Item>Copy</Item>
|
||||
<Item>Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
# Menu
|
||||
|
||||
A menu displays a list of actions or options that a user can choose.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Menu">{Template.bind({})}</Story>
|
||||
</Canvas>
|
||||
|
||||
## Menu props
|
||||
|
||||
<ArgsTable story="Menu" of={Menu} />
|
||||
|
||||
## MenuList props
|
||||
|
||||
<ArgsTable of={MenuList} />
|
||||
|
||||
## Item props
|
||||
|
||||
Item props are not pulled up in the ArgsTable, the data can be found [here](https://react-spectrum.adobe.com/react-aria/Menu.html#item).
|
||||
|
||||
# Placement
|
||||
|
||||
The placement of the menu can be changed by passing the `placement` prop.
|
||||
|
||||
<Story name="Menu placement">
|
||||
<Menu placement="left">
|
||||
<Button>Left</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
<Menu placement="top">
|
||||
<Button>Top</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
<Menu placement="bottom">
|
||||
<Button>Bottom</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
<Menu placement="right">
|
||||
<Button>Right</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</Story>
|
||||
|
||||
# Menu example
|
||||
|
||||
<Canvas>
|
||||
<Story name="Menu example">
|
||||
<Menu
|
||||
items={[
|
||||
{ id: 1, name: "New" },
|
||||
{ id: 2, name: "Open" },
|
||||
]}
|
||||
onAction={(key) => console.log(key)}
|
||||
>
|
||||
<Button>Menu trigger</Button>
|
||||
<MenuList>{(item) => <Item key={item.name}>{item.name}</Item>}</MenuList>
|
||||
</Menu>
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
<Source
|
||||
dark
|
||||
code={`
|
||||
<Menu
|
||||
items={[
|
||||
{ id: 1, name: "New" },
|
||||
{ id: 2, name: "Open" },
|
||||
]}
|
||||
onAction={(key) => console.log(key)}
|
||||
>
|
||||
<Button>Menu trigger</Button>
|
||||
<MenuList>{(item) => <Item key={item.name}>{item.name}</Item>}</MenuList>
|
||||
</Menu>
|
||||
`}
|
||||
/>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { Menu, Button, MenuList, Item } from "@design-system/headless";
|
||||
|
||||
/**
|
||||
* A menu displays a list of actions or options that a user can choose.
|
||||
*
|
||||
* Item props are not pulled up in the ArgsTable, the data can be found [here](https://react-spectrum.adobe.com/react-aria/Menu.html#item).
|
||||
*/
|
||||
|
||||
const meta: Meta<typeof Menu> = {
|
||||
component: Menu,
|
||||
title: "Design-system/headless/Menu",
|
||||
subcomponents: {
|
||||
//@ts-expect-error: don't need props to pass here
|
||||
MenuList,
|
||||
},
|
||||
render: (args) => (
|
||||
<Menu {...args}>
|
||||
<Button>Menu trigger</Button>
|
||||
<MenuList>
|
||||
<Item>Cut</Item>
|
||||
<Item>Copy</Item>
|
||||
<Item>Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Menu>;
|
||||
|
||||
export const Main: Story = {};
|
||||
|
||||
/**
|
||||
* The placement of the menu can be changed by passing the `placement` prop.
|
||||
*/
|
||||
export const Placement: Story = {
|
||||
render: () => (
|
||||
<>
|
||||
<Menu placement="left">
|
||||
<Button>Left</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
<Menu placement="top">
|
||||
<Button>Top</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
<Menu placement="bottom">
|
||||
<Button>Bottom</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
<Menu placement="right">
|
||||
<Button>Right</Button>
|
||||
<MenuList>
|
||||
<Item key="copy">Copy</Item>
|
||||
<Item key="cut">Cut</Item>
|
||||
<Item key="paste">Paste</Item>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
import {
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
PopoverModalContent,
|
||||
Button,
|
||||
} from "@design-system/headless";
|
||||
import { ControlledPopover } from "./ControlledPopover";
|
||||
import { Canvas, Meta, Story, ArgsTable, Source } from "@storybook/addon-docs";
|
||||
|
||||
<Meta title="Design-system/Headless/Popover" component={Popover} />
|
||||
|
||||
export const Template = (args) => {
|
||||
return (
|
||||
<Popover {...args}>
|
||||
<PopoverTrigger>
|
||||
<Button>My trigger</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
# Popover
|
||||
|
||||
A popover is an interactive mini-dialog floating element that displays information related to an anchor element when the element is clicked.
|
||||
|
||||
Based on the [headless Popover component](/?path=/docs/design-system-headless-popover--docs).
|
||||
|
||||
<Canvas>
|
||||
<Story name="Popover">{Template.bind({})}</Story>
|
||||
</Canvas>
|
||||
|
||||
## Popover props
|
||||
|
||||
<ArgsTable story="Popover" of={Popover} />
|
||||
|
||||
## PopoverTrigger props
|
||||
|
||||
<ArgsTable of={PopoverTrigger} />
|
||||
|
||||
## PopoverContent props
|
||||
|
||||
<ArgsTable of={PopoverContent} />
|
||||
|
||||
# Modal
|
||||
|
||||
A modal is a floating element that displays information that requires immediate attention, appearing over the page content and blocking interactions with the page until it is dismissed.
|
||||
|
||||
## PopoverModalContent props
|
||||
|
||||
<ArgsTable of={PopoverModalContent} />
|
||||
|
||||
<Source
|
||||
dark
|
||||
code={`
|
||||
export const Modal = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const ref = useRef(null);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onPress={() => setIsOpen(!isOpen)} ref={ref}>
|
||||
Controlled popover
|
||||
</Button>
|
||||
<Popover isOpen={isOpen} setOpen={setIsOpen} triggerRef={ref}>
|
||||
<PopoverContent>Controlled popover content</PopoverContent>
|
||||
</Popover>
|
||||
</>
|
||||
);
|
||||
|
||||
};
|
||||
`}
|
||||
/>
|
||||
|
||||
# Placement
|
||||
|
||||
The placement of the popover can be changed by passing the `placement` prop.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Popover placement">
|
||||
<Popover placement="left">
|
||||
<PopoverTrigger>
|
||||
<Button>Left</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
<Popover placement="top">
|
||||
<PopoverTrigger>
|
||||
<Button>Top</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
<Popover placement="bottom">
|
||||
<PopoverTrigger>
|
||||
<Button>Bottom</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
<Popover placement="right">
|
||||
<PopoverTrigger>
|
||||
<Button>Right</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
# Controlled popover
|
||||
|
||||
<Canvas>
|
||||
<Story name="Controlled popover">
|
||||
<ControlledPopover />
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
<Source
|
||||
dark
|
||||
code={`
|
||||
export const ControlledPopover = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
return (
|
||||
<Popover isOpen={isOpen} setOpen={setIsOpen}>
|
||||
<PopoverTrigger>
|
||||
<Button onPress={() => setIsOpen(!isOpen)}>Controlled popover</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>Controlled popover content</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
`}
|
||||
/>
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import {
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
PopoverModalContent,
|
||||
Button,
|
||||
} from "@design-system/headless";
|
||||
import { ControlledPopover as ControlledPopoverExample } from "./ControlledPopover";
|
||||
|
||||
/**
|
||||
* A popover is an interactive mini-dialog floating element that displays information related to an anchor element when the element is clicked.
|
||||
*
|
||||
* Based on the [headless Popover component](/?path=/docs/design-system-headless-popover--docs).
|
||||
*
|
||||
* A popover is a floating element that displays information that requires immediate attention, appearing over the page content and blocking interactions with the page until it is dismissed.
|
||||
*/
|
||||
|
||||
const meta: Meta<typeof Popover> = {
|
||||
component: Popover,
|
||||
title: "Design-system/headless/Popover",
|
||||
subcomponents: {
|
||||
//@ts-expect-error: don't need props to pass here
|
||||
PopoverTrigger,
|
||||
//@ts-expect-error: don't need props to pass here
|
||||
PopoverContent,
|
||||
//@ts-expect-error: don't need props to pass here
|
||||
PopoverModalContent,
|
||||
},
|
||||
render: (args) => (
|
||||
<Popover {...args}>
|
||||
<PopoverTrigger>
|
||||
<Button>My trigger</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Popover>;
|
||||
|
||||
export const Main: Story = {};
|
||||
|
||||
/**
|
||||
* The placement of the menu can be changed by passing the `placement` prop.
|
||||
*/
|
||||
export const Placement: Story = {
|
||||
render: () => (
|
||||
<>
|
||||
<Popover placement="left">
|
||||
<PopoverTrigger>
|
||||
<Button>Left</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
<Popover placement="top">
|
||||
<PopoverTrigger>
|
||||
<Button>Top</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
<Popover placement="bottom">
|
||||
<PopoverTrigger>
|
||||
<Button>Bottom</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
<Popover placement="right">
|
||||
<PopoverTrigger>
|
||||
<Button>Right</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>My popover</PopoverContent>
|
||||
</Popover>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
export const ControlledPopover: Story = {
|
||||
render: () => <ControlledPopoverExample />,
|
||||
};
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { RadioGroup, Radio } from "@design-system/headless";
|
||||
|
||||
/**
|
||||
* A Radio group is a group of radio buttons that are related to each other in some way. For example, they may all represent a single question on a survey. The Radio group component is a headless component that provides the logic and accessibility implementation for a group of radio buttons.
|
||||
*
|
||||
* Note: The `<input="radio" />` is visually hidden by default. Use the `<span data-icon />` to render custom looking radio.
|
||||
*/
|
||||
const meta: Meta<typeof RadioGroup> = {
|
||||
component: RadioGroup,
|
||||
title: "Design-system/headless/RadioGroup",
|
||||
subcomponents: {
|
||||
//@ts-expect-error: don't need props to pass here
|
||||
Radio,
|
||||
},
|
||||
render: (args) => (
|
||||
<RadioGroup label="Radio group" {...args}>
|
||||
<Radio value="option 1">Option 1</Radio>
|
||||
<Radio value="option 2">Option 2</Radio>
|
||||
</RadioGroup>
|
||||
),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof RadioGroup>;
|
||||
|
||||
export const Main: Story = {};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import { RadioGroup, Radio } from "@design-system/headless";
|
||||
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
|
||||
|
||||
<Meta
|
||||
title="Design-system/Headless/RadioGroup"
|
||||
component={RadioGroup}
|
||||
args={{
|
||||
label: "Radio group",
|
||||
children: (
|
||||
<>
|
||||
<Radio value="option 1">Option 1</Radio>
|
||||
<Radio value="option 2">Option 2</Radio>
|
||||
</>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
export const Template = (args) => <RadioGroup {...args} />;
|
||||
|
||||
# RadioGroup
|
||||
|
||||
A Radio group is a group of radio buttons that are related to each other in some way. For example, they may all represent a single question on a survey. The Radio group component is a headless component that provides the logic and accessibility implementation for a group of radio buttons.
|
||||
|
||||
Note: The `<input="radio" />` is visually hidden by default. Use the `<span data-icon />` to render custom looking radio.
|
||||
|
||||
<Canvas>
|
||||
<Story name="RadioGroup">{Template.bind({})}</Story>
|
||||
</Canvas>
|
||||
|
||||
<ArgsTable story="RadioGroup" of={RadioGroup} />
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
|
||||
|
||||
import { TextInput } from "../";
|
||||
|
||||
<Meta
|
||||
title="Design-system/headless/TextInput"
|
||||
component={TextInput}
|
||||
args={{
|
||||
label: "Label",
|
||||
placeholder: "Placeholder",
|
||||
}}
|
||||
/>
|
||||
|
||||
export const Template = (args) => <TextInput {...args} />;
|
||||
|
||||
# TextInput
|
||||
|
||||
TextInput component allows users to input text. It is mostly used in forms.
|
||||
|
||||
<Canvas>
|
||||
<Story name="TextInput">{Template.bind({})}</Story>
|
||||
</Canvas>
|
||||
|
||||
# Props
|
||||
|
||||
<ArgsTable of={TextInput} />
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { TextInput } from "@design-system/headless";
|
||||
|
||||
/**
|
||||
* TextInput component allows users to input text. It is mostly used in forms.
|
||||
*/
|
||||
const meta: Meta<typeof TextInput> = {
|
||||
component: TextInput,
|
||||
title: "Design-system/headless/TextInput",
|
||||
args: {
|
||||
label: "Label",
|
||||
placeholder: "Placeholder",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof TextInput>;
|
||||
|
||||
export const Main: Story = {};
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
import {
|
||||
TooltipRoot,
|
||||
TooltipTrigger,
|
||||
TooltipContent,
|
||||
Button,
|
||||
} from "@design-system/headless";
|
||||
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
|
||||
|
||||
<Meta
|
||||
title="Design-system/Headless/Tooltip"
|
||||
component={TooltipRoot}
|
||||
args={{
|
||||
open: undefined,
|
||||
onOpenChange: undefined,
|
||||
}}
|
||||
/>
|
||||
|
||||
export const Template = (args) => {
|
||||
return (
|
||||
<TooltipRoot {...args}>
|
||||
<TooltipTrigger>
|
||||
<Button>My trigger</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
);
|
||||
};
|
||||
|
||||
# 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.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Tooltip">{Template.bind({})}</Story>
|
||||
</Canvas>
|
||||
|
||||
<ArgsTable story="Tooltip" of={TooltipRoot} />
|
||||
|
||||
# Placement
|
||||
|
||||
The placement of the tooltip can be changed by passing the `placement` prop.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Tooltip placement">
|
||||
<TooltipRoot placement="left">
|
||||
<TooltipTrigger>
|
||||
<Button>Left</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot placement="top">
|
||||
<TooltipTrigger>
|
||||
<Button>Top</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot placement="bottom">
|
||||
<TooltipTrigger>
|
||||
<Button>Bottom</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot placement="right">
|
||||
<TooltipTrigger>
|
||||
<Button>Right</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
# Disabled
|
||||
|
||||
If the trigger is disabled, the tooltip will not be displayed.
|
||||
|
||||
<Canvas>
|
||||
<Story name="Tooltip disabled">
|
||||
<TooltipRoot>
|
||||
<TooltipTrigger>
|
||||
<Button isDisabled>Disabled</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent disabled>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
import React from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import {
|
||||
TooltipRoot,
|
||||
TooltipTrigger,
|
||||
TooltipContent,
|
||||
Button,
|
||||
} from "@design-system/headless";
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
const meta: Meta<typeof TooltipRoot> = {
|
||||
component: TooltipRoot,
|
||||
title: "Design-system/headless/Tooltip",
|
||||
subcomponents: {
|
||||
TooltipTrigger,
|
||||
TooltipContent,
|
||||
},
|
||||
render: (args) => (
|
||||
<TooltipRoot {...args}>
|
||||
<TooltipTrigger>
|
||||
<Button>My trigger</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof TooltipRoot>;
|
||||
|
||||
export const Main: Story = {};
|
||||
|
||||
/**
|
||||
* The placement of the tooltip can be changed by passing the `placement` prop.
|
||||
*/
|
||||
export const Placement: Story = {
|
||||
render: () => (
|
||||
<>
|
||||
<TooltipRoot placement="left">
|
||||
<TooltipTrigger>
|
||||
<Button>Left</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot placement="top">
|
||||
<TooltipTrigger>
|
||||
<Button>Top</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot placement="bottom">
|
||||
<TooltipTrigger>
|
||||
<Button>Bottom</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot placement="right">
|
||||
<TooltipTrigger>
|
||||
<Button>Right</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
/**
|
||||
* If the trigger is disabled, the tooltip will not be displayed.
|
||||
*/
|
||||
export const Disabled: Story = {
|
||||
render: () => (
|
||||
<TooltipRoot>
|
||||
<TooltipTrigger>
|
||||
<Button isDisabled>Disabled</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>My tooltip</TooltipContent>
|
||||
</TooltipRoot>
|
||||
),
|
||||
};
|
||||
|
|
@ -6,6 +6,8 @@ import {
|
|||
StyledSquarePreview,
|
||||
} from "@design-system/storybook";
|
||||
|
||||
import { Icon } from "@design-system/widgets";
|
||||
|
||||
<Meta title="Design-system/Theme/Tokens/Dimension" />
|
||||
|
||||
# Dimension
|
||||
|
|
@ -114,10 +116,14 @@ Border radii on various elements are fluid and additionally adjusted by theme co
|
|||
|
||||
export const BorderRadius = () => {
|
||||
const { theme } = useTheme();
|
||||
const { borderRadius } = theme;
|
||||
console.log(theme);
|
||||
const { borderRadiusElevation } = theme;
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<TokenTable prefix="border-radius" tokens={borderRadius}>
|
||||
<TokenTable
|
||||
prefix="border-radius-elevation"
|
||||
tokens={borderRadiusElevation}
|
||||
>
|
||||
{(cssVar) => (
|
||||
<StyledSquarePreview
|
||||
style={{
|
||||
|
|
@ -134,11 +140,37 @@ export const BorderRadius = () => {
|
|||
|
||||
### Icon Sizing
|
||||
|
||||
--
|
||||
export const IconSizing = () => {
|
||||
const { theme } = useTheme();
|
||||
const { iconSize } = theme;
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<TokenTable prefix="icon-size" tokens={iconSize}>
|
||||
{(cssVar) => (
|
||||
<Icon name="star" style={{ width: cssVar, height: cssVar }} />
|
||||
)}
|
||||
</TokenTable>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
<IconSizing />
|
||||
|
||||
### Icon Stroke
|
||||
|
||||
--
|
||||
export const IconStroke = () => {
|
||||
const { theme } = useTheme();
|
||||
const { strokeWidth } = theme;
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<TokenTable prefix="stroke-width" tokens={strokeWidth}>
|
||||
{(cssVar) => <Icon name="star" style={{ strokeWidth: cssVar }} />}
|
||||
</TokenTable>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
<IconStroke />
|
||||
|
||||
[Table will be here once scale is implemented]
|
||||
|
||||