@financial-times/n-myft-ui 28.1.0 → 28.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.
- package/build-state/npm-shrinkwrap.json +7 -7
- package/myft/main.scss +6 -0
- package/myft/ui/lib/relationship-config.js +0 -6
- package/myft/ui/lib/tracking.js +2 -4
- package/myft/ui/lists.js +75 -0
- package/myft/ui/myft-buttons/init.js +1 -0
- package/myft/ui/save-article-to-list-variant.js +61 -54
- package/package.json +3 -3
@@ -15,7 +15,7 @@
|
|
15
15
|
"form-serialize": "^0.7.2",
|
16
16
|
"ftdomdelegate": "^4.0.6",
|
17
17
|
"js-cookie": "^2.2.1",
|
18
|
-
"next-myft-client": "^10.
|
18
|
+
"next-myft-client": "^10.3.0",
|
19
19
|
"next-session-client": "^4.0.0",
|
20
20
|
"superstore-sync": "^2.1.1"
|
21
21
|
},
|
@@ -14265,9 +14265,9 @@
|
|
14265
14265
|
}
|
14266
14266
|
},
|
14267
14267
|
"node_modules/next-myft-client": {
|
14268
|
-
"version": "10.
|
14269
|
-
"resolved": "https://registry.npmjs.org/next-myft-client/-/next-myft-client-10.
|
14270
|
-
"integrity": "sha512-
|
14268
|
+
"version": "10.3.0",
|
14269
|
+
"resolved": "https://registry.npmjs.org/next-myft-client/-/next-myft-client-10.3.0.tgz",
|
14270
|
+
"integrity": "sha512-dAaIs6PhvYGczEsOHGNrI3FKKFDOcm6rSv06SaL9emltqlHqUXt7esun8m4N3D2iL2FzVXKLeMd9/gv/GDryOg==",
|
14271
14271
|
"hasInstallScript": true,
|
14272
14272
|
"dependencies": {
|
14273
14273
|
"black-hole-stream": "0.0.1",
|
@@ -34770,9 +34770,9 @@
|
|
34770
34770
|
}
|
34771
34771
|
},
|
34772
34772
|
"next-myft-client": {
|
34773
|
-
"version": "10.
|
34774
|
-
"resolved": "https://registry.npmjs.org/next-myft-client/-/next-myft-client-10.
|
34775
|
-
"integrity": "sha512-
|
34773
|
+
"version": "10.3.0",
|
34774
|
+
"resolved": "https://registry.npmjs.org/next-myft-client/-/next-myft-client-10.3.0.tgz",
|
34775
|
+
"integrity": "sha512-dAaIs6PhvYGczEsOHGNrI3FKKFDOcm6rSv06SaL9emltqlHqUXt7esun8m4N3D2iL2FzVXKLeMd9/gv/GDryOg==",
|
34776
34776
|
"requires": {
|
34777
34777
|
"black-hole-stream": "0.0.1",
|
34778
34778
|
"fetchres": "^1.7.2",
|
package/myft/main.scss
CHANGED
@@ -11,12 +11,6 @@ const relationshipConfig = {
|
|
11
11
|
subjectType: 'concept',
|
12
12
|
uiSelector: '[data-myft-ui="follow"]'
|
13
13
|
},
|
14
|
-
contained: {
|
15
|
-
actorType: 'list',
|
16
|
-
idProperty: 'data-content-id',
|
17
|
-
subjectType: 'content',
|
18
|
-
uiSelector: '[data-myft-ui="contained"]'
|
19
|
-
}
|
20
14
|
};
|
21
15
|
|
22
16
|
export default relationshipConfig;
|
package/myft/ui/lib/tracking.js
CHANGED
@@ -39,12 +39,10 @@ const getExtraContext = (subjectType, subjectId) => {
|
|
39
39
|
* @param {Object} postedData Event's extra data (required for checking if an instant alert was turned on or off)
|
40
40
|
* @return {String} label for the action to send in the custom event
|
41
41
|
*/
|
42
|
-
const getAction = (subjectType, action, postedData
|
42
|
+
const getAction = (subjectType, action, postedData) => {
|
43
43
|
if (action === 'update' && subjectType === 'concept') {
|
44
44
|
const updateState = (postedData && postedData._rel && postedData._rel.instant && postedData._rel.instant === 'true') ? 'on' : 'off';
|
45
45
|
return `instant-alert-${updateState}`;
|
46
|
-
} else if (resultData && resultData.rel && resultData.rel.type && resultData.rel.type === 'contained') {
|
47
|
-
return `${action}-to-list-success`;
|
48
46
|
} else {
|
49
47
|
return customDataSettings[subjectType][action];
|
50
48
|
}
|
@@ -57,7 +55,7 @@ const getAction = (subjectType, action, postedData, resultData) => {
|
|
57
55
|
export function custom (eventData) {
|
58
56
|
if (Object.keys(customDataSettings).indexOf(eventData.subjectType) !== -1) {
|
59
57
|
const options = Object.assign(
|
60
|
-
{action: getAction(eventData.subjectType, eventData.action, eventData.postedData
|
58
|
+
{action: getAction(eventData.subjectType, eventData.action, eventData.postedData)},
|
61
59
|
eventData.trackingInfo);
|
62
60
|
const extraContext = getExtraContext(eventData.subjectType, eventData.subjectId);
|
63
61
|
Object.assign(options, extraContext);
|
package/myft/ui/lists.js
CHANGED
@@ -51,6 +51,18 @@ function updateAfterAddToList (listId, contentId, wasAdded) {
|
|
51
51
|
content: message,
|
52
52
|
trackable: 'myft-feedback-notification'
|
53
53
|
});
|
54
|
+
|
55
|
+
document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
56
|
+
detail: {
|
57
|
+
category: 'list',
|
58
|
+
action: 'copy-success',
|
59
|
+
article_id: contentId,
|
60
|
+
list_id: listId,
|
61
|
+
teamName: 'customer-products-us-growth',
|
62
|
+
amplitudeExploratory: true
|
63
|
+
},
|
64
|
+
bubbles: true
|
65
|
+
}));
|
54
66
|
});
|
55
67
|
}
|
56
68
|
|
@@ -83,6 +95,10 @@ function setUpCreateListListeners (overlay, contentId) {
|
|
83
95
|
const createListButton = overlay.content.querySelector('.js-create-list');
|
84
96
|
const nameInput = overlay.content.querySelector('.js-name');
|
85
97
|
|
98
|
+
if (!createListButton) {
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
|
86
102
|
createListButton.addEventListener('click', event => {
|
87
103
|
event.preventDefault();
|
88
104
|
|
@@ -184,6 +200,63 @@ function openCreateListAndAddArticleOverlay (contentId) {
|
|
184
200
|
});
|
185
201
|
}
|
186
202
|
|
203
|
+
function handleRemoveToggleSubmit (event) {
|
204
|
+
event.preventDefault();
|
205
|
+
|
206
|
+
const formEl = event.target;
|
207
|
+
const submitBtnEl = formEl.querySelector('button[type="submit"]');
|
208
|
+
|
209
|
+
if (submitBtnEl.hasAttribute('disabled')) {
|
210
|
+
return;
|
211
|
+
}
|
212
|
+
|
213
|
+
const isSubmitBtnPressed = submitBtnEl.getAttribute('aria-pressed') === 'true';
|
214
|
+
const action = isSubmitBtnPressed ? 'remove' : 'add';
|
215
|
+
const contentId = formEl.dataset.contentId;
|
216
|
+
const listId = formEl.dataset.actorId;
|
217
|
+
const csrfToken = formEl.elements.token;
|
218
|
+
|
219
|
+
if (!csrfToken || !csrfToken.value) {
|
220
|
+
document.body.dispatchEvent(new CustomEvent('oErrors.log', {
|
221
|
+
bubbles: true,
|
222
|
+
detail: {
|
223
|
+
error: new Error('myFT form submitted without a CSRF token'),
|
224
|
+
info: {
|
225
|
+
action,
|
226
|
+
actorType: 'list',
|
227
|
+
actorId: listId,
|
228
|
+
relationshipName: 'contained',
|
229
|
+
subjectType: 'content',
|
230
|
+
subjectId: contentId,
|
231
|
+
},
|
232
|
+
},
|
233
|
+
}));
|
234
|
+
}
|
235
|
+
|
236
|
+
submitBtnEl.setAttribute('disabled', '');
|
237
|
+
|
238
|
+
myFtClient[action]('list', listId, 'contained', 'content', contentId, { token: csrfToken.value })
|
239
|
+
.then(() => {
|
240
|
+
myFtUiButtonStates.toggleButton(submitBtnEl, !isSubmitBtnPressed);
|
241
|
+
|
242
|
+
document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
243
|
+
detail: {
|
244
|
+
category: 'list',
|
245
|
+
action: action === 'add' ? 'add-success' : 'remove-success',
|
246
|
+
article_id: contentId,
|
247
|
+
list_id: listId,
|
248
|
+
teamName: 'customer-products-us-growth',
|
249
|
+
amplitudeExploratory: true
|
250
|
+
},
|
251
|
+
bubbles: true
|
252
|
+
}));
|
253
|
+
})
|
254
|
+
.catch(error => {
|
255
|
+
setTimeout(() => submitBtnEl.removeAttribute('disabled'));
|
256
|
+
throw error;
|
257
|
+
});
|
258
|
+
}
|
259
|
+
|
187
260
|
function initialEventListeners () {
|
188
261
|
|
189
262
|
document.body.addEventListener('myft.user.saved.content.add', event => {
|
@@ -208,6 +281,8 @@ function initialEventListeners () {
|
|
208
281
|
ev.preventDefault();
|
209
282
|
showCreateListOverlay();
|
210
283
|
});
|
284
|
+
|
285
|
+
delegate.on('submit', '[data-myft-ui="contained"]', handleRemoveToggleSubmit);
|
211
286
|
}
|
212
287
|
|
213
288
|
export function init () {
|
@@ -65,6 +65,7 @@ function signedInEventListeners () {
|
|
65
65
|
const resultData = event.detail.results && event.detail.results[0];
|
66
66
|
const isPressed = !!event.detail.results;
|
67
67
|
buttonStates.setStateOfButton(relationshipName, event.detail.subject, isPressed, undefined, resultData, true);
|
68
|
+
|
68
69
|
tracking.custom({
|
69
70
|
subjectType,
|
70
71
|
action,
|
@@ -7,9 +7,10 @@ const csrfToken = getToken();
|
|
7
7
|
|
8
8
|
let lists = [];
|
9
9
|
let haveLoadedLists = false;
|
10
|
+
let createListOverlay;
|
10
11
|
|
11
12
|
export default async function openSaveArticleToListVariant (name, contentId) {
|
12
|
-
function createList (list) {
|
13
|
+
function createList (list, cb) {
|
13
14
|
if(!list) {
|
14
15
|
if (!lists.length) attachDescription();
|
15
16
|
return contentElement.addEventListener('click', openFormHandler, { once: true });
|
@@ -18,14 +19,14 @@ export default async function openSaveArticleToListVariant (name, contentId) {
|
|
18
19
|
myFtClient.add('user', null, 'created', 'list', uuid(), { name: list, token: csrfToken })
|
19
20
|
.then(detail => {
|
20
21
|
myFtClient.add('list', detail.subject, 'contained', 'content', contentId, { token: csrfToken }).then((createdList) => {
|
21
|
-
lists.
|
22
|
+
lists.unshift({ name: list, uuid: createdList.actorId, checked: true });
|
22
23
|
const listElement = ListsElement(lists, addToList, removeFromList);
|
23
24
|
const overlayContent = document.querySelector('.o-overlay__content');
|
24
25
|
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
25
26
|
const announceListContainer = document.querySelector('.myft-ui-create-list-variant-announcement');
|
26
27
|
announceListContainer.textContent = `${list} created`;
|
27
|
-
triggerCreateListEvent(contentId);
|
28
28
|
contentElement.addEventListener('click', openFormHandler, { once: true });
|
29
|
+
cb(contentId, createdList.actorId);
|
29
30
|
});
|
30
31
|
})
|
31
32
|
.catch(() => {
|
@@ -34,33 +35,25 @@ export default async function openSaveArticleToListVariant (name, contentId) {
|
|
34
35
|
});
|
35
36
|
}
|
36
37
|
|
37
|
-
function addToList (list) {
|
38
|
+
function addToList (list, cb) {
|
38
39
|
if(!list) {
|
39
40
|
return;
|
40
41
|
}
|
41
42
|
|
42
|
-
myFtClient.add('list', list.uuid, 'contained', 'content', contentId, { token: csrfToken }).then(() => {
|
43
|
-
|
44
|
-
|
45
|
-
const listElement = ListsElement(lists, addToList, removeFromList);
|
46
|
-
const overlayContent = document.querySelector('.o-overlay__content');
|
47
|
-
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
48
|
-
triggerAddToListEvent(contentId);
|
43
|
+
myFtClient.add('list', list.uuid, 'contained', 'content', contentId, { token: csrfToken }).then((addedList) => {
|
44
|
+
cb();
|
45
|
+
triggerAddToListEvent(contentId, addedList.actorId);
|
49
46
|
});
|
50
47
|
}
|
51
48
|
|
52
|
-
function removeFromList (list) {
|
49
|
+
function removeFromList (list, cb) {
|
53
50
|
if(!list) {
|
54
51
|
return;
|
55
52
|
}
|
56
53
|
|
57
|
-
myFtClient.remove('list', list.uuid, 'contained', 'content', contentId, { token: csrfToken }).then(() => {
|
58
|
-
|
59
|
-
|
60
|
-
const listElement = ListsElement(lists, addToList, removeFromList);
|
61
|
-
const overlayContent = document.querySelector('.o-overlay__content');
|
62
|
-
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
63
|
-
triggerRemoveFromListEvent(contentId);
|
54
|
+
myFtClient.remove('list', list.uuid, 'contained', 'content', contentId, { token: csrfToken }).then((removedList) => {
|
55
|
+
cb();
|
56
|
+
triggerRemoveFromListEvent(contentId, removedList.actorId);
|
64
57
|
});
|
65
58
|
}
|
66
59
|
|
@@ -78,7 +71,7 @@ export default async function openSaveArticleToListVariant (name, contentId) {
|
|
78
71
|
const headingElement = HeadingElement();
|
79
72
|
let [contentElement, removeDescription, attachDescription] = ContentElement(!lists.length);
|
80
73
|
|
81
|
-
|
74
|
+
createListOverlay = new Overlay(name, {
|
82
75
|
html: contentElement,
|
83
76
|
heading: { title: headingElement.outerHTML },
|
84
77
|
modal: false,
|
@@ -88,7 +81,11 @@ export default async function openSaveArticleToListVariant (name, contentId) {
|
|
88
81
|
|
89
82
|
function outsideClickHandler (e) {
|
90
83
|
const overlayContent = document.querySelector('.o-overlay__content');
|
91
|
-
|
84
|
+
const overlayContainer = document.querySelector('.o-overlay');
|
85
|
+
// we don't want to close the overlay if the click happened inside the
|
86
|
+
// overlay, except if the click happened on the overlay close button
|
87
|
+
const isTargetInsideOverlay = overlayContainer.contains(e.target) && !e.target.classList.contains('o-overlay__close');
|
88
|
+
if(createListOverlay.visible && (!overlayContent || !isTargetInsideOverlay)) {
|
92
89
|
createListOverlay.close();
|
93
90
|
}
|
94
91
|
}
|
@@ -114,17 +111,17 @@ export default async function openSaveArticleToListVariant (name, contentId) {
|
|
114
111
|
const scrollHandler = getScrollHandler(createListOverlay.wrapper);
|
115
112
|
|
116
113
|
createListOverlay.wrapper.addEventListener('oOverlay.ready', (data) => {
|
117
|
-
positionOverlay(data.currentTarget);
|
118
|
-
|
119
114
|
if (lists.length) {
|
120
115
|
const listElement = ListsElement(lists, addToList, removeFromList);
|
121
116
|
const overlayContent = document.querySelector('.o-overlay__content');
|
122
117
|
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
123
118
|
}
|
124
119
|
|
120
|
+
positionOverlay(data.currentTarget);
|
121
|
+
|
125
122
|
contentElement.addEventListener('click', openFormHandler, { once: true });
|
126
123
|
|
127
|
-
document.querySelector('.article-content').addEventListener('click', outsideClickHandler
|
124
|
+
document.querySelector('.article-content').addEventListener('click', outsideClickHandler);
|
128
125
|
|
129
126
|
window.addEventListener('scroll', scrollHandler);
|
130
127
|
|
@@ -135,6 +132,8 @@ export default async function openSaveArticleToListVariant (name, contentId) {
|
|
135
132
|
window.removeEventListener('scroll', scrollHandler);
|
136
133
|
|
137
134
|
window.removeEventListener('oViewport.resize', resizeHandler);
|
135
|
+
|
136
|
+
document.querySelector('.article-content').removeEventListener('click', outsideClickHandler);
|
138
137
|
});
|
139
138
|
}
|
140
139
|
|
@@ -164,7 +163,11 @@ function FormElement (createList) {
|
|
164
163
|
event.preventDefault();
|
165
164
|
event.stopPropagation();
|
166
165
|
const inputListName = formElement.querySelector('input[name="list-name"]');
|
167
|
-
createList(inputListName.value)
|
166
|
+
createList(inputListName.value, ((contentId, listId) => {
|
167
|
+
triggerCreateListEvent(contentId, listId);
|
168
|
+
triggerAddToListEvent(contentId, listId);
|
169
|
+
positionOverlay(createListOverlay.wrapper);
|
170
|
+
}));
|
168
171
|
inputListName.value = '';
|
169
172
|
formElement.remove();
|
170
173
|
}
|
@@ -179,7 +182,7 @@ function ContentElement (hasDescription) {
|
|
179
182
|
|
180
183
|
const content = `
|
181
184
|
<div class="myft-ui-create-list-variant-footer">
|
182
|
-
<button class="myft-ui-create-list-variant-add">Add to a new list</button>
|
185
|
+
<button class="myft-ui-create-list-variant-add" data-trackable="add-to-new-list" text="Add to a new list">Add to a new list</button>
|
183
186
|
${hasDescription ? `
|
184
187
|
${description}
|
185
188
|
` : ''}
|
@@ -205,7 +208,7 @@ function ContentElement (hasDescription) {
|
|
205
208
|
|
206
209
|
function HeadingElement () {
|
207
210
|
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>
|
211
|
+
<span class="myft-ui-create-list-variant-heading">Added to <a href="https://www.ft.com/myft/saved-articles" data-trackable="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
212
|
`;
|
210
213
|
|
211
214
|
return stringToHTMLElement(heading);
|
@@ -237,8 +240,9 @@ function ListsElement (lists, addToList, removeFromList) {
|
|
237
240
|
|
238
241
|
function ListCheckboxElement (addToList, removeFromList) {
|
239
242
|
return function (list) {
|
243
|
+
|
240
244
|
const listCheckbox = `<label>
|
241
|
-
<input type="checkbox" name="default" value="${list.
|
245
|
+
<input type="checkbox" name="default" value="${list.uuid}" ${list.checked ? 'checked' : ''}>
|
242
246
|
<span class="o-forms-input__label">
|
243
247
|
<span class="o-normalise-visually-hidden">
|
244
248
|
${list.checked ? 'Remove article from ' : 'Add article to ' }
|
@@ -254,7 +258,15 @@ function ListCheckboxElement (addToList, removeFromList) {
|
|
254
258
|
|
255
259
|
function handleCheck (event) {
|
256
260
|
event.preventDefault();
|
257
|
-
|
261
|
+
const isChecked = event.target.checked;
|
262
|
+
|
263
|
+
function onListUpdated () {
|
264
|
+
const indexToUpdate = lists.indexOf(list);
|
265
|
+
lists[indexToUpdate] = { ...lists[indexToUpdate], checked: isChecked };
|
266
|
+
listCheckboxElement.querySelector('input').checked = isChecked;
|
267
|
+
}
|
268
|
+
|
269
|
+
return isChecked ? addToList(list, onListUpdated) : removeFromList(list, onListUpdated);
|
258
270
|
}
|
259
271
|
|
260
272
|
input.addEventListener('click', handleCheck);
|
@@ -287,10 +299,11 @@ function positionOverlay (target) {
|
|
287
299
|
|
288
300
|
if (isMobile()) {
|
289
301
|
const shareNavComponent = document.querySelector('.share-nav__horizontal');
|
302
|
+
const topHalfOffset = target.clientHeight + 10;
|
290
303
|
target.style['position'] = 'absolute';
|
291
304
|
target.style['margin-left'] = 0;
|
292
305
|
target.style['margin-top'] = 0;
|
293
|
-
target.style['top'] = calculateLargerScreenHalf(shareNavComponent) === 'ABOVE' ?
|
306
|
+
target.style['top'] = calculateLargerScreenHalf(shareNavComponent) === 'ABOVE' ? `-${topHalfOffset}px` : '50px';
|
294
307
|
} else {
|
295
308
|
target.style['position'] = 'absolute';
|
296
309
|
target.style['margin-left'] = '45px';
|
@@ -318,20 +331,21 @@ function calculateLargerScreenHalf (target) {
|
|
318
331
|
return spaceBelow < spaceAbove ? 'ABOVE' : 'BELOW';
|
319
332
|
}
|
320
333
|
|
321
|
-
async function getLists () {
|
322
|
-
return myFtClient.
|
323
|
-
.then(
|
324
|
-
|
325
|
-
return
|
326
|
-
});
|
334
|
+
async function getLists (contentId) {
|
335
|
+
return myFtClient.getListsContent()
|
336
|
+
.then(results => results.items.map(list => {
|
337
|
+
const isChecked = Array.isArray(list.content) && list.content.some(content => content.uuid === contentId);
|
338
|
+
return { name: list.name, uuid: list.uuid, checked: isChecked, content: list.content };
|
339
|
+
}));
|
327
340
|
}
|
328
341
|
|
329
|
-
function triggerAddToListEvent (contentId) {
|
342
|
+
function triggerAddToListEvent (contentId, listId) {
|
330
343
|
return document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
331
344
|
detail: {
|
332
|
-
category: '
|
333
|
-
action: 'add-
|
345
|
+
category: 'list',
|
346
|
+
action: 'add-success',
|
334
347
|
article_id: contentId,
|
348
|
+
list_id: listId,
|
335
349
|
teamName: 'customer-products-us-growth',
|
336
350
|
amplitudeExploratory: true
|
337
351
|
},
|
@@ -339,12 +353,13 @@ function triggerAddToListEvent (contentId) {
|
|
339
353
|
}));
|
340
354
|
}
|
341
355
|
|
342
|
-
function triggerRemoveFromListEvent (contentId) {
|
356
|
+
function triggerRemoveFromListEvent (contentId, listId) {
|
343
357
|
return document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
344
358
|
detail: {
|
345
|
-
category: '
|
346
|
-
action: 'remove-
|
359
|
+
category: 'list',
|
360
|
+
action: 'remove-success',
|
347
361
|
article_id: contentId,
|
362
|
+
list_id: listId,
|
348
363
|
teamName: 'customer-products-us-growth',
|
349
364
|
amplitudeExploratory: true
|
350
365
|
},
|
@@ -352,24 +367,16 @@ function triggerRemoveFromListEvent (contentId) {
|
|
352
367
|
}));
|
353
368
|
}
|
354
369
|
|
355
|
-
function triggerCreateListEvent (contentId) {
|
370
|
+
function triggerCreateListEvent (contentId, listId) {
|
356
371
|
document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
357
372
|
detail: {
|
358
|
-
category: '
|
359
|
-
action: 'create-
|
373
|
+
category: 'list',
|
374
|
+
action: 'create-success',
|
360
375
|
article_id: contentId,
|
376
|
+
list_id: listId,
|
361
377
|
teamName: 'customer-products-us-growth',
|
362
378
|
amplitudeExploratory: true
|
363
379
|
},
|
364
380
|
bubbles: true
|
365
381
|
}));
|
366
|
-
|
367
|
-
return document.body.dispatchEvent(new CustomEvent('oTracking.event', {
|
368
|
-
detail: {
|
369
|
-
category: 'myFT',
|
370
|
-
action: 'create-list-success',
|
371
|
-
article_id: contentId
|
372
|
-
},
|
373
|
-
bubbles: true
|
374
|
-
}));
|
375
382
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@financial-times/n-myft-ui",
|
3
|
-
"version": "28.
|
3
|
+
"version": "28.2.0",
|
4
4
|
"description": "Client side component for interaction with myft",
|
5
5
|
"main": "server.js",
|
6
6
|
"scripts": {
|
@@ -103,13 +103,13 @@
|
|
103
103
|
"form-serialize": "^0.7.2",
|
104
104
|
"ftdomdelegate": "^4.0.6",
|
105
105
|
"js-cookie": "^2.2.1",
|
106
|
-
"next-myft-client": "^10.
|
106
|
+
"next-myft-client": "^10.3.0",
|
107
107
|
"next-session-client": "^4.0.0",
|
108
108
|
"superstore-sync": "^2.1.1"
|
109
109
|
},
|
110
110
|
"volta": {
|
111
111
|
"node": "16.14.2",
|
112
|
-
"npm": "7.
|
112
|
+
"npm": "7.24.2"
|
113
113
|
},
|
114
114
|
"engines": {
|
115
115
|
"node": "14.x || 16.x",
|