Skip to content

Study Condition in URL#1023

Merged
jaykim1213 merged 42 commits intodevfrom
jk/studyConditionURL
Feb 20, 2026
Merged

Study Condition in URL#1023
jaykim1213 merged 42 commits intodevfrom
jk/studyConditionURL

Conversation

@jaykim1213
Copy link
Copy Markdown
Contributor

@jaykim1213 jaykim1213 commented Jan 30, 2026

Does this PR close any open issues?

Closes #799

Give a longer description of what this PR addresses and why it's needed

  • Add study condition in URL
  • Add selecting study condition and copying study links from the landing page
  • Add demo-condition
  • Support multiple conditions (comma separated)
    /path/to/study?condition=color,size
  • Add condition to tidy download
  • Add condition filter in analysis page
  • Add condition in the sidebar
"sequence": {
    "order": "fixed",
    "components": [
      "introduction",
      {
        "id": "color",
        "conditional": true,
        "components": [
          "color-trial-1",
          "color-trial-2"
        ],
        "order": "random"
      },
      {
        "id": "shape",
        "conditional": true,
        "components": [
          "shape-trial-1",
          "shape-trial-2"
        ],
        "order": "fixed"
      }
    ]
  }

These would then be accessed via a query param:

/path/to/study?condition=size
/path/to/study?condition=color
/path/to/study?condition=size,color

The effect would be that blocks that don't match the condition specified in the query param would be ignored. So all blocks with no condition will be included, all blocks with the matching condition as well.

Provide pictures/videos of the behavior before and after these changes (optional)

Live demo:
https://revisit.dev/study/PR1023
https://revisit.dev/study/PR1023/demo-condition?condition=color

Landing page

Screenshot 2026-02-11 at 5 26 05 PM

Study

Screenshot 2026-02-11 at 5 36 57 PM Screenshot 2026-02-11 at 5 38 42 PM

Analysis

Screenshot 2026-02-11 at 4 45 46 PM

Are there any additional TODOs before this PR is ready to go?

TODOs:

  • Update relevant documentation

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jan 30, 2026

🪓 PR closed, deleted preview.

@JackWilb JackWilb linked an issue Jan 30, 2026 that may be closed by this pull request
@jaykim1213 jaykim1213 added this to the v2.4 milestone Jan 30, 2026
@jaykim1213 jaykim1213 marked this pull request as ready for review February 2, 2026 21:49
@JackWilb JackWilb requested a review from Copilot February 3, 2026 00:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements study conditions in URL query parameters, allowing researchers to define multiple experimental conditions within a single study configuration and select which condition to run via a URL parameter (e.g., ?condition=color). This addresses issue #799 by enabling condition-based filtering of study sequences without requiring duplicate study configurations.

