Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instructions tabs #1167

Merged
merged 19 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Added

- Autosave instructions
- Editable instructions
- Autosave instructions (#1163)
- Editable instructions (#1161)
- Ability to write to files in `python` (#1146)
- Support for the `outputPanels` attribute in the `PyodideRunner` (#1157)
- Downloading project instructions (#1160)
- Show instructions option in sidebar if instructions are editable (#1164)
- Open instructions panel by default if instructions are editable (#1164)
- Instructions empty state to show when instructions are editable (#1165, ##1168)
- Allow `instructions` attribute to override instructions attached to the project (#1169)
- Instructions empty state to show when instructions are editable (#1165, #1168)
- Allow `instructions` attribute to override instructions attached to the project (#1169)
- Instructions tabs for edit and viewing (#1167)

### Changed

Expand Down
65 changes: 56 additions & 9 deletions src/assets/stylesheets/Instructions.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
@use "../../../node_modules/@raspberrypifoundation/design-system-core/scss/components/squiggle.scss" as *;
@use "../../../node_modules/@raspberrypifoundation/design-system-core/scss/components/squiggle.scss"
as *;
@use "../../../node_modules/@raspberrypifoundation/design-system-core/scss/mixins/typography";
@use "./rpf_design_system/colours" as *;
@use "./rpf_design_system/spacing" as *;
@use './rpf_design_system/font-size' as *;
@use "./rpf_design_system/font-size" as *;
@use "./rpf_design_system/font-weight" as *;

.project-instructions {
block-size: 100%;

h2 {
@include font-size-1-25(bold);
margin: 0;
Expand Down Expand Up @@ -72,14 +76,11 @@
border-block-end: 1px solid $rpf-grey-600;
}



.line-numbers {
padding-inline-start: $space-3;
padding-inline-end: $space-1;
}


.line-numbers-rows {
border-color: $rpf-text-secondary-dark;

Expand All @@ -97,13 +98,16 @@
}

.language-python {
.number, .boolean, .function {
.number,
.boolean,
.function {
color: $rpf-syntax-1;
}
.keyword {
color: $rpf-syntax-4;
}
.string, .char {
.string,
.char {
color: $rpf-syntax-2;
}
.comment {
Expand All @@ -129,15 +133,17 @@
color: $rpf-syntax-4;
}

.property, .punctuation {
.property,
.punctuation {
color: $rpf-white;
}
}

.language-html {
.tag {
color: $rpf-syntax-4;
.punctuation, .attr-name {
.punctuation,
.attr-name {
color: $rpf-white;
}

Expand Down Expand Up @@ -269,3 +275,44 @@
margin: 0;
}
}

#app,
#wc {
.c-instruction-tabs {
display: flex;
conorriches marked this conversation as resolved.
Show resolved Hide resolved
flex-direction: column;
block-size: 100%;

.react-tabs {
border: 1px solid var(--editor-color-outline);

.react-tabs__tab-list {
border-block-end: 1px solid var(--editor-color-outline);
}
}

.react-tabs__tab {
background: var(--rpf-off-white);
padding-inline: var(--space-1-5);

&--selected {
background: var(--rpf-white);
}
}

.react-tabs__tab-panel {
.project-instructions {
padding-inline: var(--space-1);
}
}

textarea {
@include typography.style-1();

border: none;
block-size: 100%;
overflow-block: scroll;
padding: var(--space-1);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import React, { useEffect, useRef, useMemo, useState } from "react";
import SidebarPanel from "../SidebarPanel";
import { Trans, useTranslation } from "react-i18next";
import { useSelector, useDispatch } from "react-redux";
import { Tabs, TabList, Tab, TabPanel } from "react-tabs";
import { Link } from "react-router-dom";

import ProgressBar from "./ProgressBar/ProgressBar";
import "../../../../assets/stylesheets/Instructions.scss";
import "prismjs/plugins/highlight-keywords/prism-highlight-keywords.js";
Expand All @@ -13,7 +16,6 @@ import { setCurrentStepPosition } from "../../../../redux/InstructionsSlice";
import DesignSystemButton from "../../../DesignSystemButton/DesignSystemButton";
import { setProjectInstructions } from "../../../../redux/EditorSlice";
import demoInstructions from "../../../../assets/markdown/demoInstructions.md";
import { Link } from "react-router-dom";

const InstructionsPanel = () => {
const instructionsEditable = useSelector(
Expand All @@ -30,6 +32,7 @@ const InstructionsPanel = () => {
const stepContent = useRef();

const [isQuiz, setIsQuiz] = useState(false);
const [instructionsTab, setInstructionsTab] = useState(0);

const quizCompleted = useMemo(() => {
return quiz?.currentQuestion === quiz?.questionCount;
Expand Down Expand Up @@ -84,6 +87,7 @@ const InstructionsPanel = () => {
quiz,
quizCompleted,
isQuiz,
instructionsTab,
]);

useEffect(() => {
Expand Down Expand Up @@ -128,14 +132,32 @@ const InstructionsPanel = () => {
<div className="project-instructions">
{instructionsEditable ? (
hasInstructions ? (
<div>
{instructionsEditable && (
<textarea
data-testid="instructionTextarea"
value={project.instructions}
onChange={onChange}
></textarea>
)}
<div className="c-instruction-tabs">
<Tabs
onSelect={(index) => {
setInstructionsTab(index);
}}
>
<TabList>
<Tab>{t("instructionsPanel.edit")}</Tab>
<Tab>{t("instructionsPanel.view")}</Tab>
</TabList>
<TabPanel>
<textarea
data-testid="instructionTextarea"
value={project.instructions}
onChange={onChange}
></textarea>
</TabPanel>
<TabPanel>
<>
<div
className="project-instructions"
ref={stepContent}
></div>
</>
</TabPanel>
</Tabs>
</div>
) : (
<div className="project-instructions__empty">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ describe("When instructionsEditable is true", () => {
);
});

test("Renders two tab titles", () => {
expect(screen.getAllByRole("tab")).toHaveLength(2);
});

test("Renders two tab panels", () => {
expect(screen.getAllByRole("tabpanel")).toHaveLength(2);
});

conorriches marked this conversation as resolved.
Show resolved Hide resolved
test("Renders the edit panel", () => {
expect(screen.getByTestId("instructionTextarea")).toBeInTheDocument();
});
Expand Down Expand Up @@ -195,6 +203,14 @@ describe("When instructions are not editable", () => {
);
});

test("Renders no tab titles", () => {
expect(screen.queryAllByRole("tab")).toHaveLength(0);
});

test("Renders no tab panels", () => {
expect(screen.queryAllByRole("tabpanel")).toHaveLength(0);
});

test("Renders with correct instruction step content", () => {
expect(screen.queryByText("step 1")).toBeInTheDocument();
});
Expand Down
2 changes: 2 additions & 0 deletions src/utils/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ i18n
nextStep: "Next step",
previousStep: "Previous step",
projectSteps: "Project steps",
edit: "Edit",
view: "View",
},
projectsPanel: {
projects: "Projects",
Expand Down
Loading