Skip to content

Preview course materials - #14907

Open
marcellamaki wants to merge 1 commit into
learningequality:developfrom
marcellamaki:course-preview
Open

Preview course materials#14907
marcellamaki wants to merge 1 commit into
learningequality:developfrom
marcellamaki:course-preview

Conversation

@marcellamaki

@marcellamaki marcellamaki commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

After some slack discussion with Richard and Alex, this implements a "course content previewing" option based on the existing side panel lesson and quiz content previewing/selection experience. Within a course, specific subsections of content cannot be selected, thus no checkboxes -- it's just about seeing the content and being able to access everything a learner will see. Pre-post test assessments are not included.

References

Fixes #14149

Screen.Recording.2026-07-14.at.6.56.02.PM.mov

Reviewer guidance

Assign course workflow AND Course details workflow should be tested (although they share components, so it's unlikely that there would be significant UI differences but there might be some data bugs I suppose!)

  1. Access preview from the side panel
  2. "accurate"/expected tree navigation including into folders and the back button within the side panel
  3. All content types are preview-able
  4. Edge cases such as direct navigation to a particular page (for example, bookmarking, closing the tab, and then going directly to that URL) -- can you access properly? Does the "back" button still move you back up the tree
  5. UX feedback request -- there currently isn't a navigation guard (mainly because there isn't a selection state that is persisting like for example in quiz creation, so there isn't anything to prompt the user to "save" before closing the side panel if they click on the backdrop). Does that feel too inconsistent? But also -- if we add it, what would it prompt 🙃

one extra manual QA note: I had one instance on load where flexbook content didn't load and I didn't have my console open for an error 🤦‍♀️ . I haven't been able to reproduce it. Worth seeing if this pops up.

AI usage

Implementation done collaboratively with Claude (with moments for human in the loop feedback on the workflow from both me and Richard via slack discussions to do some decision making). Two separate rounds of human/self-review of the code. 1 upon initial completion, and now 1 ~2 weeks later when marking issue as ready for review.

@github-actions github-actions Bot added APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) DEV: frontend SIZE: medium labels Jun 30, 2026
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

@marcellamaki marcellamaki left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added just a couple of notes

// Side panel routes accessible from the course summary page
COURSE_SUMMARY_ASSIGN: 'COURSE_SUMMARY_ASSIGN',
COURSE_SUMMARY_ASSIGN_COURSE_DETAILS: 'COURSE_SUMMARY_ASSIGN_COURSE_DETAILS',
COURSE_SUMMARY_ASSIGN_COURSE_PREVIEW: 'COURSE_SUMMARY_ASSIGN_COURSE_PREVIEW',

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a bit redundant? but following the existing pattern for course routing as I suspect there was good reason for it :)

@marcellamaki
marcellamaki marked this pull request as ready for review July 14, 2026 23:06
@marcellamaki
marcellamaki requested a review from rtibblesbot July 14, 2026 23:06
@rtibblesbot

rtibblesbot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

🔵 Review posted

Last updated: 2026-07-29 22:10 UTC

@rtibblesbot rtibblesbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #14907 adds a browsable course-resource preview side panel. Implementation is clean and matches the linked scope; the tree navigation (remount :key, _topicFetchId stale-guard, no-trust-of-topic.value-while-loading) is carefully reasoned. Findings below are all non-blocking.

CI passing. Manual QA was required for these UI changes but did not run in this pipeline, so the rendered UI has not been visually verified — not approving on UI grounds.

  • suggestion — New logic-bearing components ship with no tests; the goBack/route-derivation state machine is the part most likely to regress silently (inline).
  • suggestionCourseResourcePreview :label="contentNode.kind" is dead and would be an untranslated enum if rendered (inline).
  • suggestion — Shared SidePanelModal header tweak is unrelated to this feature and silently affects the search-filters back state (inline).
  • suggestion — Topic title (content text) lacks dir="auto" for RTL (inline).
  • nitpick — Back during an in-flight topic fetch exits the whole preview (inline).

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Ran a phased review pipeline over the pull request diff:

  • Classified the diff to select review passes (core, frontend, backend) and whether manual QA was required
  • Core review pass checked correctness, design, architecture, testing, completeness, and DRY/SRP/Rule-of-Three principles
  • Specialized frontend/backend review passes applied framework-specific lenses where those files changed
  • For UI changes: manual QA and an accessibility audit against a live dev server, when available
  • Checked CI status and linked issue acceptance criteria
  • Synthesized one review from those passes and chose the verdict from the findings, CI status, and QA evidence

