@quesmed/types 2.6.234 → 2.6.235

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,8 @@ export declare enum EBlogTags {
15
15
  MLA_CSPA = "MLA_CPSA",
16
16
  MRCP_VIDEO = "MRCP_Video",
17
17
  PLAB1 = "PLAB1",
18
- PLAB2 = "PLAB2"
18
+ PLAB2 = "PLAB2",
19
+ UCAT = "UCAT"
19
20
  }
20
21
  export interface IBlogTag {
21
22
  id: Id;
@@ -18,4 +18,5 @@ var EBlogTags;
18
18
  EBlogTags["MRCP_VIDEO"] = "MRCP_Video";
19
19
  EBlogTags["PLAB1"] = "PLAB1";
20
20
  EBlogTags["PLAB2"] = "PLAB2";
21
+ EBlogTags["UCAT"] = "UCAT";
21
22
  })(EBlogTags = exports.EBlogTags || (exports.EBlogTags = {}));
@@ -204,7 +204,7 @@ export interface IQuestionRanking extends IQuestion {
204
204
  }
205
205
  export interface IQuestionSjtTwoAnswer extends IQuestion {
206
206
  answer: [string, string];
207
- sjtTwoAnswer: [string, string];
207
+ sbaAnswer: [string, string];
208
208
  }
