@livepreso/api 6.44.0 → 6.45.0

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 (127) hide show
  1. package/.eslintrc.js +3 -0
  2. package/.rush/temp/256021b5963b4c0221d3dec247b697b9691a9b2c.log +10 -0
  3. package/.rush/temp/2a322f00f12cf9d1e64afe81275cc78d01c49050.log +10 -0
  4. package/.rush/temp/30061f1865447dcbb3f20a305061205f3dbe6091.log +10 -0
  5. package/.rush/temp/45522aea0dee8cb2be1a53248ba45bd235743b43.log +10 -0
  6. package/.rush/temp/58fcbb7f15a76326d40e0839ab179755da82a891.log +10 -0
  7. package/.rush/temp/5bc0bba70b733baa4dd976667ba0a1386e516186.log +10 -0
  8. package/.rush/temp/64f1bb696f8d7d7e72907b80df316b127f72e23e.log +10 -0
  9. package/.rush/temp/6f640f951414ea68adb65c17e4ed7527cde54faf.log +10 -0
  10. package/.rush/temp/7c7b958682d4ab5697530be47d0aac62efe1adf1.log +10 -0
  11. package/.rush/temp/82bfb987463fbcfebf04022e6ed00015c73879c8.log +10 -0
  12. package/.rush/temp/844034aa6e542115075e8f3dc5ffc640973e0064.log +10 -0
  13. package/.rush/temp/8b42957a7c15da1f29cb57bee125f13affa70dca.log +10 -0
  14. package/.rush/temp/a769db9d81a23000c0e9b1bf4f1a9a9e721d0d7c.log +10 -0
  15. package/.rush/temp/a87d3a8b4ece87ec66f27c86226a9f205617681f.log +10 -0
  16. package/.rush/temp/bb7a5bdcc4af4ad1507f81f33774b31f5b4e4fb7.log +10 -0
  17. package/.rush/temp/c20e29ccaaa9231b38a28bb24451b4ce7562cdc0.log +10 -0
  18. package/.rush/temp/e21303db8f59b4625fd184c9114377d781fd24f8.log +10 -0
  19. package/.rush/temp/e6d303862765b6a5f41dd483d0f9ae083a1fae10.log +10 -0
  20. package/.rush/temp/eaf69fbc059d2f1258d7569136180d4a1d3c7072.log +10 -0
  21. package/.rush/temp/f85d279e2674966daaec83e1c3986a96f86ef304.log +10 -0
  22. package/.rush/temp/fc0a332c5b34c6b90006850cf2d93a48fb4b9a6e.log +10 -0
  23. package/.rush/temp/package-deps_build.json +170 -0
  24. package/.rush/temp/package-deps_test.json +38 -36
  25. package/.rush/temp/shrinkwrap-deps.json +231 -240
  26. package/CHANGELOG.json +17 -0
  27. package/CHANGELOG.md +8 -1
  28. package/api.build.log +4 -2
  29. package/bin/test.sh +0 -1
  30. package/cjs/auth.js +36 -10
  31. package/cjs/auth.js.map +1 -1
  32. package/cjs/auth.spec.js +12 -6
  33. package/cjs/auth.spec.js.map +1 -1
  34. package/cjs/collections/base.js +10 -2
  35. package/cjs/collections/base.js.map +1 -1
  36. package/cjs/collections/base.spec.js +22 -4
  37. package/cjs/collections/base.spec.js.map +1 -1
  38. package/cjs/collections/deck-version-screenshots.js +62 -0
  39. package/cjs/collections/deck-version-screenshots.js.map +1 -0
  40. package/cjs/collections.js +13 -0
  41. package/cjs/collections.js.map +1 -1
  42. package/cjs/models/activity-item.js +3 -1
  43. package/cjs/models/activity-item.js.map +1 -1
  44. package/cjs/models/appointment.js +11 -1
  45. package/cjs/models/appointment.js.map +1 -1
  46. package/cjs/models/auto-adjunct.js +3 -1
  47. package/cjs/models/auto-adjunct.js.map +1 -1
  48. package/cjs/models/base.js +19 -1
  49. package/cjs/models/base.js.map +1 -1
  50. package/cjs/models/base.spec.js +9 -0
  51. package/cjs/models/base.spec.js.map +1 -1
  52. package/cjs/models/deck-version-screenshot.js +59 -0
  53. package/cjs/models/deck-version-screenshot.js.map +1 -0
  54. package/cjs/models/deck-version.js +28 -5
  55. package/cjs/models/deck-version.js.map +1 -1
  56. package/cjs/models/feed-data.js +5 -0
  57. package/cjs/models/feed-data.js.map +1 -1
  58. package/cjs/models/image.js +34 -0
  59. package/cjs/models/image.js.map +1 -1
  60. package/cjs/models/manifest-json.js +1 -1
  61. package/cjs/models/manifest-json.js.map +1 -1
  62. package/cjs/models/section.js +3 -1
  63. package/cjs/models/section.js.map +1 -1
  64. package/cjs/models/slide.js +3 -1
  65. package/cjs/models/slide.js.map +1 -1
  66. package/cjs/models/template.js +3 -1
  67. package/cjs/models/template.js.map +1 -1
  68. package/cjs/models/token.js +56 -0
  69. package/cjs/models/token.js.map +1 -0
  70. package/cjs/models/user.js +2 -1
  71. package/cjs/models/user.js.map +1 -1
  72. package/cjs/models.js +26 -0
  73. package/cjs/models.js.map +1 -1
  74. package/cjs/presentation/appointment-presentation.js +7 -3
  75. package/cjs/presentation/appointment-presentation.js.map +1 -1
  76. package/cjs/presentation/base-presentation-model.js +111 -2
  77. package/cjs/presentation/base-presentation-model.js.map +1 -1
  78. package/cjs/presentation/base-presentation-model.spec.js +56 -0
  79. package/cjs/presentation/base-presentation-model.spec.js.map +1 -1
  80. package/cjs/presentation/presentation-deck.js +33 -6
  81. package/cjs/presentation/presentation-deck.js.map +1 -1
  82. package/cjs/presentation/presentation-deck.spec.js +53 -0
  83. package/cjs/presentation/presentation-deck.spec.js.map +1 -1
  84. package/cjs/presentation/presentation-section.js +42 -16
  85. package/cjs/presentation/presentation-section.js.map +1 -1
  86. package/cjs/presentation/presentation-section.spec.js +121 -3
  87. package/cjs/presentation/presentation-section.spec.js.map +1 -1
  88. package/cjs/presentation/presentation-slide.js +30 -13
  89. package/cjs/presentation/presentation-slide.js.map +1 -1
  90. package/cjs/presentation/presentation-slide.spec.js +94 -2
  91. package/cjs/presentation/presentation-slide.spec.js.map +1 -1
  92. package/cjs/presentation/presentation.js +112 -8
  93. package/cjs/presentation/presentation.js.map +1 -1
  94. package/jest.config.js +1 -0
  95. package/package.json +4 -4
  96. package/src/auth.js +44 -8
  97. package/src/auth.spec.js +2 -0
  98. package/src/collections/base.js +10 -4
  99. package/src/collections/base.spec.js +17 -3
  100. package/src/collections/deck-version-screenshots.js +48 -0
  101. package/src/collections.js +1 -0
  102. package/src/models/activity-item.js +2 -0
  103. package/src/models/appointment.js +12 -0
  104. package/src/models/auto-adjunct.js +2 -0
  105. package/src/models/base.js +19 -1
  106. package/src/models/base.spec.js +16 -9
  107. package/src/models/deck-version-screenshot.js +48 -0
  108. package/src/models/deck-version.js +30 -4
  109. package/src/models/feed-data.js +2 -0
  110. package/src/models/image.js +32 -0
  111. package/src/models/manifest-json.js +1 -1
  112. package/src/models/section.js +2 -0
  113. package/src/models/slide.js +2 -0
  114. package/src/models/template.js +2 -0
  115. package/src/models/token.js +47 -0
  116. package/src/models/user.js +2 -0
  117. package/src/models.js +2 -0
  118. package/src/presentation/appointment-presentation.js +10 -2
  119. package/src/presentation/base-presentation-model.js +77 -1
  120. package/src/presentation/base-presentation-model.spec.js +77 -0
  121. package/src/presentation/presentation-deck.js +40 -2
  122. package/src/presentation/presentation-deck.spec.js +53 -0
  123. package/src/presentation/presentation-section.js +37 -5
  124. package/src/presentation/presentation-section.spec.js +135 -2
  125. package/src/presentation/presentation-slide.js +25 -5
  126. package/src/presentation/presentation-slide.spec.js +104 -2
  127. package/src/presentation/presentation.js +24 -7