Comment thread packages/kolibri-common/components/SidePanelModal/index.vue Outdated
@pcenov

pcenov commented Jul 16, 2026

Copy link
Copy Markdown
Member

Hi @marcellamaki,

Noticed the following issues:

  1. If there's a video description it somehow impacts the back arrow button so that it's not clickable. I have to click the 'View more' button of the video description in order to enable the back arrow button. Happens in both Chrome and Firefox:
video.with.description.mp4
  1. The 'Save to bookmarks' button is not working at all for all resources:
bookmarks.mp4

Improvement suggestion:

  1. Since there is a lot of navigation going on from one folder to another I would recommend adding breadcrumb navigation so that users will know exactly where they are and will be able to quickly jump back. Personally felt lost several times... 🙃
whynobreadcrumb.mp4

@marcellamaki

Copy link
Copy Markdown
Member Author

Thank you @pcenov -- I'll address these! The video bit is particularly strange. Good find 😂

@rtibblesbot rtibblesbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #14907 — delta re-review. 1 of 5 prior findings resolved (dir="auto" on the topic title); 4 still open (all suggestion/nitpick). No new findings. CI pending; manual QA was required but did not run, so the UI is not visually verified.

Still-open findings (see inline comments):

  • CoursePreviewSidePanel.vue:226 — no *.spec.js for goBack's three paths and the stale-loading fallback; views/courses/__tests__/ already has the pattern.
  • CourseResourcePreview.vue:7 — dead :label binding on a raw enum; drop it.
  • SidePanelModal/index.vue:33 — shared-component style change is unrelated to this flow; it only affects SearchFiltersPanel's back state.
  • CoursePreviewSidePanel.vue:234 — nitpick: back during in-flight fetch exits preview rather than going up a level (documented as deliberate).
Prior-finding status

RESOLVED — CoursePreviewSidePanel.vue:26 — topic.title needs dir="auto" for RTL
UNADDRESSED — CoursePreviewSidePanel.vue:226 — no spec for goBack/route derivation
UNADDRESSED — CoursePreviewSidePanel.vue:234 — loading fallback drops user out of preview
UNADDRESSED — CourseResourcePreview.vue:7 — dead :label binding on raw enum
UNADDRESSED — SidePanelModal/index.vue:33 — unrelated shared-component change


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:

  • Retrieved prior bot reviews via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
  • Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence

Comment thread packages/kolibri-common/components/SidePanelModal/index.vue Outdated

@rtibblesbot rtibblesbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #14907 — delta re-review. All five prior findings resolved (dir="auto" persists, spec covers the three goBack paths + stale-loading fallback, dead :label replaced by KLabeledIcon+title, the unrelated SidePanelModal change is gone, loading fallback now hides the back button rather than exiting preview). One new edge-case suggestion below on the error path; not blocking.

CI pending. Manual QA was required for these UI changes but did not run this pass — the rendered UI is not visually verified, so this is not an approval on UI grounds.

  • suggestiongoBackHandler can dereference a null topic on the fetch-error path (see inline).
Prior-finding status

RESOLVED — CoursePreviewSidePanel.vue:26 — topic.title needs dir="auto" for RTL
RESOLVED — CoursePreviewSidePanel.vue:226 — no spec for goBack/route derivation
RESOLVED — CoursePreviewSidePanel.vue:234 — loading fallback drops user out of preview
RESOLVED — CourseResourcePreview.vue:7 — dead :label binding on raw enum
RESOLVED — SidePanelModal/index.vue:33 — unrelated shared-component change


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:

  • Retrieved prior bot reviews via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
  • Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence

@radinamatic

Copy link
Copy Markdown
Member

Course details workflow:

  • access preview from the side panel ✔️
  • tree navigation including into folders and the back button within the side panel ✔️
  • all content types are preview-able ✔️

Potential issue with direct navigation to a bookmarked page (preview of a single resource), "back" button apparently moves well up the tree with one difference (screenshot below):

  1. Course contents in a side panel once it has been assigned to recipients (entire class).
  2. Second browser tab where I opened a bookmarked page of a single resource preview, and repeatedly used the ⬅️, until I arrived to what seems like the same course contents in a side panel as in 1., but it also has a back ⬅️ button...? 🤨
  3. If I press that ⬅️ I get to the Select course to assign side panel. Nothing above necessarily needs to be a blocker, a part from the fact that it allowed me to assign the same course for a second time, even though it is already assigned to the entire class. I could understand it should be displayed and offered to assign again if the first one has only part of class as recipients (single learners or a group), but if a course has already been assigned to the entire class, what would be the point of it being displayed here again?
