{"id":20037826,"url":"https://github.com/openedx/studio-frontend","last_synced_at":"2025-05-05T06:31:36.084Z","repository":{"id":37887153,"uuid":"101433192","full_name":"openedx/studio-frontend","owner":"openedx","description":"📝 React front end for edX Studio","archived":false,"fork":false,"pushed_at":"2025-03-25T17:38:49.000Z","size":5066,"stargazers_count":33,"open_issues_count":27,"forks_count":35,"subscribers_count":69,"default_branch":"master","last_synced_at":"2025-04-15T10:19:39.546Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openedx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-25T18:50:55.000Z","updated_at":"2025-03-25T17:38:52.000Z","dependencies_parsed_at":"2024-05-16T04:57:06.451Z","dependency_job_id":"de9aa1a7-61ec-41c0-86d8-3089035451b3","html_url":"https://github.com/openedx/studio-frontend","commit_stats":null,"previous_names":["edx/studio-frontend"],"tags_count":127,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Fstudio-frontend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Fstudio-frontend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Fstudio-frontend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Fstudio-frontend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openedx","download_url":"https://codeload.github.com/openedx/studio-frontend/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252451527,"owners_count":21749950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T10:22:58.032Z","updated_at":"2025-05-05T06:31:35.650Z","avatar_url":"https://github.com/openedx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# studio-frontend\n[![codecov](https://codecov.io/gh/edx/studio-frontend/branch/master/graph/badge.svg)](https://codecov.io/gh/edx/studio-frontend)\n[![Build Status](https://travis-ci.com/edx/studio-frontend.svg?branch=master)](https://travis-ci.com/edx/studio-frontend)\n[![npm](https://img.shields.io/npm/v/@edx/studio-frontend.svg)](https://www.npmjs.com/package/@edx/studio-frontend)\n[![npm](https://img.shields.io/npm/dt/@edx/studio-frontend.svg)](https://www.npmjs.com/package/@edx/studio-frontend)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n\n## This repo is in the process of being deprecated [[DEPR]: studio-frontend repo](https://github.com/openedx/studio-frontend/issues/381)\nAll code changes should be made in the [course-authoring repo](https://github.com/openedx/studio-frontend).\n\nReact front end for edX Studio\n\nFor an introduction to what this repo is and how it fits into the rest of the\nedX platform, read [Studio-frontend: Developing Frontend Separate from edX\nPlatform](https://engineering.edx.org/studio-frontend-developing-frontend-separate-from-edx-platform-7c91d76c7360).\n\n## Development\n\nRequirements:\n* [Docker 17.06 CE+](https://docs.docker.com/engine/installation/), which should come with [docker-compose](https://docs.docker.com/compose/install/) built in.\n* A working, running [edX devstack](https://github.com/openedx/devstack)\n\nTo install and run locally:\n```\n$ git clone git@github.com:edx/studio-frontend.git\n$ cd studio-frontend\n$ make up\n```\nYou can append ```-detached``` to the ```make up``` command to run Docker in the background.\n\nTo install a new node package in the repo (assumes container is running):\n```\n$ make shell\n$ npm install \u003cpackage\u003e --save-dev\n$ exit\n$ git add package.json\n```\nTo make changes to the Docker image locally, modify the Dockerfile as needed and run:\n```\n$ docker build -t edxops/studio-frontend:latest .\n```\n\nWebpack will serve pages in development mode at http://localhost:18011.\n\nThe following pages are served in the development:\n\n| Page                 | URL                                              |\n|----------------------|--------------------------------------------------|\n| Assets               | http://localhost:18011/assets.html               |\n| Accessibility Policy | http://localhost:18011/accessibilityPolicy.html  |\n| Edit Image Modal     | http://localhost:18011/editImageModal.html       |\n\nNotes:\n\nThe development server will run regardless of whether devstack is running along side it. If devstack is not running, requests to the studio API will fail. You can start up the devstack at any time by following the instructions in the devstack repository, and the development server will then be able to communicate with the studio container. API requests will return the following statuses, given your current setup:\n\n| Studio Running? | Logged in?             | API return |\n|-----------------|------------------------|------------|\n| No              | n/a                    | 504        |\n| Yes             | No                     | 404        |\n| Yes             | Yes, non-staff account | 403        |\n| Yes             | Yes, staff account     | 200        |\n\n## Development Inside Devstack Studio\n\nTo load studio-frontend components from the webpack-dev-server inside your\nstudio instance running in [Devstack](https://github.com/openedx/devstack):\n\n1. In your devstack edx-platform folder, create `cms/envs/private.py` if it\n   does not exist already.\n2. Add `STUDIO_FRONTEND_CONTAINER_URL = 'http://localhost:18011'` to\n   `cms/envs/private.py`.\n3. Restart your Studio container: `make cms-restart-container`.\n\nPages in Studio that have studio-frontend components should now request assets\nfrom your studio-frontend docker container's webpack-dev-server. If you make a\nchange to a file that webpack is watching, the Studio page should hot-reload or\nauto-reload to reflect the changes.\n\n## Testing the Production Build Inside Devstack Studio\n\nThe Webpack development build of studio-frontend is optimized for speeding up\ndevelopement, but sometimes it is necessary to make sure that the production\nbuild works just like the development build. This is especially important when\nmaking changes to the Webpack configs.\n\nSandboxes use the production webpack build (see section below), but they also\ntake a long time to provision. You can more quickly test the production build in\nyour local docker devstack by following these steps:\n\n1. If you have a `cms/envs/private.py` file in your devstack edx-platform\n   folder, then make sure the line `STUDIO_FRONTEND_CONTAINER_URL =\n   'http://localhost:18011'` is commented out.\n2. Reload your Studio server: `make cms-restart-container`.\n3. Run the production build of studio-frontend by running `make shell` and then\n   `npm run build` inside the docker container.\n4. Copy the production files over to your devstack Studio's static assets\n   folder by running this make command on your host machine in the\n   studio-frontend folder: `make copy-dist`.\n5. Run Studio's static asset pipeline: `make cms-static`.\n\nYour devstack Studio should now be using the production studio-frontend files\nbuilt by your local checkout.\n\n## Testing in studio-frontend\n\n### Where do test files go?\nIf you are developing a component and you are adding new `js` or `jsx` test files,\nthe test files would go in the same location as the file. This makes it easier\nto track and test. For example, if you are developing a component `AssetsSearch`\nin `src/components/` you would name the test file after the component name\n`AssetsSearch.test.jsx`. Similarly, if you are adding a file\n`parseDateTime.jsx` in the `src/utils/` place the test file at same location with\nthe name `parseDateTime.test.jsx`.\n\n### How to run tests locally\nTo run the whole suite of tests, you can run `npm run test` inside the docker container shell.\n```\nmake shell\nnpm run test\n```\nIf you want to run a particular test file only, you can run `npm run test -t \u003cpath\u003e`.\nYou can also add `\".only\"` to any `\"it\"` or `\"describe\"` block in a particular test\nfile to only run that particular test. For example, `it.only` to run only that test\nor `describe.only` to run only the tests in that describe block.\n\n### How to debug locally running tests\nTo debug tests running locally, first open the Node debugger:\n\n1) navigate to `chrome://inspect` in your browser\n2) choose \"Open dedicated DevTools for Node\" (it will open in a new window)\n3) check that the default network configuration in the \"Connection\" tab is `127.0.0.1:9229` (i.e. port `9229` on `localhost`)\n\nNext, after adding a `debugger;` statement above the test code you'd like to debug, use these commands inside the `studio-frontend` repo:\n```\nmake shell\nnode --inspect=0.0.0.0 node_modules/.bin/jest --runInBand\n```\nThe node debugger should grab focus as soon as your first breakpoint is hit. You can specify individual test files by appending `-- path/to/yourTestFile.test.jsx` to the end of the `node` command.\n\n## Testing a Branch on a Sandbox\n\nIt is a good practice to test out any major changes to studio-frontend in a\nsandbox since it is much closer to a production environment than devstack. Once\nyou have a branch of studio-frontend up for review:\n\n1. Create a new branch in edx-platform off master.\n2. Edit the `package.json` in that branch so that it will install\n   studio-frontend from your branch in review:\n\n    ```json\n    \"@edx/studio-frontend\": \"edx/studio-frontend#your-branch-name\",\n    ```\n\n3. Commit the change and push your edx-platform branch.\n4. Follow [this document on provisioning a\n   sandbox](https://openedx.atlassian.net/wiki/spaces/EdxOps/pages/13960183/Sandboxes)\n   using your edx-platform branch.\n\nThe sandbox should automatically pull the studio-frontend branch, run the\nproduction webpack build, and then install the dist files into its static assets\nduring provisioning.\n\n## Releases\n\nThis all happens automagically on merges to master, hooray! There are just a few things to keep in mind:\n\n### What is the latest version?\n\nCheck [github](https://github.com/openedx/studio-frontend/releases), [npm](https://www.npmjs.com/package/@edx/studio-frontend), or the npm badge at [the top of this README](https://github.com/openedx/studio-frontend#studio-frontend). `package.json` no longer contains the correct version (on Github), as it creates an odd loop of \"something merged to master, run `semantic-release`\" -\u003e \"`semantic-release` modified `package.json`, better check that in and make a PR\" -\u003e \"a PR merged to master, run `semantic-release`\", etc. This is the [default behavior for `semantic-release`](https://github.com/semantic-release/semantic-release/blob/caribou/docs/support/FAQ.md#why-is-the-packagejsons-version-not-updated-in-my-repository).\n\n### Commit message linting\n\nIn order for `semantic-release` to determine which release type (major/minor/patch) to make, commits must be formatted as specified by [these Angular conventions](https://github.com/angular/angular.js/blob/62e2ec18e65f15db4f52bb9f695a92799c58b5f1/DEVELOPERS.md#-git-commit-guidelines). TravisBuddy will let you know if anything is wrong before you merge your PR. It can be difficult at first, but eventually you get used to it and the added value of automatic releases is well worth it, in our opinions.\n\n#### A note on merge messages\n\nNote that when you merge a PR to master (using a merge commit; we've disabled squash-n-merge), there are actually *2* commits that land on the master branch. The first is the one contained in your PR, which has been linted already. The other is the merge commit, which commitlint is smart enough to ignore due to [these regexes](https://github.com/marionebl/commitlint/blob/ddb470c4d45ccf6e2d5a82ce911b96594ccffb59/%40commitlint/is-ignored/src/index.js). The point here is that you should not change the default `Merge pull request \u003cnumber\u003e from \u003cbranch\u003e` message on your merge commit, or else the master build will fail and we won't get a deploy.\n\n## Updating Latest Docker Image in Docker Hub\n\nIf you are making changes to the Dockerfile or docker-compose.yml you may want to include them in the default docker container.\n\n1. Run `make from-scratch`\n2. Run `docker tag edxops/studio-frontend:latest edxops/studio-frontend:latest`\n3. Run `docker push edxops/studio-frontend:latest`\n4. Check that \"Last Updated\" was updated here: https://hub.docker.com/r/edxops/studio-frontend/tags/\n\n## Adding a new app\n\nThere's a bunch of boilerplate that needs to be created to set up a new\nstudio-frontend app that can be independently embedded into a page in Studio.\nSee the\n[openedx-workshop](https://github.com/openedx/studio-frontend/compare/openedx-workshop)\nbranch, which demonstrates setting up a very basic HelloWorld app.\n\n* Create a [new webpack\n  entry](https://github.com/openedx/studio-frontend/compare/openedx-workshop#diff-56ee2db4e3db0c7354bb996b003e70beR12)\n* Add a [new\n  HtmlWebpackPlugin](https://github.com/openedx/studio-frontend/compare/openedx-workshop#diff-d5d0cff71a84339db815178b7a3c23fcR95)\n  to create a new page in the development server to display the component.\n* Create a [new app root index\n  file](https://github.com/openedx/studio-frontend/compare/openedx-workshop#diff-78a72e926d58cefa762dc661a8745f68R1)\n  which will initialize the app.\n* For any new components that the app will use, create a new folder under\n  `src/components/` with an upper camel case name.\n    * For each component, create [an\n      index.jsx](https://github.com/openedx/studio-frontend/compare/openedx-workshop#diff-7fea6fccbbbbf8e8648b63713da96714R1)\n      to render the component.\n    * A [test\n      file](https://github.com/openedx/studio-frontend/compare/openedx-workshop#diff-4cd7210c4c2b6f2c3b6b2a0c1b67b2e5R1)\n      named with a `.test.jsx` extension that uses Jest and Enzyme to unit test\n      the component.\n    * If the component contains any display strings, a\n      [displayMessages.jsx](https://github.com/openedx/studio-frontend/compare/openedx-workshop#diff-e214e9bb31c5529b699ebb2e86be2cbfR1)\n      file.\n    * If the component needs any styling, a\n      [`.scss`](https://github.com/openedx/studio-frontend/compare/openedx-workshop#diff-5ce63f6d51132465b6b5d8980cc3dfc8R1)\n      file.\n* To embed the app inside Studio:\n    * Update the [version of\n      studio-frontend](https://github.com/openedx/edx-platform/blob/master/package.json)\n      in edx-platform.\n    * Include the component's built CSS and JS in a template using the\n      [`studiofrontend` Mako template\n      tag](https://github.com/openedx/edx-platform/compare/openedx-workshop-sfe).\n\n## CSS\n\nCSS in studio-frontend is a bit tricky. Because components are embedded in\nexisting Studio pages, we have to [isolate the\nCSS](https://engineering.edx.org/studio-frontend-developing-frontend-separate-from-edx-platform-7c91d76c7360#fdf0).\nThis prevents Studio CSS affecting studio-frontend components and from\nstudio-frontend CSS affecting the surrounding Studio page. However, there are a\nfew key points to know about this:\n\n1. All studio-frontend styles are scoped to the `.SFE-wrapper` div.\n    * In a way, this div acts like the `\u003cbody\u003e` element for the embedded\n      studio-frontend component.\n    * If any elements from studio-frontend are placed outside of this div, then\n      they will be unstyled (or only have Studio styles applied to them).\n2. Studio-frontend elements are [fully reset using a browser default\n   stylesheet](https://github.com/thallada/default-stylesheet/). So, weird\n   things will occasionally happen with the styling, because it is not a perfect\n   process.\n    * Use a browser dev tools style inspector to see what styles are being\n      applied. Remove styles from `default.css` if you think they might be\n      conflicting with other styling.\n    * E.g. for some reason, ordered lists appear as unordered. We still have not\n      figured that one out.\n3. Selectors that you write in studio-frontend `.scss` files will be prepended\n   with a selector to the wrapper div during the Webpack build process\n   (`#root.SFE .SFE-wrapper`). This is so that studio-frontend styles affect\n   only the contents of the embedded studio-frontend component and so that they\n   are [specific](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity)\n   enough that they override any Studio styling.\n4. The `edx-bootstrap.scss` file contains only the Bootstrap variables and mixin\n   definitions. This file is safe to `@import` into individual component `.scss`\n   files. It allows you to, for example, color an element using the primary\n   color defined in the current Bootstrap theme with the `$primary` variable.\n5. Only import `SFE.scss` in JavaScript at the root of a studio-frontend app.\n   This file contains all of the Bootstrap style definitions and the CSS reset.\n   There is a lot of CSS in the file, so we only want to import it once per app.\n6. We currently have CSS modules enabled in the Webpack\n   [css-loader](https://github.com/webpack-contrib/css-loader), but aren't\n   really using the features of it. CSS modules allows you to rename classname\n   selectors defined in the CSS to be more specific, but we currently have it\n   configured to leave the names alone. We found it simpler to just reference\n   Bootstrap classes with a plain string (e.g. `\"col-1\"` vs. `styles['col-1']`).\n    * CSS modules helps avoid class name collision between different components\n      on the same page. We haven't run into this issue with studio-frontend yet,\n      but we might want to consider using it in the future once we do.\n7. Make sure the font-awesome CSS is imported in JavaScript in the app root\n   index file.\n\nIdeally, studio-frontend should not need these CSS hacks. In the future,\nstudio-frontend should control the full HTML page instead of being embedded in a\nStudio page shell. That way, studio-frontend components would be free from\nlegacy Studio styles and would not need to apply any resets.\n\n## Getting Help\n\nIf you need assistance with this repository please see our documentation for [Getting Help](https://github.com/openedx/edx-platform#getting-help) for more information.\n\n\n## Issue Tracker\n\nWe use JIRA for our issue tracker, not GitHub Issues. Please see our documentation for [tracking issues](https://github.com/openedx/edx-platform#issue-tracker) for more information on how to track issues that we will be able to respond to and track accurately. Thanks!\n\n## How to Contribute\n\nContributions are very welcome, but for legal reasons, you must submit a signed individual contributor's agreement before we can accept your contribution. See our [CONTRIBUTING](https://github.com/openedx/.github/blob/master/CONTRIBUTING.md) file for more information -- it also contains guidelines for how to maintain high code quality, which will make your contribution more likely to be accepted.\n\n\n## Reporting Security Issues\n\nPlease do not report security issues in public. Please email security@openedx.org.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenedx%2Fstudio-frontend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenedx%2Fstudio-frontend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenedx%2Fstudio-frontend/lists"}