From 67233905797a168e028586bae8d547a9d7684897 Mon Sep 17 00:00:00 2001 From: EtienneLeco Date: Tue, 7 Jul 2026 16:04:38 +0200 Subject: [PATCH 1/3] feat: add method to request external navigation to parent page --- src/messaging.test.ts | 22 +++++++++++++++++++++- src/messaging.ts | 9 +++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/messaging.test.ts b/src/messaging.test.ts index 9ae6186..097956b 100644 --- a/src/messaging.test.ts +++ b/src/messaging.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { requestConnectionDetails } from "./messaging"; +import { requestConnectionDetails, requestExternalNavigation } from "./messaging"; describe("messaging", () => { describe("requestTemporaryToken", async () => { @@ -41,4 +41,24 @@ describe("messaging", () => { await expect(promise).resolves.toEqual({ temporaryToken, apiBaseUrl }); }); }); + + describe("requestExternalNavigation", () => { + let postMessageSpy + + beforeEach(() => { + postMessageSpy = vi.spyOn(window.parent, "postMessage"); + }); + + it("should post message to request navigation", () => { + const url = "an url"; + + requestExternalNavigation(url); + + expect(postMessageSpy).toHaveBeenCalledWith({ + type: "plugin:requestExternalNavigation", + url, + version: 1 + }, "*") + }); + }); }); diff --git a/src/messaging.ts b/src/messaging.ts index 3d33271..723e881 100644 --- a/src/messaging.ts +++ b/src/messaging.ts @@ -1,5 +1,6 @@ const PLUGIN_CONNECTION_DETAILS_EVENT_TYPE = "plugin:connectionDetails"; const PLUGIN_REQUEST_CONNECTION_DETAILS_EVENT_TYPE = "plugin:requestConnectionDetails"; +const PLUGIN_REQUEST_EXTERNAL_NAVIGATION_EVENT_TYPE = "plugin:requestExternalNavigation"; const MAX_LISTENER_TIME_IN_MS = 1000 * 60; @@ -36,4 +37,12 @@ export async function requestConnectionDetails(): Promise { reject(); } }); +} + +export async function requestExternalNavigation(url: string) { + window.parent.postMessage({ + type: PLUGIN_REQUEST_EXTERNAL_NAVIGATION_EVENT_TYPE, + url, + version: 1 + }, "*"); } \ No newline at end of file From 664a21ccf71f5e4c0d24fd17544ab28f727df18e Mon Sep 17 00:00:00 2001 From: EtienneLeco Date: Tue, 7 Jul 2026 16:40:43 +0200 Subject: [PATCH 2/3] feat: add method to sdk for external navigation --- src/SDK.test.ts | 16 ++++++++++++++++ src/SDK.ts | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/SDK.test.ts b/src/SDK.test.ts index 124c3a7..2334700 100644 --- a/src/SDK.test.ts +++ b/src/SDK.test.ts @@ -8,6 +8,7 @@ import type { MockInstance } from "vitest"; describe("SDK", () => { let requestConnectionDetailsStub: MockInstance; + let requestExternalNavigationStub: MockInstance; beforeEach(() => { vi.spyOn(headers, "buildHeaders").mockReturnValue({}); @@ -132,6 +133,21 @@ describe("SDK", () => { await expect(promise).rejects.toThrowError("Error 403 received from the API"); }); }); + + describe("navigateToExternalUrl", () => { + beforeEach(() => { + requestExternalNavigationStub = vi.spyOn(messaging, "requestExternalNavigation").mockReturnValue(); + }); + + it("should request external navigation", () => { + const url = "an url"; + const sdk = new SDK(); + + sdk.navigateToExternalUrl(url); + + expect(requestExternalNavigationStub).toHaveBeenCalledWith(url); + }); + }); }); function buildUnauthorizedResponse() { diff --git a/src/SDK.ts b/src/SDK.ts index 3855282..dd12bca 100644 --- a/src/SDK.ts +++ b/src/SDK.ts @@ -1,6 +1,6 @@ import { APIError } from "./errors"; import { buildAuthedHeaders, buildHeaders } from "./headers"; -import { requestConnectionDetails } from "./messaging"; +import { requestConnectionDetails, requestExternalNavigation } from "./messaging"; const PLUGIN_AUTH_ENDPOINT = "api/v2/plugin/oauth2/client-token"; const STATUS_CODE_UNAUTHORIZED_401 = 401; @@ -44,6 +44,10 @@ export class SDK { await this.authenticate(); } + navigateToExternalUrl(url: string) { + requestExternalNavigation(url); + } + private async authenticate() { const { apiBaseUrl, temporaryToken } = await requestConnectionDetails(); this.apiBaseUrl = apiBaseUrl; From 63c6f156e211bb98ecb42c848fa4a61afb64ec27 Mon Sep 17 00:00:00 2001 From: EtienneLeco Date: Tue, 7 Jul 2026 16:43:52 +0200 Subject: [PATCH 3/3] feat: document new method in readme --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a2a941f..5c61900 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A SDK for the client part of plugin developed for 360Learning products ## Getting started -First, import sdk to your project : +First, import sdk to your project : ``` yarn add 360learning-plugin-client-sdk @@ -12,7 +12,7 @@ yarn add 360learning-plugin-client-sdk npm install 360learning-plugin-client-sdk ``` -Then create a sdk instance +Then create a sdk instance ```typescript import { createSDK } from “360learning-plugin-client-sdk”; @@ -42,3 +42,13 @@ await sdk.init(); const user = await sdk.fetch("api/v2/uaa/users/me", { method: "GET" }); ``` + +### navigateToExternalUrl + +`navigateToExternalUrl` is used to trigger a navigation to an external website. This would make the page to leave the 360Learning website. + +```typescript +const sdk = createSDK(); + +sdk.navigateToUrl("http://github.com"); +```