Ubuntu22 04 2606 (start)  Running  - Oracle VirtualBox_015

there isn't anything to prompt the user to "save" before closing the side panel if they click on the backdrop). Does that feel too inconsistent? But also -- if we add it, what would it prompt 🙃

Maybe a question for @jtamiace?

one instance on load where flexbook content didn't load

I couldn't replicate this with any Flexbox resources included in the 2 courses. Will keep an 👁️

Of the 2 issues reported by @pcenov, bookmarking resources during preview is now working correctly ✔️, but it is still not possible to use the back ⬅️ button if the video has a description (one must first press View more, so weird 😳).

@rtibbles rtibbles self-assigned this Jul 27, 2026
@marcellamaki

Copy link
Copy Markdown
Member Author

Per slack chat with @radinamatic and @rtibbles, we are going to just remove the bookmark functionality all together (not required for previewing, adds more headaches than it's probably worth at least for now).

I also have double-double checked the video preview back button and really think it's fixed so hopefully QA team agrees with me 😂 🤞

ready for re-review -- thank you!

@rtibblesbot rtibblesbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #14907 — delta re-review (d7ba770edaa67d). 9 of 10 prior findings resolved; 1 still open (see inline). Removing bookmarking from the preview panel is a clean scope reduction, and it came with a test that renders the real AccessibleResourceCard.

CI still pending (only Python/Morango jobs outstanding — none touch this diff); frontend tests and lint pass. Manual QA did not run, so nothing here is visually verified.

New, both non-blocking and inline: the shared SlotTruncator CSS fix looks correct but silently changes overlay geometry for three consumers outside this feature, and :showBookmarkButton is bound on the folder-card branch of <component :is> where the prop doesn't exist.

Prior-finding status

RESOLVED — CoursePreviewSidePanel.vue:26 — topic.title needs dir="auto" for RTL
RESOLVED — CoursePreviewSidePanel.vue:226 — no spec for goBack/route derivation (round 1)
RESOLVED — CoursePreviewSidePanel.vue:226 — no spec for goBack/route derivation (round 2)
RESOLVED — CoursePreviewSidePanel.vue:180 — branching route derivation untested/duplicated
RESOLVED — CoursePreviewSidePanel.vue:234 — loading fallback drops user out of preview (round 1)
RESOLVED — CoursePreviewSidePanel.vue:234 — loading fallback drops user out of preview (round 2)
RESOLVED — CourseResourcePreview.vue:7 — dead :label binding on raw enum (round 1)
RESOLVED — CourseResourcePreview.vue:7 — dead :label binding on raw enum (round 2)
RESOLVED — SidePanelModal/index.vue:33 — unrelated shared-component change
UNADDRESSED — CoursePreviewSidePanel.vue:171 — goBackHandler dereferences null topic on the fetch-error path


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:

  • Retrieved prior bot reviews via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
  • Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence

Comment thread packages/kolibri-common/components/SlotTruncator.vue
@pcenov

pcenov commented Jul 29, 2026

Copy link
Copy Markdown
Member

Hi @marcellamaki - already looks great and I confirm that the rogue Back button is working fine now. :)

For the breadcrumb navigation I was wondering whether it would be possible to add a direct link to the actual main Courses page and not just to the course that one is currently previewing?
For example I would expect the breadcrumb navigation to look like this Courses > Hummingbird Biology > Flight Mechanics so that when I click on Courses I would go back straight to the initial state of the side panel instead of first going to Hummingbird Biology and then having to click twice the Back button to get back to the initial page.

navigation.mp4

Also observed the following issue: I'm sometimes getting an error when I go to a kpub resource such as Into computing > Functions & Modularity > Defining functions after having previewed an exercise prior to that. I'm able to replicate the error in all supported browsers. Refreshing the page fixes the issue:

error.mp4

Console:

useFetchContentNode.js:20 TypeError: First parameter has member 'readable' that is not a ReadableStream.
    at K (polyfill.js:8:3934)
    at polyfill.js:8:49855
    at rg.pipeThrough (polyfill.js:8:50037)
    at new eW (codec-worker.js:69:6)
    at codec-pool.js:79:11
    at Object.<anonymous> (kolibri.plugins.safe_html5_viewer.main-0.19.6.dev2359+gb2ec3a73d.js:1:101052)
    at e$ (kolibri.plugins.safe_html5_viewer.main-0.19.6.dev2359+gb2ec3a73d.js:1:99678)
    at i (kolibri.plugins.safe_html5_viewer.main-0.19.6.dev2359+gb2ec3a73d.js:1:99876)
    at kolibri.plugins.safe_html5_viewer.main-0.19.6.dev2359+gb2ec3a73d.js:1:99937
    at new Promise (<anonymous>)

