@doenet/assignment-viewer 0.1.0-alpha1 → 0.1.0-alpha2

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.
Files changed (2) hide show
  1. package/dist/index.js +167 -315
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1861,6 +1861,9 @@ function generateNewSelectAttempt({
1861
1861
  const source = state.source;
1862
1862
  const numToSelect = source.numToSelect;
1863
1863
  const numChildren = state.latestChildStates.length;
1864
+ if (numChildren === 0) {
1865
+ return { finalQuestionCounter: initialQuestionCounter, state };
1866
+ }
1864
1867
  const numVariantsPerChild = state.latestChildStates.map(
1865
1868
  (a) => calcNumVariantsFromState(a, numActivityVariants)
1866
1869
  );
@@ -1868,7 +1871,7 @@ function generateNewSelectAttempt({
1868
1871
  if (numToSelect > totalNumOptions) {
1869
1872
  if (source.selectByVariant) {
1870
1873
  throw Error(
1871
- "The specified number to select of a select activity is larger than the number of available variants."
1874
+ `For a select activity, "number to select" is ${numToSelect.toString()}, which is larger than the number of available variants (${totalNumOptions.toString()}).`
1872
1875
  );
1873
1876
  } else {
1874
1877
  const totalNumChildVariants = numVariantsPerChild.reduce(
@@ -1876,11 +1879,11 @@ function generateNewSelectAttempt({
1876
1879
  );
1877
1880
  if (numToSelect > totalNumChildVariants) {
1878
1881
  throw Error(
1879
- "The specified number to select of a select activity is larger than the number of available activities."
1882
+ `For a select activity, "number to select" is ${numToSelect.toString()}, which is larger than the number of available activities (${totalNumOptions.toString()}).`
1880
1883
  );
1881
1884
  } else {
1882
1885
  throw Error(
1883
- 'The specified number to select of a select activity is larger than the number of available activities. Turning on "select by variant" will add enough options for the select activity to function.'
1886
+ `For a select activity, "number to select" is ${numToSelect.toString()}, which is larger than the number of available activities (${totalNumOptions.toString()}). (Turning on "select by variant" will add enough options for the select activity to function.)`
1884
1887
  );
1885
1888
  }
1886
1889
  }
@@ -3337,7 +3340,18 @@ function getItemSequence(state) {
3337
3340
  } else {
3338
3341
  const numAttempts = state.attempts.length;
3339
3342
  if (numAttempts === 0) {
3340
- return [state.id];
3343
+ if (state.latestChildStates.length === 0) {
3344
+ return [];
3345
+ } else {
3346
+ const prelimResult = state.latestChildStates.flatMap(
3347
+ (a) => getItemSequence(a)
3348
+ );
3349
+ if (state.type === "sequence") {
3350
+ return prelimResult;
3351
+ } else {
3352
+ return prelimResult.slice(0, state.source.numToSelect);
3353
+ }
3354
+ }
3341
3355
  }
3342
3356
  return state.attempts[numAttempts - 1].activities.flatMap(
3343
3357
  (a) => getItemSequence(a)
@@ -3366,49 +3380,6 @@ function calcNumVariantsFromState(state, numActivityVariants) {
3366
3380
  }
3367
3381
  return numVariants;
3368
3382
  }
3369
- function getUninitializedActivityState(source) {
3370
- switch (source.type) {
3371
- case "singleDoc": {
3372
- return {
3373
- type: "singleDoc",
3374
- id: source.id,
3375
- parentId: null,
3376
- source,
3377
- initialVariant: 0,
3378
- creditAchieved: 0,
3379
- attempts: []
3380
- };
3381
- }
3382
- case "select": {
3383
- return {
3384
- type: "select",
3385
- id: source.id,
3386
- parentId: null,
3387
- source,
3388
- initialVariant: 0,
3389
- creditAchieved: 0,
3390
- attempts: [],
3391
- latestChildStates: source.items.map(
3392
- getUninitializedActivityState
3393
- )
3394
- };
3395
- }
3396
- case "sequence": {
3397
- return {
3398
- type: "sequence",
3399
- id: source.id,
3400
- parentId: null,
3401
- source,
3402
- initialVariant: 0,
3403
- creditAchieved: 0,
3404
- attempts: [],
3405
- latestChildStates: source.items.map(
3406
- getUninitializedActivityState
3407
- )
3408
- };
3409
- }
3410
- }
3411
- }
3412
3383
  function validateIds(source) {
3413
3384
  if (source.id.includes("|")) {
3414
3385
  throw Error(`Id "${source.id}" contains a "|".`);
@@ -3424,6 +3395,25 @@ function validateIds(source) {
3424
3395
  }
3425
3396
  return idsFound;
3426
3397
  }
3398
+ function gatherDocumentStructure(source) {
3399
+ if (source.type === "singleDoc") {
3400
+ return {
3401
+ numActivityVariants: { [source.id]: source.numVariants ?? 1 },
3402
+ questionCounts: {
3403
+ [source.id]: source.baseLevelComponentCounts ? (source.baseLevelComponentCounts.question ?? 0) + (source.baseLevelComponentCounts.problem ?? 0) + (source.baseLevelComponentCounts.exercise ?? 0) : 1
3404
+ }
3405
+ };
3406
+ } else {
3407
+ const numActivityVariants = {};
3408
+ const questionCounts = {};
3409
+ for (const item of source.items) {
3410
+ const res = gatherDocumentStructure(item);
3411
+ Object.assign(numActivityVariants, res.numActivityVariants);
3412
+ Object.assign(questionCounts, res.questionCounts);
3413
+ }
3414
+ return { numActivityVariants, questionCounts };
3415
+ }
3416
+ }
3427
3417
  function validateStateAndSource(state, source) {
3428
3418
  if (!isExportedActivityState(state) || !isActivitySource(source)) {
3429
3419
  return false;
@@ -3511,13 +3501,6 @@ function propagateStateChangeToRoot({
3511
3501
  id: newParentState.id
3512
3502
  });
3513
3503
  }
3514
- function isDocumentStructureData(obj) {
3515
- const typeObj = obj;
3516
- return (
3517
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
3518
- typeObj !== null && typeof typeObj === "object" && typeof typeObj.activityId === "string" && typeof typeObj.docId === "string" && typeof typeObj.args === "object" && Array.isArray(typeObj.args.allPossibleVariants) && typeObj.args.allPossibleVariants.every((v) => typeof v === "string") && typeof typeObj.args.baseLevelComponentCounts === "object" && typeof typeObj.args.success === "boolean"
3519
- );
3520
- }
3521
3504
  function isSingleDocReportStateMessage(obj) {
3522
3505
  const typeObj = obj;
3523
3506
  return (
@@ -3679,7 +3662,6 @@ function SelectActivity({
3679
3662
  showAnswerTitles = false,
3680
3663
  state,
3681
3664
  reportScoreAndStateCallback,
3682
- documentStructureCallback,
3683
3665
  checkRender,
3684
3666
  checkHidden,
3685
3667
  allowItemAttemptButtons = false,
@@ -3708,7 +3690,6 @@ function SelectActivity({
3708
3690
  darkMode,
3709
3691
  showAnswerTitles,
3710
3692
  reportScoreAndStateCallback,
3711
- documentStructureCallback,
3712
3693
  checkRender,
3713
3694
  checkHidden,
3714
3695
  allowItemAttemptButtons,
@@ -3723,37 +3704,11 @@ function SelectActivity({
3723
3704
  selectedIds.push(activity.id);
3724
3705
  }
3725
3706
  }
3726
- const unselectedActivities = state.latestChildStates.filter((activity) => !selectedIds.includes(activity.id)).map((activity) => /* @__PURE__ */ jsxRuntimeExports$1.jsx(
3727
- Activity,
3728
- {
3729
- state: activity,
3730
- flags,
3731
- baseId,
3732
- forceDisable,
3733
- forceShowCorrectness,
3734
- forceShowSolution,
3735
- forceUnsuppressCheckwork,
3736
- linkSettings,
3737
- darkMode,
3738
- showAnswerTitles,
3739
- reportScoreAndStateCallback,
3740
- documentStructureCallback,
3741
- checkRender: () => false,
3742
- checkHidden,
3743
- hasRenderedCallback,
3744
- reportVisibility,
3745
- reportVisibilityCallback
3746
- },
3747
- activity.id
3748
- ));
3749
- return /* @__PURE__ */ jsxRuntimeExports$1.jsxs(
3707
+ return /* @__PURE__ */ jsxRuntimeExports$1.jsx(
3750
3708
  "div",
3751
3709
  {
3752
3710
  hidden: !checkRender(state),
3753
- children: [
3754
- /* @__PURE__ */ jsxRuntimeExports$1.jsx("div", { children: selectedActivities }),
3755
- /* @__PURE__ */ jsxRuntimeExports$1.jsx("div", { hidden: true, children: unselectedActivities })
3756
- ]
3711
+ children: /* @__PURE__ */ jsxRuntimeExports$1.jsx("div", { children: selectedActivities })
3757
3712
  },
3758
3713
  // Replace the activity in the DOM when a new attempt is created,
3759
3714
  // except preserve it if just a single item was replaced with the other items staying unchanged.
@@ -3774,7 +3729,6 @@ function SequenceActivity({
3774
3729
  showAnswerTitles = false,
3775
3730
  state,
3776
3731
  reportScoreAndStateCallback,
3777
- documentStructureCallback,
3778
3732
  checkRender,
3779
3733
  checkHidden,
3780
3734
  allowItemAttemptButtons = false,
@@ -3802,37 +3756,6 @@ function SequenceActivity({
3802
3756
  darkMode,
3803
3757
  showAnswerTitles,
3804
3758
  reportScoreAndStateCallback,
3805
- documentStructureCallback,
3806
- checkRender,
3807
- checkHidden,
3808
- allowItemAttemptButtons,
3809
- generateNewItemAttempt,
3810
- hasRenderedCallback,
3811
- reportVisibility,
3812
- reportVisibilityCallback
3813
- },
3814
- activity.id
3815
- )
3816
- );
3817
- }
3818
- } else {
3819
- for (const activity of state.latestChildStates) {
3820
- activityList.push(
3821
- /* @__PURE__ */ jsxRuntimeExports$1.jsx(
3822
- Activity,
3823
- {
3824
- state: activity,
3825
- flags,
3826
- baseId,
3827
- forceDisable,
3828
- forceShowCorrectness,
3829
- forceShowSolution,
3830
- forceUnsuppressCheckwork,
3831
- linkSettings,
3832
- darkMode,
3833
- showAnswerTitles,
3834
- reportScoreAndStateCallback,
3835
- documentStructureCallback,
3836
3759
  checkRender,
3837
3760
  checkHidden,
3838
3761
  allowItemAttemptButtons,
@@ -53464,7 +53387,6 @@ function SingleDocActivity({
53464
53387
  showAnswerTitles = false,
53465
53388
  state,
53466
53389
  reportScoreAndStateCallback,
53467
- documentStructureCallback,
53468
53390
  checkRender,
53469
53391
  checkHidden,
53470
53392
  allowItemAttemptButtons = false,
@@ -53544,9 +53466,6 @@ function SingleDocActivity({
53544
53466
  initialState: initialDoenetState,
53545
53467
  initializeCounters: initialCounters,
53546
53468
  reportScoreAndStateCallback,
53547
- documentStructureCallback: (args) => {
53548
- documentStructureCallback(args);
53549
- },
53550
53469
  initializedCallback: () => {
53551
53470
  setRendered(true);
53552
53471
  hasRenderedCallback(state.id);
@@ -53587,7 +53506,6 @@ function Activity({
53587
53506
  showAnswerTitles = false,
53588
53507
  state,
53589
53508
  reportScoreAndStateCallback,
53590
- documentStructureCallback,
53591
53509
  checkRender,
53592
53510
  checkHidden,
53593
53511
  allowItemAttemptButtons = false,
@@ -53612,7 +53530,6 @@ function Activity({
53612
53530
  showAnswerTitles,
53613
53531
  state,
53614
53532
  reportScoreAndStateCallback,
53615
- documentStructureCallback,
53616
53533
  checkRender,
53617
53534
  checkHidden,
53618
53535
  allowItemAttemptButtons,
@@ -53638,7 +53555,6 @@ function Activity({
53638
53555
  showAnswerTitles,
53639
53556
  state,
53640
53557
  reportScoreAndStateCallback,
53641
- documentStructureCallback,
53642
53558
  checkRender,
53643
53559
  checkHidden,
53644
53560
  allowItemAttemptButtons,
@@ -53664,7 +53580,6 @@ function Activity({
53664
53580
  showAnswerTitles,
53665
53581
  state,
53666
53582
  reportScoreAndStateCallback,
53667
- documentStructureCallback,
53668
53583
  checkRender,
53669
53584
  checkHidden,
53670
53585
  allowItemAttemptButtons,
@@ -53679,33 +53594,13 @@ function Activity({
53679
53594
  }
53680
53595
  function activityStateReducer(state, action) {
53681
53596
  switch (action.type) {
53682
- case "reset": {
53683
- return getUninitializedActivityState(action.source);
53684
- }
53685
53597
  case "initialize": {
53686
- const initialState = initializeActivityState({
53598
+ return initializeActivityState({
53687
53599
  source: state.source,
53688
53600
  variant: action.variantIndex,
53689
53601
  parentId: null,
53690
53602
  numActivityVariants: action.numActivityVariants
53691
53603
  });
53692
- const { state: newActivityState } = generateNewActivityAttempt({
53693
- state: initialState,
53694
- numActivityVariants: action.numActivityVariants,
53695
- initialQuestionCounter: action.initialQuestionCounter,
53696
- questionCounts: action.questionCounts,
53697
- parentAttempt: 1
53698
- });
53699
- if (action.allowSaveState) {
53700
- const scoreByItem = extractActivityItemCredit(newActivityState);
53701
- window.postMessage({
53702
- score: newActivityState.creditAchieved,
53703
- scoreByItem,
53704
- subject: "SPLICE.reportScoreByItem",
53705
- activityId: action.baseId
53706
- });
53707
- }
53708
- return newActivityState;
53709
53604
  }
53710
53605
  case "set": {
53711
53606
  const scoreByItem = extractActivityItemCredit(action.state);
@@ -53721,7 +53616,11 @@ function activityStateReducer(state, action) {
53721
53616
  }
53722
53617
  case "generateNewActivityAttempt": {
53723
53618
  let newActivityState;
53619
+ let firstAttempt = false;
53724
53620
  if (!action.id || action.id === state.id) {
53621
+ if (state.attempts.length === 0) {
53622
+ firstAttempt = true;
53623
+ }
53725
53624
  ({ state: newActivityState } = generateNewActivityAttempt({
53726
53625
  state,
53727
53626
  numActivityVariants: action.numActivityVariants,
@@ -53740,20 +53639,29 @@ function activityStateReducer(state, action) {
53740
53639
  }
53741
53640
  if (action.allowSaveState) {
53742
53641
  const scoreByItem = extractActivityItemCredit(newActivityState);
53743
- const sourceHash = hash(newActivityState.source);
53744
- window.postMessage({
53745
- state: {
53746
- state: pruneActivityStateForSave(
53747
- newActivityState,
53748
- false
53749
- ),
53750
- sourceHash
53751
- },
53752
- score: newActivityState.creditAchieved,
53753
- scoreByItem,
53754
- subject: "SPLICE.reportScoreAndState",
53755
- activityId: action.baseId
53756
- });
53642
+ if (firstAttempt) {
53643
+ window.postMessage({
53644
+ score: newActivityState.creditAchieved,
53645
+ scoreByItem,
53646
+ subject: "SPLICE.reportScoreByItem",
53647
+ activityId: action.baseId
53648
+ });
53649
+ } else {
53650
+ const sourceHash = hash(newActivityState.source);
53651
+ window.postMessage({
53652
+ state: {
53653
+ state: pruneActivityStateForSave(
53654
+ newActivityState,
53655
+ false
53656
+ ),
53657
+ sourceHash
53658
+ },
53659
+ score: newActivityState.creditAchieved,
53660
+ scoreByItem,
53661
+ subject: "SPLICE.reportScoreAndState",
53662
+ activityId: action.baseId
53663
+ });
53664
+ }
53757
53665
  }
53758
53666
  return newActivityState;
53759
53667
  }
@@ -53836,63 +53744,28 @@ function Viewer({
53836
53744
  showAnswerTitles = false,
53837
53745
  showTitle = true
53838
53746
  }) {
53839
- const numSourceDocs = useMemo$4(() => getNumSourceDocs(source), [source]);
53840
53747
  const [errMsg, setErrMsg] = useState$3(null);
53841
- const [numActivityVariants, setNumActivityVariants] = useState$3({});
53842
- const [questionCounts, setQuestionCounts] = useState$3(
53843
- {}
53844
- );
53845
- const [initialized, setInitialized] = useState$3(false);
53846
- const [needNewAssignmentState, setNeedNewAssignmentState] = useState$3(false);
53847
- useEffect$5(() => {
53848
- setInitialized(false);
53849
- setNumActivityVariants({});
53850
- setQuestionCounts({});
53851
- }, [activityId, userId, source]);
53852
- useEffect$5(() => {
53748
+ const initialPass = useRef$6(true);
53749
+ const { numActivityVariants, questionCounts } = useMemo$4(() => {
53853
53750
  try {
53854
53751
  validateIds(source);
53752
+ return gatherDocumentStructure(source);
53855
53753
  } catch (e2) {
53856
53754
  const message = e2 instanceof Error ? e2.message : "";
53857
53755
  setErrMsg(`Error in activity source: ${message}`);
53756
+ return { numActivityVariants: {}, questionCounts: {} };
53858
53757
  }
53859
53758
  }, [source]);
53860
53759
  const [activityState, activityStateDispatch] = useReducer(
53861
53760
  activityStateReducer,
53862
- source,
53863
- getUninitializedActivityState
53761
+ {
53762
+ source,
53763
+ variant: initialVariantIndex,
53764
+ parentId: null,
53765
+ numActivityVariants
53766
+ },
53767
+ initializeActivityState
53864
53768
  );
53865
- useEffect$5(() => {
53866
- if (!initialized && Object.keys(numActivityVariants).length === numSourceDocs && Object.keys(questionCounts).length === numSourceDocs) {
53867
- if (needNewAssignmentState) {
53868
- try {
53869
- activityStateDispatch({
53870
- type: "initialize",
53871
- variantIndex: initialVariantIndex,
53872
- numActivityVariants,
53873
- initialQuestionCounter: 1,
53874
- questionCounts,
53875
- allowSaveState: flags.allowSaveState,
53876
- baseId: activityId
53877
- });
53878
- setNeedNewAssignmentState(false);
53879
- } catch (e2) {
53880
- const message = e2 instanceof Error ? e2.message : "";
53881
- setErrMsg(`Error in activity: ${message}`);
53882
- }
53883
- }
53884
- setInitialized(true);
53885
- }
53886
- }, [
53887
- numActivityVariants,
53888
- questionCounts,
53889
- numSourceDocs,
53890
- flags.allowSaveState,
53891
- initialized,
53892
- activityId,
53893
- needNewAssignmentState,
53894
- initialVariantIndex
53895
- ]);
53896
53769
  const itemSequence = getItemSequence(activityState);
53897
53770
  const numItems = itemSequence.length;
53898
53771
  const [currentItemIdx, setCurrentItemIdx] = useState$3(0);
@@ -53914,36 +53787,36 @@ function Viewer({
53914
53787
  }
53915
53788
  const checkRender = useCallback$5(
53916
53789
  (state) => {
53917
- if (!initialized) {
53918
- return false;
53919
- }
53920
53790
  if (state.type === "singleDoc") {
53921
53791
  return itemsToRender.includes(state.id);
53922
53792
  } else {
53923
53793
  return true;
53924
53794
  }
53925
53795
  },
53926
- [initialized, itemsToRender]
53796
+ [itemsToRender]
53927
53797
  );
53928
53798
  const checkHidden = useCallback$5(
53929
53799
  (state) => {
53930
- if (!initialized) {
53931
- return true;
53932
- }
53933
53800
  if (state.type === "singleDoc") {
53934
53801
  return paginate && currentItemId !== state.id;
53935
53802
  } else {
53936
53803
  return false;
53937
53804
  }
53938
53805
  },
53939
- [initialized, currentItemId, paginate]
53806
+ [currentItemId, paginate]
53940
53807
  );
53941
53808
  useEffect$5(() => {
53942
- activityStateDispatch({
53943
- type: "reset",
53944
- source
53945
- });
53946
- }, [activityId, source]);
53809
+ if (initialPass.current) {
53810
+ initialPass.current = false;
53811
+ } else {
53812
+ activityStateDispatch({
53813
+ type: "initialize",
53814
+ source,
53815
+ variantIndex: initialVariantIndex,
53816
+ numActivityVariants
53817
+ });
53818
+ }
53819
+ }, [activityId, source, initialVariantIndex, numActivityVariants]);
53947
53820
  useEffect$5(() => {
53948
53821
  const listenersAdded = [];
53949
53822
  const timeoutIdsAdded = [];
@@ -54012,6 +53885,21 @@ function Viewer({
54012
53885
  timeoutIdsAdded.push(timeoutId);
54013
53886
  });
54014
53887
  }
53888
+ function getNewActivityState() {
53889
+ try {
53890
+ activityStateDispatch({
53891
+ type: "generateNewActivityAttempt",
53892
+ numActivityVariants,
53893
+ initialQuestionCounter: 1,
53894
+ questionCounts,
53895
+ allowSaveState: flags.allowSaveState,
53896
+ baseId: activityId
53897
+ });
53898
+ } catch (e2) {
53899
+ const message = e2 instanceof Error ? e2.message : "";
53900
+ setErrMsg(`Error in activity: ${message}`);
53901
+ }
53902
+ }
54015
53903
  if (flags.allowLoadState) {
54016
53904
  loadState().then((state) => {
54017
53905
  if (isActivityState(state)) {
@@ -54022,7 +53910,7 @@ function Viewer({
54022
53910
  baseId: activityId
54023
53911
  });
54024
53912
  } else if (state === null) {
54025
- setNeedNewAssignmentState(true);
53913
+ getNewActivityState();
54026
53914
  } else {
54027
53915
  setErrMsg(`Invalid state returned`);
54028
53916
  }
@@ -54032,7 +53920,7 @@ function Viewer({
54032
53920
  );
54033
53921
  });
54034
53922
  } else {
54035
- setNeedNewAssignmentState(true);
53923
+ getNewActivityState();
54036
53924
  }
54037
53925
  return () => {
54038
53926
  for (const listener3 of listenersAdded) {
@@ -54047,7 +53935,9 @@ function Viewer({
54047
53935
  flags.allowSaveState,
54048
53936
  activityId,
54049
53937
  userId,
54050
- source
53938
+ source,
53939
+ numActivityVariants,
53940
+ questionCounts
54051
53941
  ]);
54052
53942
  function clickNext() {
54053
53943
  setCurrentItemIdx((was) => Math.min(numItems - 1, was + 1));
@@ -54055,29 +53945,6 @@ function Viewer({
54055
53945
  function clickPrevious() {
54056
53946
  setCurrentItemIdx((was) => Math.max(0, was - 1));
54057
53947
  }
54058
- function documentStructureCallback(data) {
54059
- if (isDocumentStructureData(data)) {
54060
- if (data.args.success) {
54061
- const docId = data.docId.split("|")[0];
54062
- setNumActivityVariants((was) => {
54063
- if (docId in was) {
54064
- return was;
54065
- }
54066
- const obj = { ...was };
54067
- obj[docId] = data.args.allPossibleVariants.length;
54068
- return obj;
54069
- });
54070
- setQuestionCounts((was) => {
54071
- if (docId in was) {
54072
- return was;
54073
- }
54074
- const obj = { ...was };
54075
- obj[docId] = (data.args.baseLevelComponentCounts.question ?? 0) + (data.args.baseLevelComponentCounts.problem ?? 0) + (data.args.baseLevelComponentCounts.exercise ?? 0);
54076
- return obj;
54077
- });
54078
- }
54079
- }
54080
- }
54081
53948
  function reportScoreAndStateCallback(msg) {
54082
53949
  if (isSingleDocReportStateMessage(msg)) {
54083
53950
  activityStateDispatch({
@@ -54091,37 +53958,35 @@ function Viewer({
54091
53958
  }
54092
53959
  }
54093
53960
  function generateNewItemAttempt(id2, initialQuestionCounter) {
54094
- if (initialized) {
54095
- activityStateDispatch({
54096
- type: "generateNewActivityAttempt",
54097
- id: id2,
54098
- numActivityVariants,
54099
- initialQuestionCounter,
54100
- questionCounts,
54101
- allowSaveState: flags.allowSaveState,
54102
- baseId: activityId
54103
- });
54104
- setItemsRendered((was) => {
54105
- const idx = was.indexOf(id2);
54106
- if (idx === -1) {
54107
- return was;
54108
- } else {
54109
- const arr = [...was];
54110
- arr.splice(idx, 1);
54111
- return arr;
54112
- }
54113
- });
54114
- setItemsToRender((was) => {
54115
- const idx = was.indexOf(id2);
54116
- if (idx === -1) {
54117
- return was;
54118
- } else {
54119
- const arr = [...was];
54120
- arr.splice(idx, 1);
54121
- return arr;
54122
- }
54123
- });
54124
- }
53961
+ activityStateDispatch({
53962
+ type: "generateNewActivityAttempt",
53963
+ id: id2,
53964
+ numActivityVariants,
53965
+ initialQuestionCounter,
53966
+ questionCounts,
53967
+ allowSaveState: flags.allowSaveState,
53968
+ baseId: activityId
53969
+ });
53970
+ setItemsRendered((was) => {
53971
+ const idx = was.indexOf(id2);
53972
+ if (idx === -1) {
53973
+ return was;
53974
+ } else {
53975
+ const arr = [...was];
53976
+ arr.splice(idx, 1);
53977
+ return arr;
53978
+ }
53979
+ });
53980
+ setItemsToRender((was) => {
53981
+ const idx = was.indexOf(id2);
53982
+ if (idx === -1) {
53983
+ return was;
53984
+ } else {
53985
+ const arr = [...was];
53986
+ arr.splice(idx, 1);
53987
+ return arr;
53988
+ }
53989
+ });
54125
53990
  }
54126
53991
  function hasRenderedCallback(id2) {
54127
53992
  setItemsRendered((was) => {
@@ -54185,27 +54050,25 @@ function Viewer({
54185
54050
  }
54186
54051
  );
54187
54052
  }
54188
- if (initialized && !needNewAssignmentState) {
54189
- if (paginate) {
54190
- if (!itemsRendered.includes(currentItemId)) {
54191
- addItemToRender(currentItemId);
54053
+ if (paginate) {
54054
+ if (!itemsRendered.includes(currentItemId)) {
54055
+ addItemToRender(currentItemId);
54056
+ } else {
54057
+ const nextItemId = itemSequence[currentItemIdx + 1];
54058
+ if (currentItemIdx < numItems - 1 && !itemsRendered.includes(nextItemId)) {
54059
+ addItemToRender(nextItemId);
54192
54060
  } else {
54193
- const nextItemId = itemSequence[currentItemIdx + 1];
54194
- if (currentItemIdx < numItems - 1 && !itemsRendered.includes(nextItemId)) {
54195
- addItemToRender(nextItemId);
54196
- } else {
54197
- const prevItemId = itemSequence[currentItemIdx - 1];
54198
- if (currentItemIdx > 0 && !itemsRendered.includes(prevItemId)) {
54199
- addItemToRender(prevItemId);
54200
- }
54061
+ const prevItemId = itemSequence[currentItemIdx - 1];
54062
+ if (currentItemIdx > 0 && !itemsRendered.includes(prevItemId)) {
54063
+ addItemToRender(prevItemId);
54201
54064
  }
54202
54065
  }
54203
- } else {
54204
- for (const id2 of itemSequence) {
54205
- if (!itemsRendered.includes(id2) && itemsVisible.includes(id2)) {
54206
- addItemToRender(id2);
54207
- break;
54208
- }
54066
+ }
54067
+ } else {
54068
+ for (const id2 of itemSequence) {
54069
+ if (!itemsRendered.includes(id2) && itemsVisible.includes(id2)) {
54070
+ addItemToRender(id2);
54071
+ break;
54209
54072
  }
54210
54073
  }
54211
54074
  }
@@ -54223,7 +54086,7 @@ function Viewer({
54223
54086
  borderRadius: "10px",
54224
54087
  padding: "5px 20px"
54225
54088
  },
54226
- disabled: currentItemIdx === 0,
54089
+ disabled: currentItemIdx <= 0,
54227
54090
  children: "Previous"
54228
54091
  }
54229
54092
  ),
@@ -54241,7 +54104,7 @@ function Viewer({
54241
54104
  borderRadius: "10px",
54242
54105
  padding: "5px 20px"
54243
54106
  },
54244
- disabled: currentItemIdx === numItems - 1,
54107
+ disabled: currentItemIdx >= numItems - 1,
54245
54108
  children: "Next"
54246
54109
  }
54247
54110
  ),
@@ -54249,7 +54112,7 @@ function Viewer({
54249
54112
  "button",
54250
54113
  {
54251
54114
  onClick: generateActivityAttempt,
54252
- disabled: !initialized,
54115
+ disabled: numItems === 0,
54253
54116
  style: {
54254
54117
  marginLeft: "30px",
54255
54118
  backgroundColor: "lightgray",
@@ -54263,7 +54126,7 @@ function Viewer({
54263
54126
  /* @__PURE__ */ jsxRuntimeExports$1.jsx(
54264
54127
  "div",
54265
54128
  {
54266
- hidden: itemsRendered.length > 0,
54129
+ hidden: itemsRendered.length > 0 || numItems === 0,
54267
54130
  style: { marginLeft: "20px", marginTop: "20px" },
54268
54131
  children: "Initializing..."
54269
54132
  }
@@ -54281,7 +54144,6 @@ function Viewer({
54281
54144
  darkMode,
54282
54145
  showAnswerTitles,
54283
54146
  state: activityState,
54284
- documentStructureCallback,
54285
54147
  reportScoreAndStateCallback,
54286
54148
  checkRender,
54287
54149
  checkHidden,
@@ -54294,19 +54156,6 @@ function Viewer({
54294
54156
  )
54295
54157
  ] });
54296
54158
  }
54297
- function getNumSourceDocs(activity) {
54298
- switch (activity.type) {
54299
- case "singleDoc": {
54300
- return 1;
54301
- }
54302
- case "select": {
54303
- return activity.items.reduce((a, c2) => a + getNumSourceDocs(c2), 0);
54304
- }
54305
- case "sequence": {
54306
- return activity.items.reduce((a, c2) => a + getNumSourceDocs(c2), 0);
54307
- }
54308
- }
54309
- }
54310
54159
  const defaultFlags = {
54311
54160
  showCorrectness: true,
54312
54161
  readOnly: false,
@@ -54404,17 +54253,20 @@ function ActivityViewer({
54404
54253
  class ErrorBoundary extends Component {
54405
54254
  constructor(props) {
54406
54255
  super(props);
54407
- this.state = { hasError: false };
54256
+ this.state = { hasError: false, message: "" };
54408
54257
  }
54409
- static getDerivedStateFromError(_2) {
54410
- return { hasError: true };
54258
+ static getDerivedStateFromError(error) {
54259
+ return { hasError: true, message: error.message };
54411
54260
  }
54412
54261
  componentDidCatch(error, errorInfo) {
54413
54262
  console.error("Uncaught error", error, errorInfo);
54414
54263
  }
54415
54264
  render() {
54416
54265
  if (this.state.hasError) {
54417
- return /* @__PURE__ */ jsxRuntimeExports$1.jsx("h1", { children: "Sorry, something went wrong" });
54266
+ return /* @__PURE__ */ jsxRuntimeExports$1.jsxs("div", { style: { marginLeft: "20px" }, children: [
54267
+ /* @__PURE__ */ jsxRuntimeExports$1.jsx("h1", { children: "An error occurred" }),
54268
+ /* @__PURE__ */ jsxRuntimeExports$1.jsx("p", { children: this.state.message })
54269
+ ] });
54418
54270
  }
54419
54271
  return this.props.children;
54420
54272
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@doenet/assignment-viewer",
3
3
  "private": false,
4
4
  "description": "View assignments from questions written in DoenetML",
5
- "version": "0.1.0-alpha1",
5
+ "version": "0.1.0-alpha2",
6
6
  "license": "AGPL-3.0-or-later",
7
7
  "homepage": "https://github.com/Doenet/assignment-viewer#readme",
8
8
  "type": "module",