@financial-times/n-myft-ui 27.1.0 → 27.2.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.
@@ -3,7 +3,8 @@
|
|
3
3
|
data-content-id="{{contentId}}"
|
4
4
|
data-myft-ui="saved"
|
5
5
|
action="/myft/save/{{contentId}}"
|
6
|
-
data-js-action="/__myft/api/core/saved/content/{{contentId}}?method=put"
|
6
|
+
data-js-action="/__myft/api/core/saved/content/{{contentId}}?method=put"
|
7
|
+
{{#ifEquals @root.flags.professorLists 'variant'}}data-myft-ui-variant="createListAndSaveArticleVariant"{{/ifEquals}}>
|
7
8
|
{{> n-myft-ui/components/csrf-token/input}}
|
8
9
|
<div
|
9
10
|
class="n-myft-ui__announcement o-normalise-visually-hidden"
|
package/myft/main.scss
CHANGED
@@ -173,3 +173,148 @@ $spacing-unit: 20px;
|
|
173
173
|
}
|
174
174
|
|
175
175
|
}
|
176
|
+
|
177
|
+
.share-nav {
|
178
|
+
&.data-overlap-initialised {
|
179
|
+
.o-overlay {
|
180
|
+
transition: opacity 0.15s ease-in;
|
181
|
+
opacity: 0;
|
182
|
+
z-index: -1;
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
.myft-ui-create-list-variant {
|
187
|
+
border-radius: 10px;
|
188
|
+
border: 1px solid oColorsByName('black-5');
|
189
|
+
background: oColorsByName('white-80');
|
190
|
+
|
191
|
+
.o-overlay__heading {
|
192
|
+
border-radius: 10px 10px 0 0;
|
193
|
+
background: oColorsByName('white-60');
|
194
|
+
@include oTypographySans($scale: 2);
|
195
|
+
color: oColorsByName('black-80');
|
196
|
+
}
|
197
|
+
|
198
|
+
.o-overlay__content {
|
199
|
+
@include oTypographySans($scale: 0);
|
200
|
+
color: oColorsByName('black-80');
|
201
|
+
padding: 0;
|
202
|
+
}
|
203
|
+
|
204
|
+
.o-overlay__title {
|
205
|
+
margin: 8px 14px 0 8px;
|
206
|
+
}
|
207
|
+
|
208
|
+
&-container {
|
209
|
+
display: block;
|
210
|
+
width: 340px;
|
211
|
+
top: 115.5px;
|
212
|
+
left: 50px;
|
213
|
+
}
|
214
|
+
|
215
|
+
&-add {
|
216
|
+
border: 0;
|
217
|
+
background: none;
|
218
|
+
@include oTypographySans($scale: 1, $weight: 'semibold');
|
219
|
+
color: oColorsByName('black-80');
|
220
|
+
|
221
|
+
padding-left: 0;
|
222
|
+
margin-left: -8px;
|
223
|
+
|
224
|
+
&:hover {
|
225
|
+
text-decoration: underline;
|
226
|
+
}
|
227
|
+
|
228
|
+
&::before {
|
229
|
+
content: '';
|
230
|
+
@include oIconsContent(
|
231
|
+
'plus',
|
232
|
+
oColorsByName('black-80'),
|
233
|
+
28,
|
234
|
+
$iconset-version: 1
|
235
|
+
);
|
236
|
+
vertical-align: middle;
|
237
|
+
margin-top: -2px;
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
&-add-description {
|
242
|
+
margin: 4px 0;
|
243
|
+
}
|
244
|
+
|
245
|
+
&-heading {
|
246
|
+
&::before {
|
247
|
+
content: '';
|
248
|
+
@include oIconsContent(
|
249
|
+
'tick',
|
250
|
+
oColorsByName('teal'),
|
251
|
+
32,
|
252
|
+
$iconset-version: 1
|
253
|
+
);
|
254
|
+
vertical-align: middle;
|
255
|
+
margin-top: -2px;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
&-footer {
|
260
|
+
border-top: 1px solid oColorsByName('black-5');
|
261
|
+
padding: 16px;
|
262
|
+
}
|
263
|
+
|
264
|
+
&-icon {
|
265
|
+
&::before {
|
266
|
+
content: "";
|
267
|
+
display: inline-block;
|
268
|
+
background-repeat: no-repeat;
|
269
|
+
background-size: contain;
|
270
|
+
background-position: 50%;
|
271
|
+
background-color: transparent;
|
272
|
+
background-image: url(https://www.ft.com/__origami/service/image/v2/images/raw/ftlogo-v1:brand-myft?source=next-article);
|
273
|
+
width: 42px;
|
274
|
+
height: 42px;
|
275
|
+
vertical-align: middle;
|
276
|
+
margin-top: -2px;
|
277
|
+
}
|
278
|
+
|
279
|
+
&-visually-hidden {
|
280
|
+
clip: rect(0 0 0 0);
|
281
|
+
clip-path: inset(50%);
|
282
|
+
height: 1px;
|
283
|
+
overflow: hidden;
|
284
|
+
position: absolute;
|
285
|
+
white-space: nowrap;
|
286
|
+
width: 1px;
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
&-form {
|
291
|
+
display: flex;
|
292
|
+
width: calc(100% - 32px);
|
293
|
+
justify-content: space-between;
|
294
|
+
height: 40px;
|
295
|
+
gap: 8px;
|
296
|
+
padding: 0 16px 16px;
|
297
|
+
|
298
|
+
& > * {
|
299
|
+
flex: 1 1 auto;
|
300
|
+
}
|
301
|
+
|
302
|
+
.o-forms-input {
|
303
|
+
margin-top: 0;
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
&-lists {
|
308
|
+
padding: 16px 16px 0;
|
309
|
+
@include oTypographySans($scale: 1);
|
310
|
+
&-text {
|
311
|
+
@include oTypographySans($weight: 'semibold');
|
312
|
+
color: oColorsByName('black-80');
|
313
|
+
margin-bottom: 16px;
|
314
|
+
}
|
315
|
+
&-container {
|
316
|
+
margin-top: 0;
|
317
|
+
}
|
318
|
+
}
|
319
|
+
}
|
320
|
+
}
|
package/myft/ui/lists.js
CHANGED
@@ -6,6 +6,7 @@ import nNotification from 'n-notification';
|
|
6
6
|
import { uuid } from 'n-ui-foundations';
|
7
7
|
import getToken from './lib/get-csrf-token';
|
8
8
|
import oForms from 'o-forms';
|
9
|
+
import openSaveArticleToListVariant from './save-article-to-list-variant';
|
9
10
|
|
10
11
|
const delegate = new Delegate(document.body);
|
11
12
|
const csrfToken = getToken();
|
@@ -161,6 +162,10 @@ function showArticleSavedOverlay (contentId) {
|
|
161
162
|
showListsOverlay('Article saved', `/myft/list?fragment=true&fromArticleSaved=true&contentId=${contentId}`, contentId);
|
162
163
|
}
|
163
164
|
|
165
|
+
function showCreateListAndAddArticleOverlay (contentId, name = 'myft-ui-create-list-variant') {
|
166
|
+
return openSaveArticleToListVariant(name, contentId);
|
167
|
+
}
|
168
|
+
|
164
169
|
function handleArticleSaved (contentId) {
|
165
170
|
return myFtClient.getAll('created', 'list')
|
166
171
|
.then(createdLists => createdLists.filter(list => !list.isRedirect))
|
@@ -171,10 +176,27 @@ function handleArticleSaved (contentId) {
|
|
171
176
|
});
|
172
177
|
}
|
173
178
|
|
179
|
+
function openCreateListAndAddArticleOverlay (contentId) {
|
180
|
+
return myFtClient.getAll('created', 'list')
|
181
|
+
.then(createdLists => createdLists.filter(list => !list.isRedirect))
|
182
|
+
.then(createdLists => {
|
183
|
+
return !createdLists.length ? showCreateListAndAddArticleOverlay(contentId) : showArticleSavedOverlay(contentId);
|
184
|
+
});
|
185
|
+
}
|
186
|
+
|
174
187
|
function initialEventListeners () {
|
175
188
|
|
176
189
|
document.body.addEventListener('myft.user.saved.content.add', event => {
|
177
190
|
const contentId = event.detail.subject;
|
191
|
+
|
192
|
+
// Checks if the createListAndSaveArticle variant is active
|
193
|
+
// and will show the variant overlay if the user has no lists,
|
194
|
+
// otherwise it will show the classic overlay
|
195
|
+
const createListVariant = event.currentTarget.querySelector('[data-myft-ui-variant="createListAndSaveArticleVariant"]');
|
196
|
+
if (createListVariant) {
|
197
|
+
return openCreateListAndAddArticleOverlay(contentId);
|
198
|
+
}
|
199
|
+
|
178
200
|
handleArticleSaved(contentId);
|
179
201
|
});
|
180
202
|
|
@@ -0,0 +1,376 @@
|
|
1
|
+
import Overlay from 'o-overlay';
|
2
|
+
import myFtClient from 'next-myft-client';
|
3
|
+
import { uuid } from 'n-ui-foundations';
|
4
|
+
import getToken from './lib/get-csrf-token';
|
5
|
+
import oTooltip from 'o-tooltip';
|
6
|
+
|
7
|
+
const csrfToken = getToken();
|
8
|
+
|
9
|
+
let lists;
|
10
|
+
|
11
|
+
export default async function showSaveArticleToListVariant (name, contentId) {
|
12
|
+
try {
|
13
|
+
await openSaveArticleToListVariant (name, contentId);
|
14
|
+
} catch(error) {
|
15
|
+
handleError(error);
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
async function openSaveArticleToListVariant (name, contentId) {
|
20
|
+
function createList (list) {
|
21
|
+
if(!list) {
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
myFtClient.add('user', null, 'created', 'list', uuid(), { name: list, token: csrfToken })
|
26
|
+
.then(detail => {
|
27
|
+
myFtClient.add('list', detail.subject, 'contained', 'content', contentId, { token: csrfToken }).then((createdList) => {
|
28
|
+
lists.push({ name: list, uuid: createdList.actorId, checked: true });
|
29
|
+
const listElement = ListsElement(lists, addToList, removeFromList);
|
30
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
31
|
+
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
32
|
+
const announceListContainer = document.querySelector('.myft-ui-create-list-variant-announcement');
|
33
|
+
announceListContainer.textContent = `${list} created`;
|
34
|
+
triggerCreateListEvent(contentId);
|
35
|
+
});
|
36
|
+
});
|
37
|
+
}
|
38
|
+
|
39
|
+
function addToList (list) {
|
40
|
+
if(!list) {
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
|
44
|
+
myFtClient.add('list', list.uuid, 'contained', 'content', contentId, { token: csrfToken }).then(() => {
|
45
|
+
const indexToUpdate = lists.indexOf(list);
|
46
|
+
lists[indexToUpdate] = { ...lists[indexToUpdate], checked: true };
|
47
|
+
const listElement = ListsElement(lists, addToList, removeFromList);
|
48
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
49
|
+
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
50
|
+
triggerAddToListEvent(contentId);
|
51
|
+
});
|
52
|
+
}
|
53
|
+
|
54
|
+
function removeFromList (list) {
|
55
|
+
if(!list) {
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
|
59
|
+
myFtClient.remove('list', list.uuid, 'contained', 'content', contentId, { token: csrfToken }).then(() => {
|
60
|
+
const indexToUpdate = lists.indexOf(list);
|
61
|
+
lists[indexToUpdate] = { ...lists[indexToUpdate], checked: false };
|
62
|
+
const listElement = ListsElement(lists, addToList, removeFromList);
|
63
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
64
|
+
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
65
|
+
triggerRemoveFromListEvent(contentId);
|
66
|
+
});
|
67
|
+
}
|
68
|
+
|
69
|
+
if (!lists) {
|
70
|
+
lists = await getLists(contentId);
|
71
|
+
}
|
72
|
+
|
73
|
+
const overlays = Overlay.getOverlays();
|
74
|
+
const existingOverlay = overlays[name];
|
75
|
+
if (existingOverlay) {
|
76
|
+
existingOverlay.destroy();
|
77
|
+
}
|
78
|
+
|
79
|
+
const contentElement = ContentElement();
|
80
|
+
const headingElement = HeadingElement();
|
81
|
+
|
82
|
+
const createListOverlay = new Overlay(name, {
|
83
|
+
html: contentElement,
|
84
|
+
heading: { title: headingElement.outerHTML },
|
85
|
+
modal: false,
|
86
|
+
parentnode: isMobile() ? '.o-share--horizontal' : '.o-share--vertical',
|
87
|
+
class: 'myft-ui-create-list-variant',
|
88
|
+
});
|
89
|
+
|
90
|
+
const realignListener = realignOverlay(window.scrollY);
|
91
|
+
|
92
|
+
function outsideClickHandler (e) {
|
93
|
+
try {
|
94
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
95
|
+
if(!overlayContent || !overlayContent.contains(e.target)) {
|
96
|
+
createListOverlay.close();
|
97
|
+
}
|
98
|
+
} catch(error) {
|
99
|
+
handleError(error);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
function openFormHandler () {
|
104
|
+
try {
|
105
|
+
const formElement = FormElement(createList);
|
106
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
107
|
+
overlayContent.insertAdjacentElement('beforeend', formElement);
|
108
|
+
formElement.elements[0].focus();
|
109
|
+
} catch(error) {
|
110
|
+
handleError(error);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
createListOverlay.open();
|
115
|
+
createListOverlay.wrapper.addEventListener('oOverlay.ready', (data) => {
|
116
|
+
realignListener(data.currentTarget);
|
117
|
+
|
118
|
+
if (lists && lists.length) {
|
119
|
+
const listElement = ListsElement(lists, addToList, removeFromList);
|
120
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
121
|
+
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
122
|
+
}
|
123
|
+
|
124
|
+
contentElement.addEventListener('click', openFormHandler);
|
125
|
+
|
126
|
+
document.querySelector('.article-content').addEventListener('click', outsideClickHandler);
|
127
|
+
});
|
128
|
+
|
129
|
+
createListOverlay.wrapper.addEventListener('oOverlay.destroy', () => {
|
130
|
+
const tooltipTemplate = document.createElement('div');
|
131
|
+
const opts = {
|
132
|
+
target: 'o-header-top-link-myft',
|
133
|
+
content: 'Go to saved articles in myFT to find your lists',
|
134
|
+
showOnConstruction: true,
|
135
|
+
closeAfter: 5,
|
136
|
+
position: 'below'
|
137
|
+
};
|
138
|
+
|
139
|
+
new oTooltip(tooltipTemplate, opts);
|
140
|
+
|
141
|
+
contentElement.removeEventListener('click', openFormHandler);
|
142
|
+
|
143
|
+
document.querySelector('.article-content').removeEventListener('click', outsideClickHandler);
|
144
|
+
});
|
145
|
+
|
146
|
+
window.addEventListener('scroll', function () {
|
147
|
+
realignListener(createListOverlay.wrapper, window.scrollY);
|
148
|
+
});
|
149
|
+
|
150
|
+
window.addEventListener('oViewport.resize', () => {
|
151
|
+
realignListener(createListOverlay.wrapper);
|
152
|
+
});
|
153
|
+
}
|
154
|
+
|
155
|
+
function stringToHTMLElement (string) {
|
156
|
+
const template = document.createElement('template');
|
157
|
+
template.innerHTML = string.trim();
|
158
|
+
return template.content.firstChild;
|
159
|
+
}
|
160
|
+
|
161
|
+
function FormElement (createList) {
|
162
|
+
const formString = `
|
163
|
+
<form class="myft-ui-create-list-variant-form">
|
164
|
+
<label class="o-forms-field">
|
165
|
+
<span class="o-forms-input o-forms-input--text">
|
166
|
+
<input type="text" name="list-name" aria-label="List name">
|
167
|
+
</span>
|
168
|
+
</label>
|
169
|
+
<button class="o-buttons o-buttons--secondary" type="submit">
|
170
|
+
Save
|
171
|
+
</button>
|
172
|
+
</form>
|
173
|
+
`;
|
174
|
+
|
175
|
+
const formElement = stringToHTMLElement(formString);
|
176
|
+
|
177
|
+
function handleSubmit (event) {
|
178
|
+
try {
|
179
|
+
event.preventDefault();
|
180
|
+
event.stopPropagation();
|
181
|
+
const inputListName = formElement.querySelector('input[name="list-name"]');
|
182
|
+
createList(inputListName.value);
|
183
|
+
inputListName.value = '';
|
184
|
+
formElement.remove();
|
185
|
+
} catch(error) {
|
186
|
+
handleError(error);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
formElement.querySelector('button[type="submit"]').addEventListener('click', handleSubmit);
|
191
|
+
|
192
|
+
return formElement;
|
193
|
+
}
|
194
|
+
|
195
|
+
function ContentElement () {
|
196
|
+
let content = `
|
197
|
+
<div class="myft-ui-create-list-variant-footer">
|
198
|
+
<button class="myft-ui-create-list-variant-add">Add to a new list</button>
|
199
|
+
${!lists.length ? '<p class="myft-ui-create-list-variant-add-description">Lists are a simple way to curate your content</p>' : ''}
|
200
|
+
</div>
|
201
|
+
`;
|
202
|
+
|
203
|
+
return stringToHTMLElement(content);
|
204
|
+
}
|
205
|
+
|
206
|
+
function HeadingElement () {
|
207
|
+
const heading = `
|
208
|
+
<span class="myft-ui-create-list-variant-heading">Added to <a href="https://www.ft.com/myft/saved-articles">saved articles</a> in <span class="myft-ui-create-list-variant-icon"><span class="myft-ui-create-list-variant-icon-visually-hidden">my FT</span></span></span>
|
209
|
+
`;
|
210
|
+
|
211
|
+
return stringToHTMLElement(heading);
|
212
|
+
}
|
213
|
+
|
214
|
+
function ListsElement (lists, addToList, removeFromList) {
|
215
|
+
const currentList = document.querySelector('.myft-ui-create-list-variant-lists');
|
216
|
+
if (currentList) {
|
217
|
+
currentList.remove();
|
218
|
+
}
|
219
|
+
|
220
|
+
const listCheckboxElement = ListCheckboxElement(addToList, removeFromList);
|
221
|
+
|
222
|
+
const listsTemplate = `
|
223
|
+
<div class="myft-ui-create-list-variant-lists o-forms-field o-forms-field--optional" role="group">
|
224
|
+
<span class="myft-ui-create-list-variant-lists-text">Add to a list</span>
|
225
|
+
<span class="myft-ui-create-list-variant-lists-container o-forms-input o-forms-input--checkbox">
|
226
|
+
</span>
|
227
|
+
</div>
|
228
|
+
`;
|
229
|
+
const listsElement = stringToHTMLElement(listsTemplate);
|
230
|
+
|
231
|
+
const listsElementContainer = listsElement.querySelector('.myft-ui-create-list-variant-lists-container');
|
232
|
+
|
233
|
+
lists.map(list => listsElementContainer.insertAdjacentElement('beforeend', listCheckboxElement(list)));
|
234
|
+
|
235
|
+
return listsElement;
|
236
|
+
}
|
237
|
+
|
238
|
+
function ListCheckboxElement (addToList, removeFromList) {
|
239
|
+
return function (list) {
|
240
|
+
const listCheckbox = `<label>
|
241
|
+
<input type="checkbox" name="default" value="${list.name}" ${list.checked ? 'checked' : ''}>
|
242
|
+
<span class="o-forms-input__label">
|
243
|
+
<span class="o-normalise-visually-hidden">
|
244
|
+
${list.checked ? 'Remove article from ' : 'Add article to ' }
|
245
|
+
</span>
|
246
|
+
${list.name}
|
247
|
+
</span>
|
248
|
+
</label>
|
249
|
+
`;
|
250
|
+
|
251
|
+
const listCheckboxElement = stringToHTMLElement(listCheckbox);
|
252
|
+
|
253
|
+
const [ input ] = listCheckboxElement.children;
|
254
|
+
|
255
|
+
function handleCheck (event) {
|
256
|
+
event.preventDefault();
|
257
|
+
return event.target.checked ? addToList(list) : removeFromList(list);
|
258
|
+
}
|
259
|
+
|
260
|
+
input.addEventListener('click', handleCheck);
|
261
|
+
|
262
|
+
return listCheckboxElement;
|
263
|
+
};
|
264
|
+
}
|
265
|
+
|
266
|
+
function realignOverlay (originalScrollPosition) {
|
267
|
+
return function (target, currentScrollPosition) {
|
268
|
+
try {
|
269
|
+
if(currentScrollPosition && Math.abs(currentScrollPosition - originalScrollPosition) < 120) {
|
270
|
+
return;
|
271
|
+
}
|
272
|
+
|
273
|
+
originalScrollPosition = currentScrollPosition;
|
274
|
+
|
275
|
+
target.style['min-width'] = '340px';
|
276
|
+
target.style['width'] = '100%';
|
277
|
+
target.style['margin-top'] = '-50px';
|
278
|
+
target.style['left'] = 0;
|
279
|
+
|
280
|
+
if (isMobile()) {
|
281
|
+
target.style['position'] = 'absolute';
|
282
|
+
target.style['margin-left'] = 0;
|
283
|
+
target.style['margin-top'] = 0;
|
284
|
+
target.style['top'] = calculateLargerScreenHalf(target) === 'ABOVE' ? '-120px' : '50px';
|
285
|
+
} else {
|
286
|
+
target.style['position'] = 'absolute';
|
287
|
+
target.style['margin-left'] = '45px';
|
288
|
+
target.style['top'] = '220px';
|
289
|
+
}
|
290
|
+
} catch (error) {
|
291
|
+
handleError(error);
|
292
|
+
}
|
293
|
+
};
|
294
|
+
}
|
295
|
+
|
296
|
+
function isMobile () {
|
297
|
+
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
298
|
+
|
299
|
+
return vw <= 980;
|
300
|
+
}
|
301
|
+
|
302
|
+
function calculateLargerScreenHalf (target) {
|
303
|
+
const vh = Math.min(document.documentElement.clientHeight || 0, window.innerHeight || 0);
|
304
|
+
|
305
|
+
const targetBox = target.getBoundingClientRect();
|
306
|
+
const spaceAbove = targetBox.top;
|
307
|
+
const spaceBelow = vh - targetBox.bottom;
|
308
|
+
|
309
|
+
return spaceBelow < spaceAbove ? 'ABOVE' : 'BELOW';
|
310
|
+
}
|
311
|
+
|
312
|
+
async function getLists () {
|
313
|
+
return myFtClient.getAll('created', 'list')
|
314
|
+
.then(lists => lists.filter(list => !list.isRedirect))
|
315
|
+
.then(lists => {
|
316
|
+
return lists.map(list => ({ name: list.name, uuid: list.uuid, checked: false }));
|
317
|
+
});
|
318
|
+
}
|
319
|
+
|
320
|
+
function triggerAddToListEvent (contentId) {
|
321
|
+
return document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
322
|
+
detail: {
|
323
|
+
category: 'professorLists',
|
324
|
+
action: 'add-to-list',
|
325
|
+
article_id: contentId,
|
326
|
+
teamName: 'customer-products-us-growth',
|
327
|
+
amplitudeExploratory: true
|
328
|
+
},
|
329
|
+
bubbles: true
|
330
|
+
}));
|
331
|
+
}
|
332
|
+
|
333
|
+
function triggerRemoveFromListEvent (contentId) {
|
334
|
+
return document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
335
|
+
detail: {
|
336
|
+
category: 'professorLists',
|
337
|
+
action: 'remove-from-list',
|
338
|
+
article_id: contentId,
|
339
|
+
teamName: 'customer-products-us-growth',
|
340
|
+
amplitudeExploratory: true
|
341
|
+
},
|
342
|
+
bubbles: true
|
343
|
+
}));
|
344
|
+
}
|
345
|
+
|
346
|
+
function triggerCreateListEvent (contentId) {
|
347
|
+
document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
348
|
+
detail: {
|
349
|
+
category: 'professorLists',
|
350
|
+
action: 'create-list',
|
351
|
+
article_id: contentId,
|
352
|
+
teamName: 'customer-products-us-growth',
|
353
|
+
amplitudeExploratory: true
|
354
|
+
},
|
355
|
+
bubbles: true
|
356
|
+
}));
|
357
|
+
|
358
|
+
return document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
359
|
+
detail: {
|
360
|
+
category: 'myFT',
|
361
|
+
action: 'create-list-success',
|
362
|
+
article_id: contentId
|
363
|
+
},
|
364
|
+
bubbles: true
|
365
|
+
}));
|
366
|
+
}
|
367
|
+
|
368
|
+
function handleError (error) {
|
369
|
+
document.body.dispatchEvent(new CustomEvent('oErrors.log', {
|
370
|
+
bubbles: true,
|
371
|
+
detail: {
|
372
|
+
error,
|
373
|
+
info: { component: 'professorLists' },
|
374
|
+
}
|
375
|
+
}));
|
376
|
+
}
|