diff --git a/.talismanrc b/.talismanrc index 2b8bd7d7..cab0c297 100644 --- a/.talismanrc +++ b/.talismanrc @@ -10,6 +10,15 @@ fileignoreconfig: checksum: 3badd6a142456b6a361569e6fc546349a38ac6b366bef7fd5255d1e93220444e - filename: src/visualBuilder/components/Collab/ThreadPopup/__test__/CommentTextArea.test.tsx checksum: d0ef271ee5381d9feab06bda6e7e89bd0a882fee87495627bd811c1f0a5459c7 + - filename: src/visualBuilder/utils/__test__/getVisualBuilderRedirectionUrl.test.ts + checksum: 136be2b65e28df8a0fec100cb0f2dfb735341162038f46b5492c803771b58d55 - filename: package-lock.json checksum: fd06363871d0ee16ebfb5d9d0cc479e0922a615bb76584b80bb6933ee6c3e237 + - filename: src/visualBuilder/components/FieldLocationIcon.tsx + checksum: d7d1330dcc55c8c1d3e154e1c55ed16132255d502046e3b23eb88b0b38833c24 + - filename: src/visualBuilder/components/FieldLocationAppList.tsx + checksum: 5cf8f044f0e285120a0f4527bc875fc5b874d9598579e272b37f325e060f9eef + - filename: src/visualBuilder/components/__test__/startEditingButton.test.tsx + checksum: 3205d6199640ad160ddb62232882a019d735bb94fde87cf662629ae191e285c7 + - filename: src/visualBuilder/components/FieldLocationAppList.tsx version: "1.0" diff --git a/src/visualBuilder/components/__test__/startEditingButton.test.tsx b/src/visualBuilder/components/__test__/startEditingButton.test.tsx index b4aa7122..0e8f1a7c 100644 --- a/src/visualBuilder/components/__test__/startEditingButton.test.tsx +++ b/src/visualBuilder/components/__test__/startEditingButton.test.tsx @@ -42,7 +42,7 @@ describe("StartEditingButtonComponent", () => { const button = getByTestId("vcms-start-editing-btn"); expect(button?.getAttribute("href")).toBe( - "https://app.contentstack.com/#!/stack/bltapikey/visual-builder?branch=main&environment=bltenvironment&target-url=http%3A%2F%2Flocalhost%3A3000%2F&locale=en-us" + "https://app.contentstack.com/#!/stack/bltapikey/visual-builder?target-url=http%3A%2F%2Flocalhost%3A3000&branch=main&environment=bltenvironment&locale=en-us" ); }); @@ -137,4 +137,4 @@ describe("StartEditingButtonComponent", () => { }); -}); +}); \ No newline at end of file diff --git a/src/visualBuilder/utils/__test__/generateStartEditingButton.test.ts b/src/visualBuilder/utils/__test__/generateStartEditingButton.test.ts index e652fffe..21684dcc 100644 --- a/src/visualBuilder/utils/__test__/generateStartEditingButton.test.ts +++ b/src/visualBuilder/utils/__test__/generateStartEditingButton.test.ts @@ -39,7 +39,7 @@ describe("generateStartEditingButton", () => { button?.click(); expect(button?.getAttribute("href")).toBe( - "https://app.contentstack.com/#!/stack//visual-builder?branch=main&target-url=http%3A%2F%2Flocalhost%3A3000%2F&locale=en-us" + "https://app.contentstack.com/#!/stack//visual-builder?target-url=http%3A%2F%2Flocalhost%3A3000&branch=main&locale=en-us" ); }); @@ -57,7 +57,7 @@ describe("generateStartEditingButton", () => { button?.click(); expect(button?.getAttribute("href")).toBe( - "https://app.contentstack.com/#!/stack//visual-builder?branch=main&target-url=http%3A%2F%2Flocalhost%3A3000%2F&locale=en-us" + "https://app.contentstack.com/#!/stack//visual-builder?target-url=http%3A%2F%2Flocalhost%3A3000&branch=main&locale=en-us" ); }); }); diff --git a/src/visualBuilder/utils/__test__/getVisualBuilderRedirectionUrl.test.ts b/src/visualBuilder/utils/__test__/getVisualBuilderRedirectionUrl.test.ts index e7232ad6..fbd5c91e 100644 --- a/src/visualBuilder/utils/__test__/getVisualBuilderRedirectionUrl.test.ts +++ b/src/visualBuilder/utils/__test__/getVisualBuilderRedirectionUrl.test.ts @@ -27,7 +27,9 @@ describe('getVisualBuilderRedirectionUrl', () => { }); const result = getVisualBuilderRedirectionUrl(); - expect(result.toString()).toBe('https://app.example.com/#!/stack/12345/visual-builder?branch=main&environment=production&target-url=https%3A%2F%2Fexample.com%2F&locale=en-US'); + expect(result.toString()).toBe( + "https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com&branch=main&environment=production&locale=en-US" + ); }); it('should return the correct URL without branch and environment', () => { @@ -44,7 +46,7 @@ describe('getVisualBuilderRedirectionUrl', () => { }); const result = getVisualBuilderRedirectionUrl(); - expect(result.toString()).toBe('https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com%2F&locale=en-US'); + expect(result.toString()).toBe('https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com&locale=en-US'); }); it('should use locale from data-cslp attribute if present', () => { @@ -64,7 +66,7 @@ describe('getVisualBuilderRedirectionUrl', () => { extractDetailsFromCslp.mockReturnValue({ locale: 'fr-FR' }); const result = getVisualBuilderRedirectionUrl(); - expect(result.toString()).toBe('https://app.example.com/#!/stack/12345/visual-builder?branch=main&environment=production&target-url=https%3A%2F%2Fexample.com%2F&locale=fr-FR'); + expect(result.toString()).toBe('https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com&branch=main&environment=production&locale=fr-FR'); }); it('should return the correct URL without locale', () => { @@ -82,6 +84,120 @@ describe('getVisualBuilderRedirectionUrl', () => { }); const result = getVisualBuilderRedirectionUrl(); - expect(result.toString()).toBe('https://app.example.com/#!/stack/12345/visual-builder?branch=main&environment=production&target-url=https%3A%2F%2Fexample.com%2F'); + expect(result.toString()).toBe('https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com&branch=main&environment=production'); }); -}); \ No newline at end of file + it("should return the correct URL without query parameters in target-url", () => { + Object.defineProperty(window, "location", { + writable: true, + value: new URL("https://example.com/page?query=test"), + }); + + Config.get.mockReturnValue({ + stackDetails: { + branch: "main", + apiKey: "12345", + environment: "production", + locale: "en-US", + }, + clientUrlParams: { + url: "https://app.example.com", + }, + }); + + const result = getVisualBuilderRedirectionUrl(); + expect(result.toString()).toContain( + "target-url=https%3A%2F%2Fexample.com%2Fpage" + ); + expect(result.toString()).not.toContain("?query=test"); + }); + it("should return the correct URL with slash type hash routing", () => { + Object.defineProperty(window, "location", { + writable: true, + value: new URL("https://example.com/#/page"), + }); + Config.get.mockReturnValue({ + stackDetails: { + branch: "main", + apiKey: "12345", + environment: "production", + locale: "en-US", + }, + clientUrlParams: { + url: "https://app.example.com", + }, + }); + + const result = getVisualBuilderRedirectionUrl(); + expect(result.toString()).toBe( + "https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com%2Fpage&branch=main&environment=production&locale=en-US" + ); + }); + + it("should return the correct URL with no slash type hash routing", () => { + Object.defineProperty(window, "location", { + writable: true, + value: new URL("https://example.com/#page"), + }); + Config.get.mockReturnValue({ + stackDetails: { + branch: "main", + apiKey: "12345", + environment: "production", + locale: "en-US", + }, + clientUrlParams: { + url: "https://app.example.com", + }, + }); + + const result = getVisualBuilderRedirectionUrl(); + expect(result.toString()).toBe( + "https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com%2Fpage&branch=main&environment=production&locale=en-US" + ); + }); + it("should return the correct URL with hash bang type hash routing", () => { + Object.defineProperty(window, "location", { + writable: true, + value: new URL("https://example.com/#!/page"), + }); + Config.get.mockReturnValue({ + stackDetails: { + branch: "main", + apiKey: "12345", + environment: "production", + locale: "en-US", + }, + clientUrlParams: { + url: "https://app.example.com", + }, + }); + + const result = getVisualBuilderRedirectionUrl(); + expect(result.toString()).toBe( + "https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com%2Fpage&branch=main&environment=production&locale=en-US" + ); + }); + + it("should return the correct URL with hash bang type hash routing", () => { + Object.defineProperty(window, "location", { + writable: true, + value: new URL("https://example.com/#!/page?query=test"), + }); + Config.get.mockReturnValue({ + stackDetails: { + branch: "main", + apiKey: "12345", + environment: "production", + locale: "en-US", + }, + clientUrlParams: { + url: "https://app.example.com", + }, + }); + + const result = getVisualBuilderRedirectionUrl(); + expect(result.toString()).toBe( + "https://app.example.com/#!/stack/12345/visual-builder?target-url=https%3A%2F%2Fexample.com%2Fpage&branch=main&environment=production&locale=en-US" + ); + }); +}); diff --git a/src/visualBuilder/utils/getVisualBuilderRedirectionUrl.ts b/src/visualBuilder/utils/getVisualBuilderRedirectionUrl.ts index 955e466c..17e5b374 100644 --- a/src/visualBuilder/utils/getVisualBuilderRedirectionUrl.ts +++ b/src/visualBuilder/utils/getVisualBuilderRedirectionUrl.ts @@ -11,15 +11,42 @@ export default function getVisualBuilderRedirectionUrl(): URL { const { url: appUrl } = clientUrlParams; const searchParams = new URLSearchParams(); + + const hash = window.location.hash; + const isHashSlash = hash.startsWith("#/"); + const isHashBang = hash.startsWith("#!/"); + const isNoSlash = hash.length > 1 && !isHashSlash && !isHashBang; + const isHashRouting = isHashSlash || isHashBang || isNoSlash; + + const url = new URL(window.location.href); + // remove query parameters from the url + url.search = ""; + if (isHashRouting) { + // if the hash is #!/about-us or #/about-us or #about-us, we want /about-us + let pathFromHash; + if (isHashBang) { + pathFromHash = hash.substring(2); + } else if (isHashSlash) { + pathFromHash = hash.substring(1); + } else { + pathFromHash = "/" + hash.substring(1); + } + // remove query parameters from the path if we have both hash routing and query string + let onlyPathname = pathFromHash.split("?")[0]; + url.pathname = (url.pathname + onlyPathname).replace(/\/\//g, "/"); + url.hash = ""; + } else { + url.hash = ""; + } + const targetUrl = url.toString().replace(/\/$/, ""); + + searchParams.set("target-url", targetUrl); if (branch) { searchParams.set("branch", branch); } if (environment) { searchParams.set("environment", environment); } - - searchParams.set("target-url", window.location.href); - // get the locale from the data cslp attribute const elementWithDataCslp = document.querySelector(`[data-cslp]`);