Study
=====
This documentation explains the **purpose**, **props/events**, and **integration patterns** for each modal connected to study.
Use these patterns to add study features or wire the modals into dashboards and routes.
Key features:
- **End-to-end session flow**: join/start, resume, finish, evaluate, and report.
- **Store-backed rendering**: lists of sessions, tags, comments, and annotations are pulled from :doc:`../vuex_store` ``table/*`` stores.
- **WebSocket actions**: starting/finishing sessions, updating evaluations, etc.
- **Navigation & telemetry hooks**: emit events to scroll the PDF/Sidebar, emit optional :doc:`../stats` events, and route back to :doc:`dashboard`.
StudyModal
----------
Location: ``frontend/src/components/study/StudyModal.vue``
**Purpose**
Gatekeeper to a study: either **start/join** a session (collab or solo), **resume** open sessions, or **finish** specific ones from a table of sessions.
**Highlights**
- Renders a sessions table for the selected study with **contextual action buttons**:
- **Start session** (if resumable = false and session not started)
- **Resume session** (if resumable and started)
- **Finish session** (close an open session)
- Shows study description (read-only) and meta-info (time limit, collab, session limits).
- Emits:
- ``@start({ studySessionId })`` — after a successful ``studySessionStart`` socket call
- ``@finish({ studySessionId })`` — when user triggers finish from the table
**Initialization / Data dependencies**
- Props:
- ``studyId`` (Number, required)
- ``studyClosed`` (Boolean)
- ``studySessionId`` (Number, default 0)
- Reads from Vuex:
- ``table/study`` (study meta, scheduling, constraints)
- ``table/study_session`` (all sessions for the study, transformed for the table)
- WebSocket:
- ``studySessionStart`` — start/join a session
- Optional stats: emits a ``stats`` event on session actions if ``acceptStats`` is provided via inject.
**Usage**
.. code-block:: html
In a dashboard list:
.. code-block:: html
In a study route:
.. code-block:: html
.. _finish-modal:
FinishModal
-----------
Location: ``frontend/src/components/study/FinishModal.vue``
**Purpose**
Confirm final submission of a study; show *time up* information when applicable, then thank-you and link back to dashboard after finishing.
**Highlights**
- Props:
- ``studySessionId`` (Number, required)
- ``closeable`` (Boolean) — disables closing with keyboard/close button if false
- ``showTimeUp`` (Boolean) — displays *time expired* message
- ``finished`` (Boolean) — if already finished, auto-opens in thank-you view
- Emits:
- ``@finish`` — when user clicks “Finish study”
- Navigation:
- “Back to Dashboard” button after finish
**Usage**
.. code-block:: html
ReviewModal
-----------
Location: ``frontend/src/components/study/ReviewModal.vue``
**Purpose**
Allow a reviewer to **accept** or **decline** a **finished** study session with an optional comment.
**Highlights**
- Only actionable if the target session has an ``end`` timestamp (i.e., it’s closed).
- Props via inject:
- ``studySessionId`` — used to fetch the session and to validate state
- Emits no custom event; instead it **writes via socket**:
- ``studySessionUpdate`` with fields ``evaluation`` (0/1) and ``reviewComment``
- Computed:
- ``evaluated`` checks if current session already has an evaluation
**Usage**
.. code-block:: javascript
this.$refs.reviewModal.open();
ReportModal (+ ReportItem)
--------------------------
Location:
- ``frontend/src/components/study/ReportModal.vue``
- ``frontend/src/components/study/ReportItem.vue``
**Purpose**
Generate a **review report** for a study by grouping annotations by tag (sections) and listing **general notes** (top).
Each entry is clickable and **jumps to the PDF & Sidebar** position (see :doc:`annotator`).
**Highlights**
- Collects **annotations** (from all sessions of the current study) and **comments** without annotation (general notes).
- Groups by **tagId** to create sections (with tag color).
- Sorting:
- Anchored annotations are sorted by ``TextPositionSelector.start`` (see :doc:`annotator`)
- Items without anchors are listed first
- Interaction:
- Clicking an item emits ``sidebarScroll`` and ``pdfScroll`` with the related id
- The **ReportItem** component:
- Displays the annotation’s leading comment or “(no text)”
- Shows a citation button rendering the **quote** (``TextQuoteSelector.exact``) as tooltip
- Emits back to ReportModal which forwards PDF/Sidebar scroll events and closes itself
**Usage**
.. code-block:: javascript
this.$refs.reportModal.open();