Skip to content

Commit 33465b1

Browse files
authored
Merge branch 'DouglasNeuroInformatics:main' into set-sample-data
2 parents b9562ab + 99dc341 commit 33465b1

File tree

8 files changed

+3305
-5001
lines changed

8 files changed

+3305
-5001
lines changed

packages/instrument-library/src/forms/patient-health-questionnaire-9/index.ts

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
/* eslint-disable perfectionist/sort-objects */
22

33
import { defineInstrument } from '/runtime/v1/@opendatacapture/runtime-core';
4-
import { sum } from '/runtime/v1/[email protected]';
4+
import { omit, sum } from '/runtime/v1/[email protected]';
55
import { z } from '/runtime/v1/[email protected]';
66

7+
const $Response = z.number().int().min(0).max(3);
8+
79
export default defineInstrument({
810
kind: 'FORM',
911
language: ['en', 'fr'],
1012
tags: {
11-
en: ['Health'],
12-
fr: ['Santé']
13+
en: ['Health', 'Depression'],
14+
fr: ['Santé', 'Dépression']
1315
},
1416
internal: {
1517
edition: 1,
@@ -90,16 +92,16 @@ export default defineInstrument({
9092
},
9193
options: {
9294
en: {
93-
0: 'Not at all',
94-
1: 'Several days',
95-
2: 'More than half of days',
95+
0: 'Not at All',
96+
1: 'Several Days',
97+
2: 'More than half the days',
9698
3: 'Nearly every day'
9799
},
98100
fr: {
99-
0: 'Not at all',
100-
1: 'Several days',
101-
2: 'More than half of days',
102-
3: 'Nearly every day'
101+
0: 'Jamais',
102+
1: 'Plusieurs jours',
103+
2: 'Plus de la moitié des jours',
104+
3: 'Presque tous les jours'
103105
}
104106
},
105107
variant: 'likert'
@@ -216,21 +218,33 @@ export default defineInstrument({
216218
totalScore: {
217219
kind: 'computed',
218220
label: { en: 'Total Score', fr: 'Score total' },
219-
value: ({ questions }) => sum(Object.values(questions))
221+
value: ({ questions }) => sum(Object.values(omit(questions, 'impactOnFunctioning')))
220222
}
221223
},
222-
validationSchema: z.object({
223-
questions: z.object({
224-
interestPleasure: z.number().int().min(0).max(3),
225-
feelingDown: z.number().int().min(0).max(3),
226-
sleepIssues: z.number().int().min(0).max(3),
227-
energyLevel: z.number().int().min(0).max(3),
228-
appetiteChanges: z.number().int().min(0).max(3),
229-
selfWorth: z.number().int().min(0).max(3),
230-
concentrationIssues: z.number().int().min(0).max(3),
231-
psychomotorChanges: z.number().int().min(0).max(3),
232-
suicidalThoughts: z.number().int().min(0).max(3)
233-
}),
234-
impactOnFunctioning: z.number().int().min(0).max(3).optional()
235-
})
224+
validationSchema: z
225+
.object({
226+
questions: z.object({
227+
interestPleasure: $Response,
228+
feelingDown: $Response,
229+
sleepIssues: $Response,
230+
energyLevel: $Response,
231+
appetiteChanges: $Response,
232+
selfWorth: $Response,
233+
concentrationIssues: $Response,
234+
psychomotorChanges: $Response,
235+
suicidalThoughts: $Response
236+
}),
237+
impactOnFunctioning: $Response.optional()
238+
})
239+
.superRefine(({ impactOnFunctioning, questions }, ctx) => {
240+
const isAnyNonZero = sum(Object.values(questions)) > 0;
241+
// If any response is not zero, then impactOnFunctioning is required
242+
if (isAnyNonZero && impactOnFunctioning === undefined) {
243+
ctx.addIssue({
244+
code: 'custom',
245+
message: 'This question is required / Cette question est obligatoire',
246+
path: ['impactOnFunctioning']
247+
});
248+
}
249+
})
236250
});

pnpm-lock.yaml

Lines changed: 3023 additions & 4976 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runtime/v1/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@jspsych/plugin-image-button-response__2.x": "workspace:*",
3838
"@jspsych/plugin-image-keyboard-response__1.x": "workspace:*",
3939
"@jspsych/plugin-image-keyboard-response__2.x": "workspace:*",
40+
"@jspsych/plugin-instructions__2.x": "workspace:*",
4041
"@jspsych/plugin-preload__1.x": "workspace:*",
4142
"@jspsych/plugin-preload__2.x": "workspace:*",
4243
"@jspsych/plugin-survey-html-form__1.x": "workspace:*",

runtime/v1/runtime.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default {
1414
'@jspsych/plugin-image-keyboard-response__2.x',
1515
'@jspsych/plugin-preload__1.x',
1616
'@jspsych/plugin-preload__2.x',
17+
'@jspsych/plugin-instructions__2.x',
1718
'@jspsych/plugin-survey-html-form__1.x',
1819
'@jspsych/plugin-survey-html-form__2.x',
1920
'@jspsych/plugin-survey-text__1.x',
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2014-2022 Joshua R. de Leeuw
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "@jspsych/plugin-instructions__2.x",
3+
"type": "module",
4+
"version": "2.0.0",
5+
"license": "MIT",
6+
"exports": {
7+
".": {
8+
"types": "./src/index.d.ts",
9+
"import": "./src/index.js"
10+
},
11+
"./package.json": "./package.json"
12+
},
13+
"dependencies": {
14+
"@jspsych/plugin-instructions": "2.0.0",
15+
"jspsych__8.x": "workspace:*"
16+
}
17+
}
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import { JsPsychPlugin, ParameterType, JsPsych, TrialType } from 'jspsych__8.x';
2+
3+
declare const info: {
4+
readonly name: 'instructions';
5+
readonly version: string;
6+
readonly parameters: {
7+
/** Each element of the array is the content for a single page. Each page should be an HTML-formatted string. */
8+
readonly pages: {
9+
readonly type: ParameterType.HTML_STRING;
10+
readonly default: any;
11+
readonly array: true;
12+
};
13+
/** This is the key that the participant can press in order to advance to the next page. This key should be
14+
* specified as a string (e.g., `'a'`, `'ArrowLeft'`, `' '`, `'Enter'`). */
15+
readonly key_forward: {
16+
readonly type: ParameterType.KEY;
17+
readonly default: 'ArrowRight';
18+
};
19+
/** This is the key that the participant can press to return to the previous page. This key should be specified as a
20+
* string (e.g., `'a'`, `'ArrowLeft'`, `' '`, `'Enter'`). */
21+
readonly key_backward: {
22+
readonly type: ParameterType.KEY;
23+
readonly default: 'ArrowLeft';
24+
};
25+
/** If true, the participant can return to previous pages of the instructions. If false, they may only advace to the next page. */
26+
readonly allow_backward: {
27+
readonly type: ParameterType.BOOL;
28+
readonly default: true;
29+
};
30+
/** If `true`, the participant can use keyboard keys to navigate the pages. If `false`, they may not. */
31+
readonly allow_keys: {
32+
readonly type: ParameterType.BOOL;
33+
readonly default: true;
34+
};
35+
/** If true, then a `Previous` and `Next` button will be displayed beneath the instructions. Participants can
36+
* click the buttons to navigate. */
37+
readonly show_clickable_nav: {
38+
readonly type: ParameterType.BOOL;
39+
readonly default: false;
40+
};
41+
/** If true, and clickable navigation is enabled, then Page x/y will be shown between the nav buttons. */
42+
readonly show_page_number: {
43+
readonly type: ParameterType.BOOL;
44+
readonly default: false;
45+
};
46+
/** The text that appears before x/y pages displayed when show_page_number is true.*/
47+
readonly page_label: {
48+
readonly type: ParameterType.STRING;
49+
readonly default: 'Page';
50+
};
51+
/** The text that appears on the button to go backwards. */
52+
readonly button_label_previous: {
53+
readonly type: ParameterType.STRING;
54+
readonly default: 'Previous';
55+
};
56+
/** The text that appears on the button to go forwards. */
57+
readonly button_label_next: {
58+
readonly type: ParameterType.STRING;
59+
readonly default: 'Next';
60+
};
61+
/** The callback function when page changes */
62+
readonly on_page_change: {
63+
readonly type: ParameterType.FUNCTION;
64+
readonly pretty_name: 'Page change callback';
65+
readonly default: (current_page: number) => void;
66+
};
67+
};
68+
readonly data: {
69+
/** An array containing the order of pages the participant viewed (including when the participant returned to previous pages)
70+
* and the time spent viewing each page. Each object in the array represents a single page view,
71+
* and contains keys called `page_index` (the page number, starting with 0) and `viewing_time`
72+
* (duration of the page view). This will be encoded as a JSON string when data is saved using the `.json()` or `.csv()`
73+
* functions.
74+
*/
75+
readonly view_history: {
76+
readonly type: ParameterType.COMPLEX;
77+
readonly array: true;
78+
readonly parameters: {
79+
readonly page_index: {
80+
readonly type: ParameterType.INT;
81+
};
82+
readonly viewing_time: {
83+
readonly type: ParameterType.INT;
84+
};
85+
};
86+
};
87+
/** The response time in milliseconds for the participant to view all of the pages. */
88+
readonly rt: {
89+
readonly type: ParameterType.INT;
90+
};
91+
};
92+
};
93+
type Info = typeof info;
94+
/**
95+
* This plugin is for showing instructions to the participant. It allows participants to navigate through multiple pages
96+
* of instructions at their own pace, recording how long the participant spends on each page. Navigation can be done using
97+
* the mouse or keyboard. participants can be allowed to navigate forwards and backwards through pages, if desired.
98+
*
99+
* @author Josh de Leeuw
100+
* @see {@link https://www.jspsych.org/latest/plugins/instructions/ instructions plugin documentation on jspsych.org}
101+
*/
102+
declare class InstructionsPlugin implements JsPsychPlugin<Info> {
103+
private jsPsych;
104+
static info: {
105+
readonly name: 'instructions';
106+
readonly version: string;
107+
readonly parameters: {
108+
/** Each element of the array is the content for a single page. Each page should be an HTML-formatted string. */
109+
readonly pages: {
110+
readonly type: ParameterType.HTML_STRING;
111+
readonly default: any;
112+
readonly array: true;
113+
};
114+
/** This is the key that the participant can press in order to advance to the next page. This key should be
115+
* specified as a string (e.g., `'a'`, `'ArrowLeft'`, `' '`, `'Enter'`). */
116+
readonly key_forward: {
117+
readonly type: ParameterType.KEY;
118+
readonly default: 'ArrowRight';
119+
};
120+
/** This is the key that the participant can press to return to the previous page. This key should be specified as a
121+
* string (e.g., `'a'`, `'ArrowLeft'`, `' '`, `'Enter'`). */
122+
readonly key_backward: {
123+
readonly type: ParameterType.KEY;
124+
readonly default: 'ArrowLeft';
125+
};
126+
/** If true, the participant can return to previous pages of the instructions. If false, they may only advace to the next page. */
127+
readonly allow_backward: {
128+
readonly type: ParameterType.BOOL;
129+
readonly default: true;
130+
};
131+
/** If `true`, the participant can use keyboard keys to navigate the pages. If `false`, they may not. */
132+
readonly allow_keys: {
133+
readonly type: ParameterType.BOOL;
134+
readonly default: true;
135+
};
136+
/** If true, then a `Previous` and `Next` button will be displayed beneath the instructions. Participants can
137+
* click the buttons to navigate. */
138+
readonly show_clickable_nav: {
139+
readonly type: ParameterType.BOOL;
140+
readonly default: false;
141+
};
142+
/** If true, and clickable navigation is enabled, then Page x/y will be shown between the nav buttons. */
143+
readonly show_page_number: {
144+
readonly type: ParameterType.BOOL;
145+
readonly default: false;
146+
};
147+
/** The text that appears before x/y pages displayed when show_page_number is true.*/
148+
readonly page_label: {
149+
readonly type: ParameterType.STRING;
150+
readonly default: 'Page';
151+
};
152+
/** The text that appears on the button to go backwards. */
153+
readonly button_label_previous: {
154+
readonly type: ParameterType.STRING;
155+
readonly default: 'Previous';
156+
};
157+
/** The text that appears on the button to go forwards. */
158+
readonly button_label_next: {
159+
readonly type: ParameterType.STRING;
160+
readonly default: 'Next';
161+
};
162+
/** The callback function when page changes */
163+
readonly on_page_change: {
164+
readonly type: ParameterType.FUNCTION;
165+
readonly pretty_name: 'Page change callback';
166+
readonly default: (current_page: number) => void;
167+
};
168+
};
169+
readonly data: {
170+
/** An array containing the order of pages the participant viewed (including when the participant returned to previous pages)
171+
* and the time spent viewing each page. Each object in the array represents a single page view,
172+
* and contains keys called `page_index` (the page number, starting with 0) and `viewing_time`
173+
* (duration of the page view). This will be encoded as a JSON string when data is saved using the `.json()` or `.csv()`
174+
* functions.
175+
*/
176+
readonly view_history: {
177+
readonly type: ParameterType.COMPLEX;
178+
readonly array: true;
179+
readonly parameters: {
180+
readonly page_index: {
181+
readonly type: ParameterType.INT;
182+
};
183+
readonly viewing_time: {
184+
readonly type: ParameterType.INT;
185+
};
186+
};
187+
};
188+
/** The response time in milliseconds for the participant to view all of the pages. */
189+
readonly rt: {
190+
readonly type: ParameterType.INT;
191+
};
192+
};
193+
};
194+
constructor(jsPsych: JsPsych);
195+
trial(display_element: HTMLElement, trial: TrialType<Info>): void;
196+
simulate(trial: TrialType<Info>, simulation_mode: any, simulation_options: any, load_callback: () => void): void;
197+
private create_simulation_data;
198+
private simulate_data_only;
199+
private simulate_visual;
200+
}
201+
202+
export { InstructionsPlugin as default };
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default, default as InstructionsPlugin } from '@jspsych/plugin-instructions';

0 commit comments

Comments
 (0)