@livepreso/api 6.42.1 → 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 (196) 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/build-cache-tar.log +7 -0
  18. package/.rush/temp/c20e29ccaaa9231b38a28bb24451b4ce7562cdc0.log +10 -0
  19. package/.rush/temp/e21303db8f59b4625fd184c9114377d781fd24f8.log +10 -0
  20. package/.rush/temp/e6d303862765b6a5f41dd483d0f9ae083a1fae10.log +10 -0
  21. package/.rush/temp/eaf69fbc059d2f1258d7569136180d4a1d3c7072.log +10 -0
  22. package/.rush/temp/f85d279e2674966daaec83e1c3986a96f86ef304.log +10 -0
  23. package/.rush/temp/fc0a332c5b34c6b90006850cf2d93a48fb4b9a6e.log +10 -0
  24. package/.rush/temp/package-deps_build.json +152 -134
  25. package/.rush/temp/package-deps_test.json +172 -0
  26. package/.rush/temp/shrinkwrap-deps.json +946 -847
  27. package/CHANGELOG.json +41 -0
  28. package/CHANGELOG.md +22 -1
  29. package/api.build.log +3 -26
  30. package/babel.config.js +1 -1
  31. package/bin/test.sh +0 -1
  32. package/cjs/api.js +1 -1
  33. package/cjs/api.js.map +1 -1
  34. package/cjs/auth.js +38 -11
  35. package/cjs/auth.js.map +1 -1
  36. package/cjs/auth.spec.js +12 -6
  37. package/cjs/auth.spec.js.map +1 -1
  38. package/cjs/caching.js +3 -3
  39. package/cjs/collections/activity.js +2 -2
  40. package/cjs/collections/appointment-adjunct-tags.js +28 -0
  41. package/cjs/collections/appointment-adjunct-tags.js.map +1 -0
  42. package/cjs/collections/appointment-deckversion-tags.js +28 -0
  43. package/cjs/collections/appointment-deckversion-tags.js.map +1 -0
  44. package/cjs/collections/appointment-section-tags.js +28 -0
  45. package/cjs/collections/appointment-section-tags.js.map +1 -0
  46. package/cjs/collections/appointment-slide-tags.js +28 -0
  47. package/cjs/collections/appointment-slide-tags.js.map +1 -0
  48. package/cjs/collections/appointment-tags.js +208 -0
  49. package/cjs/collections/appointment-tags.js.map +1 -0
  50. package/cjs/collections/appointments.js +2 -2
  51. package/cjs/collections/auto-adjuncts.js +2 -2
  52. package/cjs/collections/base.js +84 -3
  53. package/cjs/collections/base.js.map +1 -1
  54. package/cjs/collections/base.spec.js +178 -0
  55. package/cjs/collections/base.spec.js.map +1 -1
  56. package/cjs/collections/deck-version-screenshots.js +62 -0
  57. package/cjs/collections/deck-version-screenshots.js.map +1 -0
  58. package/cjs/collections/deck-versions.js +2 -2
  59. package/cjs/collections/tags.js +28 -0
  60. package/cjs/collections/tags.js.map +1 -0
  61. package/cjs/collections.js +91 -0
  62. package/cjs/collections.js.map +1 -1
  63. package/cjs/models/activity-item.js +5 -3
  64. package/cjs/models/activity-item.js.map +1 -1
  65. package/cjs/models/appointment-adjunct-tags.js +52 -0
  66. package/cjs/models/appointment-adjunct-tags.js.map +1 -0
  67. package/cjs/models/appointment-deckversion-tags.js +52 -0
  68. package/cjs/models/appointment-deckversion-tags.js.map +1 -0
  69. package/cjs/models/appointment-duplicate.js +2 -2
  70. package/cjs/models/appointment-section-tags.js +52 -0
  71. package/cjs/models/appointment-section-tags.js.map +1 -0
  72. package/cjs/models/appointment-slide-tags.js +52 -0
  73. package/cjs/models/appointment-slide-tags.js.map +1 -0
  74. package/cjs/models/appointment-tags.js +16 -15
  75. package/cjs/models/appointment-tags.js.map +1 -1
  76. package/cjs/models/appointment.js +19 -3
  77. package/cjs/models/appointment.js.map +1 -1
  78. package/cjs/models/auto-adjunct.js +3 -1
  79. package/cjs/models/auto-adjunct.js.map +1 -1
  80. package/cjs/models/base.js +19 -1
  81. package/cjs/models/base.js.map +1 -1
  82. package/cjs/models/base.spec.js +9 -0
  83. package/cjs/models/base.spec.js.map +1 -1
  84. package/cjs/models/deck-tags.js +61 -0
  85. package/cjs/models/deck-tags.js.map +1 -0
  86. package/cjs/models/deck-version-screenshot.js +59 -0
  87. package/cjs/models/deck-version-screenshot.js.map +1 -0
  88. package/cjs/models/deck-version.js +30 -5
  89. package/cjs/models/deck-version.js.map +1 -1
  90. package/cjs/models/deck.js +4 -1
  91. package/cjs/models/deck.js.map +1 -1
  92. package/cjs/models/feed-data.js +5 -0
  93. package/cjs/models/feed-data.js.map +1 -1
  94. package/cjs/models/image.js +34 -0
  95. package/cjs/models/image.js.map +1 -1
  96. package/cjs/models/manifest-json.js +56 -13
  97. package/cjs/models/manifest-json.js.map +1 -1
  98. package/cjs/models/preset.js +21 -1
  99. package/cjs/models/preset.js.map +1 -1
  100. package/cjs/models/section.js +3 -1
  101. package/cjs/models/section.js.map +1 -1
  102. package/cjs/models/slide.js +3 -1
  103. package/cjs/models/slide.js.map +1 -1
  104. package/cjs/models/tag.js +54 -0
  105. package/cjs/models/tag.js.map +1 -0
  106. package/cjs/models/template.js +3 -1
  107. package/cjs/models/template.js.map +1 -1
  108. package/cjs/models/token.js +56 -0
  109. package/cjs/models/token.js.map +1 -0
  110. package/cjs/models/user.js +4 -2
  111. package/cjs/models/user.js.map +1 -1
  112. package/cjs/models.js +104 -0
  113. package/cjs/models.js.map +1 -1
  114. package/cjs/presentation/appointment-presentation.js +11 -4
  115. package/cjs/presentation/appointment-presentation.js.map +1 -1
  116. package/cjs/presentation/base-presentation-model.js +167 -9
  117. package/cjs/presentation/base-presentation-model.js.map +1 -1
  118. package/cjs/presentation/base-presentation-model.spec.js +96 -6
  119. package/cjs/presentation/base-presentation-model.spec.js.map +1 -1
  120. package/cjs/presentation/presentation-deck.js +36 -8
  121. package/cjs/presentation/presentation-deck.js.map +1 -1
  122. package/cjs/presentation/presentation-deck.spec.js +53 -0
  123. package/cjs/presentation/presentation-deck.spec.js.map +1 -1
  124. package/cjs/presentation/presentation-section.js +64 -25
  125. package/cjs/presentation/presentation-section.js.map +1 -1
  126. package/cjs/presentation/presentation-section.spec.js +536 -0
  127. package/cjs/presentation/presentation-section.spec.js.map +1 -0
  128. package/cjs/presentation/presentation-slide.js +43 -18
  129. package/cjs/presentation/presentation-slide.js.map +1 -1
  130. package/cjs/presentation/presentation-slide.spec.js +386 -0
  131. package/cjs/presentation/presentation-slide.spec.js.map +1 -0
  132. package/cjs/presentation/presentation-subslide.js +5 -2
  133. package/cjs/presentation/presentation-subslide.js.map +1 -1
  134. package/cjs/presentation/presentation-subslide.spec.js +58 -12
  135. package/cjs/presentation/presentation-subslide.spec.js.map +1 -1
  136. package/cjs/presentation/presentation.js +120 -6
  137. package/cjs/presentation/presentation.js.map +1 -1
  138. package/cjs/state-register.js +11 -1
  139. package/cjs/state-register.js.map +1 -1
  140. package/cjs/sync.js +1 -1
  141. package/cjs/utils.js +5 -5
  142. package/config/rush-project.json +11 -0
  143. package/jest.config.js +1 -0
  144. package/package.json +66 -66
  145. package/src/api.js +1 -1
  146. package/src/auth.js +44 -8
  147. package/src/auth.spec.js +2 -0
  148. package/src/collections/appointment-adjunct-tags.js +18 -0
  149. package/src/collections/appointment-deckversion-tags.js +21 -0
  150. package/src/collections/appointment-section-tags.js +18 -0
  151. package/src/collections/appointment-slide-tags.js +18 -0
  152. package/src/collections/appointment-tags.js +136 -0
  153. package/src/collections/base.js +80 -3
  154. package/src/collections/base.spec.js +108 -1
  155. package/src/collections/deck-version-screenshots.js +48 -0
  156. package/src/collections/tags.js +18 -0
  157. package/src/collections.js +7 -0
  158. package/src/models/activity-item.js +2 -0
  159. package/src/models/appointment-adjunct-tags.js +41 -0
  160. package/src/models/appointment-deckversion-tags.js +41 -0
  161. package/src/models/appointment-section-tags.js +41 -0
  162. package/src/models/appointment-slide-tags.js +41 -0
  163. package/src/models/appointment-tags.js +16 -14
  164. package/src/models/appointment.js +18 -1
  165. package/src/models/auto-adjunct.js +2 -0
  166. package/src/models/base.js +19 -1
  167. package/src/models/base.spec.js +16 -9
  168. package/src/models/deck-tags.js +52 -0
  169. package/src/models/deck-version-screenshot.js +48 -0
  170. package/src/models/deck-version.js +32 -4
  171. package/src/models/deck.js +2 -0
  172. package/src/models/feed-data.js +2 -0
  173. package/src/models/image.js +32 -0
  174. package/src/models/manifest-json.js +55 -7
  175. package/src/models/preset.js +19 -0
  176. package/src/models/section.js +2 -0
  177. package/src/models/slide.js +2 -0
  178. package/src/models/tag.js +42 -0
  179. package/src/models/template.js +2 -0
  180. package/src/models/token.js +47 -0
  181. package/src/models/user.js +4 -0
  182. package/src/models.js +8 -0
  183. package/src/presentation/appointment-presentation.js +13 -2
  184. package/src/presentation/base-presentation-model.js +129 -8
  185. package/src/presentation/base-presentation-model.spec.js +121 -6
  186. package/src/presentation/presentation-deck.js +41 -2
  187. package/src/presentation/presentation-deck.spec.js +53 -0
  188. package/src/presentation/presentation-section.js +57 -14
  189. package/src/presentation/presentation-section.spec.js +496 -0
  190. package/src/presentation/presentation-slide.js +41 -8
  191. package/src/presentation/presentation-slide.spec.js +352 -0
  192. package/src/presentation/presentation-subslide.js +7 -2
  193. package/src/presentation/presentation-subslide.spec.js +32 -3
  194. package/src/presentation/presentation.js +35 -6
  195. package/src/state-register.js +7 -0
  196. package/api.build.error.log +0 -16
