diff --git a/src/components/ProjectBar/ProjectBar.jsx b/src/components/ProjectBar/ProjectBar.jsx index 1b790663e..33c331166 100644 --- a/src/components/ProjectBar/ProjectBar.jsx +++ b/src/components/ProjectBar/ProjectBar.jsx @@ -19,6 +19,7 @@ const ProjectBar = ({ nameEditable = true }) => { const loading = useSelector((state) => state.editor.loading); const lastSavedTime = useSelector((state) => state.editor.lastSavedTime); const offlineEnabled = useSelector((state) => state.editor.offlineEnabled); + const saveDisabled = useSelector((state) => state.editor.saveDisabled); const projectOwner = isOwner(user, project); const readOnly = useSelector((state) => state.editor.readOnly); const isOnline = useIsOnline(); @@ -39,7 +40,7 @@ const ProjectBar = ({ nameEditable = true }) => { type="tertiary" /> - {!projectOwner && !readOnly && ( + {!projectOwner && !readOnly && !saveDisabled && (
diff --git a/src/components/ProjectBar/ProjectBar.test.js b/src/components/ProjectBar/ProjectBar.test.js index 46c7f0cfc..0db25b777 100644 --- a/src/components/ProjectBar/ProjectBar.test.js +++ b/src/components/ProjectBar/ProjectBar.test.js @@ -95,6 +95,25 @@ describe("When logged in and user owns project", () => { }); }); +describe("When logged in and save is disabled", () => { + beforeEach(() => { + renderProjectBar({ + editor: { + project, + saveDisabled: true, + lastSavedTime: new Date().getTime(), + }, + auth: { + user, + }, + }); + }); + + test("Save button is not shown", () => { + expect(screen.queryByText("header.save")).not.toBeInTheDocument(); + }); +}); + describe("When logged in and no project identifier", () => { const projectWithoutId = { ...project, identifier: null }; diff --git a/src/containers/WebComponentLoader.jsx b/src/containers/WebComponentLoader.jsx index 0aef37da2..72198c689 100644 --- a/src/containers/WebComponentLoader.jsx +++ b/src/containers/WebComponentLoader.jsx @@ -5,6 +5,7 @@ import { setSenseHatAlwaysEnabled, setOfflineEnabled, setFriendlyErrorsEnabled, + setSaveDisabled, setLoadRemixDisabled, setReactAppApiEndpoint, setScratchApiEndpoint, @@ -72,6 +73,7 @@ const WebComponentLoader = (props) => { loadCache = true, // Always use cache unless explicitly disabled initialProject = null, offlineEnabled = false, + saveDisabled = false, } = props; const dispatch = useDispatch(); @@ -204,6 +206,10 @@ const WebComponentLoader = (props) => { dispatch(setOfflineEnabled(offlineEnabled)); }, [offlineEnabled, dispatch]); + useEffect(() => { + dispatch(setSaveDisabled(saveDisabled)); + }, [saveDisabled, dispatch]); + useEffect(() => { // Create a script element to save the existing Prism object if there is one const script = document.createElement("script"); diff --git a/src/redux/EditorSlice.js b/src/redux/EditorSlice.js index abf7b5276..d6bd05c51 100644 --- a/src/redux/EditorSlice.js +++ b/src/redux/EditorSlice.js @@ -128,6 +128,7 @@ export const editorInitialState = { scratchIframeProjectIdentifier: null, friendlyErrorsEnabled: false, friendlyError: null, + saveDisabled: false, }; const isScratchProject = (state) => @@ -300,6 +301,9 @@ const EditorSlice = createSlice({ setFriendlyError: (state, action) => { state.friendlyError = action.payload; }, + setSaveDisabled: (state, action) => { + state.saveDisabled = action.payload; + }, setLoadRemixDisabled: (state, action) => { state.loadRemixDisabled = action.payload; }, @@ -531,6 +535,7 @@ export const { setSenseHatEnabled, setFriendlyErrorsEnabled, setLoadRemixDisabled, + setSaveDisabled, setReactAppApiEndpoint, setScratchApiEndpoint, stopCodeRun, diff --git a/src/redux/EditorSlice.test.js b/src/redux/EditorSlice.test.js index 37c529f0f..6e4b9897d 100644 --- a/src/redux/EditorSlice.test.js +++ b/src/redux/EditorSlice.test.js @@ -23,6 +23,7 @@ import reducer, { scratchSaveFailed, setFriendlyErrorsEnabled, setFriendlyError, + setSaveDisabled, } from "./EditorSlice"; const mockCreateRemix = jest.fn(); @@ -128,6 +129,12 @@ test("Action setOfflineEnabled correctly sets offlineEnabled", () => { ); }); +test("Action setSaveDisabled sets saveDisabled", () => { + const previousState = { saveDisabled: false }; + const expectedState = { saveDisabled: true }; + expect(reducer(previousState, setSaveDisabled(true))).toEqual(expectedState); +}); + test("Action addProjectComponent adds component to project with correct content", () => { const previousState = { project: { diff --git a/src/web-component.js b/src/web-component.js index aa9e90281..8f49316c7 100644 --- a/src/web-component.js +++ b/src/web-component.js @@ -81,6 +81,7 @@ class WebComponent extends HTMLElement { "load_cache", "offline_enabled", "friendly_errors_enabled", + "save_disabled", ]; } @@ -101,6 +102,7 @@ class WebComponent extends HTMLElement { "load_cache", "offline_enabled", "friendly_errors_enabled", + "save_disabled", ]; const jsonAttrs = [ "instructions",