From 9f21256960d271267e5c18a7c87608352370543d Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Wed, 22 Oct 2025 17:23:45 -0500 Subject: [PATCH 01/18] feat: update footer template https://github.com/overhangio/tutor-indigo/commit/2d5a8825430c30e6f0b41286061be08ac985ca01 --- tutorindigo/templates/indigo/lms/templates/footer.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/templates/footer.html b/tutorindigo/templates/indigo/lms/templates/footer.html index ec99fa637..bc4753476 100644 --- a/tutorindigo/templates/indigo/lms/templates/footer.html +++ b/tutorindigo/templates/indigo/lms/templates/footer.html @@ -42,12 +42,12 @@
  • Powered by:
  • - Runs on Tutor + Runs on Tutor
  • - ${footer['openedx_link']['title']} + ${footer['openedx_link']['title']}
  • From 854d1b67eaaa1d8d2a0194b757dd4c85313286db Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Wed, 22 Oct 2025 17:38:52 -0500 Subject: [PATCH 02/18] feat: update courseware templates --- .../lms/templates/courseware/course_about.html | 10 ++++------ .../indigo/lms/templates/courseware/courses.html | 13 +++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/templates/courseware/course_about.html b/tutorindigo/templates/indigo/lms/templates/courseware/course_about.html index 6d33cd9ef..aad744d79 100644 --- a/tutorindigo/templates/indigo/lms/templates/courseware/course_about.html +++ b/tutorindigo/templates/indigo/lms/templates/courseware/course_about.html @@ -54,7 +54,7 @@ <%block name="pagetitle">${course.display_name_with_default} -
    +
    <%block name="course_about_header"> @@ -71,7 +71,7 @@

    % if get_course_about_section(request, course, "video"):
    - +
    @@ -79,7 +79,7 @@

    - +
    % endif @@ -87,12 +87,10 @@

    %if user.is_authenticated and registered: + ${_("Already Enrolled")} %if show_courseware_link: %endif - - ${_("Already Enrolled")} - %if show_courseware_link: ${_("View Course")} diff --git a/tutorindigo/templates/indigo/lms/templates/courseware/courses.html b/tutorindigo/templates/indigo/lms/templates/courseware/courses.html index c267a33cb..c63131e02 100644 --- a/tutorindigo/templates/indigo/lms/templates/courseware/courses.html +++ b/tutorindigo/templates/indigo/lms/templates/courseware/courses.html @@ -25,7 +25,8 @@ ${course_discovery_meanings | n, dump_js_escaped_json}, getParameterByName('search_query'), "${user_language | n, js_escaped_string}", - "${user_timezone | n, js_escaped_string}" + "${user_timezone | n, js_escaped_string}", + ${set_default_filter | n, dump_js_escaped_json} ); @@ -66,17 +67,17 @@

    ${_('Refine Your Search')}

    From 1dfd43388cc40f39103629e89a1e67056b864ed0 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Wed, 22 Oct 2025 17:42:33 -0500 Subject: [PATCH 03/18] feat: update discovery templates --- .../lms/templates/discovery/course_card.underscore | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/templates/discovery/course_card.underscore b/tutorindigo/templates/indigo/lms/templates/discovery/course_card.underscore index d3be84f72..3ee320913 100644 --- a/tutorindigo/templates/indigo/lms/templates/discovery/course_card.underscore +++ b/tutorindigo/templates/indigo/lms/templates/discovery/course_card.underscore @@ -2,18 +2,21 @@
    - <%- content.display_name %> <%- content.number %> +
    -
    diff --git a/tutorindigo/templates/indigo/lms/templates/header/user_dropdown.html b/tutorindigo/templates/indigo/lms/templates/header/user_dropdown.html index 9181b19ff..a20dcff04 100644 --- a/tutorindigo/templates/indigo/lms/templates/header/user_dropdown.html +++ b/tutorindigo/templates/indigo/lms/templates/header/user_dropdown.html @@ -4,13 +4,13 @@ <%! import json +from urllib.parse import urljoin from django.conf import settings from django.urls import reverse from django.utils.translation import gettext as _ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_urls_for_user -from openedx.core.djangoapps.user_api.accounts.toggles import should_redirect_to_order_history_microfrontend from openedx.features.enterprise_support.utils import get_enterprise_learner_generic_name, get_enterprise_learner_portal %> @@ -23,7 +23,7 @@ enterprise_customer_portal = get_enterprise_learner_portal(request) ## Enterprises with the learner portal enabled should not show order history, as it does ## not apply to the learner's method of purchasing content. -should_show_order_history = should_redirect_to_order_history_microfrontend() and not enterprise_customer_portal +should_show_order_history = not getattr(settings, 'DISABLE_ORDER_HISTORY_TAB', True) and not enterprise_customer_portal %> @@ -39,8 +39,8 @@ % endif - - + + % if should_show_order_history: % endif From 4fc29a0f844b7800b798b513e4460b406f0e6ddf Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 10:53:55 -0500 Subject: [PATCH 05/18] feat: update instructor templates --- .../instructor_dashboard_2/instructor_dashboard_2.html | 1 - 1 file changed, 1 deletion(-) diff --git a/tutorindigo/templates/indigo/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html b/tutorindigo/templates/indigo/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html index c0820fa6a..9ff210d9d 100644 --- a/tutorindigo/templates/indigo/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html +++ b/tutorindigo/templates/indigo/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html @@ -61,7 +61,6 @@ <%static:webpack entry='HtmlBlockEditor'/> <%static:js group='instructor_dash'/> - <%static:js group='application'/> ## Backbone classes declared explicitly until RequireJS is supported From dd7076e0f58449b4015d019f0584eee0e1e7ac81 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 10:56:13 -0500 Subject: [PATCH 06/18] feat: update learner_dashboard templates --- .../lms/templates/learner_dashboard/program_card.underscore | 5 ----- .../lms/templates/learner_dashboard/programs_fragment.html | 3 --- 2 files changed, 8 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/templates/learner_dashboard/program_card.underscore b/tutorindigo/templates/indigo/lms/templates/learner_dashboard/program_card.underscore index 6aeafb29c..67c9ddd24 100644 --- a/tutorindigo/templates/indigo/lms/templates/learner_dashboard/program_card.underscore +++ b/tutorindigo/templates/indigo/lms/templates/learner_dashboard/program_card.underscore @@ -63,8 +63,3 @@ -<% if (isSubscribed) { %> -
    - <%- gettext('Subscribed') %> -
    -<% } %> diff --git a/tutorindigo/templates/indigo/lms/templates/learner_dashboard/programs_fragment.html b/tutorindigo/templates/indigo/lms/templates/learner_dashboard/programs_fragment.html index dd3e94bcb..2c7eb2b4d 100644 --- a/tutorindigo/templates/indigo/lms/templates/learner_dashboard/programs_fragment.html +++ b/tutorindigo/templates/indigo/lms/templates/learner_dashboard/programs_fragment.html @@ -31,11 +31,8 @@ ProgramListFactory({ marketingUrl: '${marketing_url | n, js_escaped_string}', programsData: ${programs | n, dump_js_escaped_json}, - programsSubscriptionData: ${programs_subscription_data | n, dump_js_escaped_json}, - subscriptionUpsellData: ${subscription_upsell_data | n, dump_js_escaped_json}, userProgress: ${progress | n, dump_js_escaped_json}, userPreferences: ${user_preferences | n, dump_js_escaped_json}, - isUserB2CSubscriptionsEnabled: ${is_user_b2c_subscriptions_enabled | n, dump_js_escaped_json}, mobileOnly: ${mobile_only | n, dump_js_escaped_json} }); From 7cb52ba29693c24171d5901455b1a5d9712b3830 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 11:08:01 -0500 Subject: [PATCH 07/18] feat: update github folder --- .github/workflows/auto-add-to-project.yml | 5 ++++- .github/workflows/test.yml | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/auto-add-to-project.yml b/.github/workflows/auto-add-to-project.yml index af1f35190..0e12752e6 100644 --- a/.github/workflows/auto-add-to-project.yml +++ b/.github/workflows/auto-add-to-project.yml @@ -1,9 +1,12 @@ -name: Auto Add Issues to Project +name: Auto Add Issues and Pull Requests to Project on: issues: types: - opened + pull_request_target: + types: + - opened jobs: # https://github.com/actions/add-to-project diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5a023449b..fde891c36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,8 +15,6 @@ jobs: uses: actions/setup-python@v2 with: python-version: 3.9 - - name: Upgrade pip - run: python -m pip install --upgrade pip setuptools - name: Install dependencies run: | pip install .[dev] From da77d1447bc48ef679b0ca725ab85186d2a1a038 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 11:08:32 -0500 Subject: [PATCH 08/18] feat: update general files --- .gitignore | 6 ++ CHANGELOG.md | 87 ++++++++++++++++++--- MANIFEST.in | 1 - README.rst | 6 +- pyproject.toml | 68 +++++++++++++++- setup.py | 62 --------------- tutorindigo/__about__.py | 2 +- tutorindigo/plugin.py | 162 +++++++++++++++++++-------------------- 8 files changed, 235 insertions(+), 159 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 setup.py diff --git a/.gitignore b/.gitignore index f6a874f21..e6c3f6d8b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,9 @@ __pycache__ *.egg-info/ /build/ /dist/ +.DS_Store + +### Editors ### +*~ +/temp +/.vscode diff --git a/CHANGELOG.md b/CHANGELOG.md index 38d6a7f1b..61b55d0ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,68 +19,136 @@ instructions, because git commits are used to generate release notes: + +## v20.0.1 (2025-09-23) + +- [Improvement] Make latex response editor background colours WCAG compliant in dark theme. (by @Danyal-Faheem) + +- [Improvement] Sync footer in both MFE pages and templates (by @zubairshakoorarbisoft) + + + +## v20.0.0 (2025-06-16) + +- πŸ’₯[Feature] Upgrade to teak. (by @HammadYousaf01) + +- [Bugfix] Remove reference to old account toggles. (by @ahmed-arb) + +- [BugFix] Bump Indigo Header and Footer versions to fix image build failure due to React 18 upgrades in upstream MFEs (by @HammadYousaf01) + + + +## v19.0.3 (2025-06-05) + +- [Improvement] Fix multiple accessibility issues across the platform including screen reader compatibility, keyboard navigation, focus visibility, and WCAG compliance improvements. (by @arbirali and @zubairshakoorarbisoft) + - Add visible titles to image-based links for better screen reader support (#150) + - Make "Learn More" links accessible to screen readers (#151) + - Improve "Open Responses" table headers for keyboard accessibility (#152) + - Add accessible names to social media icons (#155) + - Enhance theme toggle with descriptive labels (#156) + - Increase focus visible thickness for better visibility (#158) + - Fix "Skip to main content" link display (#159) + - Resolve accessibility and reflow issues in Wiki, Teams, and Instructor Dashboard (#163) + - General accessibility fixes reported during review (#147) + + + +## v19.0.2 (2025-05-27) + +- [Improvement] Migrate from `setup.py` (setuptools) to `pyproject.toml` (hatch). (by @ahmed-arb) + +- [Improvement] Add hatch_build.py in sdist target to fix the installation issues (by @dawoudsheraz) + +- [BugFix] Fix runtime footer import error in env.config.jsx for unsupported MFEs. (by @ahmed-arb) + +- [BugFix] Maintain selected emoji color in survey xblock. (by @mlabeeb03) + +- [Improvement] Change color of headings and list items in dark mode to improve readability. (by @mlabeeb03) + + + +## v19.0.1 (2025-01-26) + +- [BugFix] Fix env.config.jsx for dark theme and Indigo footer by including the patches folder in MANIFEST.in for python pypi package. (by @hinakhadim) + + + +## v19.0.0 (2024-12-11) + +- πŸ’₯[Feature] Upgrade to Sumac (by @hinakhadim) + + ## v18.3.0 (2024-12-11) - πŸ’₯ [Deprecation] Drop support for python 3.8 and set Python 3.9 as the minimum supported python version. (by @hinakhadim) - πŸ’₯[Improvement] Rename Tutor's two branches (by @DawoudSheraz): - * Rename **master** to **release**, as this branch runs the latest official Open edX release tag. - * Rename **nightly** to **main**, as this branch runs the Open edX master branches, which are the basis for the next Open edX release. + - Rename **master** to **release**, as this branch runs the latest official Open edX release tag. + - Rename **nightly** to **main**, as this branch runs the Open edX master branches, which are the basis for the next Open edX release. - [Bugfix] Fix dropdown select rendering issue on light theme (by @dawoudsheraz) - - ".wrapper-problem-response" did not need any dark theme variables outside dark-theme class for dropdown problems. This was causing the dropdown to use dark theme variables regardless of the theme that user selected. + - ".wrapper-problem-response" did not need any dark theme variables outside dark-theme class for dropdown problems. This was causing the dropdown to use dark theme variables regardless of the theme that user selected. - [Bugfix] Add dark-theme for Course Handouts and Course Updates that appears on Learning MFE Course Outline Page (by @hinakhadim) - [Bugfix] Update dark-theme styles for ORA (Open Response Assessment) so that it becomes readable, usable, beautiful, and appealing (by @hinakhadim) - - The readability of styles in the `scss` file is challenging and will be improved in subsequent releases. + - The readability of styles in the `scss` file is challenging and will be improved in subsequent releases. - [Bugfix] Fix various dark theme issues with Teams tab on LMS. (by @dawoudsheraz) - [Bugfix] Update dark-theme styles for Notes and Textbook Page (by @hinakhadim) + ## v18.2.2 (2024-10-29) - [Feature] Upgrade upstream apps to open-release/redwood.3. In particular, this will resolve serious issues with [course creation](https://github.com/openedx/frontend-app-authoring/issues/1199) and [language switching](https://github.com/openedx/frontend-app-account/issues/1052). (by @regisb) + ## v18.2.1 (2024-10-11) - [Feature] Introduced theme toggle feature with enable/disable option and runtime switch between light and dark modes. (by @hinakhadim) + ## v18.1.1 (2024-08-27) - [BugFix] Add the Indigo footer in MFEs via env.config.jsx to resolve display issues on the /account/ page after upgrading to Redwood. (by @hinakhadim) + ## v18.1.0 (2024-07-23) - [Improvement] Instead of forcing users to use Authentication MFe, the platform decides how users should log in. (by @CodeWithEmad) -- [Feature] Dark theme: the Indigo theme now covers dark theme for LMS pages, including the MFEs, and they are more beautiful! (by @tanveer65 and @hinakhadim) +- [Feature] Dark theme: the Indigo theme now covers dark theme for LMS pages, including the MFEs, and they are more beautiful! (by @tanveer65 and @hinakhadim) + ## v18.0.0 (2024-06-20) - πŸ’₯[Feature] Upgrade to Redwood (by @hinakhadim) + ## v17.4.2 (2024-06-11) - [BugFix] Add big screen variable of screen responsiveness (by @tanveer65) + ## v17.4.1 (2024-06-10) - [BugFix] Remove undefined variables of dark-theme. (by @hinakhadim) + ## v17.4.0 (2024-06-10) - [Bugfix] Make plugin compatible with Python 3.12 by removing dependency on `pkg_resources`. (by @regisb) -- [Bugfix] *.scss files in cms directory were not rendered in the tutor environment because they are stored in a "partials" subdirectory. (by @Talha-Rizwan) +- [Bugfix] \*.scss files in cms directory were not rendered in the tutor environment because they are stored in a "partials" subdirectory. (by @Talha-Rizwan) - [Improvement] Add styles for Profile and Account MFE and increase container width for better readability. (by @tanveer65) + ## v17.3.0 (2024-03-04) - πŸ’₯[Improvement] Allow the no_course_image.png image to pull from the current theme, not specifically named indigo (by @misilot) @@ -90,20 +158,21 @@ instructions, because git commits are used to generate release notes: - [Improvement] Style static pages of About, Contact, Privacy and bookmarks page (by @tanveer65) + ## v17.2.0 (2024-01-27) - πŸ’₯[Bugfix] Fixes: Minor Bug fixes with styling updates for discussion and learner-dashboard MFEs (by @hinakhadim and @TanveerAhmed) + ## v17.1.0 (2023-12-13) - πŸ’₯[Improvement] Complete overhaul and redesign: the Indigo theme now covers more pages, including the MFE footer and header, and they are more beautiful than ever! (by @hinakhadim and @TanveerAhmed) + ## v17.0.0 (2023-12-09) - πŸ’₯[Feature] Upgrade to Quince (by @hinakhadim) - [Improvement] Add a scriv-compliant changelog. (by @regisb) -- [Improvement] Added Makefile and test action to repository and formatted code with Black and isort. (by @CodeWithEmad) - - +- [Improvement] Added Makefile and test action to repository and formatted code with Black and isort. (by @CodeWithEmad) \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 3d2c03b12..000000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -recursive-include tutorindigo/templates * diff --git a/README.rst b/README.rst index 5868f50f2..2a407fe77 100644 --- a/README.rst +++ b/README.rst @@ -86,11 +86,11 @@ Overriding the default "about", "contact", etc. static pages By default, the ``/about`` and ``/contact`` pages contain a simple line of text: "This page left intentionally blank. Feel free to add your own content". This is of course unusable in production. In the following, we detail how to override just any of the static templates used in Open edX. -The static templates used by Open edX to render those pages are all stored in the `edx-platform/lms/templates/static_templates `__ folder. To override those templates, you should add your own in the following folder:: +The static templates used by Open edX to render those pages are all stored in the `edx-platform/lms/templates/static_templates `__ folder. To override those templates, you should add your own in the following folder:: ls tutorindigo/templates/indigo/lms/templates/static_templates" -For instance, edit the "donate.html" file in this directory. We can derive the content of this file from the contents of the `donate.html `__ static template in edx-platform: +For instance, edit the "donate.html" file in this directory. We can derive the content of this file from the contents of the `donate.html `__ static template in edx-platform: .. code-block:: mako @@ -131,7 +131,7 @@ The indigo theme can’t override styles for MFEs directly. It overrides the sty )) -This Tutor plugin is maintained by Hina Khadim from `Edly `__. Community support is available from the official `Open edX forum `__. Do you need help with this plugin? See the `troubleshooting `__ section from the Tutor documentation. +This Tutor plugin is maintained by Ahmed Khalid and Hammad Yousaf from `Edly `__. Community support is available from the official `Open edX forum `__. Do you need help with this plugin? See the `troubleshooting `__ section from the Tutor documentation. License diff --git a/pyproject.toml b/pyproject.toml index d1e6ae6e5..d13c3de9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,2 +1,68 @@ +#https://hatch.pypa.io/latest/config/build/ + +[project] +name = "tutor-indigo" +description = "Indigo theme plugin for Tutor" +readme = { file = "README.rst", content-type = "text/x-rst" } +license = { text = "AGPLv3" } +requires-python = ">=3.9" +authors = [{ name = "Edly" }, { email = "hello@edly.io" }] +maintainers = [ + { name = "Ahmed Khalid" }, { email = "ahmed.khalid@arbisoft.com" }, + { name = "Hammad Yousaf" }, { email = "hammad.yousaf@arbisoft.com" } +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU Affero General Public License v3", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "tutor-mfe>=20.0.0,<21.0.0", + "tutor>=20.0.0,<21.0.0" +] + +# hatch_build.py will set it later +dynamic = ["version"] + +[project.optional-dependencies] +dev = [ + "tutor[dev]>=20.0.0,<21.0.0", + "pylint", + "black" +] + +[project.entry-points."tutor.plugin.v1"] +indigo = "tutorindigo.plugin" + +[project.urls] +Code = "https://github.com/overhangio/tutor-indigo" +Community = "https://discuss.openedx.org" +Documentation = "https://docs.tutor.edly.io/" +Homepage = "https://github.com/overhangio/tutor-indigo" +Changelog = "https://github.com/overhangio/tutor-indigo/blob/release/CHANGELOG.md" +Issues = "https://github.com/overhangio/tutor-indigo/issues" + +# hatch related configurations [build-system] -requires = ["setuptools", "wheel"] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.sdist] +# Disable strict naming, otherwise twine is not able to detect name/version +strict-naming = false +include = ["/tutorindigo", ".hatch_build.py"] +exclude = ["tests*"] + +# we need this becuase our project escapes default hatch file selection. +# see https://hatch.pypa.io/latest/plugins/builder/wheel/#default-file-selection +[tool.hatch.build.targets.wheel] +packages = ["/tutorindigo"] + +[tool.hatch.metadata.hooks.custom] +path = ".hatch_build.py" diff --git a/setup.py b/setup.py deleted file mode 100644 index 6cdca5a7e..000000000 --- a/setup.py +++ /dev/null @@ -1,62 +0,0 @@ -import io -import os -from setuptools import setup, find_packages - -HERE = os.path.abspath(os.path.dirname(__file__)) - - -def load_readme(): - with io.open(os.path.join(HERE, "README.rst"), "rt", encoding="utf8") as f: - return f.read() - - -def load_about(): - about = {} - with io.open( - os.path.join(HERE, "tutorindigo", "__about__.py"), - "rt", - encoding="utf-8", - ) as f: - exec(f.read(), about) # pylint: disable=exec-used - return about - - -ABOUT = load_about() - - -setup( - name="tutor-indigo", - version=ABOUT["__version__"], - url="https://github.com/overhangio/tutor-indigo", - project_urls={ - "Documentation": "https://docs.tutor.edly.io/", - "Code": "https://github.com/overhangio/tutor-indigo", - "Issue tracker": "https://github.com/overhangio/tutor-indigo/issues", - "Community": "https://discuss.openedx.org", - }, - license="AGPLv3", - author="Edly", - author_email="hello@edly.io", - maintainer="Edly", - maintainer_email="hina.khadim@arbisoft.com", - description="Indigo theme plugin for Tutor", - long_description=load_readme(), - long_description_content_type="text/x-rst", - packages=find_packages(exclude=["tests*"]), - include_package_data=True, - python_requires=">=3.9", - install_requires=["tutor>=18.0.0,<19.0.0", "tutor-mfe>=18.0.0,<19.0.0"], - extras_require={"dev": "tutor[dev]>=18.0.0,<19.0.0"}, - entry_points={"tutor.plugin.v1": ["indigo = tutorindigo.plugin"]}, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "License :: OSI Approved :: GNU Affero General Public License v3", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - ], -) diff --git a/tutorindigo/__about__.py b/tutorindigo/__about__.py index 22ed76922..dd71ced3d 100644 --- a/tutorindigo/__about__.py +++ b/tutorindigo/__about__.py @@ -1 +1 @@ -__version__ = "18.3.0" +__version__ = "20.0.1" diff --git a/tutorindigo/plugin.py b/tutorindigo/plugin.py index e20ea63f0..6f25e4351 100644 --- a/tutorindigo/plugin.py +++ b/tutorindigo/plugin.py @@ -2,11 +2,12 @@ import os import typing as t +from glob import glob import importlib_resources from tutor import hooks from tutor.__about__ import __version_suffix__ -from tutormfe.hooks import MFE_APPS +from tutormfe.hooks import PLUGIN_SLOTS from .__about__ import __version__ @@ -21,7 +22,7 @@ "defaults": { "VERSION": __version__, "WELCOME_MESSAGE": "The place for all your online learning", - "PRIMARY_COLOR": "#4600c7", # Indigo + "PRIMARY_COLOR": "#15376D", # Indigo "ENABLE_DARK_TOGGLE": True, # Footer links are dictionaries with a "title" and "url" # To remove all links, run: @@ -77,7 +78,7 @@ # Override openedx & mfe docker image names @hooks.Filters.CONFIG_DEFAULTS.add(priority=hooks.priorities.LOW) def _override_openedx_docker_image( - items: list[tuple[str, t.Any]] + items: list[tuple[str, t.Any]], ) -> list[tuple[str, t.Any]]: openedx_image = "" mfe_image = "" @@ -103,68 +104,43 @@ def _override_openedx_docker_image( hooks.Filters.CONFIG_OVERRIDES.add_items(list(config["overrides"].items())) -hooks.Filters.ENV_PATCHES.add_items( - [ - # MFE will install header version 3.0.x and will include indigo-footer as a - # separate package for use in env.config.jsx - ( - "mfe-dockerfile-post-npm-install-learning", - """ -RUN npm install '@edx/brand@https://github.com/MubeenFayyaz-Arbisoft/brand-openedx.git#v1.0.2' -RUN npm install '@edx/frontend-component-header@npm:@edly-io/indigo-frontend-component-header@^3.1.3' -RUN npm install @edly-io/indigo-frontend-component-footer@^2.0.0 +# MFEs that are styled using Indigo +indigo_styled_mfes = [ + "learning", + "learner-dashboard", + "profile", + "account", + "discussions", +] -COPY indigo/env.config.jsx /openedx/app/ -""", - ), - ( - "mfe-dockerfile-post-npm-install-authn", - """ -RUN npm install '@edx/brand@https://github.com/MubeenFayyaz-Arbisoft/brand-openedx.git#v1.0.2' -""", - ), - # Tutor-Indigo v2.1 targets the styling updates in discussions and learner-dashboard MFE - # brand-openedx is related to styling updates while others are for header and footer updates - ( - "mfe-dockerfile-post-npm-install-discussions", - """ -RUN npm install '@edx/brand@https://github.com/MubeenFayyaz-Arbisoft/brand-openedx.git#v1.0.2' -RUN npm install '@edx/frontend-component-header@npm:@edly-io/indigo-frontend-component-header@^3.1.3' -RUN npm install @edly-io/indigo-frontend-component-footer@^2.0.0 -COPY indigo/env.config.jsx /openedx/app/ -""", - ), - ( - "mfe-dockerfile-post-npm-install-learner-dashboard", - """ -RUN npm install '@edx/brand@https://github.com/MubeenFayyaz-Arbisoft/brand-openedx.git#v1.0.2' -RUN npm install @edly-io/indigo-frontend-component-footer@^2.0.0 +for mfe in indigo_styled_mfes: + hooks.Filters.ENV_PATCHES.add_items( + [ + ( + f"mfe-dockerfile-post-npm-install-{mfe}", + """ +RUN npm install @edly-io/indigo-frontend-component-footer@^3.0.0 +RUN npm install '@edx/frontend-component-header@npm:@edly-io/indigo-frontend-component-header@^4.0.0' +RUN npm install '@edx/brand@npm:@edly-io/indigo-brand-openedx@^2.2.2' -COPY indigo/env.config.jsx /openedx/app/ """, - ), - ( - "mfe-dockerfile-post-npm-install-profile", - """ -RUN npm install '@edx/brand@https://github.com/MubeenFayyaz-Arbisoft/brand-openedx.git#v1.0.2' -RUN npm install '@edx/frontend-component-header@npm:@edly-io/indigo-frontend-component-header@^3.1.3' -RUN npm install @edly-io/indigo-frontend-component-footer@^2.0.0 - -COPY indigo/env.config.jsx /openedx/app/ + ), + ( + f"mfe-env-config-runtime-definitions-{mfe}", + """ +const { default: IndigoFooter } = await import('@edly-io/indigo-frontend-component-footer'); """, - ), - ( - "mfe-dockerfile-post-npm-install-account", - """ -RUN npm install '@edx/brand@https://github.com/MubeenFayyaz-Arbisoft/brand-openedx.git#v1.0.2' -RUN npm install '@edx/frontend-component-header@npm:@edly-io/indigo-frontend-component-header@^3.1.3' -RUN npm install @edly-io/indigo-frontend-component-footer@^2.0.0 + ), + ] + ) -COPY indigo/env.config.jsx /openedx/app/ -""", - ), - ] + +hooks.Filters.ENV_PATCHES.add_item( + ( + "mfe-dockerfile-post-npm-install-authn", + "RUN npm install '@edx/brand@npm:@edly-io/indigo-brand-openedx@^2.2.2'", + ) ) # Include js file in lms main.html, main_django.html, and certificate.html @@ -195,37 +171,59 @@ def _override_openedx_docker_image( PIPELINE['JAVASCRIPT'][filename]['source_filenames'] += dark_theme_filepath MFE_CONFIG['INDIGO_ENABLE_DARK_TOGGLE'] = {{ INDIGO_ENABLE_DARK_TOGGLE }} +MFE_CONFIG['INDIGO_FOOTER_NAV_LINKS'] = {{ INDIGO_FOOTER_NAV_LINKS }} """, ), ( "openedx-lms-production-settings", """ MFE_CONFIG['INDIGO_ENABLE_DARK_TOGGLE'] = {{ INDIGO_ENABLE_DARK_TOGGLE }} +MFE_CONFIG['INDIGO_FOOTER_NAV_LINKS'] = {{ INDIGO_FOOTER_NAV_LINKS }} """, ), ] ) -@MFE_APPS.add() -def _add_my_mfe(mfes): - mfes["authn"] = { - "repository": "https://github.com/edly-io/frontend-app-authn.git", - "port": 1999, - "version": "nelc-v1.0.1", # optional, will default to the Open edX current tag. - } - mfes["learning"] = { - "repository": "https://github.com/edly-io/frontend-app-learning.git", - "port": 2000, - "version": "nelc-v1.0.1", # optional, will default to the Open edX current tag. - } - mfes["discussions"] = { - "repository": "https://github.com/edly-io/frontend-app-discussions.git", - "port": 2002, - "version": "nelc-v1.0.1", # optional, will default to the Open edX current tag. - } - mfes["learner-dashboard"] = { - "repository": "https://github.com/edly-io/frontend-app-learner-dashboard.git", - "port": 1996, - "version": "nelc-v1.0.1", # optional, will default to the Open edX current tag. - } - return mfes + +# Apply patches from tutor-indigo +for path in glob( + os.path.join( + str(importlib_resources.files("tutorindigo") / "patches"), + "*", + ) +): + with open(path, encoding="utf-8") as patch_file: + hooks.Filters.ENV_PATCHES.add_item((os.path.basename(path), patch_file.read())) + + +for mfe in indigo_styled_mfes: + PLUGIN_SLOTS.add_item( + ( + mfe, + "footer_slot", + """ + { + op: PLUGIN_OPERATIONS.Hide, + widgetId: 'default_contents', + }, + { + op: PLUGIN_OPERATIONS.Insert, + widget: { + id: 'default_contents', + type: DIRECT_PLUGIN, + priority: 1, + RenderWidget: , + }, + }, + { + op: PLUGIN_OPERATIONS.Insert, + widget: { + id: 'read_theme_cookie', + type: DIRECT_PLUGIN, + priority: 2, + RenderWidget: AddDarkTheme, + }, + }, + """, + ), + ) From 739fbf0ce0de80ffee700eaebdaad258081e1f74 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 11:16:04 -0500 Subject: [PATCH 09/18] feat: update static js folder --- .../indigo/lms/static/js/dark-theme.js | 19 +++ .../indigo/lms/static/js/responsive-nav.js | 119 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 tutorindigo/templates/indigo/lms/static/js/responsive-nav.js diff --git a/tutorindigo/templates/indigo/lms/static/js/dark-theme.js b/tutorindigo/templates/indigo/lms/static/js/dark-theme.js index a34dd330a..a12534264 100644 --- a/tutorindigo/templates/indigo/lms/static/js/dark-theme.js +++ b/tutorindigo/templates/indigo/lms/static/js/dark-theme.js @@ -8,11 +8,25 @@ $(document).ready(function() { $('body').toggleClass("indigo-dark-theme", theme === 'dark'); // append or remove dark-class based on cookie-value // update expiry $.cookie(themeCookie, theme, { domain: window.location.hostname, expires: 90, path: '/' }); + updateAccessibility(); } function setThemeToggleBtnState(){ const theme = $.cookie(themeCookie); $("#toggle-switch-input").prop("checked", theme === 'dark'); + updateAccessibility(); + } + + function updateAccessibility() { + const theme = $.cookie(themeCookie); + const textWrapper = $('#theme-label'); + if (theme === 'dark') { + textWrapper.text('Switch to Light Mode'); + textWrapper.attr('aria-checked', 'true'); + } else { + textWrapper.text('Switch to Dark Mode'); + textWrapper.attr('aria-checked', 'false'); + } } function toggleTheme(){ @@ -33,4 +47,9 @@ $(document).ready(function() { setThemeToggleBtnState(); // check/uncheck toggle btn based on theme $('#toggle-switch').on('change', toggleTheme); + $('#toggle-switch-input').on('keydown', function (event) { + if (event.key === "Enter") { + toggleTheme(); + } + }); }); diff --git a/tutorindigo/templates/indigo/lms/static/js/responsive-nav.js b/tutorindigo/templates/indigo/lms/static/js/responsive-nav.js new file mode 100644 index 000000000..4ee775a34 --- /dev/null +++ b/tutorindigo/templates/indigo/lms/static/js/responsive-nav.js @@ -0,0 +1,119 @@ +/** + * Temporary fix for a legacy issue specific to the Tutor Indigo theme. + * This can be removed once the upstream fix is included in Open edX. + */ + +$(document).ready(function () { + $(".course-tabs, .instructor-nav").each(function () { + var $navList = $(this); + + // Skip if already initialized + if ($navList.hasClass("responsive-nav-initialized")) { + return; + } + $navList.addClass("responsive-nav responsive-nav-initialized"); + + var moreButtonClass = $navList.hasClass("instructor-nav") ? "btn-link" : ""; + var moreListItemClass = $navList.hasClass("instructor-nav") ? "nav-item" : "tab"; + var menuType = $navList.hasClass("instructor-nav") ? "instructor-nav" : "course-tabs"; + + // Create More dropdown + var $more = $( + '
  • ' + + '' + + '' + + '
  • ' + ); + $navList.append($more); + var $moreBtn = $more.find(".more-button"); + var $moreMenu = $more.find(".more-menu"); + + // Toggle dropdown + $moreBtn.on("click", function () { + var isOpen = $more.hasClass("open"); + $more.toggleClass("open"); + $moreBtn.attr("aria-expanded", !isOpen); + }); + + // Keyboard support + $moreBtn.on("keydown", function (e) { + if (e.key === "Enter" || e.key === " " || e.key === "Spacebar") { + e.preventDefault(); + $moreBtn.click(); + } else if (e.key === "Escape") { + $more.removeClass("open"); + $moreBtn.attr("aria-expanded", "false").focus(); + } + }); + + $moreMenu.on("keydown", function (e) { + var $items = $moreMenu.find("[role='menuitem']"); + var index = $items.index(document.activeElement); + + if (e.key === "ArrowDown") { + e.preventDefault(); + if (index < $items.length - 1) $items.eq(index + 1).focus(); + } else if (e.key === "ArrowUp") { + e.preventDefault(); + if (index > 0) $items.eq(index - 1).focus(); + } else if (e.key === "Escape") { + $more.removeClass("open"); + $moreBtn.attr("aria-expanded", "false").focus(); + } + }); + + // Close on outside click + $(document).on("click", function (e) { + if (!$more.is(e.target) && $more.has(e.target).length === 0) { + $more.removeClass("open"); + $moreBtn.attr("aria-expanded", "false"); + } + }); + + function updateNav() { + $moreMenu.children("li").each(function () { + $(this).insertBefore($more); + }); + + var navWidth = $navList.width(); + var usedWidth = $more.outerWidth(true); + var $items = $navList.children("li").not($more); + + var hideItems = []; + $items.each(function () { + usedWidth += $(this).outerWidth(true); + if (usedWidth > navWidth) { + hideItems.push(this); + } + }); + + if (hideItems.length > 0) { + $(hideItems).each(function () { + $(this).attr("role", "menuitem").attr("tabindex", "-1"); + }).appendTo($moreMenu); + $more.show(); + } else { + $more.hide().removeClass("open"); + } + + $moreBtn.attr("aria-expanded", "false"); + } + + // Store for reuse + $navList.data("updateNav", updateNav); + + // Initial call + updateNav(); + }); + + // On resize, update all responsive navs + $(window).on("resize", function () { + $(".responsive-nav-initialized").each(function () { + var update = $(this).data("updateNav"); + if (typeof update === "function") { + update(); + } + }); + }); +}); From af0a5520c455c75d5055ee898124bf8eefa15994 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 11:16:19 -0500 Subject: [PATCH 10/18] feat: update static images folder --- .../indigo/lms/static/images/tutor-logo.png | Bin 37976 -> 5836 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/static/images/tutor-logo.png b/tutorindigo/templates/indigo/lms/static/images/tutor-logo.png index 33a146ebf2be9856d64649841f02e7c95589cdc1..56860275917dc247f1cda700b16189dcab3b5de1 100644 GIT binary patch literal 5836 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 z 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 Date: Thu, 23 Oct 2025 11:35:38 -0500 Subject: [PATCH 11/18] feat: update sass courseware folder --- .../lms/static/sass/courseware/_about.scss | 47 ++++++++++++------- .../static/sass/courseware/_bookmarks.scss | 2 +- .../lms/static/sass/courseware/_discover.scss | 11 +++-- .../sass/courseware/_responsive-nav.scss | 45 ++++++++++++++++++ 4 files changed, 83 insertions(+), 22 deletions(-) create mode 100644 tutorindigo/templates/indigo/lms/static/sass/courseware/_responsive-nav.scss diff --git a/tutorindigo/templates/indigo/lms/static/sass/courseware/_about.scss b/tutorindigo/templates/indigo/lms/static/sass/courseware/_about.scss index e062e7064..d11b5830f 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/courseware/_about.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/courseware/_about.scss @@ -84,6 +84,9 @@ border-radius: 8px; border: 1px solid $primary-light; } + .play-intro{ + z-index: 10; + } } } } @@ -91,26 +94,36 @@ @include media-breakpoint-up(md) { margin: -50px 0 0; } - a { - text-decoration: none !important; - span { - display: inline-block; - vertical-align: top; - padding: 7px 14px; - color: #374151; - border-radius: 6px; - background: #fff; - font-size: 16px; - line-height: 24px; - font-weight: 500; - text-decoration: none !important; - border: 1px solid #d1d5db; - margin-right: 20px; - @include media-breakpoint-up(md) { - padding: 12px 24px; + span { + &.register { + &.disabled { + display: inline-block; + vertical-align: top; + padding: 7px 14px; + color: #374151; + border-radius: 6px; + background: #fff; + font-size: 16px; + line-height: 24px; + font-weight: 500; + text-decoration: none !important; + border: 1px solid #D1D5DB; + margin-right: 20px; + @include media-breakpoint-up(md) { + padding: 12px 24px; + } + + &:hover { + opacity: 1; + } } } } + + a { + display: inline-block; + text-decoration: none !important; + } a.register, a strong, > span.register, diff --git a/tutorindigo/templates/indigo/lms/static/sass/courseware/_bookmarks.scss b/tutorindigo/templates/indigo/lms/static/sass/courseware/_bookmarks.scss index f0714654d..b476f228a 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/courseware/_bookmarks.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/courseware/_bookmarks.scss @@ -79,7 +79,7 @@ .course-bookmarks { .bookmarks-results-list { a.bookmarks-results-list-item { - border: 1px solid #E5E7EB; + border: 1px solid $gray-light; border-left: 8px solid $primary-light; padding: 20px 30px; border-radius: 8px; diff --git a/tutorindigo/templates/indigo/lms/static/sass/courseware/_discover.scss b/tutorindigo/templates/indigo/lms/static/sass/courseware/_discover.scss index a0f7a18c2..6ff2d7025 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/courseware/_discover.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/courseware/_discover.scss @@ -204,12 +204,12 @@ } } .discover-search { - overflow: hidden; + width: 100%; .wrapper-search-context { overflow: hidden; .wrapper-search-input { float: none; - display: block; + display: flex; margin: 0; width: auto; &:after { @@ -245,7 +245,7 @@ } } .input-holder { - overflow: hidden; + flex-grow: 1; border-radius: 6px; background: $primary-light; padding: 0 0 0 33px; @@ -283,9 +283,12 @@ } } .filter-block { - float: left; + flex: 0 0 80px; position: relative; z-index: 9; + @include media-breakpoint-up(sm) { + flex: 0 0 130px; + } &.show { .dropdown-menu { display: block; diff --git a/tutorindigo/templates/indigo/lms/static/sass/courseware/_responsive-nav.scss b/tutorindigo/templates/indigo/lms/static/sass/courseware/_responsive-nav.scss new file mode 100644 index 000000000..9bebc90e7 --- /dev/null +++ b/tutorindigo/templates/indigo/lms/static/sass/courseware/_responsive-nav.scss @@ -0,0 +1,45 @@ +/** + * Temporary fix for a legacy issue specific to the Tutor Indigo theme. + * This can be removed once the upstream fix is included in Open edX. + */ + +.responsive-nav { + white-space: nowrap; + position: relative; + + > li { + display: inline-block; + vertical-align: middle; + } + + .open { + + .more-responsive-menu { + display: block; + } + } +} + +.more-responsive-menu { + position: absolute; + top: 100%; + right: 0; + margin: 0; + padding: 0; + width: 250px; + border: 1px solid $gray-light; + z-index: 999; + background: $body-bg; + display: none; + + li { + display: block !important; + width: 100%; + margin: 0; + + a, + button { + display: block; + } + } +} From a8301e75e0375dd763cd96098be4b5d1c3d0d69e Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 11:44:59 -0500 Subject: [PATCH 12/18] feat: update sass extra folder --- .../indigo/lms/static/sass/extra/_header.scss | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tutorindigo/templates/indigo/lms/static/sass/extra/_header.scss b/tutorindigo/templates/indigo/lms/static/sass/extra/_header.scss index b5d00b0b6..978da2f16 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/extra/_header.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/extra/_header.scss @@ -130,9 +130,13 @@ header.global-header { } } .hamburger-menu { - height: 12px; + height: 17px; width: 20px; top: 18px; + background: none; + border: 0; + padding: 0; + box-shadow: none; right: 20px !important; left: unset !important; &:dir(rtl){ @@ -229,6 +233,12 @@ header.global-header { opacity: 0; width: 0; height: 0; + &:focus { + ~ .slider { + outline: 2px solid $primary; + outline-offset: 1px; + } + } } /* The slider */ @@ -345,6 +355,13 @@ body.indigo-dark-theme { } #toggle-switch { .switch { + input { + &:focus { + ~ .slider { + outline-color: $primary-d; + } + } + } /* The slider */ .slider { background-color: #ccc; From bd0b03d7bb1c96deee154129b5ba573e63bf8d9d Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 11:48:37 -0500 Subject: [PATCH 13/18] feat: update sass home folder --- .../indigo/lms/static/sass/home/_home.scss | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/static/sass/home/_home.scss b/tutorindigo/templates/indigo/lms/static/sass/home/_home.scss index 2543bc6cb..790707768 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/home/_home.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/home/_home.scss @@ -32,6 +32,7 @@ section.home { #main .home.style-logout { header { background: none; + overflow: visible; .outer-wrapper { .title { width: 100%; @@ -73,13 +74,8 @@ section.home { .course-search { padding: 0; .search-field-wrapper { - &:after { - clear: both; - content: ""; - display: block; - } + display: flex; .button-holder { - float: right; button { position: static; margin: 0 0 0 16px; @@ -105,7 +101,7 @@ section.home { } } .input-holder { - overflow: hidden; + flex-grow: 1; border-radius: 6px; background: $primary-light; padding: 0 0 0 33px; @@ -127,6 +123,12 @@ section.home { font-size: 14px; line-height: 20px; padding: 9px 10px; + + &:focus, + &:focus-visible { + outline: revert; + outline-width: 2px; + } } } } From a7eb10e69d2f366fb248ac516142ad2e1193a984 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 12:10:43 -0500 Subject: [PATCH 14/18] feat: update sass partials folder --- .../sass/partials/lms/theme/_extras.scss | 187 ++++++++++++++++-- .../sass/partials/lms/theme/_variables.scss | 7 +- 2 files changed, 181 insertions(+), 13 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_extras.scss b/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_extras.scss index f51122c6b..915c52bd8 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_extras.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_extras.scss @@ -36,6 +36,22 @@ input:-webkit-autofill:active { transition: background-color 5000s ease-in-out 0s; box-shadow: none; } + +.register-btn, +.sign-in-btn, +.search-button, +.learn-more, +.see-children a, +.add-article-btn, +.member-list-widget .add, +section.wiki .btn.btn-primary { + + &:focus, + &:focus-visible { + outline-offset: 3px; + } +} + .page-content-container { max-width: 1600px; margin: 0 auto; @@ -43,6 +59,11 @@ input:-webkit-autofill:active { border: none; } +:focus, +:focus-visible { + outline-width: 2px; +} + %btn-pl-default-base { border-radius: 0; } @@ -333,12 +354,28 @@ body.view-wiki { margin: 0 auto; max-width: 1600px; padding: 20px 15px !important; + + .course-material { + overflow: visible; + } + .tabs.course-tabs { margin: 0 0 10px; border-bottom: 1px solid $border-color; li { margin: 0 32px 0 0; - a { + + &.more { + margin-right: 0; + } + + button { + border: 0; + background: none; + } + + a, + button { border-width: 2px; font-size: 14px; font-weight: 500; @@ -441,6 +478,14 @@ body.view-instructordash { } .instructor-dashboard-content-2 { padding: 0; + + .wrap-instructor-info { + @include media-breakpoint-down(xs) { + display: block; + text-align: right; + } + } + h2.instructor-dashboard-title { font-size: 24px; line-height: 30px; @@ -449,23 +494,20 @@ body.view-instructordash { background: $primary; color: white; margin: 0 0 10px; + outline-offset: 3px; + @include media-breakpoint-down(xs) { + display: inline-block; + float: none; + } } .instructor-nav { - overflow: hidden; + display: flex; width: 100%; white-space: nowrap; - overflow-x: auto; border: 1px solid $border-color; - border-radius: 6px; + border-radius: 0; padding: 0 !important; - letter-spacing: -0.32em; li { - letter-spacing: normal; - &:first-child { - button { - border: none; - } - } button { border: none !important; border-radius: 0 !important; @@ -476,6 +518,7 @@ body.view-instructordash { padding: 9px 17px; color: #374151; text-decoration: none !important; + outline-offset: 3px; &.active-section { background: $primary !important; color: white !important; @@ -483,6 +526,30 @@ body.view-instructordash { &:hover { color: #111827; } + &:focus { + position: relative; + z-index: 1; + } + } + + &:first-of-type { + button { + border: none; + border-radius: 6px 0 0 6px; + } + } + + &:last-of-type { + button { + border-radius: 0 6px 6px 0; + } + } + } + + .more-responsive-menu { + button { + display: block; + width: 100%; } } } @@ -817,6 +884,61 @@ body.view-wiki { } } } + +body { + .slick-header-column.ui-state-default { + height: auto; + } + .instructor-dashboard-wrapper-2 { + section.idash-section { + line-height: 1.3; + + &#membership .batch-beta-testers .request-res-section h3 { + color: $text-color-d; + } + &#student_admin input[type="text"] { + width: 100%; + max-width: 650px; + } + &#extensions { + select { + height: 35px; + border-color: $instructor-input-border-color; + + @include media-breakpoint-down(xs) { + display: block; + width: 100%; + } + + @include media-breakpoint-down(md) { + margin-bottom: 10px; + } + } + + input[type="text"] { + width: 100%; + + + input { + @include media-breakpoint-down(xs) { + margin-top: 10px; + } + } + + @include media-breakpoint-up(sm) { + max-width: 235px; + } + @include media-breakpoint-up(md) { + max-width: 300px; + } + } + } + } + .location-example { + word-wrap: break-word; + } + } +} + // Textbook Page body div.book-wrapper { margin: 0 auto; @@ -951,6 +1073,9 @@ body.indigo-dark-theme { &:hover { color: $text-color-d; } + &:focus { + box-shadow: inset 0 0 0 2px $border-color !important; + } } } } @@ -1454,6 +1579,43 @@ body.view-instructordash { } } +#data_download { + + .profile-data-display-table { + overflow-x: auto; + } + + .slick-cell { + padding: 3px; + height: 30px; + + &.active { + box-shadow: inset 0 0 0 2px $primary; + + .indigo-dark-theme & { + box-shadow: inset 0 0 0 2px $primary-d; + } + } + + a { + display: inline-block; + padding: 0 5px; + } + } +} + +.open-response-assessment-block { + .open-response-assessment-main-table { + th { + button { + &:focus { + outline: revert + } + } + } + } +} + @import "../../../instructor/instructor"; @import "../../../wiki/wiki"; @import "../../../extra/footer"; @@ -1468,3 +1630,6 @@ body.view-instructordash { @import "../../../programs/programs"; @import "../../../certificates/certificate"; @import "../../../xblock/xblock"; +@import '../../../views/teams'; +@import '../../../views/wiki'; +@import '../../../courseware/responsive-nav'; diff --git a/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_variables.scss b/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_variables.scss index 234f8aeb9..029b06cc7 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_variables.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/partials/lms/theme/_variables.scss @@ -28,7 +28,9 @@ $border-color-l:#e4e4e4; $primary-d: #AEC7F6; $primary-light-d: #292A2C; -$light-drak-d: #374151; +$gray-light: #E5E7EB; +$gray-lighter: #c8c8c8; +$light-dark-d: #374151; $text-color-d: #f8f8f8; $text-color-primary: #DDDFE2; $border-color-d: #777792; @@ -36,8 +38,9 @@ $light-overlay-d: #36383B; $danger-d: #FFA07A; $success-d: #54CF5E; $btn-color-d: #112F6B; -$body-bg-d:#0D0D0E; +$body-bg-d: #0D0D0E; +$instructor-input-border-color: $gray-lighter; $warning-400: #ffe340; $page-color-transition: transparent .2s ease, color .2s ease; From da1e74f4505794c8bf3a79a3fb1bacbb389562cd Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 12:15:19 -0500 Subject: [PATCH 15/18] feat: add views folder --- .../indigo/lms/static/sass/views/_teams.scss | 36 +++++++++++++++++++ .../indigo/lms/static/sass/views/_wiki.scss | 23 ++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 tutorindigo/templates/indigo/lms/static/sass/views/_teams.scss create mode 100644 tutorindigo/templates/indigo/lms/static/sass/views/_wiki.scss diff --git a/tutorindigo/templates/indigo/lms/static/sass/views/_teams.scss b/tutorindigo/templates/indigo/lms/static/sass/views/_teams.scss new file mode 100644 index 000000000..f4dc8c6f6 --- /dev/null +++ b/tutorindigo/templates/indigo/lms/static/sass/views/_teams.scss @@ -0,0 +1,36 @@ +.view-teams { + + .topics-paging-header { + + .listing-tools { + margin: 2px 0 $baseline * 1.5; + } + } + + .cards-list { + box-sizing: border-box; + padding-bottom: $baseline; + + @include media-breakpoint-up(sm) { + display: flex; + flex-wrap: wrap; + gap: $baseline * 2; + } + + .card { + margin: 0 0 $baseline * 2; + box-sizing: border-box; + width: 100%; + display: block; + + @include media-breakpoint-up(sm) { + margin: 0; + width: calc(50% - #{$baseline}); + } + + @include media-breakpoint-up(md) { + width: calc(33% - 25px); + } + } + } +} diff --git a/tutorindigo/templates/indigo/lms/static/sass/views/_wiki.scss b/tutorindigo/templates/indigo/lms/static/sass/views/_wiki.scss new file mode 100644 index 000000000..c4da3d889 --- /dev/null +++ b/tutorindigo/templates/indigo/lms/static/sass/views/_wiki.scss @@ -0,0 +1,23 @@ +.view-wiki { + + .wiki-wrapper { + + section.wiki { + line-height: 1.5; + + #hint_id_content { + position: static; + } + } + } +} + +.open-response-assessment { + line-height: 1.3; +} + +.open-response-assessment-summary, +.open-response-assessment-main-table { + max-width: 100%; + overflow-x: auto; +} From 05c7bca52d0b6f5072245eb867d50c7ab2ae72b5 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 23 Oct 2025 12:17:48 -0500 Subject: [PATCH 16/18] feat: update sass xblock folder --- .../lms/static/sass/xblock/_xblock.scss | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tutorindigo/templates/indigo/lms/static/sass/xblock/_xblock.scss b/tutorindigo/templates/indigo/lms/static/sass/xblock/_xblock.scss index 4a83a4de1..46d86f935 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/xblock/_xblock.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/xblock/_xblock.scss @@ -470,6 +470,41 @@ } + #feedback-container{ + background: $body-bg-d; + border: 1px solid $text-color-d; + p{ + color: $text-color-d; + } + } + + .emoji-button{ + background-color: $body-bg-d; + border: 1px solid $light-overlay-d; + + &:hover, + &:hover:not(:disabled){ + background-color: $light-dark-d; + } + } + + .emoji-button-highlighted{ + background-color: $text-color-d; + + &:hover, + &:hover:not(:disabled){ + background-color: $text-color-d; + } + } + .xblock.xmodule_display.xmodule_HtmlBlock .blue-text{color: $primary;} + .xblock.xmodule_display.xmodule_HtmlBlock ul li::marker, + .xblock.xmodule_display.xmodule_HtmlBlock ul li strong{ + color: $text-color-d; + } + .xblock.xmodule_display.xmodule_HtmlBlock .course-structure h3{ + color: $text-color-d; + } + .edx-notes-wrapper{ .annotator-hl{ background: orange; From f87293f1f0a8b3ae6086efff4439a43976751183 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Thu, 27 Nov 2025 12:33:20 -0500 Subject: [PATCH 17/18] fix: update variable name in wiki scss file --- .../templates/indigo/lms/static/sass/wiki/_wiki.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorindigo/templates/indigo/lms/static/sass/wiki/_wiki.scss b/tutorindigo/templates/indigo/lms/static/sass/wiki/_wiki.scss index 5624e12cb..92af8d9b8 100644 --- a/tutorindigo/templates/indigo/lms/static/sass/wiki/_wiki.scss +++ b/tutorindigo/templates/indigo/lms/static/sass/wiki/_wiki.scss @@ -105,7 +105,7 @@ } a.btn { border-color: $new-border-color !important; - color: $light-drak-d !important; + color: $light-dark-d !important; &:hover { border-color: $new-border-color !important; background: $bg-color !important; @@ -124,7 +124,7 @@ } a.btn { border-color: $new-border-color !important; - color: $light-drak-d !important; + color: $light-dark-d !important; &:hover { border-color: $new-border-color !important; background: $bg-color !important; @@ -144,7 +144,7 @@ } a.btn { border-color: $new-border-color !important; - color: $light-drak-d !important; + color: $light-dark-d !important; &:hover { border-color: $new-border-color !important; background: $bg-color !important; From d5e516593354b310480606adeed33fc6eee0a06c Mon Sep 17 00:00:00 2001 From: shadinaif Date: Wed, 3 Dec 2025 14:11:44 +0300 Subject: [PATCH 18/18] fix: open-in-new-tab no working --- .../lms/templates/fx_templates/fx_header_navbar_links.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorindigo/templates/indigo/lms/templates/fx_templates/fx_header_navbar_links.html b/tutorindigo/templates/indigo/lms/templates/fx_templates/fx_header_navbar_links.html index 0e49add1d..25ec0262a 100644 --- a/tutorindigo/templates/indigo/lms/templates/fx_templates/fx_header_navbar_links.html +++ b/tutorindigo/templates/indigo/lms/templates/fx_templates/fx_header_navbar_links.html @@ -8,7 +8,7 @@
    % for h_section in header_sections: