From 1581abc5c543c2610094b6a6fa8ad6c4e1a6e32a Mon Sep 17 00:00:00 2001 From: Henrik Nygren Date: Thu, 5 Dec 2024 13:41:31 +0200 Subject: [PATCH 1/2] Update docs (#1345) * Add deployment.md * Fix database names * Update links * Specify production database * Add index.md for docs * Update testing docs * Remove table of contents from documentation index --- docs/deployment.md | 103 ++++++++++++++++++ docs/index.md | 57 ++++++++++ docs/tests.md | 236 +++++++++++++++++++++++++++++++++++------ system-tests/README.md | 121 --------------------- 4 files changed, 363 insertions(+), 154 deletions(-) create mode 100644 docs/deployment.md create mode 100644 docs/index.md delete mode 100644 system-tests/README.md diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 000000000000..90e6a0f12e4f --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,103 @@ +# Deployments + +This project is designed to run on Kubernetes, ensuring a consistent and reliable setup across all environments. For local development, we use **Minikube** and **Skaffold** to start a Kubernetes cluster locally and deploy all project services in a production-like manner. + +> [!TIP] +> +> ## TL;DR +> +> - **Automated Production Deployment**: Fully automated with GitHub Actions, Skaffold, and Minikube. +> - **Production Environment**: Deployed to Google Cloud Platform (GCP) Kubernetes. +> - **Local Testing**: Use `bin/test` to replicate the production environment locally. +> - **Run System Tests**: Use `bin/system-tests-run-tests` for end-to-end testing. This validates that the system as a whole functions correctly before deployment. + +## Production Deployment Workflow + +Our CI/CD pipeline ensures efficient and reliable deployments through three main stages: + +### 1. Build + +- Multi-stage builds are used to create: + - **Cache Images**: Captures dependencies to speed up future builds. + - **Slim Images**: Deployment-ready images with only essential components. +- Docker images and build outputs are saved for reuse during testing and deployment. + +### 2. Test + +- Images are deployed to a Minikube Kubernetes cluster using Skaffold. +- System tests, via `bin/system-tests-run-tests`, validate application behavior. +- Additional unit and integration tests are executed in the pipeline. +- Deployment is blocked if any test fails. + +### 3. Deploy + +- If all tests pass on the `master` branch: + - Docker images are pushed to a cloud container registry. + - Skaffold runs database migrations. + - Validated images are deployed to the GCP Kubernetes cluster using Skaffold and Kustomize. + +This workflow ensures every change is tested in a production-like environment before reaching live users. + +## Kustomize for Environment Management + +We use **Kustomize** to manage and customize Kubernetes manifests across environments. A shared base configuration defines most settings, while overlays adjust environment-specific configurations. This ensures consistency while keeping configurations modular. + +| Environment | Inherits From | Key Differences | +| --------------- | ------------- | --------------------------------------------------------------------------------------------------- | +| **Base** | None | Contains most configurations; other environments override specifics as needed. | +| **Development** | Base | Used in `bin/dev`; services run in development mode. | +| **Production** | Base | Used for live deployments; services run in production mode. | +| **Test** | Production | Used in `bin/test`; mirrors production but uses local resources like databases for testing locally. | + +## Skaffold and Its Integration with Kustomize + +**Skaffold** orchestrates the development and deployment workflows for Kubernetes. It is configured to use **Kustomize**, which provides environment-specific Kubernetes manifests. + +### How They Work Together: + +1. **Kustomize** defines the manifests: + - The base configuration contains shared resources. + - Overlays customize configurations for environments like development, production, and testing. +2. **Skaffold** manages the deployment pipeline: + - For development, Skaffold uses the Kustomize overlay for the `development` environment to deploy locally. + - For production, Skaffold applies the `production` overlay to deploy live services on GCP Kubernetes. + +For example: + +- **Local Development**: Skaffold applies `kubernetes/dev/kustomization.yaml` to deploy services on Minikube. +- **Production Deployment**: Skaffold applies `kubernetes/production/kustomization.yaml` to deploy services to GCP Kubernetes. + +## Ingress Configuration + +We use **Ingress** in Kubernetes to handle HTTP routing between multiple services deployed in the same cluster. Powered by the **Ingress-NGINX** controller, it routes HTTP requests based on paths, allowing all services to share a single domain. + +Examples of routing: + +- `/api` → **headless-lms** +- `/cms` → **cms** +- `/quizzes` → **quizzes** + +Routing rules are defined in `kubernetes/base/ingress.yml`. For more details, refer to the [Ingress Documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/) or the [Ingress-NGINX Documentation](https://kubernetes.github.io/ingress-nginx/). + +## Local and Production Environments + +| Feature | `bin/dev` (Development Mode) | `bin/test` (Local Prod Mode) | Production Deployment | +| ----------------------------- | -------------------------------------------- | ---------------------------------------------- | --------------------------- | +| **Environment Variables** | Development | Development, but production settings turned on | Production-secured values | +| **Database** | Local DB with seed data (`headless_lms_dev`) | Local DB with seed data (`headless_lms_test`) | Cloud SQL for PostgreSQL | +| **Build Process** | Compiled in development mode | Compiled in production mode | Compiled in production mode | +| **Deployment Tool** | Skaffold | Skaffold | Skaffold | +| **Kubernetes Cluster** | Minikube | Minikube | GCP Kubernetes | +| **Domain** | `project-331.local` | `project-331.local` | `courses.mooc.fi` | +| **Deployments Configuration** | `skaffold.yml` | `skaffold.production.yml` | `skaffold.production.yml` | + +**`bin/dev`** is optimized for rapid iteration with live reloading. **`bin/test`** closely mirrors production, enabling a production-like system to be tested on any machine. The production deployment process is similar to `bin/test`, but it uses live infrastructure. + +## Useful Links + +- [Skaffold Documentation](https://skaffold.dev/docs/) +- [Kubernetes Documentation](https://kubernetes.io/docs/) +- [Kustomize Documentation](https://kustomize.io/) +- [Kubernetes Ingress Documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/) +- [Ingress-NGINX Documentation](https://kubernetes.github.io/ingress-nginx/) +- [Google Cloud Kubernetes Engine](https://cloud.google.com/kubernetes-engine) diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000000..e08c44831fbd --- /dev/null +++ b/docs/index.md @@ -0,0 +1,57 @@ +# Secret Project 331 Documentation Index + +## 📌 Introduction + +**Secret Project 331** is a Learning Management System (LMS) developed by the MOOC Center of the University of Helsinki. It's deployed at [https://courses.mooc.fi](https://courses.mooc.fi). This documentation is intended for developers and provides technical insights, setup instructions, and detailed guides to facilitate development and contribution. + +For non-developers: + +- **Learn more about the courses**: [https://www.mooc.fi](https://www.mooc.fi) +- **Teacher Documentation**: Refer to the **Wiki** tab in this repository. + +## 🚀 Getting Started + +- Set up local environment: [Development Environment Setup](./Development.md) +- Configure VDI: [VDI Setup for MOOC Center Employees](./vdi-setup.md) + +## 🏛 Architecture + +- System architecture overview: [Project Architecture](./architecture.md) + +## 💻 Development Guides + +- Interact with backend, shared modules: [Frontend Development](./frontend.md) +- Database interactions, migrations: [Backend Development](./headless-lms.md) +- Extend LMS with new exercises: [Plugin System](./plugin-system.md) +- Implement responsive designs: [Mobile-First CSS](./mobile-first-css.md) +- Support multiple languages: [Internationalization](./internationalization.md) +- Develop new blocks for CMS and course material: [Blocks Development](./blocks.md) + +## 📦 Deployment + +- Deployment process and CI/CD: [Deployment Workflow](./deployment.md) +- Test/manage Dockerfile changes: [Testing Changes to Dockerfiles](./updating-dockerfiles.md) + +## 🗄 Database Operations + +- Perform database operations: [DataGrip Operations](./datagrip-operations.md) + +## 🗂 Version Control + +- Enhance Git workflow: [GIT Notes](./git.md) + +## 🧪 Testing + +- Write and execute tests: [Testing](./tests.md) + +## 🔄 Updating Dependencies + +- [Updating Dependencies Guide](./updating-dependencies.md) + +## 📚 Additional Documentation + +- Additional notes: [Miscellaneous Notes](./etc.md) + +## 📞 Support and Contributions + +- **Project Repository**: [GitHub Repository](https://github.com/rage/secret-project-331) diff --git a/docs/tests.md b/docs/tests.md index 435c665f04e0..abcb2fcaa618 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -1,59 +1,229 @@ -# Tests +# Testing Guide -## Filling form fields, checkboxes and radio buttons +## Introduction -A good way to fill a text field with the label "Name" is +Learn about different types of software testing by visiting [Levels of Software Testing](https://artoftesting.com/levels-of-software-testing). -```js -await page.fill('input[label="First name"]', "User") +### Focus on System-Level Testing + +We focus mainly on **system-level testing** to make sure the entire application works as expected. We also write **unit tests** in cases where: + +- They won't break easily due to changes in how the code is implemented. +- We need to make sure we handle all possible edge cases correctly + +## Running System Tests + +### Setting Up the Test Environment + +To start the test environment, run the following commands in the project root: + +```bash +bin/test +``` + +### Running Tests + +To run all system tests, use: + +```bash +bin/system-tests-run-tests +``` + +For debugging, run: + +```bash +bin/system-tests-debug +``` + +When debugging, add `test.only` to the test you want to focus on. This will run only that test. Remember to remove `test.only` once debugging is complete. + +#### Example of `test.only` + +If you want to debug a specific test, you can add `.only` to its definition. This ensures only that test runs, skipping all others: + +```javascript +test.only("debugging a specific test", async ({ page }) => { + // Test implementation +}) +``` + +After debugging, **remove the `.only`** so all tests run as usual. + +Tests are located in the `system-tests/src/tests/` folder. + +### Available Commands + +Here are the commands you can use to run and manage system tests: + +- **`bin/system-tests-debug`** — Debug tests step by step. +- **`bin/system-tests-record-test-admin`** — Record a test as an admin user. +- **`bin/system-tests-record-test-teacher`** — Record a test as a teacher user. +- **`bin/system-tests-record-test-user`** — Record a test as a regular user. +- **`bin/system-tests-record-test-without-resetting-db`** — Record a test without resetting the database. +- **`bin/system-tests-run-tests`** — Run all tests. +- **`bin/system-tests-update-snapshots`** — Update image snapshots. +- **`bin/system-tests-run-tests-record-video`** — Run tests and save a video of the process (in `system-tests/test-results`). +- **`bin/system-tests-run-tests-slowmo`** — Run tests in slow motion with the browser visible. + +> **Tip:** These `bin/xxx` commands are not magic commands. They show the exact shell commands they run. Take a moment to look at the output to understand what they're doing. Often they also print custom messages that help you to resolve the problems you're having. + +## Writing System Tests + +### Recording New Tests + +To create a new test: + +1. Use one of the recording commands listed above. +2. Create a new file in `system-tests/src/tests/`, such as `example.spec.ts`. +3. Copy the recorded test code into this file. +4. Add assertions to verify the expected outcomes. +5. Edit the generated test as described below. + +### Editing Recorded Tests + +Always update recorded tests to make them more reliable. Key changes include: + +- **Use Helper Functions:** Replace repetitive steps with helper functions (e.g., `selectCourseInstanceIfPrompted`). +- **Improve Locators:** Replace unstable locators (like autogenerated CSS classes) with stable ones. See [Playwright Locators](https://playwright.dev/docs/locators) for tips. +- **Create New Helper Functions:** If you find a repeated pattern that's tricky to get right, write a helper function for it. + +### Helper Functions + +Here are some helpful functions available in the codebase: + +- **`getLocatorForNthExerciseServiceIframe`**: Helps interact with or capture screenshots of exercise service iframes. [See an example](https://github.com/rage/secret-project-331/blob/11f8dc9ff998277618eb77f4f0d2830da9e6344a/system-tests/src/tests/quizzes/feedback/multiple-choice.spec.ts#L41-L57). +- **`selectCourseInstanceIfPrompted`**: Selects a course instance when prompted. Always use this instead of writing custom code for the dialog. +- **`showNextToastsInfinitely` / `showToastsNormally`**: Keeps toast notifications visible for screenshots. Use `showNextToastsInfinitely` before triggering the notification and `showToastsNormally` afterward. + +### Example Tests + +- **Basic Example:** [login.spec.ts](src/tests/login/login.spec.ts) +- **Screenshot Comparison:** [mediaUpload.spec.ts](src/tests/cms/mediaUpload.spec.ts) + +## Screenshots / Visual Snapshots + +We use screenshots to track UI changes over time. The `expectScreenshotsToMatchSnapshots` function helps with this by: + +- Waiting for content to load and stabilize. +- Taking screenshots at different screen sizes. +- Storing images in version control for future comparison. +- Failing the test if the new image doesn't match the old one. +- Running accessibility checks. + +### Updating Snapshots + +If your UI changes, update snapshots using: + +```bash +bin/system-tests-update-snapshots ``` -Checking a checkbox or radio button with the label "Draft" can be done in a similar manner +Then, commit the updated snapshots. If you accidentally overwrite snapshots, restore them with: -```js -await page.check("input[label=Draft]") +```bash +bin/git-restore-screenshots-from-origin-master +``` + +### Example Usage of `expectScreenshotsToMatchSnapshots` + +```javascript +test("test with screenshots", async ({ headless, page }, testInfo) => { + await expectScreenshotsToMatchSnapshots({ + page, + testInfo, + headless, + snapshotName: "example-snapshot", // Unique name for the snapshot + waitForThisToBeVisibleAndStable: page.getByText("Welcome to the course"), // Element to wait for + }) +}) ``` -## Skipping accessibility in tests / Guide to axeSkip +## Tracing Test Results + +To analyze test results: + +1. Enable tracing so that a `trace.zip` file is generated. +2. View the trace using: + +```bash +npx playwright view-trace test-results/path_to/trace.zip +``` + +This will open a detailed view of each test step. + +## Debugging Tests + +### Method 1: Using Debug Mode + +Run `bin/system-tests-debug` and add `test.only` to focus on specific tests. A browser and debugger window will open, allowing you to step through the test and adjust locators. + +### Method 2: Playwright for VSCode -Skipping accessibility violations is done by axeSkip, below we have some instructions. +Use the [Playwright for VSCode](https://github.com/microsoft/playwright-vscode) extension. It should already be installed as part of the project workspace. Refer to its documentation for setup instructions. -You can obtain the ID for the rule from browser by pressing 'more info' and then in the top left corner there is 'Rule ID'. Below there's also example of the violation in console, in console it is just "id" +## Filling Form Fields, Checkboxes, and Radio Buttons -![More info-button location showed](./img/example1.png) +Use label-based locators for clear and reliable interactions. -axeSkip is given to the expectScreenshotsMatchSnapshots function +### Filling Text Fields -```js +To fill a text field with the label "First name": + +```javascript +await page.getByLabel("First name").fill("User") +``` + +### Checking Checkboxes and Radio Buttons + +To check a checkbox or radio button labeled "Draft": + +```javascript +await page.getByLabel("Draft").check() +``` + +## Skipping Accessibility Violations in Tests + +### Using `axeSkip` + +If you need to skip a known accessibility violation: + +1. Get the **Rule ID**: + + - In the browser, click **More Info** on the violation to see the Rule ID. + - Alternatively, find the ID in the console output. + +2. Add the Rule ID to `axeSkip`: + +```javascript await expectScreenshotsToMatchSnapshots({ - axeSkip: ["aria-hidden-focus"], + axeSkip: ["landmark-one-main"], // Replace with the relevant Rule ID(s) page, headless, - snapshotName: "search-continuous-phrases-ranked-higher-than-word-matches", - waitForThisToBeVisibleAndStable: "text=banana cat enim", + snapshotName: "example-snapshot", + waitForThisToBeVisibleAndStable: page.getByText("Example Text"), }) ``` -For example if you get the following violation +## Unit Tests -```js -Violation 1 ------------ - Rule: landmark-one-main - Description: Ensures the document has a main landmark - Impact: moderate - Help: Document should have one main landmark - Help URL: https://dequeuniversity.com/rules/axe/4.3/landmark-one-main?application=playwright - Affected DOM nodes:{ - ... - } +### Where to Find Unit Tests -``` +Unit tests are located in each service's directory. -You can skip it with this +### Running Unit Tests + +- **For JavaScript/Node.js Services:** + +Navigate to the service directory and run: + +```bash +npm run test +``` -```js +- **For the Backend (Rust):** -axeSkip: ["landmark-one-main"], +From the project root, run: +```bash +bin/cargo-test ``` diff --git a/system-tests/README.md b/system-tests/README.md deleted file mode 100644 index 59b56c5f67d6..000000000000 --- a/system-tests/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# System tests - -In project root execute `bin/test` to start test environment.
-Run test suites with command `npm run test` or `npm run test-debug` for debugging tests.
-Tests can be found in `src/tests/`. - -## Running tests - -Start test environment from project root with `bin/test`. - -The tests can be ran using the following command in the `system-tests` folder: - -```sh -npm run test -``` - -Also, following alternatives are available: - -```sh -npm run test-nohtml # runs tests without the html report -npm run test-headed # runs tests with with a visible browser -npm run test-slowmo # runs tests in slow motion -npm run test-video # runs tests and records a video to `system-tests/test-results` -npm run test-debug # For debugging a test https://playwright.dev/docs/debug#run-in-debug-mode -npm run test-ui # opens the playwright ui -npm run open # opens playwright without running tests -``` - -## Writing tests - -Record new tests with Playwright by changing directory, `cd system-tests`, and run `npm run create-login-states`.
-To start recording, run one of the following: - -- `npm run record-test` — Record without login state -- `npm run record-test-admin` — Record as admin -- `npm run record-test-teacher` — Record as teacher -- `npm run record-test-user` — Record as user - -Create a new test file somewhere in `src/tests/` named e.g. `foo.spec.ts`.
-Once you've recorded, copy the code automatically written by the recorder to your newly created test file and manually insert assertions where necessary. - -## Running tests from the repo root - -The following commands are avaialle for running the tests directly from the repo root: - -- `bin/system-tests-debug` — Running tests with a debugger that can be used to step through the code -- `bin/system-tests-record-test-admin` — Record a test as admin -- `bin/system-tests-record-test-teacher` — Record a test as teacher -- `bin/system-tests-record-test-user` — Record a test as user -- `bin/system-tests-record-test-without-resetting-db` — Record a test without resetting the database -- `bin/system-tests-run-tests` — Run tests -- `bin/system-tests-update-snapshots` — Update image snapshots -- `bin/system-tests-run-tests-record-video` — Run tests and record a video of the test run that is saved to `system-tests/test-results` -- `bin/system-tests-run-tests-slowmo` — Run tests with the browser visible in slow motion - -## Helper functions - -- getLocatorForNthExerciseServiceIframe - Locator for either interacting with an exercise service iframe or for taking a screenshot of the iframe. See [example](https://github.com/rage/secret-project-331/blob/11f8dc9ff998277618eb77f4f0d2830da9e6344a/system-tests/src/tests/quizzes/feedback/multiple-choice.spec.ts#L41-L57). -- selectCourseInstanceIfPrompted - Selects course instance in course material if the prompt appears. Useful if there are many tests that access the same course using the same user because every user gets the dialog only the first time they access the course. Always select the course instance using this funciton instead of writing custom code to interact with the dialog. -- showNextToastsInfinitely / showToastsNormally - - Sometimes we want to take a screenshot that has a toast notfication. However, this causes a race condition because by default toasts disappear automatically. To avoid this, one can call `showToastInfinetly` before clicking the thing that causes the notification to appear and then call `showToastsNormally` afterwar the screenshot has been taken. - -### Example tests - -- [login.spec.ts](src/tests/login/login.spec.ts) — Basic examples -- [mediaUpload.spec.ts](src/tests/cms/mediaUpload.spec.ts) — Screenshot comparison example - -### Screenshots / Visual snapshots - -For all UI parts of the application it is important to take screenshots in the tests so that we can track how the application looks like. We have a custom function `expectScreenshotsToMatchSnapshots` for taking these, which does the following: - -- Waits for the desired content to appear and waits it to stop moving in case the view has animations. -- Takes a screenshot of the current page in multiple screen sizes -- Records the taken image to version control so that we can make comparisons to the images in the future and so that it's easy to look at the UI changes during code review. -- Compares the taken image to a previously taken image and fails the test if they don't match -- Runs accessibility checks on the page being screenshotted - -If you have changed how the UI looks like, you can update the image snapshots with `npm run update-snapshots` and commit these to Git. If you accidentally overwrite some snapshots that you didn't intend to change in your branch, please revert the changes with the script `bin/git-restore-screenshots-from-origin-master` from the repo root. - -Example usage of `expectScreenshotsToMatchSnapshots`: - -```js -test("test with screenshots", async ({ headless, page }, testInfo) => { - // navigate somewhere, do actions until we want to take a screenshot - await expectScreenshotsToMatchSnapshots({ - screenshotTarget: page, - testInfo - headless, - // a unique name for the image - snapshotName: "model-solutions-in-submissions", - // an array of locators - // that need to be visible and not moving before taking the screenshot - // it is important to choose this carefully, because otherwise we might take the screenshot - // before the UI is ready for it - waitForTheseToBeVisibleAndStable: [page.getByText("Welcome to the course")], - }) - -} -``` - -### Tracing test results - -In order to trace the test results, run the `npm run view-trace` with the `trace.zip` file as a parameter - -```sh -npm run view-trace test-results/path_to/trace.zip -``` - -This should open a window where you can see each step of test. - -### Debugging tests / selectors - -The recommended way to debug tests is to use the [playwright-vscode](https://github.com/microsoft/playwright-vscode) extension. It should be already installed since it's a recommended extension in the project's workspace. See the extension's README for more information. - -Alternatives: `npm run test-debug` or `npm run open`. - -## Useful links - -- [Playwright](https://playwright.dev/docs/intro/) -- [Playwright test runner](https://playwright.dev/docs/test-intro) From 10b199c46e16220492840fd70f4edb2d0f3bffad Mon Sep 17 00:00:00 2001 From: Henrik Nygren Date: Mon, 9 Dec 2024 13:01:36 +0200 Subject: [PATCH 2/2] Table and footer fixes (#1349) * Update footer translations * Fix blocks overflowing the exercise block --- .../core/embeds/EmbedBlock.tsx | 27 +-------- .../embeds/variants/ThingLinkEmbedBlock.tsx | 6 +- .../core/embeds/variants/VimeoEmbedBlock.tsx | 9 +-- .../embeds/variants/YoutubeEmbedBlock.tsx | 3 +- .../core/formatting/CodeBlock/index.tsx | 2 +- .../src/components/ContentRenderer/index.tsx | 53 +++++++++++------- .../ContentRenderer/moocfi/IframeBlock.tsx | 2 +- .../RevealableContentBlock.tsx | 2 +- .../Centering/BreakFromCentered.tsx | 32 +++++++++-- .../common/src/locales/uk/shared-module.json | 4 +- .../essay-feedback-desktop-regular.png | Bin 139356 -> 139343 bytes .../essay-feedback-mobile-tall.png | Bin 85993 -> 85981 bytes 12 files changed, 73 insertions(+), 67 deletions(-) diff --git a/services/course-material/src/components/ContentRenderer/core/embeds/EmbedBlock.tsx b/services/course-material/src/components/ContentRenderer/core/embeds/EmbedBlock.tsx index c0b0956fb683..f5f8ae1ab1d6 100644 --- a/services/course-material/src/components/ContentRenderer/core/embeds/EmbedBlock.tsx +++ b/services/course-material/src/components/ContentRenderer/core/embeds/EmbedBlock.tsx @@ -20,33 +20,12 @@ const EmbedBlock: React.FC - {type === "youtube" && ( - - )} + {type === "youtube" && } {type === "twitter" && } {type === "spotify" && } - {type === "vimeo" && ( - - )} + {type === "vimeo" && } {type === "mentimeter" && } - {type === "thinglink" && ( - - )} + {type === "thinglink" && } ) } diff --git a/services/course-material/src/components/ContentRenderer/core/embeds/variants/ThingLinkEmbedBlock.tsx b/services/course-material/src/components/ContentRenderer/core/embeds/variants/ThingLinkEmbedBlock.tsx index 059a0fbb6396..ddd5b4274b45 100644 --- a/services/course-material/src/components/ContentRenderer/core/embeds/variants/ThingLinkEmbedBlock.tsx +++ b/services/course-material/src/components/ContentRenderer/core/embeds/variants/ThingLinkEmbedBlock.tsx @@ -8,11 +8,9 @@ import { baseTheme } from "@/shared-module/common/styles/theme" const THINGLINK = "thinglink" -export const ThingLinkEmbedBlock: React.FC< - React.PropsWithChildren -> = (props) => { +export const ThingLinkEmbedBlock: React.FC> = (props) => { return ( - +
+ React.PropsWithChildren > = (props) => { const [embedHtml, setEmbedHtml] = useState(undefined) const [fetching, setFetching] = useState(true) @@ -45,10 +43,7 @@ export const VimeoEmbedBlock: React.FC< <> {fetching && } {embedHtml && !fetching && ( - +
& { - dontAllowBlockToBeWiderThanContainerWidth: boolean className?: string } > = (props) => { @@ -32,7 +31,7 @@ export const YoutubeEmbedBlock: React.FC< } return ( - +
+
> =
   )
 
   if (props.dontAddWrapperDivMeantForMostOutermostContentRenderer) {
-    return content
+    return (
+      
+        {content}
+      
+    )
   }
   return (
-    
- {content} -
+
+ {content} +
+ ) } diff --git a/services/course-material/src/components/ContentRenderer/moocfi/IframeBlock.tsx b/services/course-material/src/components/ContentRenderer/moocfi/IframeBlock.tsx index caec6544d28a..efe8534bd380 100644 --- a/services/course-material/src/components/ContentRenderer/moocfi/IframeBlock.tsx +++ b/services/course-material/src/components/ContentRenderer/moocfi/IframeBlock.tsx @@ -20,7 +20,7 @@ export const IframeBlock: React.FC> = (prop const { heightPx, widthPx } = props.data.attributes return ( - +
+
(false) + export type BreakFromCenteredProps = NoSidebar | WithSidebar +/** + * BreakFromCentered component allows content to extend beyond the centered container. + * + * In our layout, content is wrapped in a container with a constrained width and centered using auto margins. + * This ensures that most content is neatly centered. However, there are cases where you need elements + * that span the full width of the browser window, exceeding the container's width. + * + * Use BreakFromCentered to achieve this full-width effect. When using this component, you are responsible + * for handling the centering of the content within it. + * + * **Props:** + * - `sidebar`: Determines if a sidebar is present. + * - When `true`, additional props like `sidebarPosition`, `sidebarWidth`, and `sidebarThreshold` are required. + * + * You can disable the BreakFromCentered behavior by using the `BreakFromCenteredDisabledContext` in a parent component. + * + * @param props - The properties for configuring the BreakFromCentered component. + * @returns A React component that allows content to break out of the centered container. + */ const BreakFromCentered: React.FC< React.PropsWithChildren> > = (props) => { - if (props.disabled) { + const disabled = useContext(BreakFromCenteredDisabledContext) + if (disabled) { return <>{props.children} } // 100vw unfortunately does not take into account the scrollbar width, so we need to calculate its width and substract it from the width of the page diff --git a/shared-module/packages/common/src/locales/uk/shared-module.json b/shared-module/packages/common/src/locales/uk/shared-module.json index 059b752140fa..dc827ee13b3b 100644 --- a/shared-module/packages/common/src/locales/uk/shared-module.json +++ b/shared-module/packages/common/src/locales/uk/shared-module.json @@ -1,9 +1,9 @@ { "about": "Про", "about-mooc-center": "Про центр MOOC", - "about-mooc-center-description": "Цей веб-сайт працює на основі програмного забезпечення з відкритим вихідним кодом, розробленого Центром MOOC Гельсінського університету. Позначити проект зірочкою на GitHub:", + "about-mooc-center-description": "Центр MOOC Університету Гельсінкі робить можливим високоякісну онлайн-освіту, розробляючи та досліджуючи освітнє програмне забезпечення та онлайн-навчальні матеріали. Викладачі Гельсінського університету та поза ним покладаються на наші інструменти для створення ефективних навчальних матеріалів. Наші популярні масові відкриті онлайн-курси (MOOC) доступні через MOOC.fi з 2012 року.", "about-this-project": "Про цей проект,", - "about-this-project-description": "Цей веб-сайт працює на основі програмного забезпечення з відкритим вихідним кодом, розробленого Центром MOOC Гельсінського університету.", + "about-this-project-description": "Цей веб-сайт працює на основі програмного забезпечення з відкритим вихідним кодом, розробленого Центром MOOC Гельсінського університету. Позначити проект зірочкою на GitHub:", "accessibility": "Доступність", "added-text": "Доданий текст", "available": "В наявності", diff --git a/system-tests/src/__screenshots__/quizzes/feedback/essay.spec.ts/essay-feedback-desktop-regular.png b/system-tests/src/__screenshots__/quizzes/feedback/essay.spec.ts/essay-feedback-desktop-regular.png index a743e39613407a10f68916670f22e3179fe15a8e..550f5cee5e206b045addf76072ace1f887af4745 100644 GIT binary patch delta 52 zcmca}faClDj)oS-ElipUYJ!Q0iAlNn`N?USx&?{psk)WAW~PSwSIynb00f?{elF{r G5}E)2@e*AC delta 65 zcmX?qfaA^qj)oS-ElipU#&U^?iAlNn`N?USx&?{psk)WA(fLVPsmUb@0Y&+_nZ>EG TlT?2nV*mnAS3j3^P6