packages/kolibri/components/internal/filePresetStrings.js] Download translation string not defined for 'kpub'

@marcellamaki

Copy link
Copy Markdown
Member Author

For example I would expect the breadcrumb navigation to look like this Courses > Hummingbird Biology > Flight Mechanics so that when I click on Courses I would go back straight to the initial state of the side panel instead of first going to Hummingbird Biology and then having to click twice the Back button to get back to the initial page.

yes, that makes sense to me, @pcenov. I think it would work well here, and on the "course details" version of this (meaning, when the course is already assigned), I will still skip that breadcrumb (as it wouldn't make sense in that context, I don't think)

As for the kpub - I am curious if this is an underlying bug with something about the kpub state management... I'll investigate

@rtibblesbot rtibblesbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #14907 — delta re-review of the new "Courses" breadcrumb crumb and its two tests (edaa67d..6a17c30).

9 of 12 prior findings resolved; 3 still open (one substantive, two acknowledged as no-action).

The crumb is correctly gated on the assign-vs-summary flow, using the same courseSessionId discriminator exitPreview() already relies on. New findings are all minor and inline. CI is still pending (outstanding checks are Python/Morango jobs that don't touch this diff); manual QA did not run in this pass, so nothing here is visually verified.

Still open from earlier rounds:

  • CoursePreviewSidePanel.vue:185suggestion: goBack guards the loading window but not the error window. useFetch leaves topic untouched and sets loading=false on rejection, so a failed first fetchTree on a deep-topic URL leaves a blank panel with a live back button that throws on topic.value.parent. Third round unaddressed and not rebutted — still non-blocking; a one-line reply saying it's intentional would close it out.
Prior-finding status

UNADDRESSED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:185 — goBackHandler dereferences null topic on the fetch-error path
ACKNOWLEDGED — packages/kolibri-common/components/SlotTruncator.vue:113 — shared CSS fix changes overlay geometry for three consumers outside this feature
ACKNOWLEDGED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:45 — :showBookmarkButton bound on the folder-card branch of <component :is>
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:26 — topic.title needs dir="auto" for RTL
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:226 — no spec for goBack/route derivation
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:180 — branching route derivation untested/duplicated
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:234 — loading fallback drops user out of preview
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CourseResourcePreview.vue:7 — dead :label binding on raw enum
RESOLVED — packages/kolibri-common/components/SidePanelModal/index.vue:33 — unrelated shared-component change


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:

  • Retrieved prior bot reviews via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
  • Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence

@rtibblesbot rtibblesbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #14907 — delta re-review of 6a17c30..9b0bbec.

11 of 11 prior findings settled (9 resolved, 2 acknowledged); 2 new non-blocking findings below. CI is green on 9b0bbec (86/86). Manual QA did not run in this pass — nothing was visually verified.

  • suggestion — the back-button guard keys off useFetch's shared error ref, so a failed "View more" hides the back button on an otherwise fully-loaded topic (inline).
  • nitpick — the fetch-error state still renders as an empty panel (inline).
Prior-finding status

RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:185 — goBackHandler dereferences null topic on the fetch-error path
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/tests/CoursePreviewSidePanel.spec.js:88 — crumb test doesn't assert the destination
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:32 — redundant single crumb in the summary flow
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:32 — coursesLabel$() vs selectCourseLabel$() for the crumb
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:26 — topic.title needs dir="auto" for RTL
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:226 — no spec for goBack / route derivation
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:234 — loading fallback drops the user out of preview
RESOLVED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CourseResourcePreview.vue:7 — dead :label binding on raw enum
RESOLVED — packages/kolibri-common/components/SidePanelModal/index.vue:33 — unrelated shared-component change
ACKNOWLEDGED — packages/kolibri-common/components/SlotTruncator.vue:113 — shared CSS fix changes overlay geometry for three consumers outside this feature
ACKNOWLEDGED — kolibri/plugins/coach/frontend/views/courses/sidePanels/AssignCourse/subpages/CoursePreviewSidePanel.vue:45 — :showBookmarkButton bound on the folder-card branch of <component :is>


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:

  • Retrieved prior bot reviews via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
  • Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence


<template v-else>
<KCircularLoader v-if="loading" />
<div v-else-if="children">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Consuming error closed the crash, but nothing renders it: on a rejected first fetchTree, loading is false and children is null, so this branch is false and the body is empty — and the back button is now hidden too, leaving SidePanelModal's close/backdrop as the only exit. CourseUnitView/index.vue:954 has the in-repo one-liner (watch(error, ... handleApiError({ error }))) if you want it. Flagging only because the guard fix makes the blank state slightly more of a dead end than before.

Implement rtibblesbot cleanup fixes

@rtibblesbot rtibblesbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #14907 — delta re-review of 9b0bbec6e821b9 (7 added / 6 removed lines, all in CoursePreviewSidePanel.vue).

11 of 14 prior findings resolved; 2 acknowledged, 1 still open (see inline). One new nitpick on how the narrowed back-button guard was wrapped — nothing blocking.

The guard now keys on topic.value?.id !== currentTopicId.value instead of loading || error, which is the right invariant: a failed "View more" on a fully-rendered topic no longer hides the back button, and all three stale/missing-topic cases stay covered by the existing specs.

CI: frontend tests, lint, CodeQL and Python 3.10 unit tests green on 6e821b9; remaining jobs are packaging/Android/Morango, none of which touch this frontend-only diff. Manual QA did not run in this pass, so nothing here is a statement about the rendered UI.

Prior-finding status

RESOLVED — CoursePreviewSidePanel.vue:26 — topic.title needs dir="auto" for RTL
RESOLVED — CoursePreviewSidePanel.vue:226 — no spec for goBack/route derivation
RESOLVED — CoursePreviewSidePanel.vue:180 — branching route derivation untested/duplicated
RESOLVED — CoursePreviewSidePanel.vue:234 — loading fallback drops user out of preview
RESOLVED — CourseResourcePreview.vue:7 — dead :label binding on raw enum
RESOLVED — SidePanelModal/index.vue:33 — unrelated shared-component change
RESOLVED — CoursePreviewSidePanel.vue:185 — goBackHandler dereferences null topic on the fetch-error path
RESOLVED — CoursePreviewSidePanel.vue:32 — redundant single breadcrumb at course root
RESOLVED — CoursePreviewSidePanel.vue:147 — crumb label ambiguous (coursesLabel$selectCourseLabel$)
RESOLVED — tests/CoursePreviewSidePanel.spec.js:91 — crumb test asserted text, not destination
RESOLVED — CoursePreviewSidePanel.vue:199 — isAmbiguousParent conflated fetchMore errors with an ambiguous parent
ACKNOWLEDGED — SlotTruncator.vue:113 — shared CSS fix affects three consumers outside this feature
ACKNOWLEDGED — CoursePreviewSidePanel.vue:45 — :showBookmarkButton bound on the folder-card branch
UNADDRESSED — CoursePreviewSidePanel.vue:19 — fetch error is never surfaced


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:

  • Retrieved prior bot reviews via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
  • Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence

// or if the fetch fails, it may still hold stale data (or none at all). Hide
// the back button in both cases rather than navigating to a wrong/missing parent.
const goBack = computed(() => {
const isAmbiguousParent = computed(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: The inner computed() should be a plain expression — it buys nothing over the boolean and leaks a watcher per evaluation.

const goBack = computed(() => {
  const isAmbiguousParent =
    !previewContentId.value &&
    currentTopicId.value !== route.params.courseId &&
    topic.value?.id !== currentTopicId.value;
  return isAmbiguousParent ? null : goBackHandler;
});

Vue 2.7.16's computed() constructs new Watcher(vm, getter, noop, { lazy: true }) (vue/dist/vue.runtime.common.dev.js:1312), whose constructor calls recordEffectScope(this, … vm._scope …) (:3352-3360) — pushing the watcher into the component's effect scope, released only on destroy. Computed getters run inside _render where setCurrentInstance(vm) is active (:2600), so every re-evaluation of goBack (each route/topic change) appends another never-collected lazy watcher on the same deps. Bounded by the panel's lifetime and not user-visible, so purely cleanup.


<template v-else>
<KCircularLoader v-if="loading" />
<div v-else-if="children">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Still open from the last round, raised for the record. error is no longer destructured from useFetch at all, so a rejected first fetchTree leaves loading false and children null — the panel body renders empty with the back button hidden and no way to retry or understand why. A v-else branch with an error message (and ideally a retry) would close it.

@marcellamaki marcellamaki changed the title Add ability to side-panel preview course materials Preview course materials Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

APP: Coach Re: Coach App (lessons, quizzes, groups, reports, etc.) DEV: frontend DEV: renderers HTML5 apps, videos, exercises, etc. SIZE: large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Course description - Missing 'Preview' button

5 participants