fix: update settings pane validations (#18739)
* init fix * button style update * decode url in preview * bring back custom slug validation * custom slug validation on type * remove imports * handle special characters in url preview * change label * code clean up * remove pageId from action name selector * messages clean up * tests for validations * cypress cases update * Renamed helper methods * add index for test cases * AppSettings specs script ts updates * Added Bud id in title #18698 * GIt Import spec fix * GItImport spec fix * Git import unskip * Skipping Git import Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
This commit is contained in:
parent
f67f8571ec
commit
284571803b
|
|
@ -1,17 +1,9 @@
|
||||||
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
|
import * as _objects from "../../../../support/Objects/ObjectsCore"
|
||||||
|
|
||||||
const {
|
|
||||||
AggregateHelper: agHelper,
|
|
||||||
DeployMode: deployMode,
|
|
||||||
EntityExplorer: ee,
|
|
||||||
JSEditor: jsEditor,
|
|
||||||
PropertyPane: propPane,
|
|
||||||
} = ObjectsRegistry;
|
|
||||||
|
|
||||||
describe("clearStore Action test", () => {
|
describe("clearStore Action test", () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
ee.DragDropWidgetNVerify("buttonwidget", 100, 100);
|
_objects.ee.DragDropWidgetNVerify("buttonwidget", 100, 100);
|
||||||
ee.NavigateToSwitcher("explorer");
|
_objects.ee.NavigateToSwitcher("explorer");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("1. Feature 11639 : Clear all store value", function() {
|
it("1. Feature 11639 : Clear all store value", function() {
|
||||||
|
|
@ -33,7 +25,7 @@ describe("clearStore Action test", () => {
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
// Create js object
|
// Create js object
|
||||||
jsEditor.CreateJSObject(JS_OBJECT_BODY, {
|
_objects.jsEditor.CreateJSObject(JS_OBJECT_BODY, {
|
||||||
paste: true,
|
paste: true,
|
||||||
completeReplace: true,
|
completeReplace: true,
|
||||||
toRun: false,
|
toRun: false,
|
||||||
|
|
@ -41,40 +33,40 @@ describe("clearStore Action test", () => {
|
||||||
shouldCreateNewJSObj: true,
|
shouldCreateNewJSObj: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
ee.SelectEntityByName("Button1", "Widgets");
|
_objects.ee.SelectEntityByName("Button1", "Widgets");
|
||||||
propPane.UpdatePropertyFieldValue("Label", "");
|
_objects.propPane.UpdatePropertyFieldValue("Label", "");
|
||||||
propPane.TypeTextIntoField("Label", "StoreValue");
|
_objects.propPane.TypeTextIntoField("Label", "StoreValue");
|
||||||
cy.get("@jsObjName").then((jsObj: any) => {
|
cy.get("@jsObjName").then((jsObj: any) => {
|
||||||
propPane.SelectJSFunctionToExecute(
|
_objects.propPane.SelectJSFunctionToExecute(
|
||||||
"onClick",
|
"onClick",
|
||||||
jsObj as string,
|
jsObj as string,
|
||||||
"storeValue",
|
"storeValue",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
ee.DragDropWidgetNVerify("buttonwidget", 100, 200);
|
_objects.ee.DragDropWidgetNVerify("buttonwidget", 100, 200);
|
||||||
ee.SelectEntityByName("Button2", "Widgets");
|
_objects.ee.SelectEntityByName("Button2", "Widgets");
|
||||||
propPane.UpdatePropertyFieldValue("Label", "");
|
_objects.propPane.UpdatePropertyFieldValue("Label", "");
|
||||||
propPane.TypeTextIntoField("Label", "ClearStore");
|
_objects.propPane.TypeTextIntoField("Label", "ClearStore");
|
||||||
cy.get("@jsObjName").then((jsObj: any) => {
|
cy.get("@jsObjName").then((jsObj: any) => {
|
||||||
propPane.SelectJSFunctionToExecute(
|
_objects.propPane.SelectJSFunctionToExecute(
|
||||||
"onClick",
|
"onClick",
|
||||||
jsObj as string,
|
jsObj as string,
|
||||||
"clearStore",
|
"clearStore",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
deployMode.DeployApp();
|
_objects.deployMode.DeployApp();
|
||||||
agHelper.ClickButton("StoreValue");
|
_objects.agHelper.ClickButton("StoreValue");
|
||||||
agHelper.AssertContains(
|
_objects.agHelper.AssertContains(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
val1: "value 1",
|
val1: "value 1",
|
||||||
val2: "value 2",
|
val2: "value 2",
|
||||||
val3: "value 3",
|
val3: "value 3",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
agHelper.ClickButton("ClearStore");
|
_objects.agHelper.ClickButton("ClearStore");
|
||||||
agHelper.AssertContains(JSON.stringify({}));
|
_objects.agHelper.AssertContains(JSON.stringify({}));
|
||||||
deployMode.NavigateBacktoEditor();
|
_objects.deployMode.NavigateBacktoEditor();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ describe("Git import flow ", function() {
|
||||||
cy.connectToGitRepo(repoName);
|
cy.connectToGitRepo(repoName);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.wait(4000); // for git connection to settle!
|
cy.wait(5000); // for git connection to settle!
|
||||||
});
|
});
|
||||||
|
|
||||||
it("2. Import the previous app connected to Git and reconnect Postgres, MySQL and Mongo db ", () => {
|
it("2. Import the previous app connected to Git and reconnect Postgres, MySQL and Mongo db ", () => {
|
||||||
|
|
@ -90,7 +90,7 @@ describe("Git import flow ", function() {
|
||||||
.next()
|
.next()
|
||||||
.click();
|
.click();
|
||||||
cy.importAppFromGit(repoName);
|
cy.importAppFromGit(repoName);
|
||||||
cy.wait(100);
|
cy.wait(5000);
|
||||||
cy.get(reconnectDatasourceModal.Modal).should("be.visible");
|
cy.get(reconnectDatasourceModal.Modal).should("be.visible");
|
||||||
cy.ReconnectDatasource("TEDPostgres");
|
cy.ReconnectDatasource("TEDPostgres");
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
|
|
@ -142,7 +142,8 @@ describe("Git import flow ", function() {
|
||||||
// verify js object binded to input widget
|
// verify js object binded to input widget
|
||||||
cy.xpath("//input[@value='Success']").should("be.visible");
|
cy.xpath("//input[@value='Success']").should("be.visible");
|
||||||
});
|
});
|
||||||
// skipping these tests until bug #18776 is fixed
|
|
||||||
|
// skipping this due to open bug #18776
|
||||||
it.skip("4. Create a new branch, clone page and validate data on that branch in view and edit mode", () => {
|
it.skip("4. Create a new branch, clone page and validate data on that branch in view and edit mode", () => {
|
||||||
cy.createGitBranch(newBranch);
|
cy.createGitBranch(newBranch);
|
||||||
cy.get(".tbody")
|
cy.get(".tbody")
|
||||||
|
|
@ -213,6 +214,7 @@ describe("Git import flow ", function() {
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// skipping this due to open bug #18776
|
||||||
it.skip("5. Switch to master and verify data in edit and view mode", () => {
|
it.skip("5. Switch to master and verify data in edit and view mode", () => {
|
||||||
cy.switchGitBranch("master");
|
cy.switchGitBranch("master");
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
@ -236,6 +238,7 @@ describe("Git import flow ", function() {
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// skipping this due to open bug #18776
|
||||||
it.skip("6. Add widget to master, merge then checkout to child branch and verify data", () => {
|
it.skip("6. Add widget to master, merge then checkout to child branch and verify data", () => {
|
||||||
cy.get(explorer.widgetSwitchId).click();
|
cy.get(explorer.widgetSwitchId).click();
|
||||||
cy.wait(2000); // wait for transition
|
cy.wait(2000); // wait for transition
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ describe("Git with Theming:", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Bug #13860 Theming is not getting applied on view mode when the app is connected to Git", function() {
|
it("Bug #13860 Theming is not getting applied on view mode when the app is connected to Git", function() {
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
// apply theme on master branch and deploy
|
// apply theme on master branch and deploy
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
@ -65,7 +65,7 @@ describe("Git with Theming:", function() {
|
||||||
cy.wait(1000);
|
cy.wait(1000);
|
||||||
cy.get("body").click(300, 300);
|
cy.get("body").click(300, 300);
|
||||||
// change theme on tempBranch
|
// change theme on tempBranch
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
||||||
|
|
@ -1,25 +1,43 @@
|
||||||
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
|
import * as _ from "../../../../support/Objects/ObjectsCore";
|
||||||
import { checkUrl } from "../../../../support/Pages/AppSettings/Utils";
|
|
||||||
|
|
||||||
const appSettings = ObjectsRegistry.AppSettings,
|
|
||||||
deployMode = ObjectsRegistry.DeployMode,
|
|
||||||
homePage = ObjectsRegistry.HomePage;
|
|
||||||
|
|
||||||
|
let guid: string;
|
||||||
describe("General Settings", () => {
|
describe("General Settings", () => {
|
||||||
it("App name change updates URL", () => {
|
before(() => {
|
||||||
appSettings.OpenPaneFromCta();
|
_.agHelper.GenerateUUID();
|
||||||
appSettings.GoToGeneralSettings();
|
cy.get("@guid").then((uid: any) => {
|
||||||
appSettings.general.changeAppNameAndVerifyUrl(true, "myapp");
|
guid = uid;
|
||||||
homePage.GetAppName().then((appName) => {
|
|
||||||
deployMode.DeployApp();
|
|
||||||
checkUrl(appName as string, "Page1", undefined, false);
|
|
||||||
deployMode.NavigateBacktoEditor();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Handles app icon change", () => {
|
it("1. App name change updates URL", () => {
|
||||||
appSettings.OpenPaneFromCta();
|
_.appSettings.OpenAppSettings();
|
||||||
appSettings.GoToGeneralSettings();
|
_.appSettings.GoToGeneralSettings();
|
||||||
appSettings.general.changeAppIcon();
|
_.generalSettings.UpdateAppNameAndVerifyUrl(true, guid);
|
||||||
|
_.homePage.GetAppName().then((appName) => {
|
||||||
|
_.deployMode.DeployApp();
|
||||||
|
_.appSettings.CheckUrl(appName as string, "Page1", undefined, false);
|
||||||
|
_.deployMode.NavigateBacktoEditor();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("2. Handles app icon change", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToGeneralSettings();
|
||||||
|
_.generalSettings.UpdateAppIcon();
|
||||||
|
_.appSettings.ClosePane();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("3. App name allows special and accented character", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToGeneralSettings();
|
||||||
|
_.generalSettings.UpdateAppNameAndVerifyUrl(true, guid + "!@#œ™¡", guid);
|
||||||
|
_.appSettings.ClosePane();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("4. Veirfy App name doesn't allow empty", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToGeneralSettings();
|
||||||
|
_.generalSettings.AssertAppErrorMessage("", "App name cannot be empty");
|
||||||
|
_.appSettings.ClosePane();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,101 @@
|
||||||
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
|
import * as _ from "../../../../support/Objects/ObjectsCore";
|
||||||
import { checkUrl } from "../../../../support/Pages/AppSettings/Utils";
|
|
||||||
|
|
||||||
const appSettings = ObjectsRegistry.AppSettings,
|
|
||||||
ee = ObjectsRegistry.EntityExplorer,
|
|
||||||
agHelper = ObjectsRegistry.AggregateHelper,
|
|
||||||
commonLocators = ObjectsRegistry.CommonLocators,
|
|
||||||
deployMode = ObjectsRegistry.DeployMode,
|
|
||||||
homePage = ObjectsRegistry.HomePage;
|
|
||||||
|
|
||||||
describe("Page Settings", () => {
|
describe("Page Settings", () => {
|
||||||
it("Page name change updates URL", () => {
|
it("1. Page name change updates URL", () => {
|
||||||
appSettings.OpenPaneFromCta();
|
_.appSettings.OpenAppSettings();
|
||||||
appSettings.GoToPageSettings("Page1");
|
_.appSettings.GoToPageSettings("Page1");
|
||||||
appSettings.page.changePageNameAndVerifyUrl("Page2");
|
_.pageSettings.UpdatePageNameAndVerifyUrl("Page2", undefined, false);
|
||||||
homePage.GetAppName().then((appName) => {
|
_.homePage.GetAppName().then((appName) => {
|
||||||
deployMode.DeployApp();
|
_.deployMode.DeployApp();
|
||||||
checkUrl(appName as string, "Page2", undefined, false);
|
_.appSettings.CheckUrl(appName as string, "Page2", undefined, false);
|
||||||
deployMode.NavigateBacktoEditor();
|
_.deployMode.NavigateBacktoEditor();
|
||||||
});
|
});
|
||||||
cy.wait(2000);
|
_.agHelper.Sleep();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Custom slug change updates URL", () => {
|
it("2. Custom slug change updates URL", () => {
|
||||||
appSettings.OpenPaneFromCta();
|
_.appSettings.OpenAppSettings();
|
||||||
appSettings.GoToPageSettings("Page2");
|
_.appSettings.GoToPageSettings("Page2");
|
||||||
appSettings.page.changeCustomSlugAndVerifyUrl("custom");
|
_.pageSettings.UpdateCustomSlugAndVerifyUrl("custom");
|
||||||
homePage.GetAppName().then((appName) => {
|
_.homePage.GetAppName().then((appName) => {
|
||||||
deployMode.DeployApp();
|
_.deployMode.DeployApp();
|
||||||
checkUrl(appName as string, "Page2", "custom", false);
|
_.appSettings.CheckUrl(appName as string, "Page2", "custom", false);
|
||||||
deployMode.NavigateBacktoEditor();
|
_.deployMode.NavigateBacktoEditor();
|
||||||
});
|
});
|
||||||
cy.wait(2000);
|
_.agHelper.Sleep();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Check default page is updated", () => {
|
it("3. Check SetAsHome page setting", () => {
|
||||||
ee.AddNewPage();
|
_.ee.AddNewPage();
|
||||||
appSettings.OpenPaneFromCta();
|
_.appSettings.OpenAppSettings();
|
||||||
appSettings.GoToPageSettings("Page3");
|
_.appSettings.GoToPageSettings("Page3");
|
||||||
appSettings.page.setAsHomePage();
|
_.pageSettings.ToggleHomePage();
|
||||||
appSettings.page.isHomePage("Page3");
|
_.pageSettings.AssertHomePage("Page3");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Check page navigation is updated", () => {
|
it("4. Check SetPageNavigation settings", () => {
|
||||||
agHelper.GetNClick(commonLocators._previewModeToggle);
|
_.agHelper.GetNClick(_.locators._previewModeToggle);
|
||||||
agHelper.AssertElementExist(commonLocators._deployedPage);
|
_.agHelper.AssertElementExist(_.locators._deployedPage);
|
||||||
agHelper.GetNClick(commonLocators._editModeToggle);
|
_.agHelper.GetNClick(_.locators._editModeToggle);
|
||||||
appSettings.OpenPaneFromCta();
|
_.appSettings.OpenAppSettings();
|
||||||
appSettings.GoToPageSettings("Page2");
|
_.appSettings.GoToPageSettings("Page2");
|
||||||
appSettings.page.changePageNavigationSetting();
|
_.pageSettings.TogglePageNavigation();
|
||||||
agHelper.GetNClick(commonLocators._previewModeToggle);
|
_.agHelper.GetNClick(_.locators._previewModeToggle);
|
||||||
agHelper.AssertElementAbsence(commonLocators._deployedPage);
|
_.agHelper.AssertElementAbsence(_.locators._deployedPage);
|
||||||
agHelper.GetNClick(commonLocators._editModeToggle);
|
_.agHelper.GetNClick(_.locators._editModeToggle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("5. Page name allows accented character", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToPageSettings("Page3");
|
||||||
|
_.pageSettings.UpdatePageNameAndVerifyUrl("Page3œßð", "Page3");
|
||||||
|
_.appSettings.ClosePane();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("6. Page name doesn't allow special character", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToPageSettings("Page3");
|
||||||
|
_.pageSettings.UpdatePageNameAndVerifyTextValue("Page3!@#", "Page3 ");
|
||||||
|
_.appSettings.ClosePane();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("7. Page name doesn't allow empty", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToPageSettings("Page3");
|
||||||
|
_.pageSettings.AssertPageErrorMessage(
|
||||||
|
"",
|
||||||
|
"Page name cannot be empty",
|
||||||
|
);
|
||||||
|
_.appSettings.ClosePane();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("8. Bug #18698 : Page name doesn't allow duplicate name", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToPageSettings("Page3");
|
||||||
|
_.pageSettings.AssertPageErrorMessage(
|
||||||
|
"Page2",
|
||||||
|
"Page2 is already being used.",
|
||||||
|
);
|
||||||
|
_.appSettings.ClosePane();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("9. Page name doesn't allow keywords", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToPageSettings("Page3");
|
||||||
|
_.pageSettings.AssertPageErrorMessage(
|
||||||
|
"appsmith",
|
||||||
|
"appsmith is already being used.",
|
||||||
|
);
|
||||||
|
_.appSettings.ClosePane();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("10. Custom slug doesn't allow special/accented characters", () => {
|
||||||
|
_.appSettings.OpenAppSettings();
|
||||||
|
_.appSettings.GoToPageSettings("Page2");
|
||||||
|
_.pageSettings.UpdateCustomSlugAndVerifyTextValue(
|
||||||
|
"custom-slug!@#œßð",
|
||||||
|
"custom-slug",
|
||||||
|
);
|
||||||
|
_.appSettings.ClosePane();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ describe("App Theming funtionality", function() {
|
||||||
themesSection(sectionName, themeName) + "/following-sibling::button";
|
themesSection(sectionName, themeName) + "/following-sibling::button";
|
||||||
|
|
||||||
it("1. Checks if theme can be changed to one of the existing themes", function() {
|
it("1. Checks if theme can be changed to one of the existing themes", function() {
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ describe("App Theming funtionality", function() {
|
||||||
.first(0)
|
.first(0)
|
||||||
.trigger("click", { force: true });
|
.trigger("click", { force: true });
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
|
|
||||||
//Click the back button //Commenting below since expanded by default
|
//Click the back button //Commenting below since expanded by default
|
||||||
|
|
@ -219,7 +219,7 @@ describe("App Theming funtionality", function() {
|
||||||
.first(0)
|
.first(0)
|
||||||
.trigger("click", { force: true });
|
.trigger("click", { force: true });
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//#region Change Font & verify widgets:
|
//#region Change Font & verify widgets:
|
||||||
// cy.contains("Font")
|
// cy.contains("Font")
|
||||||
|
|
@ -1009,7 +1009,7 @@ describe("App Theming funtionality", function() {
|
||||||
.first(0)
|
.first(0)
|
||||||
.trigger("click", { force: true });
|
.trigger("click", { force: true });
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
|
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ describe("Theme validation usecases", function() {
|
||||||
// click on canvas to see the theming pane
|
// click on canvas to see the theming pane
|
||||||
cy.get("#canvas-selection-0").click({ force: true });
|
cy.get("#canvas-selection-0").click({ force: true });
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
// reset theme
|
// reset theme
|
||||||
cy.contains("Theme Properties")
|
cy.contains("Theme Properties")
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
|
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
|
||||||
|
|
||||||
const testdata = require("../../../../fixtures/testdata.json");
|
|
||||||
const apiwidget = require("../../../../locators/apiWidgetslocator.json");
|
|
||||||
const widgetsPage = require("../../../../locators/Widgets.json");
|
const widgetsPage = require("../../../../locators/Widgets.json");
|
||||||
const explorer = require("../../../../locators/explorerlocators.json");
|
const explorer = require("../../../../locators/explorerlocators.json");
|
||||||
const commonlocators = require("../../../../locators/commonlocators.json");
|
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||||
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
|
const formWidgetsPage = require("../../../../locators/FormWidgets.json");
|
||||||
const publish = require("../../../../locators/publishWidgetspage.json");
|
|
||||||
const themelocator = require("../../../../locators/ThemeLocators.json");
|
const themelocator = require("../../../../locators/ThemeLocators.json");
|
||||||
|
|
||||||
const appSettings = ObjectsRegistry.AppSettings;
|
const appSettings = ObjectsRegistry.AppSettings;
|
||||||
|
|
||||||
let themeBackgroudColor;
|
let themeBackgroudColor;
|
||||||
let themeFont;
|
|
||||||
|
|
||||||
describe("Theme validation for default data", function() {
|
describe("Theme validation for default data", function() {
|
||||||
it("Drag and drop form widget and validate Default color/font/shadow/border and list of font validation", function() {
|
it("Drag and drop form widget and validate Default color/font/shadow/border and list of font validation", function() {
|
||||||
|
|
@ -33,7 +29,7 @@ describe("Theme validation for default data", function() {
|
||||||
cy.get(themelocator.canvas).click({ force: true });
|
cy.get(themelocator.canvas).click({ force: true });
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//Border validation
|
//Border validation
|
||||||
//cy.contains("Border").click({ force: true });
|
//cy.contains("Border").click({ force: true });
|
||||||
|
|
@ -93,7 +89,7 @@ describe("Theme validation for default data", function() {
|
||||||
.should("have.css", "background-color")
|
.should("have.css", "background-color")
|
||||||
.and("eq", "rgb(21, 128, 61)");
|
.and("eq", "rgb(21, 128, 61)");
|
||||||
cy.get("#canvas-selection-0").click({ force: true });
|
cy.get("#canvas-selection-0").click({ force: true });
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//Change the Theme
|
//Change the Theme
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
@ -30,7 +30,7 @@ describe("Theme validation usecases", function() {
|
||||||
cy.get(themelocator.canvas).click({ force: true });
|
cy.get(themelocator.canvas).click({ force: true });
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//Border validation
|
//Border validation
|
||||||
//cy.contains("Border").click({ force: true });
|
//cy.contains("Border").click({ force: true });
|
||||||
|
|
@ -185,7 +185,7 @@ describe("Theme validation usecases", function() {
|
||||||
.and("eq", "rgb(21, 128, 61)");
|
.and("eq", "rgb(21, 128, 61)");
|
||||||
cy.get("#canvas-selection-0").click({ force: true });
|
cy.get("#canvas-selection-0").click({ force: true });
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//Change the Theme
|
//Change the Theme
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
@ -247,7 +247,7 @@ describe("Theme validation usecases", function() {
|
||||||
|
|
||||||
cy.get("#canvas-selection-0").click({ force: true });
|
cy.get("#canvas-selection-0").click({ force: true });
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//Change the Theme
|
//Change the Theme
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
@ -17,7 +17,7 @@ describe("Theme validation usecase for multi-select widget", function() {
|
||||||
cy.get(themelocator.canvas).click({ force: true });
|
cy.get(themelocator.canvas).click({ force: true });
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//Border validation
|
//Border validation
|
||||||
//cy.contains("Border").click({ force: true });
|
//cy.contains("Border").click({ force: true });
|
||||||
|
|
@ -124,7 +124,7 @@ describe("Theme validation usecase for multi-select widget", function() {
|
||||||
|
|
||||||
it("3. Validate current theme feature", function() {
|
it("3. Validate current theme feature", function() {
|
||||||
cy.get("#canvas-selection-0").click({ force: true });
|
cy.get("#canvas-selection-0").click({ force: true });
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
//Change the Theme
|
//Change the Theme
|
||||||
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
cy.get(commonlocators.changeThemeBtn).click({ force: true });
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ describe("Checkbox Widget Functionality", function() {
|
||||||
// Click on canvas to get global theme settings
|
// Click on canvas to get global theme settings
|
||||||
cy.get(commonlocators.canvas).click({ force: true });
|
cy.get(commonlocators.canvas).click({ force: true });
|
||||||
|
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
cy.get(commonlocators.themeAppBorderRadiusBtn)
|
cy.get(commonlocators.themeAppBorderRadiusBtn)
|
||||||
.last()
|
.last()
|
||||||
|
|
@ -61,7 +61,7 @@ describe("Checkbox Widget Functionality", function() {
|
||||||
|
|
||||||
// Change the theme border radius to M and check if the remove file icon's border radius is 4px;
|
// Change the theme border radius to M and check if the remove file icon's border radius is 4px;
|
||||||
cy.get(commonlocators.canvas).click({ force: true });
|
cy.get(commonlocators.canvas).click({ force: true });
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
cy.get(commonlocators.themeAppBorderRadiusBtn)
|
cy.get(commonlocators.themeAppBorderRadiusBtn)
|
||||||
.eq(1)
|
.eq(1)
|
||||||
|
|
@ -85,7 +85,7 @@ describe("Checkbox Widget Functionality", function() {
|
||||||
// Change the global theme primary color
|
// Change the global theme primary color
|
||||||
cy.get(commonlocators.canvas).click({ force: true });
|
cy.get(commonlocators.canvas).click({ force: true });
|
||||||
cy.wait(300);
|
cy.wait(300);
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
|
|
||||||
cy.get(themeLocator.inputColor).click({ force: true });
|
cy.get(themeLocator.inputColor).click({ force: true });
|
||||||
|
|
@ -118,7 +118,7 @@ describe("Checkbox Widget Functionality", function() {
|
||||||
cy.get(".uppy-Dashboard-close").click({ force: true });
|
cy.get(".uppy-Dashboard-close").click({ force: true });
|
||||||
cy.get(commonlocators.canvas).click({ force: true });
|
cy.get(commonlocators.canvas).click({ force: true });
|
||||||
cy.wait(300);
|
cy.wait(300);
|
||||||
appSettings.OpenPaneFromCta();
|
appSettings.OpenAppSettings();
|
||||||
appSettings.GoToThemeSettings();
|
appSettings.GoToThemeSettings();
|
||||||
|
|
||||||
cy.get(themeLocator.fontsSelected).click({ force: true });
|
cy.get(themeLocator.fontsSelected).click({ force: true });
|
||||||
13
app/client/cypress/support/Objects/ObjectsCore.ts
Normal file
13
app/client/cypress/support/Objects/ObjectsCore.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { ObjectsRegistry } from "../Objects/Registry";
|
||||||
|
|
||||||
|
export const agHelper = ObjectsRegistry.AggregateHelper;
|
||||||
|
export const locators = ObjectsRegistry.CommonLocators;
|
||||||
|
export const ee = ObjectsRegistry.EntityExplorer;
|
||||||
|
export const jsEditor = ObjectsRegistry.JSEditor;
|
||||||
|
export const propPane = ObjectsRegistry.PropertyPane;
|
||||||
|
export const deployMode = ObjectsRegistry.DeployMode;
|
||||||
|
export const appSettings = ObjectsRegistry.AppSettings;
|
||||||
|
export const generalSettings = ObjectsRegistry.GeneralSettings;
|
||||||
|
export const pageSettings = ObjectsRegistry.PageSettings;
|
||||||
|
export const homePage = ObjectsRegistry.HomePage;
|
||||||
|
export const theme = ObjectsRegistry.ThemeSettings;
|
||||||
|
|
@ -13,6 +13,9 @@ import { GitSync } from "../Pages/GitSync";
|
||||||
import { FakerHelper } from "../Pages/FakerHelper";
|
import { FakerHelper } from "../Pages/FakerHelper";
|
||||||
import { DebuggerHelper } from "../Pages/DebuggerHelper";
|
import { DebuggerHelper } from "../Pages/DebuggerHelper";
|
||||||
import { AppSettings } from "../Pages/AppSettings/AppSettings";
|
import { AppSettings } from "../Pages/AppSettings/AppSettings";
|
||||||
|
import { GeneralSettings } from "../Pages/AppSettings/GeneralSettings";
|
||||||
|
import { PageSettings } from "../Pages/AppSettings/PageSettings";
|
||||||
|
import { ThemeSettings } from "../Pages/AppSettings/ThemeSettings";
|
||||||
|
|
||||||
export class ObjectsRegistry {
|
export class ObjectsRegistry {
|
||||||
private static aggregateHelper__: AggregateHelper;
|
private static aggregateHelper__: AggregateHelper;
|
||||||
|
|
@ -119,20 +122,44 @@ export class ObjectsRegistry {
|
||||||
return ObjectsRegistry.fakerHelper__;
|
return ObjectsRegistry.fakerHelper__;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DebuggerHelper__: DebuggerHelper;
|
private static debuggerHelper__: DebuggerHelper;
|
||||||
static get DebuggerHelper(): DebuggerHelper {
|
static get DebuggerHelper(): DebuggerHelper {
|
||||||
if (ObjectsRegistry.DebuggerHelper__ === undefined) {
|
if (ObjectsRegistry.debuggerHelper__ === undefined) {
|
||||||
ObjectsRegistry.DebuggerHelper__ = new DebuggerHelper();
|
ObjectsRegistry.debuggerHelper__ = new DebuggerHelper();
|
||||||
}
|
}
|
||||||
return ObjectsRegistry.DebuggerHelper__;
|
return ObjectsRegistry.debuggerHelper__;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AppSettings__: AppSettings;
|
private static appSettings__: AppSettings;
|
||||||
static get AppSettings(): AppSettings {
|
static get AppSettings(): AppSettings {
|
||||||
if (ObjectsRegistry.AppSettings__ === undefined) {
|
if (ObjectsRegistry.appSettings__ === undefined) {
|
||||||
ObjectsRegistry.AppSettings__ = new AppSettings();
|
ObjectsRegistry.appSettings__ = new AppSettings();
|
||||||
}
|
}
|
||||||
return ObjectsRegistry.AppSettings__;
|
return ObjectsRegistry.appSettings__;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static generalSettings__: GeneralSettings;
|
||||||
|
static get GeneralSettings(): GeneralSettings {
|
||||||
|
if (ObjectsRegistry.generalSettings__ === undefined) {
|
||||||
|
ObjectsRegistry.generalSettings__ = new GeneralSettings();
|
||||||
|
}
|
||||||
|
return ObjectsRegistry.generalSettings__;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static pageSettings__: PageSettings;
|
||||||
|
static get PageSettings(): PageSettings {
|
||||||
|
if (ObjectsRegistry.pageSettings__ === undefined) {
|
||||||
|
ObjectsRegistry.pageSettings__ = new PageSettings();
|
||||||
|
}
|
||||||
|
return ObjectsRegistry.pageSettings__;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static themeSettings__: ThemeSettings;
|
||||||
|
static get ThemeSettings(): ThemeSettings {
|
||||||
|
if (ObjectsRegistry.themeSettings__ === undefined) {
|
||||||
|
ObjectsRegistry.themeSettings__ = new ThemeSettings();
|
||||||
|
}
|
||||||
|
return ObjectsRegistry.themeSettings__;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -526,10 +526,6 @@ export class AggregateHelper {
|
||||||
this.GetElement(selector).clear();
|
this.GetElement(selector).clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InvokeVal(selector: string) {
|
|
||||||
return cy.get(selector).invoke("val");
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeText(
|
public TypeText(
|
||||||
selector: string,
|
selector: string,
|
||||||
value: string,
|
value: string,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
import { ObjectsRegistry } from "../../Objects/Registry";
|
import { ObjectsRegistry } from "../../Objects/Registry";
|
||||||
import { ThemeSettings } from "./ThemeSettings";
|
|
||||||
import { GeneralSettings } from "./GeneralSettings";
|
|
||||||
import { PageSettings } from "./PageSettings";
|
|
||||||
|
|
||||||
export class AppSettings {
|
export class AppSettings {
|
||||||
private agHelper = ObjectsRegistry.AggregateHelper;
|
private agHelper = ObjectsRegistry.AggregateHelper;
|
||||||
|
private theme = ObjectsRegistry.ThemeSettings;
|
||||||
|
|
||||||
private locators = {
|
private locators = {
|
||||||
_appSettings_cta: "#t--app-settings-cta",
|
_appSettings: "#t--app-settings-cta",
|
||||||
_closeSettings: "#t--close-app-settings-pane",
|
_closeSettings: "#t--close-app-settings-pane",
|
||||||
_themeSettingsHeader: "#t--theme-settings-header",
|
_themeSettingsHeader: "#t--theme-settings-header",
|
||||||
_generalSettingsHeader: "#t--general-settings-header",
|
_generalSettingsHeader: "#t--general-settings-header",
|
||||||
|
|
@ -14,12 +12,13 @@ export class AppSettings {
|
||||||
`#t--page-settings-${pageName}`,
|
`#t--page-settings-${pageName}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
public readonly theme = new ThemeSettings();
|
public errorMessageSelector = (fieldId: string) => {
|
||||||
public readonly general = new GeneralSettings();
|
fieldId = fieldId[0] === "#" ? fieldId.slice(1, fieldId.length) : fieldId;
|
||||||
public readonly page = new PageSettings();
|
return `//input[@id='${fieldId}']/following-sibling::div/span`;
|
||||||
|
};
|
||||||
|
|
||||||
public OpenPaneFromCta() {
|
public OpenAppSettings() {
|
||||||
this.agHelper.GetNClick(this.locators._appSettings_cta);
|
this.agHelper.GetNClick(this.locators._appSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClosePane() {
|
public ClosePane() {
|
||||||
|
|
@ -39,7 +38,7 @@ export class AppSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPaneAndChangeTheme(themeName: string) {
|
public OpenPaneAndChangeTheme(themeName: string) {
|
||||||
this.OpenPaneFromCta();
|
this.OpenAppSettings();
|
||||||
this.GoToThemeSettings();
|
this.GoToThemeSettings();
|
||||||
this.theme.ChangeTheme(themeName);
|
this.theme.ChangeTheme(themeName);
|
||||||
this.ClosePane();
|
this.ClosePane();
|
||||||
|
|
@ -49,10 +48,70 @@ export class AppSettings {
|
||||||
primaryColorIndex: number,
|
primaryColorIndex: number,
|
||||||
backgroundColorIndex: number,
|
backgroundColorIndex: number,
|
||||||
) {
|
) {
|
||||||
this.OpenPaneFromCta();
|
this.OpenAppSettings();
|
||||||
this.GoToThemeSettings();
|
this.GoToThemeSettings();
|
||||||
this.theme.ChangeThemeColor(primaryColorIndex, "Primary");
|
this.theme.ChangeThemeColor(primaryColorIndex, "Primary");
|
||||||
this.theme.ChangeThemeColor(backgroundColorIndex, "Background");
|
this.theme.ChangeThemeColor(backgroundColorIndex, "Background");
|
||||||
this.ClosePane();
|
this.ClosePane();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CheckUrl(
|
||||||
|
appName: string,
|
||||||
|
pageName: string,
|
||||||
|
customSlug?: string,
|
||||||
|
editMode = true,
|
||||||
|
) {
|
||||||
|
cy.location("pathname").then((pathname) => {
|
||||||
|
if (customSlug && customSlug.length > 0) {
|
||||||
|
const pageId = pathname
|
||||||
|
.split("/")[2]
|
||||||
|
?.split("-")
|
||||||
|
.pop();
|
||||||
|
expect(pathname).to.be.equal(
|
||||||
|
`/app/${customSlug}-${pageId}${editMode ? "/edit" : ""}`.toLowerCase(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const pageId = pathname
|
||||||
|
.split("/")[3]
|
||||||
|
?.split("-")
|
||||||
|
.pop();
|
||||||
|
expect(pathname).to.be.equal(
|
||||||
|
`/app/${appName}/${pageName}-${pageId}${
|
||||||
|
editMode ? "/edit" : ""
|
||||||
|
}`.toLowerCase(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
public AssertErrorMessage(
|
||||||
|
fieldId: string,
|
||||||
|
newValue: string,
|
||||||
|
errorMessage: string,
|
||||||
|
resetValue = true,
|
||||||
|
) {
|
||||||
|
this.agHelper.GetText(fieldId, "val").then((currentValue) => {
|
||||||
|
if (newValue.length === 0) this.agHelper.ClearTextField(fieldId);
|
||||||
|
else
|
||||||
|
this.agHelper.RemoveCharsNType(
|
||||||
|
fieldId,
|
||||||
|
(currentValue as string).length,
|
||||||
|
newValue,
|
||||||
|
);
|
||||||
|
this.agHelper.AssertText(
|
||||||
|
this.errorMessageSelector(fieldId),
|
||||||
|
"text",
|
||||||
|
errorMessage,
|
||||||
|
);
|
||||||
|
if (resetValue) {
|
||||||
|
this.agHelper.RemoveCharsNType(
|
||||||
|
fieldId,
|
||||||
|
newValue.length,
|
||||||
|
currentValue as string,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,58 @@
|
||||||
import { ObjectsRegistry } from "../../Objects/Registry";
|
import { ObjectsRegistry } from "../../Objects/Registry";
|
||||||
import { checkUrl } from "./Utils";
|
|
||||||
|
|
||||||
export class GeneralSettings {
|
export class GeneralSettings {
|
||||||
private agHelper = ObjectsRegistry.AggregateHelper;
|
private agHelper = ObjectsRegistry.AggregateHelper;
|
||||||
|
private appSettings = ObjectsRegistry.AppSettings;
|
||||||
|
|
||||||
private locators = {
|
private locators = {
|
||||||
appNameField: "#t--general-settings-app-name",
|
_appNameField: "#t--general-settings-app-name",
|
||||||
appNonSelectedIcon: ".t--icon-not-selected",
|
_appNonSelectedIcon: ".t--icon-not-selected",
|
||||||
appIconSelector: "#t--general-settings-app-icon",
|
_appIconSelector: "#t--general-settings-app-icon",
|
||||||
};
|
};
|
||||||
|
|
||||||
changeAppNameAndVerifyUrl(
|
UpdateAppNameAndVerifyUrl(
|
||||||
reset: boolean,
|
reset: boolean,
|
||||||
newAppName: string,
|
newAppName: string,
|
||||||
|
verifyAppNameAs?: string,
|
||||||
pageName = "page1",
|
pageName = "page1",
|
||||||
) {
|
) {
|
||||||
|
const appNameToBeVerified = verifyAppNameAs ?? newAppName;
|
||||||
this.agHelper
|
this.agHelper
|
||||||
.InvokeVal(this.locators.appNameField)
|
.GetText(this.locators._appNameField, "val")
|
||||||
.then((currentAppName) => {
|
.then((currentAppName) => {
|
||||||
this.agHelper.RemoveCharsNType(
|
this.agHelper.RemoveCharsNType(
|
||||||
this.locators.appNameField,
|
this.locators._appNameField,
|
||||||
(currentAppName as string).length,
|
(currentAppName as string).length,
|
||||||
newAppName,
|
newAppName,
|
||||||
);
|
);
|
||||||
this.agHelper.PressEnter();
|
this.agHelper.PressEnter();
|
||||||
|
this.agHelper.Sleep();
|
||||||
this.agHelper.ValidateNetworkStatus("@updateApplication", 200);
|
this.agHelper.ValidateNetworkStatus("@updateApplication", 200);
|
||||||
checkUrl(newAppName, pageName);
|
this.appSettings.CheckUrl(appNameToBeVerified, pageName);
|
||||||
if (reset) {
|
if (reset) {
|
||||||
this.agHelper.RemoveCharsNType(
|
this.agHelper.RemoveCharsNType(
|
||||||
this.locators.appNameField,
|
this.locators._appNameField,
|
||||||
newAppName.length,
|
newAppName.length,
|
||||||
currentAppName as string,
|
currentAppName as string,
|
||||||
);
|
);
|
||||||
this.agHelper.PressEnter();
|
this.agHelper.PressEnter();
|
||||||
this.agHelper.ValidateNetworkStatus("@updateApplication", 200);
|
this.agHelper.ValidateNetworkStatus("@updateApplication", 200);
|
||||||
checkUrl(currentAppName as string, pageName);
|
this.appSettings.CheckUrl(currentAppName as string, pageName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeAppIcon() {
|
AssertAppErrorMessage(newAppName: string, errorMessage: string) {
|
||||||
this.agHelper.GetNClick(this.locators.appNonSelectedIcon, 0);
|
this.appSettings.AssertErrorMessage(
|
||||||
|
this.locators._appNameField,
|
||||||
|
newAppName,
|
||||||
|
errorMessage,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAppIcon() {
|
||||||
|
this.agHelper.GetNClick(this.locators._appNonSelectedIcon, 0);
|
||||||
this.agHelper.ValidateNetworkStatus("@updateApplication", 200);
|
this.agHelper.ValidateNetworkStatus("@updateApplication", 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,145 @@
|
||||||
import { ObjectsRegistry } from "../../Objects/Registry";
|
import { ObjectsRegistry } from "../../Objects/Registry";
|
||||||
import { checkUrl } from "./Utils";
|
|
||||||
|
|
||||||
export class PageSettings {
|
export class PageSettings {
|
||||||
private agHelper = ObjectsRegistry.AggregateHelper;
|
private agHelper = ObjectsRegistry.AggregateHelper;
|
||||||
private homePage = ObjectsRegistry.HomePage;
|
private homePage = ObjectsRegistry.HomePage;
|
||||||
|
private appSettings = ObjectsRegistry.AppSettings;
|
||||||
|
|
||||||
private locators = {
|
private locators = {
|
||||||
pageNameField: "#t--page-settings-name",
|
_pageNameField: "#t--page-settings-name",
|
||||||
customSlugField: "#t--page-settings-custom-slug",
|
_customSlugField: "#t--page-settings-custom-slug",
|
||||||
showPageNavSwitch: "#t--page-settings-show-nav-control",
|
_showPageNavSwitch: "#t--page-settings-show-nav-control",
|
||||||
setAsHomePageSwitch: "#t--page-settings-home-page-control",
|
_setAsHomePageSwitch: "#t--page-settings-home-page-control",
|
||||||
homePageHeader: "#t--page-settings-default-page",
|
_setHomePageToggle : ".bp3-control-indicator",
|
||||||
|
_homePageHeader: "#t--page-settings-default-page",
|
||||||
};
|
};
|
||||||
|
|
||||||
changePageNameAndVerifyUrl(newPageName: string) {
|
UpdatePageNameAndVerifyTextValue(newPageName: string, verifyPageNameAs: string) {
|
||||||
|
this.AssertPageValue(
|
||||||
|
this.locators._pageNameField,
|
||||||
|
newPageName,
|
||||||
|
verifyPageNameAs,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateCustomSlugAndVerifyTextValue(
|
||||||
|
newCustomSlug: string,
|
||||||
|
verifyCustomSlugAs: string,
|
||||||
|
) {
|
||||||
|
this.AssertPageValue(
|
||||||
|
this.locators._customSlugField,
|
||||||
|
newCustomSlug,
|
||||||
|
verifyCustomSlugAs,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssertPageValue(
|
||||||
|
locator: string,
|
||||||
|
newValue: string,
|
||||||
|
verifyValueAs: string,
|
||||||
|
) {
|
||||||
|
this.agHelper.GetText(locator, "val").then((currentValue) => {
|
||||||
|
const currentValueLength = (currentValue as string).length;
|
||||||
|
if (currentValueLength === 0) this.agHelper.TypeText(locator, newValue);
|
||||||
|
else
|
||||||
|
this.agHelper.RemoveCharsNType(locator, currentValueLength, newValue);
|
||||||
|
|
||||||
|
this.agHelper.GetText(locator, "val").then((fieldValue) => {
|
||||||
|
expect(fieldValue).to.equal(verifyValueAs);
|
||||||
|
if (currentValueLength === 0) this.agHelper.ClearTextField(locator);
|
||||||
|
else
|
||||||
|
this.agHelper.RemoveCharsNType(
|
||||||
|
locator,
|
||||||
|
(fieldValue as string).length,
|
||||||
|
currentValue as string,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdatePageNameAndVerifyUrl(
|
||||||
|
newPageName: string,
|
||||||
|
verifyPageNameAs?: string,
|
||||||
|
reset = true,
|
||||||
|
) {
|
||||||
|
const pageNameToBeVerified = verifyPageNameAs ?? newPageName;
|
||||||
this.agHelper
|
this.agHelper
|
||||||
.InvokeVal(this.locators.pageNameField)
|
.GetText(this.locators._pageNameField, "val")
|
||||||
.then((currentPageName) => {
|
.then((currentPageName) => {
|
||||||
const currentPageNameLength = (currentPageName as string).length;
|
const currentPageNameLength = (currentPageName as string).length;
|
||||||
|
|
||||||
this.homePage.GetAppName().then((appName) => {
|
this.homePage.GetAppName().then((appName) => {
|
||||||
this.agHelper.RemoveCharsNType(
|
this.agHelper.RemoveCharsNType(
|
||||||
this.locators.pageNameField,
|
this.locators._pageNameField,
|
||||||
currentPageNameLength,
|
currentPageNameLength,
|
||||||
newPageName,
|
newPageName,
|
||||||
);
|
);
|
||||||
this.agHelper.PressEnter();
|
this.agHelper.PressEnter();
|
||||||
this.agHelper.ValidateNetworkStatus("@updatePage", 200);
|
this.agHelper.ValidateNetworkStatus("@updatePage", 200);
|
||||||
checkUrl(appName as string, newPageName);
|
this.appSettings.CheckUrl(appName as string, pageNameToBeVerified);
|
||||||
|
if (reset) {
|
||||||
|
this.agHelper.RemoveCharsNType(
|
||||||
|
this.locators._pageNameField,
|
||||||
|
newPageName.length,
|
||||||
|
currentPageName as string,
|
||||||
|
);
|
||||||
|
this.agHelper.PressEnter();
|
||||||
|
this.agHelper.ValidateNetworkStatus("@updatePage", 200);
|
||||||
|
this.appSettings.CheckUrl(appName as string, currentPageName as string);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeCustomSlugAndVerifyUrl(customSlug: string) {
|
UpdateCustomSlugAndVerifyUrl(customSlug: string) {
|
||||||
this.agHelper
|
this.agHelper
|
||||||
.InvokeVal(this.locators.customSlugField)
|
.GetText(this.locators._customSlugField, "val")
|
||||||
.then((currentCustomSlug) => {
|
.then((currentCustomSlug) => {
|
||||||
const currentCustomSlugLength = (currentCustomSlug as string).length;
|
const currentCustomSlugLength = (currentCustomSlug as string).length;
|
||||||
|
|
||||||
this.homePage.GetAppName().then((appName) => {
|
this.homePage.GetAppName().then((appName) => {
|
||||||
if (currentCustomSlugLength === 0) {
|
if (currentCustomSlugLength === 0) {
|
||||||
this.agHelper.TypeText(this.locators.customSlugField, customSlug);
|
this.agHelper.TypeText(this.locators._customSlugField, customSlug);
|
||||||
} else {
|
} else {
|
||||||
this.agHelper.RemoveCharsNType(
|
this.agHelper.RemoveCharsNType(
|
||||||
this.locators.customSlugField,
|
this.locators._customSlugField,
|
||||||
currentCustomSlugLength,
|
currentCustomSlugLength,
|
||||||
customSlug,
|
customSlug,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.agHelper.PressEnter();
|
this.agHelper.PressEnter();
|
||||||
this.agHelper.ValidateNetworkStatus("@updatePage", 200);
|
this.agHelper.ValidateNetworkStatus("@updatePage", 200);
|
||||||
checkUrl(appName as string, "", customSlug);
|
this.appSettings.CheckUrl(appName as string, "", customSlug);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changePageNavigationSetting() {
|
AssertPageErrorMessage(newPageName: string, errorMessage: string) {
|
||||||
|
this.appSettings.AssertErrorMessage(
|
||||||
|
this.locators._pageNameField,
|
||||||
|
newPageName,
|
||||||
|
errorMessage,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TogglePageNavigation() {
|
||||||
this.agHelper.GetSiblingNClick(
|
this.agHelper.GetSiblingNClick(
|
||||||
this.locators.showPageNavSwitch,
|
this.locators._showPageNavSwitch,
|
||||||
".bp3-control-indicator",
|
this.locators._setHomePageToggle,
|
||||||
);
|
);
|
||||||
this.agHelper.ValidateNetworkStatus("@updatePage", 200);
|
this.agHelper.ValidateNetworkStatus("@updatePage", 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAsHomePage() {
|
ToggleHomePage() {
|
||||||
this.agHelper.GetSiblingNClick(
|
this.agHelper.GetSiblingNClick(
|
||||||
this.locators.setAsHomePageSwitch,
|
this.locators._setAsHomePageSwitch,
|
||||||
".bp3-control-indicator",
|
this.locators._setHomePageToggle,
|
||||||
);
|
);
|
||||||
this.agHelper.ValidateNetworkStatus("@makePageDefault", 200);
|
this.agHelper.ValidateNetworkStatus("@makePageDefault", 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
isHomePage(pageName: string) {
|
AssertHomePage(pageName: string) {
|
||||||
this.agHelper.AssertText(this.locators.homePageHeader, "text", pageName);
|
this.agHelper.AssertText(this.locators._homePageHeader, "text", pageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1391,12 +1391,14 @@ export const PAGE_SETTINGS_PAGE_URL_VERSION_UPDATE_3 = () =>
|
||||||
"your app URL to new readable format to change this";
|
"your app URL to new readable format to change this";
|
||||||
export const PAGE_SETTINGS_SHOW_PAGE_NAV = () => "Show page navigation";
|
export const PAGE_SETTINGS_SHOW_PAGE_NAV = () => "Show page navigation";
|
||||||
export const PAGE_SETTINGS_SHOW_PAGE_NAV_TOOLTIP = () =>
|
export const PAGE_SETTINGS_SHOW_PAGE_NAV_TOOLTIP = () =>
|
||||||
"Hide or show the appsmith navbar containing the app name and page switcher";
|
"Show or hide the page in the appsmith navbar in view mode";
|
||||||
export const PAGE_SETTINGS_SET_AS_HOMEPAGE = () => "Set as home page";
|
export const PAGE_SETTINGS_SET_AS_HOMEPAGE = () => "Set as home page";
|
||||||
export const PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP = () =>
|
export const PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP = () =>
|
||||||
"This is the current home page, you can change this by setting another page as the home page";
|
"This is the current home page, you can change this by setting another page as the home page";
|
||||||
export const PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP_NON_HOME_PAGE = () =>
|
export const PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP_NON_HOME_PAGE = () =>
|
||||||
"Set this page as your home page. This will override your previously set home page.";
|
"Set this page as your home page. This will override your previously set home page.";
|
||||||
|
export const PAGE_SETTINGS_ACTION_NAME_CONFLICT_ERROR = (name: string) =>
|
||||||
|
`${name} is already being used.`;
|
||||||
|
|
||||||
// Alert options and labels for showMessage types
|
// Alert options and labels for showMessage types
|
||||||
export const ALERT_STYLE_OPTIONS = [
|
export const ALERT_STYLE_OPTIONS = [
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ export class URLBuilder {
|
||||||
baseURLRegistry[URL_TYPE.CUSTOM_SLUG][APP_MODE.PUBLISHED];
|
baseURLRegistry[URL_TYPE.CUSTOM_SLUG][APP_MODE.PUBLISHED];
|
||||||
return generatePath(urlPattern, {
|
return generatePath(urlPattern, {
|
||||||
pageId,
|
pageId,
|
||||||
customSlug: `${customSlug.replaceAll(" ", "-")}-`,
|
customSlug: `${customSlug}-`,
|
||||||
}).toLowerCase();
|
}).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,7 +182,7 @@ export class URLBuilder {
|
||||||
|
|
||||||
const formattedParams = this.getFormattedParams(pageId);
|
const formattedParams = this.getFormattedParams(pageId);
|
||||||
|
|
||||||
formattedParams.pageSlug = `${pageName.replaceAll(" ", "-")}-`;
|
formattedParams.pageSlug = `${pageName}-`;
|
||||||
|
|
||||||
return generatePath(urlPattern, formattedParams).toLowerCase();
|
return generatePath(urlPattern, formattedParams).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import {
|
||||||
GENERAL_SETTINGS_APP_ICON_LABEL,
|
GENERAL_SETTINGS_APP_ICON_LABEL,
|
||||||
GENERAL_SETTINGS_APP_NAME_LABEL,
|
GENERAL_SETTINGS_APP_NAME_LABEL,
|
||||||
GENERAL_SETTINGS_NAME_EMPTY_MESSAGE,
|
GENERAL_SETTINGS_NAME_EMPTY_MESSAGE,
|
||||||
GENERAL_SETTINGS_NAME_SPECIAL_CHARACTER_ERROR,
|
|
||||||
} from "ce/constants/messages";
|
} from "ce/constants/messages";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import {
|
import {
|
||||||
|
|
@ -24,9 +23,7 @@ import {
|
||||||
} from "selectors/applicationSelectors";
|
} from "selectors/applicationSelectors";
|
||||||
import { getCurrentApplicationId } from "selectors/editorSelectors";
|
import { getCurrentApplicationId } from "selectors/editorSelectors";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { checkRegex } from "utils/validation/CheckRegex";
|
|
||||||
import TextLoaderIcon from "../Components/TextLoaderIcon";
|
import TextLoaderIcon from "../Components/TextLoaderIcon";
|
||||||
import { appNameRegex } from "../Utils";
|
|
||||||
|
|
||||||
const IconSelectorWrapper = styled.div`
|
const IconSelectorWrapper = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
@ -60,8 +57,8 @@ function GeneralSettings() {
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setApplicationName(application?.name);
|
!isSavingAppName && setApplicationName(application?.name);
|
||||||
}, [application?.name]);
|
}, [application, application?.name, isSavingAppName]);
|
||||||
|
|
||||||
const updateAppSettings = useCallback(
|
const updateAppSettings = useCallback(
|
||||||
debounce((icon?: AppIconName) => {
|
debounce((icon?: AppIconName) => {
|
||||||
|
|
@ -106,13 +103,20 @@ function GeneralSettings() {
|
||||||
}}
|
}}
|
||||||
placeholder="App name"
|
placeholder="App name"
|
||||||
type="input"
|
type="input"
|
||||||
validator={checkRegex(
|
validator={(value: string) => {
|
||||||
appNameRegex,
|
let result: { isValid: boolean; message?: string } = {
|
||||||
GENERAL_SETTINGS_NAME_SPECIAL_CHARACTER_ERROR(),
|
isValid: true,
|
||||||
true,
|
};
|
||||||
setIsAppNameValid,
|
if (!value || value.trim().length === 0) {
|
||||||
GENERAL_SETTINGS_NAME_EMPTY_MESSAGE(),
|
setIsAppNameValid(false);
|
||||||
)}
|
result = {
|
||||||
|
isValid: false,
|
||||||
|
message: GENERAL_SETTINGS_NAME_EMPTY_MESSAGE(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
setIsAppNameValid(result.isValid);
|
||||||
|
return result;
|
||||||
|
}}
|
||||||
value={applicationName}
|
value={applicationName}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
PAGE_SETTINGS_NAME_EMPTY_MESSAGE,
|
PAGE_SETTINGS_NAME_EMPTY_MESSAGE,
|
||||||
PAGE_SETTINGS_SHOW_PAGE_NAV_TOOLTIP,
|
PAGE_SETTINGS_SHOW_PAGE_NAV_TOOLTIP,
|
||||||
PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP_NON_HOME_PAGE,
|
PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP_NON_HOME_PAGE,
|
||||||
PAGE_SETTINGS_NAME_SPECIAL_CHARACTER_ERROR as PAGE_SETTINGS_SPECIAL_CHARACTER_ERROR,
|
PAGE_SETTINGS_ACTION_NAME_CONFLICT_ERROR,
|
||||||
} from "ce/constants/messages";
|
} from "ce/constants/messages";
|
||||||
import { Page } from "ce/constants/ReduxActionConstants";
|
import { Page } from "ce/constants/ReduxActionConstants";
|
||||||
import { hasManagePagePermission } from "@appsmith/utils/permissionHelpers";
|
import { hasManagePagePermission } from "@appsmith/utils/permissionHelpers";
|
||||||
|
|
@ -24,7 +24,7 @@ import AdsSwitch from "design-system/build/Switch";
|
||||||
import ManualUpgrades from "pages/Editor/BottomBar/ManualUpgrades";
|
import ManualUpgrades from "pages/Editor/BottomBar/ManualUpgrades";
|
||||||
import PropertyHelpLabel from "pages/Editor/PropertyPane/PropertyHelpLabel";
|
import PropertyHelpLabel from "pages/Editor/PropertyPane/PropertyHelpLabel";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { shallowEqual, useDispatch, useSelector } from "react-redux";
|
||||||
import {
|
import {
|
||||||
getCurrentApplicationId,
|
getCurrentApplicationId,
|
||||||
selectApplicationVersion,
|
selectApplicationVersion,
|
||||||
|
|
@ -32,9 +32,11 @@ import {
|
||||||
import { getUpdatingEntity } from "selectors/explorerSelector";
|
import { getUpdatingEntity } from "selectors/explorerSelector";
|
||||||
import { getPageLoadingState } from "selectors/pageListSelectors";
|
import { getPageLoadingState } from "selectors/pageListSelectors";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { checkRegex } from "utils/validation/CheckRegex";
|
|
||||||
import TextLoaderIcon from "../Components/TextLoaderIcon";
|
import TextLoaderIcon from "../Components/TextLoaderIcon";
|
||||||
import { getUrlPreview, specialCharacterCheckRegex } from "../Utils";
|
import { getUrlPreview } from "../Utils";
|
||||||
|
import { AppState } from "ce/reducers";
|
||||||
|
import { getUsedActionNames } from "selectors/actionSelectors";
|
||||||
|
import { isNameValid, resolveAsSpaceChar } from "utils/helpers";
|
||||||
|
|
||||||
const SwitchWrapper = styled.div`
|
const SwitchWrapper = styled.div`
|
||||||
&&&&&&&
|
&&&&&&&
|
||||||
|
|
@ -79,6 +81,8 @@ const UrlPreviewScroll = styled.div`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const specialCharacterCheckRegex = /^[A-Za-z0-9\s\-]+$/g;
|
||||||
|
|
||||||
function PageSettings(props: { page: Page }) {
|
function PageSettings(props: { page: Page }) {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const page = props.page;
|
const page = props.page;
|
||||||
|
|
@ -100,7 +104,6 @@ function PageSettings(props: { page: Page }) {
|
||||||
const [isPageNameValid, setIsPageNameValid] = useState(true);
|
const [isPageNameValid, setIsPageNameValid] = useState(true);
|
||||||
|
|
||||||
const [customSlug, setCustomSlug] = useState(page.customSlug);
|
const [customSlug, setCustomSlug] = useState(page.customSlug);
|
||||||
const [isCustomSlugValid, setIsCustomSlugValid] = useState(true);
|
|
||||||
const [isCustomSlugSaving, setIsCustomSlugSaving] = useState(false);
|
const [isCustomSlugSaving, setIsCustomSlugSaving] = useState(false);
|
||||||
|
|
||||||
const [isShown, setIsShown] = useState(!!!page.isHidden);
|
const [isShown, setIsShown] = useState(!!!page.isHidden);
|
||||||
|
|
@ -117,6 +120,16 @@ function PageSettings(props: { page: Page }) {
|
||||||
page.customSlug,
|
page.customSlug,
|
||||||
])(page.pageId, pageName, page.pageName, customSlug, page.customSlug);
|
])(page.pageId, pageName, page.pageName, customSlug, page.customSlug);
|
||||||
|
|
||||||
|
const conflictingNames = useSelector(
|
||||||
|
(state: AppState) => getUsedActionNames(state, ""),
|
||||||
|
shallowEqual,
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasActionNameConflict = useCallback(
|
||||||
|
(name: string) => !isNameValid(name, conflictingNames),
|
||||||
|
[conflictingNames],
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPageName(page.pageName);
|
setPageName(page.pageName);
|
||||||
setCustomSlug(page.customSlug || "");
|
setCustomSlug(page.customSlug || "");
|
||||||
|
|
@ -151,15 +164,14 @@ function PageSettings(props: { page: Page }) {
|
||||||
}, [page.pageId, page.pageName, pageName, isPageNameValid]);
|
}, [page.pageId, page.pageName, pageName, isPageNameValid]);
|
||||||
|
|
||||||
const saveCustomSlug = useCallback(() => {
|
const saveCustomSlug = useCallback(() => {
|
||||||
if (!canManagePages || !isCustomSlugValid || page.customSlug === customSlug)
|
if (!canManagePages || page.customSlug === customSlug) return;
|
||||||
return;
|
|
||||||
const payload: UpdatePageRequest = {
|
const payload: UpdatePageRequest = {
|
||||||
id: page.pageId,
|
id: page.pageId,
|
||||||
customSlug: customSlug || "",
|
customSlug: customSlug || "",
|
||||||
};
|
};
|
||||||
setIsCustomSlugSaving(true);
|
setIsCustomSlugSaving(true);
|
||||||
dispatch(updatePage(payload));
|
dispatch(updatePage(payload));
|
||||||
}, [page.pageId, page.customSlug, customSlug, isCustomSlugValid]);
|
}, [page.pageId, page.customSlug, customSlug]);
|
||||||
|
|
||||||
const saveIsShown = useCallback(
|
const saveIsShown = useCallback(
|
||||||
(isShown: boolean) => {
|
(isShown: boolean) => {
|
||||||
|
|
@ -190,7 +202,9 @@ function PageSettings(props: { page: Page }) {
|
||||||
fill
|
fill
|
||||||
id="t--page-settings-name"
|
id="t--page-settings-name"
|
||||||
onBlur={savePageName}
|
onBlur={savePageName}
|
||||||
onChange={setPageName}
|
onChange={(value: string) =>
|
||||||
|
setPageName(resolveAsSpaceChar(value, 30))
|
||||||
|
}
|
||||||
onKeyPress={(ev: React.KeyboardEvent) => {
|
onKeyPress={(ev: React.KeyboardEvent) => {
|
||||||
if (ev.key === "Enter") {
|
if (ev.key === "Enter") {
|
||||||
savePageName();
|
savePageName();
|
||||||
|
|
@ -198,13 +212,27 @@ function PageSettings(props: { page: Page }) {
|
||||||
}}
|
}}
|
||||||
placeholder="Page name"
|
placeholder="Page name"
|
||||||
type="input"
|
type="input"
|
||||||
validator={checkRegex(
|
validator={(value: string) => {
|
||||||
specialCharacterCheckRegex,
|
let result: { isValid: boolean; message?: string } = {
|
||||||
PAGE_SETTINGS_SPECIAL_CHARACTER_ERROR(),
|
isValid: true,
|
||||||
true,
|
};
|
||||||
setIsPageNameValid,
|
if (!value || value.trim().length === 0) {
|
||||||
PAGE_SETTINGS_NAME_EMPTY_MESSAGE(),
|
result = {
|
||||||
)}
|
isValid: false,
|
||||||
|
message: PAGE_SETTINGS_NAME_EMPTY_MESSAGE(),
|
||||||
|
};
|
||||||
|
} else if (
|
||||||
|
value !== page.pageName &&
|
||||||
|
hasActionNameConflict(value)
|
||||||
|
) {
|
||||||
|
result = {
|
||||||
|
isValid: false,
|
||||||
|
message: PAGE_SETTINGS_ACTION_NAME_CONFLICT_ERROR(value),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
setIsPageNameValid(result.isValid);
|
||||||
|
return result;
|
||||||
|
}}
|
||||||
value={pageName}
|
value={pageName}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -230,7 +258,6 @@ function PageSettings(props: { page: Page }) {
|
||||||
className={classNames({
|
className={classNames({
|
||||||
"py-1 relative": true,
|
"py-1 relative": true,
|
||||||
"pb-2": appNeedsUpdate,
|
"pb-2": appNeedsUpdate,
|
||||||
"pb-6": !appNeedsUpdate && !isCustomSlugValid,
|
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{isCustomSlugSaving && <TextLoaderIcon />}
|
{isCustomSlugSaving && <TextLoaderIcon />}
|
||||||
|
|
@ -240,7 +267,11 @@ function PageSettings(props: { page: Page }) {
|
||||||
fill
|
fill
|
||||||
id="t--page-settings-custom-slug"
|
id="t--page-settings-custom-slug"
|
||||||
onBlur={saveCustomSlug}
|
onBlur={saveCustomSlug}
|
||||||
onChange={setCustomSlug}
|
onChange={(value: string) =>
|
||||||
|
value.length > 0
|
||||||
|
? specialCharacterCheckRegex.test(value) && setCustomSlug(value)
|
||||||
|
: setCustomSlug(value)
|
||||||
|
}
|
||||||
onKeyPress={(ev: React.KeyboardEvent) => {
|
onKeyPress={(ev: React.KeyboardEvent) => {
|
||||||
if (ev.key === "Enter") {
|
if (ev.key === "Enter") {
|
||||||
saveCustomSlug();
|
saveCustomSlug();
|
||||||
|
|
@ -249,12 +280,6 @@ function PageSettings(props: { page: Page }) {
|
||||||
placeholder="Page URL"
|
placeholder="Page URL"
|
||||||
readOnly={appNeedsUpdate}
|
readOnly={appNeedsUpdate}
|
||||||
type="input"
|
type="input"
|
||||||
validator={checkRegex(
|
|
||||||
specialCharacterCheckRegex,
|
|
||||||
PAGE_SETTINGS_SPECIAL_CHARACTER_ERROR(),
|
|
||||||
false,
|
|
||||||
setIsCustomSlugValid,
|
|
||||||
)}
|
|
||||||
value={customSlug}
|
value={customSlug}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,6 @@ import { APP_MODE } from "entities/App";
|
||||||
import urlBuilder from "entities/URLRedirect/URLAssembly";
|
import urlBuilder from "entities/URLRedirect/URLAssembly";
|
||||||
import { splitPathPreview } from "utils/helpers";
|
import { splitPathPreview } from "utils/helpers";
|
||||||
|
|
||||||
export const specialCharacterCheckRegex = /^[A-Za-z0-9\s\-]+$/;
|
|
||||||
export const appNameRegex = /^[A-Za-z0-9\s\-()]+$/;
|
|
||||||
|
|
||||||
export const getUrlPreview = (
|
export const getUrlPreview = (
|
||||||
pageId: string,
|
pageId: string,
|
||||||
newPageName: string,
|
newPageName: string,
|
||||||
|
|
@ -14,6 +11,13 @@ export const getUrlPreview = (
|
||||||
) => {
|
) => {
|
||||||
let relativePath: string;
|
let relativePath: string;
|
||||||
|
|
||||||
|
newPageName = filterAccentedAndSpecialCharacters(newPageName);
|
||||||
|
currentPageName = filterAccentedAndSpecialCharacters(currentPageName);
|
||||||
|
newCustomSlug &&
|
||||||
|
(newCustomSlug = filterAccentedAndSpecialCharacters(newCustomSlug));
|
||||||
|
currentCustomSlug &&
|
||||||
|
(currentCustomSlug = filterAccentedAndSpecialCharacters(currentCustomSlug));
|
||||||
|
|
||||||
// when page name is changed
|
// when page name is changed
|
||||||
// and when custom slug doesn't exist
|
// and when custom slug doesn't exist
|
||||||
if (!newCustomSlug && newPageName !== currentPageName) {
|
if (!newCustomSlug && newPageName !== currentPageName) {
|
||||||
|
|
@ -41,3 +45,9 @@ export const getUrlPreview = (
|
||||||
splitRelativePath: splitPathPreview(relativePath, newCustomSlug),
|
splitRelativePath: splitPathPreview(relativePath, newCustomSlug),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filterAccentedAndSpecialCharacters = (value: string) => {
|
||||||
|
return decodeURI(value)
|
||||||
|
.replaceAll(" ", "-")
|
||||||
|
.replaceAll(/[^A-Za-z0-9-]/g, "");
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export function CanvasPropertyPane() {
|
||||||
position={PopoverPosition.BOTTOM}
|
position={PopoverPosition.BOTTOM}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
category={Category.tertiary}
|
category={Category.secondary}
|
||||||
fill
|
fill
|
||||||
id="t--app-settings-cta"
|
id="t--app-settings-cta"
|
||||||
onClick={openAppSettingsPane}
|
onClick={openAppSettingsPane}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ export const GetNavigationMenuData = ({
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
text: "Go to dashboard",
|
text: "Home",
|
||||||
onClick: () => history.replace(APPLICATIONS_URL),
|
onClick: () => history.replace(APPLICATIONS_URL),
|
||||||
type: MenuTypes.MENU,
|
type: MenuTypes.MENU,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
|
|
|
||||||
|
|
@ -155,11 +155,6 @@ export function PageContextMenu(props: {
|
||||||
</CustomLabel>
|
</CustomLabel>
|
||||||
) as ReactNode) as string,
|
) as ReactNode) as string,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
value: "settings",
|
|
||||||
onSelect: openAppSettingsPane,
|
|
||||||
label: createMessage(CONTEXT_SETTINGS),
|
|
||||||
},
|
|
||||||
!props.isDefaultPage &&
|
!props.isDefaultPage &&
|
||||||
canManagePages && {
|
canManagePages && {
|
||||||
value: "setdefault",
|
value: "setdefault",
|
||||||
|
|
@ -173,6 +168,11 @@ export function PageContextMenu(props: {
|
||||||
value: "setdefault",
|
value: "setdefault",
|
||||||
label: createMessage(CONTEXT_SET_AS_HOME_PAGE),
|
label: createMessage(CONTEXT_SET_AS_HOME_PAGE),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: "settings",
|
||||||
|
onSelect: openAppSettingsPane,
|
||||||
|
label: createMessage(CONTEXT_SETTINGS),
|
||||||
|
},
|
||||||
!props.isDefaultPage &&
|
!props.isDefaultPage &&
|
||||||
canDeletePages && {
|
canDeletePages && {
|
||||||
className: "t--apiFormDeleteBtn single-select",
|
className: "t--apiFormDeleteBtn single-select",
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
export const checkRegex = (
|
|
||||||
regex: RegExp,
|
|
||||||
errorMessage: string,
|
|
||||||
checkEmpty = true,
|
|
||||||
callback?: (isValid: boolean) => void,
|
|
||||||
emptyMessage = "Cannot be empty",
|
|
||||||
) => {
|
|
||||||
return (value: string) => {
|
|
||||||
const isEmpty = value.length === 0;
|
|
||||||
const regexMismatch = !isEmpty && !regex.test(value);
|
|
||||||
const hasError = (checkEmpty && isEmpty) || regexMismatch;
|
|
||||||
|
|
||||||
callback?.(!hasError);
|
|
||||||
|
|
||||||
let message = "";
|
|
||||||
if (checkEmpty && isEmpty) message = emptyMessage;
|
|
||||||
else if (regexMismatch) message = errorMessage;
|
|
||||||
|
|
||||||
return {
|
|
||||||
isValid: !hasError,
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
Loading…
Reference in New Issue
Block a user