@@ -41,6 +41,7 @@ export const PresentationDeck = BasePresentationModel.extend(
41
41
  * @property {boolean} editable
42
42
  * @property {array} tags
43
43
  * @property {number} version
44
+ * @property {string[]} cmsvalkey_set
44
45
  */
45
46
  props: {
46
47
  html: "string",
@@ -57,6 +58,7 @@ export const PresentationDeck = BasePresentationModel.extend(
57
58
  editable: "boolean",
58
59
  tags: "array",
59
60
  version: "number",
61
+ cmsvalkey_set: "array",
60
62
  },
61
63
 
62
64
  /**
@@ -109,11 +111,13 @@ PresentationDeck.createFromDeckVersion = function (
109
111
  ) {
110
112
  _.defaults(options, {
111
113
  index: 0,
114
+ autoAdjuncts: new collections.AutoAdjunctCollection(),
112
115
  adjunctSections: new collections.AdjunctSectionCollection(),
113
116
  adjunctSlides: new collections.AdjunctSlideCollection(),
114
117
  adjunctSubSlides: new collections.AdjunctSubSlideCollection(),
115
118
  sectionSelections: new collections.SectionSelectionCollection(),
116
119
  slideSelections: new collections.SlideSelectionCollection(),
120
+ screenshots: new collections.DeckVersionScreenshotCollection(),
117
121
  rootAssetPath: null,
118
122
  templates: null,
119
123
  choicelist: null,
@@ -138,7 +142,10 @@ PresentationDeck.createFromDeckVersion = function (
138
142
  css,
139
143
  id: deckVersionModel.id,
140
144
  index: options.index,
141
- thumbnail: deckVersionModel.image_256,
145
+ thumbnail: PresentationDeck.getThumbnail(
146
+ deckVersionModel,
147
+ options.screenshots
148
+ ),
142
149
  deckID: deckVersionModel.deck.id,
143
150
  visible: true,
144
151
  key: deckVersionModel.deck.key,
@@ -148,6 +155,7 @@ PresentationDeck.createFromDeckVersion = function (
148
155
  tags,
149
156
  version: deckVersionModel.version,
150
157
  usesImpostorSections: isImpostorDeck(deckVersionModel),
158
+ cmsvalkey_set: deckVersionModel.cmsvalkey_set || [],
151
159
  });
152
160
 
153
161
  if (!deck.key) {
@@ -342,13 +350,41 @@ PresentationDeck.createFromDeckVersion = function (
342
350
  options.templates.map((template, index) => {
343
351
  return PresentationSection.createFromTemplate(
344
352
  template,
345
- index,
353
+ deck.sections.length + index,
346
354
  options.getUniqueAdjunctID()
347
355
  );
348
356
  })
349
357
  );
350
358
  }
351
359
 
360
+ // This is generally only used by screenshots
361
+ if (options.autoAdjuncts) {
362
+ const autoSections = options.autoAdjuncts.map((auto, index) => {
363
+ // We already have the template on the deckversion, so we can find it here.
364
+ if (!auto.template) {
365
+ throw new Error(
366
+ "Attempted to use an autoadjunct that has no template."
367
+ );
368
+ }
369
+
370
+ const section = PresentationSection.createFromTemplate(
371
+ auto.template,
372
+ deck.sections.length + index,
373
+ options.getUniqueAdjunctID()
374
+ );
375
+
376
+ // We've just borrowed the "from template" method above. We want to add
377
+ // back some of the specific keys about the auto.
378
+ section.autoAdjunctID = auto.id;
379
+ section.key = auto.key;
380
+ section.title = auto.name;
381
+
382
+ return section;
383
+ });
384
+
385
+ deck.sections.add(autoSections);
386
+ }
387
+
352
388
  setSequentialSequences(deck);
353
389
 
354
390
  return deck;
@@ -368,6 +404,7 @@ PresentationDeck.createFromManifestJSON = function (manifestJSON) {
368
404
  title: "Local",
369
405
  version: 1,
370
406
  tags: manifestJSON.tags[""] || [],
407
+ cmsvalkey_set: [],
371
408
  });
372
409
 
373
410
  const usesImpostorSections = _.some(
@@ -391,6 +428,7 @@ PresentationDeck.createFromManifestJSON = function (manifestJSON) {
391
428
  css: url2.resolve(manifestJSON.getAssetPath(key), "slide.css"),
392
429
  title: manifestJSON.titles[key],
393
430
  tags: manifestJSON.tags[key] || [],
431
+ cmsvalkey_set: [],
394
432
  };
395
433
  });
396
434
 
@@ -1,4 +1,5 @@
1
1
  import { DeckVersionModel } from "../models/deck-version";
2
+ import { DeckVersionScreenshotCollection } from "../collections/deck-version-screenshots.js";
2
3
  import { G } from "sp-test/api";
3
4
  import { ManifestJSONModel } from "../models/manifest-json";
4
5
  import { PresentationDeck } from "./presentation-deck";
@@ -57,6 +58,7 @@ describe("#createFromManifestJSON", () => {
57
58
 
58
59
  describe("#createFromDeckVersion", () => {
59
60
  const deckVersionJSON = {
61
+ image_256: "http://path/to/deck/thumbnail.png",
60
62
  template_set: [
61
63
  {
62
64
  id: 20,
@@ -87,6 +89,7 @@ describe("#createFromDeckVersion", () => {
87
89
  {
88
90
  id: 1,
89
91
  title: "Section 1",
92
+ image_256: "default_section.png",
90
93
  index_asset: {
91
94
  url: "http://path/to/index.html",
92
95
  },
@@ -99,6 +102,7 @@ describe("#createFromDeckVersion", () => {
99
102
  index_asset: {
100
103
  url: "http://path/to/index.html",
101
104
  },
105
+ image_256: "default_slide.png",
102
106
  subslide_set: [],
103
107
  section: { id: 1 },
104
108
  },
@@ -107,6 +111,7 @@ describe("#createFromDeckVersion", () => {
107
111
  {
108
112
  id: 2,
109
113
  title: "Section 2",
114
+ image_256: "default_section.png",
110
115
  index_asset: {
111
116
  url: "http://path/to/index.html",
112
117
  },
@@ -117,6 +122,7 @@ describe("#createFromDeckVersion", () => {
117
122
  {
118
123
  id: 3,
119
124
  title: "Section 3",
125
+ image_256: "default_section.png",
120
126
  index_asset: {
121
127
  url: "http://path/to/index.html",
122
128
  },
@@ -158,4 +164,51 @@ describe("#createFromDeckVersion", () => {
158
164
  );
159
165
  expect(lastSection.css).toEqual("http://path/to/template/orange/slide.css");
160
166
  });
167
+
168
+ describe("Screenshots", () => {
169
+ it("should use the default image from the slide if no screenshot found", () => {
170
+ const deck = new DeckVersionModel(deckVersionJSON);
171
+ const presentationDeck = PresentationDeck.createFromDeckVersion(deck);
172
+ expect(presentationDeck.thumbnail).toEqual(deckVersionJSON.image_256);
173
+ });
174
+
175
+ it("should use the screenshot model if it matches", () => {
176
+ const deck = new DeckVersionModel(deckVersionJSON);
177
+ const options = {
178
+ screenshots: new DeckVersionScreenshotCollection([
179
+ { subject: deck.url(), image_256: "test-screenshot.png" },
180
+ ]),
181
+ };
182
+
183
+ const presentationDeck = PresentationDeck.createFromDeckVersion(
184
+ deck,
185
+ options
186
+ );
187
+ expect(presentationDeck.thumbnail).toEqual("test-screenshot.png");
188
+ });
189
+
190
+ it("should pass screenshots to nested models", () => {
191
+ const deck = new DeckVersionModel(deckVersionJSON);
192
+ const section = deck.section_set.first();
193
+ const slide = section.slide_set.first();
194
+
195
+ const options = {
196
+ screenshots: new DeckVersionScreenshotCollection([
197
+ { subject: deck.url(), image_256: "test-screenshot.png" },
198
+ { subject: section.url(), image_256: "test-screenshot.png" },
199
+ { subject: slide.url(), image_256: "test-screenshot.png" },
200
+ ]),
201
+ };
202
+
203
+ const presentationDeck = PresentationDeck.createFromDeckVersion(
204
+ deck,
205
+ options
206
+ );
207
+ const presentationSection = presentationDeck.sections.first();
208
+ const presentationSlide = presentationSection.slides.first();
209
+
210
+ expect(presentationSection.thumbnail).toEqual("test-screenshot.png");
211
+ expect(presentationSlide.thumbnail).toEqual("test-screenshot.png");
212
+ });
213
+ });
161
214
  });
@@ -1,5 +1,7 @@
1
1
  import "./presentation-slides.js";
2
2
 
3
+ import * as collections from "../collections.js";
4
+
3
5
  import {
4
6
  AdjunctSectionModel,
5
7
  AdjunctSlideModel,
@@ -50,6 +52,7 @@ export const PresentationSection = BasePresentationModel.extend(
50
52
  * @property {array} tags
51
53
  * @property {boolean} impostor
52
54
  * @property {boolean} isWelcome
55
+ * @property {string[]} cmsvalkey_set
53
56
  */
54
57
  props: {
55
58
  id: "number",
@@ -95,6 +98,7 @@ export const PresentationSection = BasePresentationModel.extend(
95
98
  type: "boolean",
96
99
  default: () => false,
97
100
  },
101
+ cmsvalkey_set: "array",
98
102
  },
99
103
 
100
104
  /**
@@ -169,6 +173,7 @@ PresentationSection.createFromSection = function (sectionModel, options = {}) {
169
173
  rootAssetPath: null,
170
174
  selections: null,
171
175
  choicelist: null,
176
+ screenshots: new collections.DeckVersionScreenshotCollection(),
172
177
  });
173
178
 
174
179
  let html;
@@ -201,7 +206,10 @@ PresentationSection.createFromSection = function (sectionModel, options = {}) {
201
206
  css,
202
207
  key: sectionModel.key,
203
208
  adjunctSlideLimit: sectionModel.adjunctslide_limit,
204
- thumbnail: sectionModel.image_256,
209
+ thumbnail: PresentationSection.getThumbnail(
210
+ sectionModel,
211
+ options.screenshots
212
+ ),
205
213
  custom: false,
206
214
  impostor: false,
207
215
  title: sectionModel.title,
@@ -212,6 +220,7 @@ PresentationSection.createFromSection = function (sectionModel, options = {}) {
212
220
  sequence: config.sequence,
213
221
  visible: config.visible,
214
222
  selectionID: config.selectionID,
223
+ cmsvalkey_set: sectionModel.cmsvalkey_set,
215
224
  });
216
225
 
217
226
  return section;
@@ -237,6 +246,7 @@ PresentationSection.createFromAdjunctSection = function (
237
246
  getUniqueAdjunctID: () => {
238
247
  return parseInt(_.uniqueId(), 10);
239
248
  },
249
+ screenshots: new collections.DeckVersionScreenshotCollection(),
240
250
  });
241
251
 
242
252
  const keyID =
@@ -284,6 +294,7 @@ PresentationSection.createFromAdjunctSection = function (
284
294
  index: config.sequence,
285
295
  sequence: config.sequence,
286
296
  visible: config.visible,
297
+ cmsvalkey_set: [],
287
298
  });
288
299
 
289
300
  if (adjunctSectionModel.template) {
@@ -308,7 +319,13 @@ PresentationSection.createFromAdjunctSection = function (
308
319
  }
309
320
  section.html = html;
310
321
  section.css = css;
311
- section.thumbnail = adjunctSectionModel.template.image_256;
322
+ section.thumbnail =
323
+ // Try and use autoadjunct screenshot (if there is one), otherwise
324
+ // use the template's image as a fallback
325
+ PresentationSection.getThumbnail(
326
+ adjunctSectionModel.creator_autoadjunct,
327
+ options.screenshots
328
+ ) || adjunctSectionModel.template.image_256;
312
329
  } else {
313
330
  section.image = adjunctSectionModel.image_original;
314
331
  }
@@ -325,6 +342,7 @@ PresentationSection.createFromImpostorSection = function (
325
342
  rootAssetPath: null,
326
343
  selections: null,
327
344
  choicelist: null,
345
+ screenshots: new collections.DeckVersionScreenshotCollection(),
328
346
  });
329
347
 
330
348
  let html;
@@ -359,7 +377,10 @@ PresentationSection.createFromImpostorSection = function (
359
377
  css,
360
378
  key: slideModel.key,
361
379
  adjunctSlideLimit: slideModel.adjunctslide_limit,
362
- thumbnail: slideModel.image_256,
380
+ thumbnail: PresentationSection.getThumbnail(
381
+ slideModel,
382
+ options.screenshots
383
+ ),
363
384
  custom: false,
364
385
  impostor: true,
365
386
  title: slideModel.title,
@@ -370,6 +391,7 @@ PresentationSection.createFromImpostorSection = function (
370
391
  sequence: config.sequence,
371
392
  visible: config.visible,
372
393
  selectionID: config.selectionID,
394
+ cmsvalkey_set: slideModel.cmsvalkey_set,
373
395
  });
374
396
 
375
397
  return section;
@@ -393,6 +415,7 @@ PresentationSection.createFromManifestJSON = function (
393
415
  visible: true,
394
416
  deckversion: 1,
395
417
  tags: manifestJSON.tags[sectionKey] || null,
418
+ cmsvalkey_set: [],
396
419
  });
397
420
 
398
421
  const slideKeys = Object.keys(manifestJSON.titles).filter((slideKey) => {
@@ -455,6 +478,7 @@ PresentationSection.createFromAutoAdjunct = function (model, opts = {}) {
455
478
  deckversionID: -1,
456
479
  sequence: opts.index,
457
480
  impostor: false,
481
+ screenshots: new collections.DeckVersionScreenshotCollection(),
458
482
  });
459
483
 
460
484
  const tags = PresentationSection.getTags(
@@ -480,7 +504,10 @@ PresentationSection.createFromAutoAdjunct = function (model, opts = {}) {
480
504
  index: options.index,
481
505
  key: autoAdjunct.key,
482
506
  createdByAutoAdjunct: false,
483
- thumbnail: autoAdjunct.image_256,
507
+ thumbnail: PresentationSection.getThumbnail(
508
+ autoAdjunct,
509
+ options.screenshots
510
+ ),
484
511
  temporary: true,
485
512
  title: autoAdjunct.name,
486
513
  visible: options.visible,
@@ -488,10 +515,14 @@ PresentationSection.createFromAutoAdjunct = function (model, opts = {}) {
488
515
  deckversion: options.deckversionID,
489
516
  impostor: options.impostor,
490
517
  tags,
518
+ cmsvalkey_set: autoAdjunct.cmsvalkey_set,
491
519
  });
492
520
 
493
521
  if (autoAdjunct.template) {
494
- autoAdjunctSection.thumbnail = autoAdjunct.template.image_256;
522
+ // If we've found a new screenshot for it, we don't want to override it here
523
+ if (!autoAdjunctSection.thumbnail) {
524
+ autoAdjunctSection.thumbnail = autoAdjunct.template.image_256;
525
+ }
495
526
  autoAdjunctSection.createdByTemplate = true;
496
527
  autoAdjunctSection.templateID = autoAdjunct.template.id;
497
528
  autoAdjunctSection.html = autoAdjunct.template.index_asset.url();
@@ -525,6 +556,7 @@ PresentationSection.createFromTemplate = function (template, index, minID = 0) {
525
556
  sequence: 9000 + templateModel.sequence,
526
557
  createdByTemplate: true,
527
558
  index,
559
+ cmsvalkey_set: [],
528
560
  });
529
561
 
530
562
  return presentationSection;
@@ -1,5 +1,6 @@
1
1
  import { AdjunctSectionModel } from "../models/adjunct-section";
2
2
  import { AutoAdjunctModel } from "../models/auto-adjunct";
3
+ import { DeckVersionScreenshotCollection } from "../collections/deck-version-screenshots.js";
3
4
  import { PresentationSection } from "./presentation-section";
4
5
  import { SectionModel } from "../models/section";
5
6
  import { SlideModel } from "../models/slide";
@@ -90,10 +91,49 @@ describe("#createFromSection", () => {
90
91
 
91
92
  expect(presentationSection.tags).toEqual(["section-tag"]);
92
93
  });
94
+
95
+ describe("Screenshots", () => {
96
+ it("should use the default image from the slide if no screenshot found", () => {
97
+ const data = getSectionJSON();
98
+ const section = new SectionModel(data);
99
+ const presentationSection =
100
+ PresentationSection.createFromSection(section);
101
+ expect(presentationSection.thumbnail).toEqual(data.image_256);
102
+ });
103
+
104
+ it("should use the screenshot model if it matches", () => {
105
+ const section = new SectionModel(getSectionJSON());
106
+ const options = {
107
+ screenshots: new DeckVersionScreenshotCollection([
108
+ { subject: section.url(), image_256: "test-screenshot.png" },
109
+ ]),
110
+ };
111
+
112
+ const presentationSection = PresentationSection.createFromSection(
113
+ section,
114
+ options
115
+ );
116
+ expect(presentationSection.thumbnail).toEqual("test-screenshot.png");
117
+ });
118
+ });
93
119
  });
94
120
 
95
121
  describe("#createFromAdjunctSection", () => {
96
- const getAdjunctSectionJSON = () => {
122
+ const getAdjunctSectionJSON = (includeTemplate) => {
123
+ const template = {
124
+ id: 1,
125
+ image_256: "template.png",
126
+ index_asset: {
127
+ created_date: "2021-07-22T04:57:32.977770Z",
128
+ data: "index.html",
129
+ id: 148204,
130
+ modified_date: "2021-07-22T04:57:32.977790Z",
131
+ orig_path: "templates/test-template/foo",
132
+ pack: "https://staging-test.salespreso.com/api/packs/410/",
133
+ url: "https://staging-test-cdn.salespreso.com/media/pack/410/assets/sections/test-deck/slides/slide-key/index.html",
134
+ },
135
+ };
136
+
97
137
  return {
98
138
  adjunct: "https://staging-test.salespreso.com/api/adjuncts/7470/",
99
139
  appointment: "https://staging-test.salespreso.com/api/appointments/2422/",
@@ -120,7 +160,7 @@ describe("#createFromAdjunctSection", () => {
120
160
  modified_date: "2021-09-20T01:57:55.125229Z",
121
161
  sequence: 1,
122
162
  tags: [],
123
- template: null,
163
+ template: includeTemplate ? template : null,
124
164
  title: "Five",
125
165
  url: "https://staging-test.salespreso.com/api/adjunctsections/1737/",
126
166
  };
@@ -162,6 +202,7 @@ describe("#createFromAdjunctSection", () => {
162
202
  title: "Five",
163
203
  url: "/api/adjunctsections/1737/",
164
204
  visible: true,
205
+ cmsvalkey_set: [],
165
206
  };
166
207
 
167
208
  expect(presentationSection.toJSON()).toEqual(expected);
@@ -180,6 +221,40 @@ describe("#createFromAdjunctSection", () => {
180
221
 
181
222
  expect(presentationSection.tags).toEqual(["adjunctsection-tag"]);
182
223
  });
224
+
225
+ describe("Screenshots", () => {
226
+ it("should use the default image from the model if no screenshot found", () => {
227
+ const data = getAdjunctSectionJSON(true);
228
+ const adjunctSection = new AdjunctSectionModel(data);
229
+ const presentationSlide = PresentationSection.createFromAdjunctSection(
230
+ adjunctSection,
231
+ { id: 1 }
232
+ );
233
+ expect(presentationSlide.thumbnail).toEqual(data.template.image_256);
234
+ });
235
+
236
+ it("should use the screenshot model if it matches", () => {
237
+ const adjunctSection = new AdjunctSectionModel(
238
+ getAdjunctSectionJSON(true)
239
+ );
240
+
241
+ const options = {
242
+ screenshots: new DeckVersionScreenshotCollection([
243
+ {
244
+ subject: "/api/autoadjuncts/545/",
245
+ image_256: "test-screenshot.png",
246
+ },
247
+ ]),
248
+ };
249
+
250
+ const presentationSection = PresentationSection.createFromAdjunctSection(
251
+ adjunctSection,
252
+ { id: 1 },
253
+ options
254
+ );
255
+ expect(presentationSection.thumbnail).toEqual("test-screenshot.png");
256
+ });
257
+ });
183
258
  });
184
259
 
185
260
  describe("#createFromImpostorSection", () => {
@@ -273,6 +348,34 @@ describe("#createFromImpostorSection", () => {
273
348
 
274
349
  expect(presentationSection.tags).toEqual(["impostorsection-tag"]);
275
350
  });
351
+
352
+ describe("Screenshots", () => {
353
+ it("should use the default image from the model if no screenshot found", () => {
354
+ const data = getImpostorSectionJSON();
355
+ const impostorSection = new SlideModel(data);
356
+ const presentationSection = PresentationSection.createFromImpostorSection(
357
+ impostorSection,
358
+ null
359
+ );
360
+ expect(presentationSection.thumbnail).toEqual(data.image_256);
361
+ });
362
+
363
+ it("should use the screenshot model if it matches", () => {
364
+ const impostorSection = new SlideModel(getImpostorSectionJSON());
365
+ const options = {
366
+ screenshots: new DeckVersionScreenshotCollection([
367
+ { subject: impostorSection.url(), image_256: "test-screenshot.png" },
368
+ ]),
369
+ };
370
+
371
+ const presentationSection = PresentationSection.createFromImpostorSection(
372
+ impostorSection,
373
+ null,
374
+ options
375
+ );
376
+ expect(presentationSection.thumbnail).toEqual("test-screenshot.png");
377
+ });
378
+ });
276
379
  });
277
380
 
278
381
  describe("#createFromAutoAdjunct", () => {
@@ -360,4 +463,34 @@ describe("#createFromAutoAdjunct", () => {
360
463
 
361
464
  expect(presentationSection.tags).toEqual(["autoadjunct-tag"]);
362
465
  });
466
+
467
+ describe("Screenshots", () => {
468
+ it("should use the default image from the model if no screenshot found", () => {
469
+ const data = getAutoAdjunctJSON();
470
+ const options = { index: 3, deckversionID: 12 };
471
+ const autoAdjunct = new AutoAdjunctModel(data);
472
+ const presentationSection = PresentationSection.createFromAutoAdjunct(
473
+ autoAdjunct,
474
+ options
475
+ );
476
+ expect(presentationSection.thumbnail).toEqual(data.image_256);
477
+ });
478
+
479
+ it("should use the screenshot model if it matches", () => {
480
+ const autoAdjunct = new AutoAdjunctModel(getAutoAdjunctJSON());
481
+ const options = {
482
+ index: 3,
483
+ deckversionID: 12,
484
+ screenshots: new DeckVersionScreenshotCollection([
485
+ { subject: autoAdjunct.url(), image_256: "test-screenshot.png" },
486
+ ]),
487
+ };
488
+
489
+ const presentationSection = PresentationSection.createFromAutoAdjunct(
490
+ autoAdjunct,
491
+ options
492
+ );
493
+ expect(presentationSection.thumbnail).toEqual("test-screenshot.png");
494
+ });
495
+ });
363
496
  });
@@ -41,6 +41,7 @@ export const PresentationSlide = BasePresentationModel.extend(
41
41
  * @property {number} selectionID
42
42
  * @property {bool} editable
43
43
  * @property {array} tags
44
+ * @property {string[]} cmsvalkey_set
44
45
  */
45
46
  props: {
46
47
  id: "number",
@@ -77,6 +78,7 @@ export const PresentationSlide = BasePresentationModel.extend(
77
78
  selectionID: "number",
78
79
  editable: "boolean",
79
80
  tags: "array",
81
+ cmsvalkey_set: "array",
80
82
  },
81
83
 
82
84
  /**
@@ -116,6 +118,7 @@ export const PresentationSlide = BasePresentationModel.extend(
116
118
  PresentationSlide.createFromSlide = function (slideModel, options = {}) {
117
119
  _.defaults(options, {
118
120
  adjunctSubSlides: new collections.AdjunctSubSlideCollection(),
121
+ screenshots: new collections.DeckVersionScreenshotCollection(),
119
122
  rootAssetPath: null,
120
123
  selections: null,
121
124
  choicelist: null,
@@ -154,7 +157,7 @@ PresentationSlide.createFromSlide = function (slideModel, options = {}) {
154
157
  html,
155
158
  css,
156
159
  key: slideModel.key,
157
- thumbnail: slideModel.image_256,
160
+ thumbnail: PresentationSlide.getThumbnail(slideModel, options.screenshots),
158
161
  custom: false,
159
162
  editable: tags.indexOf("editable") > -1,
160
163
  title: slideModel.title,
@@ -164,6 +167,7 @@ PresentationSlide.createFromSlide = function (slideModel, options = {}) {
164
167
  sequence: config.sequence,
165
168
  visible: config.visible,
166
169
  selectionID: config.selectionID,
170
+ cmsvalkey_set: slideModel.cmsvalkey_set,
167
171
  });
168
172
 
169
173
  slide.subslides.add(
@@ -229,6 +233,7 @@ PresentationSlide.createFromAdjunctSlide = function (
229
233
  getUniqueAdjunctID: () => {
230
234
  return parseInt(_.uniqueId(), 10);
231
235
  },
236
+ screenshots: new collections.DeckVersionScreenshotCollection(),
232
237
  });
233
238
 
234
239
  const keyID =
@@ -272,6 +277,7 @@ PresentationSlide.createFromAdjunctSlide = function (
272
277
  index: config.sequence,
273
278
  sequence: config.sequence,
274
279
  visible: config.visible,
280
+ cmsvalkey_set: [],
275
281
  });
276
282
 
277
283
  if (adjunctSlideModel.template) {
@@ -296,7 +302,14 @@ PresentationSlide.createFromAdjunctSlide = function (
296
302
  }
297
303
  slide.html = html;
298
304
  slide.css = css;
299
- slide.thumbnail = adjunctSlideModel.template.image_256;
305
+
306
+ slide.thumbnail =
307
+ // Try and use autoadjunct screenshot (if there is one), otherwise
308
+ // use the template's image as a fallback
309
+ PresentationSlide.getThumbnail(
310
+ adjunctSlideModel.creator_autoadjunct,
311
+ options.screenshots
312
+ ) || adjunctSlideModel.template.image_256;
300
313
  } else {
301
314
  slide.image = adjunctSlideModel.image_original;
302
315
  }
@@ -326,6 +339,7 @@ PresentationSlide.createFromManifestJSON = function (
326
339
  visible: true,
327
340
  section: sectionID,
328
341
  tags: manifestJSON.tags[key] || null,
342
+ cmsvalkey_set: [],
329
343
  });
330
344
 
331
345
  return slide;
@@ -368,11 +382,12 @@ PresentationSlide.createFromTemplate = function (
368
382
  autoAdjunctID: Number(_.uniqueId()),
369
383
  index,
370
384
  createdByTemplate: true,
385
+ cmsvalkey_set: [],
371
386
  });
372
387
  return presentationSlide;
373
388
  };
374
389
 
375
- PresentationSlide.createFromAutoAdjunct = function (model, opts) {
390
+ PresentationSlide.createFromAutoAdjunct = function (model, opts = {}) {
376
391
  const requiredKeys = ["index", "deckversionID"];
377
392
  for (const key of requiredKeys) {
378
393
  if (typeof opts[key] === "undefined") {
@@ -387,6 +402,7 @@ PresentationSlide.createFromAutoAdjunct = function (model, opts) {
387
402
  deckversionID: -1,
388
403
  sequence: opts.index,
389
404
  impostor: false,
405
+ screenshots: new collections.DeckVersionScreenshotCollection(),
390
406
  });
391
407
 
392
408
  const tags = PresentationSlide.getTags(
@@ -412,7 +428,7 @@ PresentationSlide.createFromAutoAdjunct = function (model, opts) {
412
428
  index: options.index,
413
429
  key: autoAdjunct.key,
414
430
  createdByAutoAdjunct: false,
415
- thumbnail: autoAdjunct.image_256,
431
+ thumbnail: PresentationSlide.getThumbnail(autoAdjunct, options.screenshots),
416
432
  temporary: true,
417
433
  title: autoAdjunct.name,
418
434
  visible: options.visible,
@@ -420,10 +436,14 @@ PresentationSlide.createFromAutoAdjunct = function (model, opts) {
420
436
  deckversion: options.deckversionID,
421
437
  impostor: options.impostor,
422
438
  tags,
439
+ cmsvalkey_set: autoAdjunct.cmsvalkey_set,
423
440
  });
424
441
 
425
442
  if (autoAdjunct.template) {
426
- autoAdjunctSlide.thumbnail = autoAdjunct.template.image_256;
443
+ // If we've found a new screenshot for it, we don't want to override it here
444
+ if (!autoAdjunctSlide.thumbnail) {
445
+ autoAdjunctSlide.thumbnail = autoAdjunct.template.image_256;
446
+ }
427
447
  autoAdjunctSlide.createdByTemplate = true;
428
448
  autoAdjunctSlide.templateID = autoAdjunct.template.id;
429
449
  autoAdjunctSlide.html = autoAdjunct.template.index_asset.url();