@@ -8,26 +8,28 @@ import { register } from "../state-register.js";
8
8
  */
9
9
  export const AppointmentTagsModel = BaseModel.extend(
10
10
  /** @lends models.AppointmentTagsModel# */ {
11
- modelName: "appointment-tags",
11
+ urlMatchKeys: {
12
+ "appointment.id": "number",
13
+ },
12
14
 
13
15
  /**
14
- * @property {object} tags
16
+ * @property {string[]} tags
17
+ * @property {string} content_type
18
+ * @property {string} content_url
15
19
  */
16
20
  props: {
17
- items: "object",
18
- },
19
-
20
- url() {
21
- if (this.parent && this.parent.modelName === "appointments") {
22
- return this.getFullURLPath(`${this.parent.getPlainURL()}tags/`);
23
- }
24
- return BaseModel.prototype.url.call(this);
21
+ tags: "array",
22
+ content_type: "string",
23
+ content_url: "string",
25
24
  },
26
25
 
27
- fetch() {
28
- return BaseModel.prototype.fetch.call(this).tap((tags) => {
29
- this.items = tags;
30
- });
26
+ /**
27
+ * @property {models.AppointmentModel} appointment
28
+ * @property {models.UserModel} user
29
+ */
30
+ children: {
31
+ appointment: "AppointmentModel",
32
+ user: "UserModel",
31
33
  },
32
34
  }
33
35
  );
@@ -14,6 +14,7 @@ import "../collections/section-selections.js";
14
14
  import "../collections/slide-selections.js";
15
15
  import "../collections/dispatches.js";
16
16
  import "../collections/users.js";
17
+ import "../collections/appointment-tags";
17
18
 
18
19
  import { AdjunctSectionCollection } from "../collections/adjunct-sections.js";
19
20
  import { AdjunctSlideCollection } from "../collections/adjunct-slides.js";
@@ -49,6 +50,7 @@ export const AppointmentModel = BaseModel.extend(
49
50
  * @property {string} display_title
50
51
  * @property {string} viewtype
51
52
  * @property {boolean} support_mode
53
+ * @property {boolean} is_muted
52
54
  * @property {date} no_edit_after
53
55
  * @property {date} no_share_after
54
56
  * @property {date} no_delete_after
@@ -72,6 +74,7 @@ export const AppointmentModel = BaseModel.extend(
72
74
  display_title: "stringSanitized",
73
75
  viewtype: "string",
74
76
  support_mode: "boolean",
77
+ is_muted: "boolean",
75
78
  no_edit_after: "date",
76
79
  no_share_after: "date",
77
80
  no_delete_after: "date",
@@ -94,6 +97,11 @@ export const AppointmentModel = BaseModel.extend(
94
97
  appointmentsslide_set: "SlideSelectionCollection",
95
98
  dispatch_set: "DispatchCollection",
96
99
  current_editor_set: "UserCollection",
100
+ tags: "AppointmentTagsCollection",
101
+ appointmentdeckversiontags_set: "AppointmentDeckVersionTagsCollection",
102
+ appointmentsectiontags_set: "AppointmentSectionTagsCollection",
103
+ appointmentslidetags_set: "AppointmentSlideTagsCollection",
104
+ appointmentadjuncttags_set: "AppointmentAdjunctTagsCollection",
97
105
  },
98
106
 
99
107
  /**
@@ -109,7 +117,6 @@ export const AppointmentModel = BaseModel.extend(
109
117
  user: "UserModel",
110
118
  latest_tele: "HostedPresoModel",
111
119
  stats: "AppointmentStatsModel",
112
- tags: "AppointmentTagsModel",
113
120
  team: "TeamModel",
114
121
  },
115
122
 
@@ -205,6 +212,14 @@ export const AppointmentModel = BaseModel.extend(
205
212
  },
206
213
  },
207
214
  },
215
+
216
+ getHooksPath() {
217
+ if (!this.deckversion_set.length) {
218
+ throw new Error("Requires a deckversion to get hooks.");
219
+ }
220
+ return this.deckversion_set.first().getHooksPath();
221
+ },
222
+
208
223
  fetchAll(fetchSelf = false, options = {}) {
209
224
  return Promise.resolve()
210
225
  .then(() => {
@@ -272,6 +287,7 @@ export const AppointmentModel = BaseModel.extend(
272
287
  return Promise.all(
273
288
  this.deckversion_set.map((model) => {
274
289
  return Promise.all([
290
+ model.screenshots.fetch(options),
275
291
  model.template_set.fetchSet(options),
276
292
  model.manifest_json.fetch(options),
277
293
  model.deck.fetch(options),
@@ -298,6 +314,7 @@ export const AppointmentModel = BaseModel.extend(
298
314
  viewtype: appointment.viewtype,
299
315
  preset: this._retrieveURL(appointment.preset),
300
316
  locks: appointment.locks,
317
+ is_muted: appointment.is_muted,
301
318
  no_edit_after: appointment.no_edit_after,
302
319
  no_share_after: appointment.no_share_after,
303
320
  no_delete_after: appointment.no_delete_after,
@@ -25,6 +25,7 @@ export const AutoAdjunctModel = BaseModel.extend(
25
25
  * @property {string} after_key
26
26
  * @property {boolean} enabled
27
27
  * @property {number} sequence
28
+ * @property {string[]} cmsvalkey_set
28
29
  */
29
30
  props: {
30
31
  image_128: "string",
@@ -39,6 +40,7 @@ export const AutoAdjunctModel = BaseModel.extend(
39
40
  enabled: "boolean",
40
41
  sequence: "number",
41
42
  tags: "array",
43
+ cmsvalkey_set: "array",
42
44
  },
43
45
 
44
46
  /**
@@ -26,6 +26,10 @@ export const BaseModel = Model.extend(
26
26
  // behaviour from automatically hydrating all children and collections on a fetch.
27
27
  isFetching: false,
28
28
 
29
+ // Useful to figure out whether the model is just a URL (unfetched), or has been
30
+ // fetched from the server (an object).
31
+ _isFetched: true,
32
+
29
33
  // Object of regexes that should be used to match a url in `matchesURL`
30
34
  // For example the URL: /api/foo/{pk}/bar/ might have the following:
31
35
  //
@@ -38,11 +42,13 @@ export const BaseModel = Model.extend(
38
42
  // ```
39
43
  urlMatchKeys: {},
40
44
 
41
- constructor(data = {}, opts = {}) {
45
+ constructor(_data = {}, opts = {}) {
42
46
  const options = _.defaults(opts, {
43
47
  data: {},
44
48
  });
45
49
 
50
+ let data = _data;
51
+
46
52
  this._unsetChildren = {};
47
53
  this._unsetCollections = {};
48
54
  this._expandedValues = {};
@@ -61,6 +67,13 @@ export const BaseModel = Model.extend(
61
67
  // Convert any strings into a url format we can understand
62
68
  if (_.isString(data)) {
63
69
  data = { url: data };
70
+ this._isFetched = false;
71
+ }
72
+
73
+ // Convert model ids into a format we can understand
74
+ if (_.isNumber(data)) {
75
+ data = { id: data };
76
+ this._isFetched = false;
64
77
  }
65
78
 
66
79
  const dataCopy = _.extend({}, data);
@@ -402,6 +415,7 @@ export const BaseModel = Model.extend(
402
415
 
403
416
  this.isFetching = true;
404
417
  return Model.prototype.fetch.apply(this, arguments).tap((response) => {
418
+ this._isFetched = true;
405
419
  this.isFetching = false;
406
420
  this._updateResponse(response);
407
421
  });
@@ -421,6 +435,10 @@ export const BaseModel = Model.extend(
421
435
  });
422
436
  },
423
437
 
438
+ isFetched() {
439
+ return this._isFetched;
440
+ },
441
+
424
442
  getSafeAttrs(key) {
425
443
  if (!_.isUndefined(key)) {
426
444
  return !_.isUndefined(this._expandedValues[key])
@@ -7,7 +7,7 @@ import log from "../log.js";
7
7
  import moment from "moment";
8
8
  import td from "testdouble";
9
9
 
10
- it("should set date types correctly (SP-2698)", function () {
10
+ it("should set date types correctly (SP-2698)", () => {
11
11
  const TestModel = BaseModel.extend({ props: { testDate: "date" } });
12
12
 
13
13
  const model = new TestModel();
@@ -48,7 +48,7 @@ it("should not append a slash to a get query", () => {
48
48
  expect(model.url()).toEqual("/api/tests/?foo=bar");
49
49
  });
50
50
 
51
- it("should replace child model strings with the registered model", function () {
51
+ it("should replace child model strings with the registered model", () => {
52
52
  const TestModel = G(BaseModel, "TestModel");
53
53
  const Model = G(
54
54
  BaseModel.extend({
@@ -59,7 +59,7 @@ it("should replace child model strings with the registered model", function () {
59
59
  expect(model.test).toBeInstanceOf(TestModel);
60
60
  });
61
61
 
62
- it("should allow the model to be passed in", function () {
62
+ it("should allow the model to be passed in", () => {
63
63
  const TestModel = G(BaseModel, "TestModel");
64
64
  const Model = G(
65
65
  BaseModel.extend({
@@ -71,7 +71,7 @@ it("should allow the model to be passed in", function () {
71
71
  expect(model.test).toBeInstanceOf(TestModel);
72
72
  });
73
73
 
74
- it("should reference parent model if foreign key exists", function () {
74
+ it("should reference parent model if foreign key exists", () => {
75
75
  G(BaseModel, "TestModel");
76
76
  const Model = G(
77
77
  BaseModel.extend({
@@ -92,7 +92,7 @@ it("should throw an error if the child model doesn't exist", () => {
92
92
  expect(() => new Model()).toThrow();
93
93
  });
94
94
 
95
- it("should convert a url into a model", function () {
95
+ it("should convert a url into a model", () => {
96
96
  G(BaseModel.extend({ modelName: "tests" }), "TestModel");
97
97
  const Model = G(
98
98
  BaseModel.extend({
@@ -103,7 +103,14 @@ it("should convert a url into a model", function () {
103
103
  expect(model.test.id).toEqual(1);
104
104
  });
105
105
 
106
- it("should convert an object into a model", function () {
106
+ it("should convert an id into a model", () => {
107
+ const TestModel = BaseModel.extend({ modelName: "test" });
108
+ const testModel = new TestModel(1);
109
+ expect(testModel.id).toEqual(1);
110
+ expect(testModel.url()).toEqual("/test/1/");
111
+ });
112
+
113
+ it("should convert an object into a model", () => {
107
114
  G(BaseModel, "TestModel");
108
115
  const Model = G(
109
116
  BaseModel.extend({
@@ -114,7 +121,7 @@ it("should convert an object into a model", function () {
114
121
  expect(model.test.id).toEqual(1);
115
122
  });
116
123
 
117
- it("should replace collection strings with their registered state", function () {
124
+ it("should replace collection strings with their registered state", () => {
118
125
  G(BaseModel, "TestModel");
119
126
  const TestCollection = G(
120
127
  BaseCollection.extend({
@@ -133,7 +140,7 @@ it("should replace collection strings with their registered state", function ()
133
140
  expect(model.tests).toBeInstanceOf(TestCollection);
134
141
  });
135
142
 
136
- it("should allow a list of models to be passed into a collection", function () {
143
+ it("should allow a list of models to be passed into a collection", () => {
137
144
  const TestModel = G(BaseModel, "TestModel");
138
145
  G(
139
146
  BaseCollection.extend({
@@ -211,7 +218,7 @@ it("should convert an array of objects into a collection", () => {
211
218
  expect(model.tests.at(1).id).toEqual(2);
212
219
  });
213
220
 
214
- it("should correctly sanitize strings of multibyte characters (preserving spaces)", function () {
221
+ it("should correctly sanitize strings of multibyte characters (preserving spaces)", () => {
215
222
  const TestModel = BaseModel.extend({
216
223
  props: {
217
224
  normalString: "string",
@@ -0,0 +1,52 @@
1
+ import { BaseModel } from "./base.js";
2
+ import { register } from "../state-register.js";
3
+
4
+ /**
5
+ * @constructor
6
+ * @alias models.DeckTagsModel
7
+ * @extends models.BaseModel
8
+ */
9
+ export const DeckTagsModel = BaseModel.extend(
10
+ /** @lends models.DeckTagsModel# */ {
11
+ modelName: "deck-tags",
12
+
13
+ /**
14
+ * @property {object} items
15
+ */
16
+ props: {
17
+ items: "object",
18
+ },
19
+
20
+ url() {
21
+ if (this.parent && this.parent.modelName === "decks") {
22
+ return this.getFullURLPath(`${this.parent.getPlainURL()}tags/`);
23
+ }
24
+ return BaseModel.prototype.url.call(this);
25
+ },
26
+
27
+ fetch(opts) {
28
+ return BaseModel.prototype.fetch.call(this, opts).tap((tags) => {
29
+ this.items = tags;
30
+ });
31
+ },
32
+
33
+ isNew() {
34
+ // Force deck-tags to always use PUT.
35
+ return false;
36
+ },
37
+
38
+ toServer() {
39
+ return this.items;
40
+ },
41
+
42
+ save() {
43
+ return BaseModel.prototype.save.call(this).tap((tags) => {
44
+ this.items = tags;
45
+ });
46
+ },
47
+ }
48
+ );
49
+
50
+ DeckTagsModel.canBeEmpty = true;
51
+
52
+ register("DeckTagsModel", DeckTagsModel);
@@ -0,0 +1,48 @@
1
+ import "./team.js";
2
+
3
+ import { BaseModel } from "./base.js";
4
+ import _ from "lodash";
5
+ import { register } from "../state-register.js";
6
+
7
+ /**
8
+ * @constructor
9
+ * @alias models.DeckVersionScreenshotModel
10
+ * @extends models.BaseModel
11
+ */
12
+ export const DeckVersionScreenshotModel = BaseModel.extend(
13
+ /** @lends models.DeckVersionScreenshotModel# */ {
14
+ modelName: "deckversion-screenshots",
15
+
16
+ urlMatchKeys: {
17
+ "deckversion.id": "number",
18
+ },
19
+
20
+ /**
21
+ * @property {date} created_date
22
+ * @property {date} modified_date
23
+ * @property {string} image_128
24
+ * @property {string} image_256
25
+ * @property {string} image_512
26
+ * @property {string} subject - A url for a screenshotted model (section, slide, etc.)
27
+ */
28
+ props: {
29
+ created_date: "date",
30
+ modified_date: "date",
31
+ image_128: "string",
32
+ image_256: "string",
33
+ image_512: "string",
34
+ subject: "string",
35
+ },
36
+
37
+ children: {
38
+ team: "TeamModel",
39
+ },
40
+
41
+ serialize() {
42
+ const data = BaseModel.prototype.serialize.call(this);
43
+ return _.omit(data, ["url"]);
44
+ },
45
+ }
46
+ );
47
+
48
+ register("DeckVersionScreenshotModel", DeckVersionScreenshotModel);
@@ -7,6 +7,7 @@ import "./asset.js";
7
7
  import "./manifest-json.js";
8
8
 
9
9
  import { BaseModel } from "./base.js";
10
+ import { DeckVersionScreenshotCollection } from "../collections/deck-version-screenshots.js";
10
11
  import Promise from "bluebird";
11
12
  import _ from "lodash";
12
13
  import { register } from "../state-register.js";
@@ -37,7 +38,9 @@ export const DeckVersionModel = BaseModel.extend(
37
38
  * @property {string} upgrade_description
38
39
  * @property {string} friendly_release_notes
39
40
  * @property {boolean} has_editable_share_support
41
+ * @property {string} point_in_time_share_policy
40
42
  * @property {string[]} tags
43
+ * @property {string[]} cmsvalkey_set
41
44
  */
42
45
  props: {
43
46
  image_128: "string",
@@ -56,7 +59,9 @@ export const DeckVersionModel = BaseModel.extend(
56
59
  upgrade_description: "string",
57
60
  friendly_release_notes: "string",
58
61
  has_editable_share_support: "boolean",
62
+ point_in_time_share_policy: "string",
59
63
  tags: "array",
64
+ cmsvalkey_set: "array",
60
65
  },
61
66
 
62
67
  /**
@@ -84,10 +89,24 @@ export const DeckVersionModel = BaseModel.extend(
84
89
  },
85
90
 
86
91
  /**
87
- * @todo This should eventually return a hooks interface
88
- * @returns {object}
92
+ * @property {collections.DeckVersionScreenshotCollection} screenshots
89
93
  */
90
- getHooks() {
94
+ derived: {
95
+ screenshots: {
96
+ deps: ["id"],
97
+ fn: function () {
98
+ const screenshots = new DeckVersionScreenshotCollection(
99
+ {},
100
+ {
101
+ deckversion: this,
102
+ }
103
+ );
104
+ return screenshots;
105
+ },
106
+ },
107
+ },
108
+
109
+ getHooksPath() {
91
110
  if (this.isNew()) {
92
111
  throw new Error(
93
112
  "Can only get hooks from a fetched deckversion or at least have an ID"
@@ -115,8 +134,17 @@ export const DeckVersionModel = BaseModel.extend(
115
134
  if (!this.manifest_json.hooks) {
116
135
  throw new Error("Manifest does not contain a hooks entry");
117
136
  }
118
- const hooksPath = `${rootAssetUrl}${this.manifest_json.hooks}`;
137
+ return `${rootAssetUrl}${this.manifest_json.hooks}`;
138
+ });
139
+ },
119
140
 
141
+ /**
142
+ * @todo This should eventually return a hooks interface
143
+ * @returns {object}
144
+ */
145
+ getHooks() {
146
+ return this.getHooksPath()
147
+ .then((hooksPath) => {
120
148
  return SystemJS.import(hooksPath);
121
149
  })
122
150
  .then((hooks) => {
@@ -1,3 +1,4 @@
1
+ import "./deck-tags.js";
1
2
  import "./deck-version.js";
2
3
 
3
4
  import { BaseModel } from "./base.js";
@@ -53,6 +54,7 @@ export const DeckModel = BaseModel.extend(
53
54
  children: {
54
55
  approved_version: "DeckVersionModel",
55
56
  head_version: "DeckVersionModel",
57
+ tags: "DeckTagsModel",
56
58
  },
57
59
  }
58
60
  );
@@ -14,10 +14,12 @@ export const FeedDataModel = BaseModel.extend(
14
14
 
15
15
  /**
16
16
  * @property {object} feed_data
17
+ * @property {object} feed_debug
17
18
  * @property {string} creation_status
18
19
  */
19
20
  props: {
20
21
  feed_data: "object",
22
+ feed_debug: {type: "object", default: () => {}},
21
23
  creation_status: "string",
22
24
  },
23
25
 
@@ -1,6 +1,8 @@
1
1
  import "./user.js";
2
2
 
3
+ import { Auth } from "../auth.js";
3
4
  import { BaseModel } from "./base.js";
5
+ import SuperAgentRequest from "superagent-bluebird-promise";
4
6
  import { register } from "../state-register.js";
5
7
 
6
8
  /**
@@ -37,6 +39,36 @@ export const ImageModel = BaseModel.extend(
37
39
  children: {
38
40
  event: "UserModel",
39
41
  },
42
+ uploadBase64(data) {
43
+ // mime will be in the format "image/png;base64"
44
+ const fileType = data.mime.split(";")[0];
45
+ const fileEnd = fileType.split("/")[1];
46
+
47
+ return fetch(data.value)
48
+ .then((res) => {
49
+ return res.blob();
50
+ })
51
+ .then((blob) => {
52
+ const file = new File([blob], `image.${fileEnd}`, { type: fileType });
53
+ const formData = new FormData();
54
+ formData.append("image_original", file);
55
+
56
+ return this.uploadFile(file);
57
+ });
58
+ },
59
+ uploadFile(file) {
60
+ const formData = new FormData();
61
+ formData.append("image_original", file);
62
+
63
+ return SuperAgentRequest.post(this.url())
64
+ .send(formData)
65
+ .set(Auth.headers)
66
+ .then((response) => {
67
+ Object.keys(response.body).forEach((key) => {
68
+ this.set(key, response.body[key]);
69
+ });
70
+ });
71
+ },
40
72
  }
41
73
  );
42
74
 
@@ -77,6 +77,9 @@ export const ManifestJSONModel = BaseModel.extend(
77
77
  type: "boolean",
78
78
  default: false,
79
79
  },
80
+ point_in_time_share_policy: {
81
+ type: "string",
82
+ },
80
83
  notify_salesperson_after_feeds_fetched: {
81
84
  type: "boolean",
82
85
  default: false,
@@ -96,6 +99,9 @@ export const ManifestJSONModel = BaseModel.extend(
96
99
  appointment: {
97
100
  show_visible_default: false,
98
101
  },
102
+ fieldsets: {
103
+ enforce_required: false,
104
+ },
99
105
  };
100
106
  },
101
107
  },
@@ -147,6 +153,41 @@ export const ManifestJSONModel = BaseModel.extend(
147
153
  * object.
148
154
  */
149
155
  ManifestJSONModel.createFromProject = function (projectFile) {
156
+ // If the deck is an impostor deck, we have to update some things for
157
+ // them to make sense in the impostor format
158
+ if (projectFile.impostor) {
159
+ // There is only one real section; all of the "sections" defined in the
160
+ // project.yaml are actually slides, and slides can't have a maxAdjunctSlides
161
+ // value. We get around this by totalling up all of the maxAdjunctSlides values
162
+ // across the sections and give that number to the real section. Later e.g. in the
163
+ // app, that number will be taken and divided by the number of impostor sections
164
+ // to get the maxAdjunctSlides value for each impostor section
165
+ const maxAdjunctSlides = projectFile.sections.reduce((num, section) => {
166
+ return num + (section.maxAdjunctSlides || 0);
167
+ }, 0);
168
+
169
+ // Create a "real" section (that will never be seen by the user) and give
170
+ // it all of the sections & slides. Impostor sections (which are technically
171
+ // slides) are given the "section-header" tag to mark them as sections
172
+ projectFile.sections = [
173
+ {
174
+ maxAdjunctSlides,
175
+ key: projectFile.key,
176
+ title: projectFile.name,
177
+ slides: projectFile.sections.reduce((sections, section) => {
178
+ const newSection = {
179
+ ...section,
180
+ slides: [],
181
+ };
182
+ newSection.tags = ["section-header"].concat(newSection.tags || []);
183
+
184
+ sections.push(newSection, ...(section.slides || []));
185
+ return sections;
186
+ }, []),
187
+ },
188
+ ];
189
+ }
190
+
150
191
  const titles = projectFile.sections.reduce((titles, section) => {
151
192
  titles[section.key] = section.title;
152
193
  for (const slide of section.slides || []) {
@@ -186,13 +227,9 @@ ManifestJSONModel.createFromProject = function (projectFile) {
186
227
  }, {});
187
228
 
188
229
  const tags = projectFile.sections.reduce((tags, section) => {
189
- if (section.tags) {
190
- tags[section.key] = section.tags;
191
- }
230
+ tags[section.key] = section.tags || [];
192
231
  for (const slide of section.slides || []) {
193
- if (slide.tags) {
194
- tags[`${section.key}/${slide.key}`] = slide.tags;
195
- }
232
+ tags[`${section.key}/${slide.key}`] = slide.tags || [];
196
233
  }
197
234
  return tags;
198
235
  }, {});
@@ -203,7 +240,7 @@ ManifestJSONModel.createFromProject = function (projectFile) {
203
240
  if (projectFile.welcome.tags) {
204
241
  // It's convention to use an empty string for the
205
242
  // Welcome slide's key
206
- tags[""] = projectFile.welcome.tags;
243
+ tags[""] = projectFile.welcome.tags || [];
207
244
  }
208
245
  }
209
246
 
@@ -249,6 +286,11 @@ ManifestJSONModel.createFromProject = function (projectFile) {
249
286
  projectFile.has_editable_share_support;
250
287
  }
251
288
 
289
+ if (projectFile.point_in_time_share_policy) {
290
+ manifest.point_in_time_share_policy =
291
+ projectFile.point_in_time_share_policy;
292
+ }
293
+
252
294
  if (projectFile.notify_salesperson_after_feeds_fetched) {
253
295
  manifest.notify_salesperson_after_feeds_fetched =
254
296
  projectFile.notify_salesperson_after_feeds_fetched;
@@ -265,6 +307,12 @@ ManifestJSONModel.createFromProject = function (projectFile) {
265
307
  };
266
308
  }
267
309
 
310
+ // For all new decks going forward, this should be set to true.
311
+ // This means we validate that a fieldset field has a value. Before
312
+ // this change, it was possible to save with a required field unfilled.
313
+ // This just keeps backwards compatability.
314
+ manifest.app_settings.fieldsets.enforce_required = false;
315
+
268
316
  return manifest;
269
317
  };
270
318
 
@@ -1,5 +1,6 @@
1
1
  import "./user.js";
2
2
  import "./deck.js";
3
+ import "./team.js";
3
4
 
4
5
  import { BaseModel } from "./base.js";
5
6
  import { register } from "../state-register.js";
@@ -32,10 +33,13 @@ export const PresetModel = BaseModel.extend(
32
33
  /**
33
34
  * @property {models.UserModel} user
34
35
  * @property {models.DeckModel} deck
36
+ * @property {models.TeamModel} team
35
37
  */
36
38
  children: {
37
39
  user: "UserModel",
38
40
  deck: "DeckModel",
41
+ team: "TeamModel",
42
+ keylist_team: "TeamModel",
39
43
  },
40
44
 
41
45
  toServer() {
@@ -54,9 +58,24 @@ export const PresetModel = BaseModel.extend(
54
58
  data.id = this.id;
55
59
  }
56
60
 
61
+ const teamURL = this._retrieveURL(this.team);
62
+
63
+ if (teamURL) {
64
+ data.team = teamURL;
65
+ }
66
+ const keylistTeamURL = this._retrieveURL(this.keylist_team);
67
+
68
+ if (keylistTeamURL) {
69
+ data.keylist_team = keylistTeamURL;
70
+ }
71
+
57
72
  return data;
58
73
  },
59
74
  }
60
75
  );
61
76
 
77
+ PresetModel.USER_VISIBILITY = "__user__";
78
+ PresetModel.GLOBAL_VISIBILITY = "__global__";
79
+ PresetModel.STANDARD_SLIDE_SOURCE = "__standard__";
80
+
62
81
  register("PresetModel", PresetModel);