Changes:

  • Added condition field to ComponentBlock and DynamicBlock types and schemas to mark conditional blocks
  • Implemented condition filtering utilities (parseConditionParam, filterSequenceByCondition, getSequenceConditions, getConditionParticipantCounts)
  • Modified sequence generation and storage to support condition-based filtering
  • Updated UI components to display and select conditions (ConfigSwitcher landing page with dropdown)
  • Preserved search parameters across navigation to maintain condition context
  • Added demo-condition study showcasing color, size, and shape condition variants

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/utils/handleSequenceConditions.ts New utility module for parsing, filtering, and analyzing conditions in sequences
src/utils/handleSequenceConditions.spec.ts Comprehensive test coverage for condition parsing and filtering functions
src/storage/engines/types.ts Modified sequence generation logic to handle conditions; added updateParticipantSearchParams method
src/utils/handleRandomSequences.tsx Updated to preserve condition field when converting ComponentBlocks to Sequences
src/utils/getSequenceFlatMap.ts Added condition field preservation in path mapping
src/store/types.ts Added optional condition field to Sequence interface
src/parser/types.ts Added condition field to ComponentBlock and DynamicBlock interfaces with documentation
src/parser/StudyConfigSchema.json Added condition property to ComponentBlock and DynamicBlock schemas
src/parser/LibraryConfigSchema.json Added condition property to library schemas
src/components/Shell.tsx Implemented condition filtering and handling for participant sessions
src/components/ConfigSwitcher.tsx Added condition selector dropdown with participant counts per condition
src/components/interface/StepsPanel.tsx Preserved search params in navigation
src/controllers/ComponentController.tsx Preserved search params when auto-forwarding participants
src/utils/useNavigateToTrial.tsx Added searchParams parameter to preserve condition when opening trials
src/analysis/individualStudy/thinkAloud/ThinkAloudFooter.tsx Preserved participant search params in replay links
src/analysis/individualStudy/table/TableView.tsx Added conditional Condition column when participants have conditions
src/analysis/individualStudy/replay/SingleTask.tsx Added searchParams to task replay navigation
src/analysis/individualStudy/replay/AllTasksTimeline.tsx Passed participant searchParams to SingleTask components
public/global.json Registered demo-condition study
public/demo-condition/config.json Demo study configuration with three conditions (color, size, shape)
public/demo-condition/assets/* HTML and markdown assets for demo trials

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/storage/engines/types.ts Outdated
Comment thread src/storage/engines/types.ts Outdated
Comment thread src/components/Shell.tsx Outdated
Comment thread src/utils/handleSequenceConditions.ts
Comment thread public/demo-condition/assets/color-trial-2.html Outdated
Comment thread public/demo-condition/assets/color-trial-2.html Outdated
Copy link
Copy Markdown
Contributor

@JackWilb JackWilb left a comment

Choose a reason for hiding this comment

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

Some thoughts

Comment thread src/utils/useNavigateToTrial.tsx Outdated
Comment thread src/components/Shell.tsx Outdated
Comment thread src/storage/engines/types.ts Outdated
if (hasConditions && config) {
// Generate fresh sequences and filter for this participant's condition
const fullSequenceArray = generateSequenceArray(config);
sequenceArray = fullSequenceArray.map((seq) => filterSequenceByCondition(seq, activeCondition));
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.

Is it possible that we don't generate a sequence with the requested condition if the config is large enough?

Comment thread src/storage/engines/types.ts Outdated
Comment thread src/utils/handleSequenceConditions.ts
JackWilb and others added 9 commits February 2, 2026 18:06
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Added reminder for participants to proceed correctly.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/Shell.tsx Outdated
Comment on lines +166 to +170
const matchingSequence = studyCondition
? generatedSequences.find(
(sequence) => getSequenceConditions(sequence).includes(studyCondition),
)
: generatedSequences[0];
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The fallback logic for finding a matching sequence when studyCondition is specified is incorrect. The code looks for a sequence that contains the specified condition using getSequenceConditions, but it should instead filter the selected sequence using filterSequenceByCondition.

Currently, if a condition is specified in the URL but an error occurs, the fallback will try to find a pre-generated sequence that happens to include that condition. However, this doesn't apply the condition filtering logic and may include all conditional blocks instead of just the matching ones.

The correct approach would be to select a sequence (e.g., generatedSequences[0]) and then apply filterSequenceByCondition to it, similar to how it's done in the success path at line 148.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated it to filter using filterSequenceByCondition

const matchingSequence = generatedSequences[0];
        const fallbackSequence = filterSequenceByCondition(
          matchingSequence,
          studyCondition,
        );

Comment thread src/components/interface/StepsPanel.tsx Outdated
Copy link
Copy Markdown
Contributor

@JackWilb JackWilb left a comment

Choose a reason for hiding this comment

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

Some questions

>
<g>
<SingleTask incomplete={answer.startTime === 0} isCorrect={isCorrect} hasCorrect={hasCorrect} key={name} labelHeight={currentHeight * LABEL_GAP} height={maxHeight} name={name} xScale={scale} scaleStart={scaleStart} scaleEnd={scaleEnd} trialOrder={answer.trialOrder} participantId={participantData.participantId} studyId={studyId} />
<SingleTask incomplete={answer.startTime === 0} isCorrect={isCorrect} hasCorrect={hasCorrect} key={name} labelHeight={currentHeight * LABEL_GAP} height={maxHeight} name={name} xScale={scale} scaleStart={scaleStart} scaleEnd={scaleEnd} trialOrder={answer.trialOrder} participantId={participantData.participantId} studyId={studyId} condition={participantData.searchParams?.condition} />
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.

Are there any issues with using participantData.searchParams here? Does this work on refresh? What if I switch to a different condition? How are the searchParams updated for a participant? They shouldn't be able to change conditions in a study, but we should be able to in dev.

Copy link
Copy Markdown
Contributor Author

@jaykim1213 jaykim1213 Feb 13, 2026

Choose a reason for hiding this comment

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

  • Add a studyCondition with the ParticipantData in storage types.ts so it also works when it's refreshed since it's saved in the storage
  • Add if the mode is developmentModeEnabled, allow updating condition

Comment thread src/components/interface/StepsPanel.tsx Outdated
Comment on lines +752 to +754
{!isComponent && conditional && (
<Badge size="xs" ml={5} variant="transparent">{label}</Badge>
)}
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.

Do we need this with the new logic in the sequence?

Copy link
Copy Markdown
Contributor Author

@jaykim1213 jaykim1213 Feb 13, 2026

Choose a reason for hiding this comment

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

Use icon and tooltip instead of a badge

Comment thread src/components/Shell.tsx
...participantSession.searchParams,
condition: studyCondition,
};
await storageEngine.updateParticipantSearchParams(updatedSearchParams);
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.

Does this let a participant change conditions mid way through a study?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It will not update the condition unless in devMode

types.ts

async updateStudyCondition(condition: string | string[]) {
...
    const modes = await this.getModes(this.studyId);
    if (!modes.developmentModeEnabled) {
      throw new Error('Cannot update study condition when development mode is disabled');
    }
...
  }

@JackWilb
Copy link
Copy Markdown
Contributor

JackWilb commented Feb 13, 2026

  • Moving the stored data
  • Gating the ability to change behind devMode
  • Expand the test to make sure we can't change unless we're in devMode
  • Study stage to tidy download
  • Multi select on study card, multi select in study browser
  • Show condition on all rows for participant in tidy download
  • Double check nested conditions

@jaykim1213 jaykim1213 removed this from the v2.4 milestone Feb 19, 2026
@jaykim1213 jaykim1213 mentioned this pull request Feb 20, 2026
13 tasks
# Conflicts:
#	src/components/ConfigSwitcher.tsx
#	src/components/downloader/DownloadTidy.tsx
@jaykim1213
Copy link
Copy Markdown
Contributor Author

jaykim1213 commented Feb 20, 2026

  • Default not selectable in multi select dropdown

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/storage/engines/types.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/Shell.tsx
Comment thread src/analysis/individualStudy/table/TableView.tsx Outdated
Comment thread src/storage/engines/types.ts Outdated
@jaykim1213 jaykim1213 merged commit e908906 into dev Feb 20, 2026
6 of 8 checks passed
@jaykim1213 jaykim1213 deleted the jk/studyConditionURL branch February 20, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Top Level Flag for Study Condition in URL

5 participants