209
209
  export interface IQuestionPrescribe extends IQuestion {
210
210
  answer: IPrescribeAnswer[];
@@ -81,10 +81,39 @@ exports.SAVE_MARKSHEET = (0, client_1.gql) `
81
81
  flagged
82
82
  mark
83
83
  }
84
+ sections {
85
+ entitlementId
86
+ marks {
87
+ isAnswered
88
+ isInDailyStack
89
+ result
90
+ score
91
+ id
92
+ marksheetId
93
+ questionChoiceId
94
+ timeTaken
95
+ flagged
96
+ mark
97
+ }
98
+ }
84
99
  }
85
100
  }
86
101
  }
87
102
  `;
103
+ function getMarksFromMarksheet(marksheets, marksheetId) {
104
+ const marksheet = marksheets.find((m) => Number(m.id) === Number(marksheetId));
105
+ if (!marksheet)
106
+ return [];
107
+ // Case 1: direct marks
108
+ if (Array.isArray(marksheet.marks) && marksheet.marks.length > 0) {
109
+ return marksheet.marks;
110
+ }
111
+ // Case 2: nested sections → flatten marks
112
+ if (Array.isArray(marksheet.sections)) {
113
+ return marksheet.sections.flatMap((section) => section.marks || []);
114
+ }
115
+ return [];
116
+ }
88
117
  const updateMarksheets = (cache, result, options) => {
89
118
  const { saveMarksheets } = result?.data?.restricted || {};
90
119
  const { variables } = options || {};
@@ -95,7 +124,7 @@ const updateMarksheets = (cache, result, options) => {
95
124
  const { input } = variables;
96
125
  for (let i = 0; i < input.length; i++) {
97
126
  const inputData = input[i];
98
- const savedMarks = saveMarksheets.find((m) => Number(m.id) === Number(inputData.marksheetId))?.marks;
127
+ const savedMarks = getMarksFromMarksheet(saveMarksheets, inputData.marksheetId);
99
128
  const savedData = savedMarks?.find((m) => m.id === inputData.markId);
100
129
  cache.writeFragment({
101
130
  id: cache.identify({
@@ -121,43 +150,68 @@ const updateMarksheets = (cache, result, options) => {
121
150
  exports.updateMarksheets = updateMarksheets;
122
151
  const optimisticSaveMarksheets = (marksheet, marksheetInput, questionIndex) => {
123
152
  const { timeTaken, choiceId, mark, marksheetId, markId } = marksheetInput;
124
- const { marks = [], ...rest } = marksheet || {};
125
- const currentMark = marks.find((m) => Number(m.id) === Number(markId));
126
- if (!currentMark) {
153
+ const { marks = [], sections = [], ...rest } = marksheet || {};
154
+ const updateMarksArray = (marksArr) => {
155
+ const currentMark = marksArr.find((m) => Number(m.id) === Number(markId));
156
+ if (!currentMark)
157
+ return marksArr;
158
+ const { psaSectionId, choices, typeId } = currentMark.question;
159
+ const { answerField } = (0, utils_1.getQuestionInfo)(typeId, psaSectionId);
160
+ const answer = currentMark.question[answerField];
161
+ const { result, score } = (0, utils_1.evaluateMark)({
162
+ mark: mark || '',
163
+ answer,
164
+ psaSectionId,
165
+ questionTypeId: typeId,
166
+ choices,
167
+ });
168
+ const updatedMark = {
169
+ ...marksArr[questionIndex],
170
+ marksheetId,
171
+ timeTaken,
172
+ questionChoiceId: choiceId ?? null,
173
+ isAnswered: true,
174
+ mark: mark || null,
175
+ result,
176
+ score,
177
+ };
178
+ return [
179
+ ...marksArr.slice(0, questionIndex),
180
+ updatedMark,
181
+ ...marksArr.slice(questionIndex + 1),
182
+ ];
183
+ };
184
+ // Case 1: marks
185
+ if (marks.length > 0) {
127
186
  return {
128
187
  restricted: {
129
- saveMarksheets: [{ ...rest, marks }],
188
+ saveMarksheets: [{ ...rest, marks: updateMarksArray(marks), sections }],
130
189
  },
131
190
  };
132
191
  }
133
- const { psaSectionId, choices, typeId } = currentMark.question;
134
- const { answerField } = (0, utils_1.getQuestionInfo)(typeId, psaSectionId);
135
- const answer = currentMark.question[answerField];
136
- const { result, score } = (0, utils_1.evaluateMark)({
137
- mark: mark || '',
138
- answer,
139
- psaSectionId,
140
- questionTypeId: typeId,
141
- choices,
142
- });
143
- const updatedMark = {
144
- ...marks[questionIndex],
145
- marksheetId,
146
- timeTaken,
147
- questionChoiceId: choiceId ?? null,
148
- isAnswered: true,
149
- mark: mark || null,
150
- result,
151
- score,
152
- };
153
- const updatedMarks = [
154
- ...marks.slice(0, questionIndex),
155
- updatedMark,
156
- ...marks.slice(questionIndex + 1),
157
- ];
192
+ // Case 2: sections
193
+ if (sections.length > 0) {
194
+ const updatedSections = sections.map((section) => {
195
+ if (!Array.isArray(section.marks))
196
+ return section;
197
+ const hasMark = section.marks.some((m) => Number(m.id) === Number(markId));
198
+ if (!hasMark)
199
+ return section;
200
+ return {
201
+ ...section,
202
+ marks: updateMarksArray(section.marks),
203
+ };
204
+ });
205
+ return {
206
+ restricted: {
207
+ saveMarksheets: [{ ...rest, sections: updatedSections, marks }],
208
+ },
209
+ };
210
+ }
211
+ // fallback
158
212
  return {
159
213
  restricted: {
160
- saveMarksheets: [{ ...rest, marks: updatedMarks }],
214
+ saveMarksheets: [{ ...rest, marks, sections }],
161
215
  },
162
216
  };
163
217
  };
@@ -46,7 +46,7 @@ const getQuestionTypeName = (typeId) => {
46
46
  [models_1.EQuestionType.DECISION_MAKING_SBA]: 'QuestionSBA',
47
47
  [models_1.EQuestionType.DECISION_MAKING_YES_NO]: 'QuestionMultiA',
48
48
  [models_1.EQuestionType.SJT_SINGLE_CHOICE]: 'QuestionSBA',
49
- [models_1.EQuestionType.SJT_TWO_ANSWERS]: 'QuestionSelect3',
49
+ [models_1.EQuestionType.SJT_TWO_ANSWERS]: 'QuestionSBA',
50
50
  };
51
51
  return mappedObj[typeId] ?? 'QuestionSBA';
52
52
  };
@@ -81,7 +81,7 @@ function getQuestionInfo(questionType, psaSectionId) {
81
81
  case models_1.EQuestionType.SJT_SINGLE_CHOICE:
82
82
  return { maxScore: 1, answerField: 'sbaAnswer' };
83
83
  case models_1.EQuestionType.SJT_TWO_ANSWERS:
84
- return { maxScore: 1, answerField: 'rankingAnswer' };
84
+ return { maxScore: 1, answerField: 'sbaAnswer' };
85
85
  default:
86
86
  return { maxScore: 1, answerField: 'answer' };
87
87
  }
@@ -15,7 +15,8 @@ export declare enum EBlogTags {
15
15
  MLA_CSPA = "MLA_CPSA",
16
16
  MRCP_VIDEO = "MRCP_Video",
17
17
  PLAB1 = "PLAB1",
18
- PLAB2 = "PLAB2"
18
+ PLAB2 = "PLAB2",
19
+ UCAT = "UCAT"
19
20
  }
20
21
  export interface IBlogTag {
21
22
  id: Id;
@@ -15,4 +15,5 @@ export var EBlogTags;
15
15
  EBlogTags["MRCP_VIDEO"] = "MRCP_Video";
16
16
  EBlogTags["PLAB1"] = "PLAB1";
17
17
  EBlogTags["PLAB2"] = "PLAB2";
18
+ EBlogTags["UCAT"] = "UCAT";
18
19
  })(EBlogTags || (EBlogTags = {}));
@@ -204,7 +204,7 @@ export interface IQuestionRanking extends IQuestion {
204
204
  }
205
205
  export interface IQuestionSjtTwoAnswer extends IQuestion {
206
206
  answer: [string, string];
207
- sjtTwoAnswer: [string, string];
207
+ sbaAnswer: [string, string];
208
208
  }
209
209
  export interface IQuestionPrescribe extends IQuestion {
210
210
  answer: IPrescribeAnswer[];
@@ -78,10 +78,39 @@ export const SAVE_MARKSHEET = gql `
78
78
  flagged
79
79
  mark
80
80
  }
81
+ sections {
82
+ entitlementId
83
+ marks {
84
+ isAnswered
85
+ isInDailyStack
86
+ result
87
+ score
88
+ id
89
+ marksheetId
90
+ questionChoiceId
91
+ timeTaken
92
+ flagged
93
+ mark
94
+ }
95
+ }
81
96
  }
82
97
  }
83
98
  }
84
99
  `;
100
+ function getMarksFromMarksheet(marksheets, marksheetId) {
101
+ const marksheet = marksheets.find((m) => Number(m.id) === Number(marksheetId));
102
+ if (!marksheet)
103
+ return [];
104
+ // Case 1: direct marks
105
+ if (Array.isArray(marksheet.marks) && marksheet.marks.length > 0) {
106
+ return marksheet.marks;
107
+ }
108
+ // Case 2: nested sections → flatten marks
109
+ if (Array.isArray(marksheet.sections)) {
110
+ return marksheet.sections.flatMap((section) => section.marks || []);
111
+ }
112
+ return [];
113
+ }
85
114
  export const updateMarksheets = (cache, result, options) => {
86
115
  const { saveMarksheets } = result?.data?.restricted || {};
87
116
  const { variables } = options || {};
@@ -92,7 +121,7 @@ export const updateMarksheets = (cache, result, options) => {
92
121
  const { input } = variables;
93
122
  for (let i = 0; i < input.length; i++) {
94
123
  const inputData = input[i];
95
- const savedMarks = saveMarksheets.find((m) => Number(m.id) === Number(inputData.marksheetId))?.marks;
124
+ const savedMarks = getMarksFromMarksheet(saveMarksheets, inputData.marksheetId);
96
125
  const savedData = savedMarks?.find((m) => m.id === inputData.markId);
97
126
  cache.writeFragment({
98
127
  id: cache.identify({
@@ -117,43 +146,68 @@ export const updateMarksheets = (cache, result, options) => {
117
146
  };
118
147
  export const optimisticSaveMarksheets = (marksheet, marksheetInput, questionIndex) => {
119
148
  const { timeTaken, choiceId, mark, marksheetId, markId } = marksheetInput;
120
- const { marks = [], ...rest } = marksheet || {};
121
- const currentMark = marks.find((m) => Number(m.id) === Number(markId));
122
- if (!currentMark) {
149
+ const { marks = [], sections = [], ...rest } = marksheet || {};
150
+ const updateMarksArray = (marksArr) => {
151
+ const currentMark = marksArr.find((m) => Number(m.id) === Number(markId));
152
+ if (!currentMark)
153
+ return marksArr;
154
+ const { psaSectionId, choices, typeId } = currentMark.question;
155
+ const { answerField } = getQuestionInfo(typeId, psaSectionId);
156
+ const answer = currentMark.question[answerField];
157
+ const { result, score } = evaluateMark({
158
+ mark: mark || '',
159
+ answer,
160
+ psaSectionId,
161
+ questionTypeId: typeId,
162
+ choices,
163
+ });
164
+ const updatedMark = {
165
+ ...marksArr[questionIndex],
166
+ marksheetId,
167
+ timeTaken,
168
+ questionChoiceId: choiceId ?? null,
169
+ isAnswered: true,
170
+ mark: mark || null,
171
+ result,
172
+ score,
173
+ };
174
+ return [
175
+ ...marksArr.slice(0, questionIndex),
176
+ updatedMark,
177
+ ...marksArr.slice(questionIndex + 1),
178
+ ];
179
+ };
180
+ // Case 1: marks
181
+ if (marks.length > 0) {
123
182
  return {
124
183
  restricted: {
125
- saveMarksheets: [{ ...rest, marks }],
184
+ saveMarksheets: [{ ...rest, marks: updateMarksArray(marks), sections }],
126
185
  },
127
186
  };
128
187
  }
129
- const { psaSectionId, choices, typeId } = currentMark.question;
130
- const { answerField } = getQuestionInfo(typeId, psaSectionId);
131
- const answer = currentMark.question[answerField];
132
- const { result, score } = evaluateMark({
133
- mark: mark || '',
134
- answer,
135
- psaSectionId,
136
- questionTypeId: typeId,
137
- choices,
138
- });
139
- const updatedMark = {
140
- ...marks[questionIndex],
141
- marksheetId,
142
- timeTaken,
143
- questionChoiceId: choiceId ?? null,
144
- isAnswered: true,
145
- mark: mark || null,
146
- result,
147
- score,
148
- };
149
- const updatedMarks = [
150
- ...marks.slice(0, questionIndex),
151
- updatedMark,
152
- ...marks.slice(questionIndex + 1),
153
- ];
188
+ // Case 2: sections
189
+ if (sections.length > 0) {
190
+ const updatedSections = sections.map((section) => {
191
+ if (!Array.isArray(section.marks))
192
+ return section;
193
+ const hasMark = section.marks.some((m) => Number(m.id) === Number(markId));
194
+ if (!hasMark)
195
+ return section;
196
+ return {
197
+ ...section,
198
+ marks: updateMarksArray(section.marks),
199
+ };
200
+ });
201
+ return {
202
+ restricted: {
203
+ saveMarksheets: [{ ...rest, sections: updatedSections, marks }],
204
+ },
205
+ };
206
+ }
207
+ // fallback
154
208
  return {
155
209
  restricted: {
156
- saveMarksheets: [{ ...rest, marks: updatedMarks }],
210
+ saveMarksheets: [{ ...rest, marks, sections }],
157
211
  },
158
212
  };
159
213
  };
@@ -42,7 +42,7 @@ export const getQuestionTypeName = (typeId) => {
42
42
  [EQuestionType.DECISION_MAKING_SBA]: 'QuestionSBA',
43
43
  [EQuestionType.DECISION_MAKING_YES_NO]: 'QuestionMultiA',
44
44
  [EQuestionType.SJT_SINGLE_CHOICE]: 'QuestionSBA',
45
- [EQuestionType.SJT_TWO_ANSWERS]: 'QuestionSelect3',
45
+ [EQuestionType.SJT_TWO_ANSWERS]: 'QuestionSBA',
46
46
  };
47
47
  return mappedObj[typeId] ?? 'QuestionSBA';
48
48
  };
@@ -78,7 +78,7 @@ export function getQuestionInfo(questionType, psaSectionId) {
78
78
  case EQuestionType.SJT_SINGLE_CHOICE:
79
79
  return { maxScore: 1, answerField: 'sbaAnswer' };
80
80
  case EQuestionType.SJT_TWO_ANSWERS:
81
- return { maxScore: 1, answerField: 'rankingAnswer' };
81
+ return { maxScore: 1, answerField: 'sbaAnswer' };
82
82
  default:
83
83
  return { maxScore: 1, answerField: 'answer' };
84
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quesmed/types",
3
- "version": "2.6.234",
3
+ "version": "2.6.235",
4
4
  "description": "Typescript types for Quesmed",
5
5
  "keywords": [
6
6
  "quesmed",