diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fae099da..7b4bb25d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Font-family variables that can be used to customise the sans-serif and monospace fonts used in the editor (#1264) - Material symbols font to web component preview page since the Design System depends on this (#1261) +- Ability for host page to force web component into its loading state (#1272) ### Changed diff --git a/src/containers/WebComponentLoader.jsx b/src/containers/WebComponentLoader.jsx index c0a63fb64..a94a92d33 100644 --- a/src/containers/WebComponentLoader.jsx +++ b/src/containers/WebComponentLoader.jsx @@ -41,6 +41,7 @@ const WebComponentLoader = (props) => { hostStyles, // Pass in styles from the host identifier, instructions, + isLoading = false, theme, loadRemixDisabled = false, locale = "en", @@ -69,7 +70,10 @@ const WebComponentLoader = (props) => { const user = useSelector((state) => state.auth.user || localStorageUser); const [loadRemix, setLoadRemix] = useState(!!user); const project = useSelector((state) => state.editor.project); - const projectOwner = useSelector((state) => state.editor.project.user_name); + const projectOwnerId = useSelector((state) => state.editor.project.user_id); + const projectOwnerName = useSelector( + (state) => state.editor.project.user_name, + ); const loading = useSelector((state) => state.editor.loading); const justLoaded = useSelector((state) => state.editor.justLoaded); const remixLoadFailed = useSelector((state) => state.editor.remixLoadFailed); @@ -126,10 +130,16 @@ const WebComponentLoader = (props) => { }, [loading, remixLoadFailed]); useEffect(() => { + const projectOwner = { + id: projectOwnerId, + name: projectOwnerName, + identifier: projectIdentifier, + }; + if (justLoaded) { document.dispatchEvent(projectOwnerLoadedEvent(projectOwner)); } - }, [projectOwner, justLoaded]); + }, [projectOwnerId, projectOwnerName, projectIdentifier, justLoaded]); useEffect(() => { if (locale) { @@ -251,7 +261,9 @@ const WebComponentLoader = (props) => { ); - if (loading === "success") { + if (isLoading) { + return renderLoadingState(); + } else if (loading === "success") { return renderSuccessState(); } else if (["idle", "failed"].includes(loading)) { return renderFailedState(); diff --git a/src/containers/WebComponentLoader.test.js b/src/containers/WebComponentLoader.test.js index 6aeedc841..297b8942f 100644 --- a/src/containers/WebComponentLoader.test.js +++ b/src/containers/WebComponentLoader.test.js @@ -1,4 +1,4 @@ -import { render, act } from "@testing-library/react"; +import { render, act, screen } from "@testing-library/react"; import React from "react"; import { Provider } from "react-redux"; import configureStore from "redux-mock-store"; @@ -665,3 +665,39 @@ describe("When user is in state", () => { }); }); }); + +describe("When isLoading prop is used", () => { + beforeEach(() => { + const middlewares = []; + const mockStore = configureStore(middlewares); + const initialState = { + editor: { + loading: "success", + project: { + components: [], + }, + openFiles: [], + focussedFileIndices: [], + hasShownSavePrompt: false, + remixLoadFailed: false, + justLoaded: false, + saveTriggered: false, + }, + instructions: {}, + auth: {}, + }; + store = mockStore(initialState); + cookies = new Cookies(); + }); + + test("it respects isLoading prop when rendering", () => { + render( + + + + + , + ); + expect(screen.queryByText("webComponent.loading")).toBeInTheDocument(); + }); +}); diff --git a/src/web-component.js b/src/web-component.js index 345502510..cbdd6dbdd 100644 --- a/src/web-component.js +++ b/src/web-component.js @@ -57,6 +57,7 @@ class WebComponent extends HTMLElement { "host_styles", "identifier", "instructions", + "is_loading", "load_remix_disabled", "locale", "output_only", @@ -83,6 +84,7 @@ class WebComponent extends HTMLElement { [ "embedded", "editable_instructions", + "is_loading", "load_remix_disabled", "output_only", "output_split_view",