@financial-times/n-myft-ui 30.4.3 → 30.4.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,6 +10,7 @@
10
10
  "hasInstallScript": true,
11
11
  "license": "ISC",
12
12
  "dependencies": {
13
+ "@financial-times/o-tracking": "^4.5.0",
13
14
  "date-fns": "2.16.1",
14
15
  "fetchres": "^1.7.2",
15
16
  "form-serialize": "^0.7.2",
@@ -3378,6 +3379,22 @@
3378
3379
  "@financial-times/o-visual-effects": "^4.0.1"
3379
3380
  }
3380
3381
  },
3382
+ "node_modules/@financial-times/o-tracking": {
3383
+ "version": "4.5.0",
3384
+ "resolved": "https://registry.npmjs.org/@financial-times/o-tracking/-/o-tracking-4.5.0.tgz",
3385
+ "integrity": "sha512-gPnAmMPqlYWf8xXNJkAYKQMpEWvHpjxajB4YnadbGhOGl2Zy8y5LJJqyzsfpqoBh51P7VDIc7yBF+A7fgaymYw==",
3386
+ "dependencies": {
3387
+ "ftdomdelegate": "^5"
3388
+ },
3389
+ "engines": {
3390
+ "npm": "^7 || ^8"
3391
+ }
3392
+ },
3393
+ "node_modules/@financial-times/o-tracking/node_modules/ftdomdelegate": {
3394
+ "version": "5.0.0",
3395
+ "resolved": "https://registry.npmjs.org/ftdomdelegate/-/ftdomdelegate-5.0.0.tgz",
3396
+ "integrity": "sha512-P9UmLMIq/ibxxFVBHlE2EIoHcFNDpamn3urRCwVWMnj3o9nAgLtqe64WVuqcGtkN4wujrBYeyxKCuN1/WO+bQw=="
3397
+ },
3381
3398
  "node_modules/@financial-times/o-typography": {
3382
3399
  "version": "7.5.0",
3383
3400
  "resolved": "https://registry.npmjs.org/@financial-times/o-typography/-/o-typography-7.5.0.tgz",
@@ -31386,6 +31403,21 @@
31386
31403
  "ftdomdelegate": "^4.0.6"
31387
31404
  }
31388
31405
  },
31406
+ "@financial-times/o-tracking": {
31407
+ "version": "4.5.0",
31408
+ "resolved": "https://registry.npmjs.org/@financial-times/o-tracking/-/o-tracking-4.5.0.tgz",
31409
+ "integrity": "sha512-gPnAmMPqlYWf8xXNJkAYKQMpEWvHpjxajB4YnadbGhOGl2Zy8y5LJJqyzsfpqoBh51P7VDIc7yBF+A7fgaymYw==",
31410
+ "requires": {
31411
+ "ftdomdelegate": "^5"
31412
+ },
31413
+ "dependencies": {
31414
+ "ftdomdelegate": {
31415
+ "version": "5.0.0",
31416
+ "resolved": "https://registry.npmjs.org/ftdomdelegate/-/ftdomdelegate-5.0.0.tgz",
31417
+ "integrity": "sha512-P9UmLMIq/ibxxFVBHlE2EIoHcFNDpamn3urRCwVWMnj3o9nAgLtqe64WVuqcGtkN4wujrBYeyxKCuN1/WO+bQw=="
31418
+ }
31419
+ }
31420
+ },
31389
31421
  "@financial-times/o-typography": {
31390
31422
  "version": "7.5.0",
31391
31423
  "resolved": "https://registry.npmjs.org/@financial-times/o-typography/-/o-typography-7.5.0.tgz",
@@ -40,7 +40,6 @@ const instantAlertsIconUpdate = ({ event, followPlusInstantAlerts }) => {
40
40
  return;
41
41
  }
42
42
 
43
-
44
43
  const instantAlertsOn = Boolean(currentConcept && currentConcept.rel && currentConcept.rel.properties && currentConcept.rel.properties.instant);
45
44
  toggleInstantAlertsClass({instantAlertsOn, followPlusInstantAlerts });
46
45
  };
@@ -72,5 +71,6 @@ export default () => {
72
71
  followPlusInstantAlerts.addEventListener('click', () => sendModalToggleEvent({followPlusInstantAlerts}));
73
72
 
74
73
  document.body.addEventListener('myft.user.followed.concept.load', (event) => instantAlertsIconLoad({event, followPlusInstantAlerts}));
74
+
75
75
  document.body.addEventListener('myft.user.followed.concept.update', (event) => instantAlertsIconUpdate({event, followPlusInstantAlerts}));
76
76
  };
@@ -1,5 +1,6 @@
1
1
  import myFtClient from 'next-myft-client';
2
2
  import getToken from '../../../myft/ui/lib/get-csrf-token';
3
+ import oTracking from '@financial-times/o-tracking';
3
4
 
4
5
  const csrfToken = getToken();
5
6
 
@@ -50,6 +51,20 @@ const preferenceModalShowAndHide = ({ event, preferencesModal }) => {
50
51
 
51
52
  if (preferencesModal.classList.contains('n-myft-ui__preferences-modal--show')) {
52
53
  positionModal({ event, preferencesModal });
54
+ const opts = {
55
+ category: 'component',
56
+ selector: '[data-component-id="myft-preferences-modal"]',
57
+ getContextData: () => {
58
+ return {
59
+ component: {
60
+ type: 'component',
61
+ name: 'pop-up-box',
62
+ id: '72de123e-5082-11ee-be56-0242ac120002',
63
+ },
64
+ };
65
+ },
66
+ };
67
+ oTracking.view.init(opts);
53
68
  } else {
54
69
  // Remove existing errors when hiding the modal
55
70
  renderError({
@@ -74,6 +89,12 @@ const removeTopic = async ({ event, conceptId, preferencesModal }) => {
74
89
  event.target.removeAttribute('disabled');
75
90
  };
76
91
 
92
+ const getAlertsPreferenceText = (addedTextBuffer) => {
93
+ const alertsEnabledText = `Your delivery channels: ${addedTextBuffer.join(', ')}.`;
94
+ const alertsDisabledText = 'You have previously disabled all delivery channels';
95
+ return Array.isArray(addedTextBuffer) && addedTextBuffer.length > 0 ? alertsEnabledText : alertsDisabledText;
96
+ };
97
+
77
98
  const getAlertsPreferences = async ({ event, preferencesModal }) => {
78
99
  const preferencesList = preferencesModal.querySelector('[data-component-id="myft-preferences-modal-list"]');
79
100
 
@@ -91,6 +112,8 @@ const getAlertsPreferences = async ({ event, preferencesModal }) => {
91
112
  }
92
113
  });
93
114
 
115
+ preferencesList.innerHTML = getAlertsPreferenceText(addedTextBuffer);
116
+
94
117
  try {
95
118
  // We need the service worker registration to check for a subscription
96
119
  const serviceWorkerRegistration = await navigator.serviceWorker.ready;
@@ -98,43 +121,50 @@ const getAlertsPreferences = async ({ event, preferencesModal }) => {
98
121
  if (subscription) {
99
122
  addedTextBuffer.push('browser');
100
123
  }
101
-
102
124
  } catch (error) {
103
125
  // eslint-disable-next-line no-console
104
126
  console.warn('There was an error fetching the browser notification preferences', error);
105
127
  }
106
- const alertsEnabledText = `Your delivery channels: ${addedTextBuffer.join(', ')}.`;
107
- const alertsDisabledText = 'You have previously disabled all delivery channels';
108
- preferencesList.innerHTML = addedTextBuffer.length > 0 ? alertsEnabledText : alertsDisabledText;
128
+
129
+ preferencesList.innerHTML = getAlertsPreferenceText(addedTextBuffer);
109
130
  };
110
131
 
111
132
  const setCheckboxForAlertConcept = ({ event, preferencesModal }) => {
112
133
  const conceptId = preferencesModal.dataset.conceptId;
113
134
  const instantAlertsCheckbox = preferencesModal.querySelector('[data-component-id="myft-preferences-modal-checkbox"]');
135
+
114
136
  // search through all the concepts that the user has followed and check whether
115
137
  // 1. the concept which this instant alert modal controls is within them, AND;
116
138
  // 2. the said concept has instant alert enabled
117
139
  // if so, check the checkbox within the modal
118
140
  const currentConcept = event.detail.items.find(item => item && item.uuid === conceptId);
119
141
  if (currentConcept && currentConcept._rel && currentConcept._rel.instant) {
142
+ instantAlertsCheckbox.dataset.trackable = 'pop-up-box|set-instant-alert-off';
120
143
  instantAlertsCheckbox.checked = true;
121
144
  } else {
145
+ instantAlertsCheckbox.dataset.trackable = 'pop-up-box|set-instant-alert-on';
122
146
  instantAlertsCheckbox.checked = false;
123
147
  }
124
148
  };
125
149
 
126
150
  const toggleInstantAlertsPreference = async ({ event, conceptId, preferencesModal }) => {
127
- const instantAlertsToggle = event.target;
151
+ const instantAlertsCheckbox = event.target;
128
152
 
129
- instantAlertsToggle.setAttribute('disabled', true);
153
+ if (!instantAlertsCheckbox) {
154
+ return;
155
+ }
156
+
157
+ instantAlertsCheckbox.setAttribute('disabled', true);
130
158
 
131
159
  const data = {
132
160
  token: csrfToken
133
161
  };
134
162
 
135
- if (instantAlertsToggle.checked) {
163
+ if (instantAlertsCheckbox.checked) {
164
+ instantAlertsCheckbox.dataset.trackable = 'pop-up-box|set-instant-alert-off';
136
165
  data._rel = {instant: 'true'};
137
166
  } else {
167
+ instantAlertsCheckbox.dataset.trackable = 'pop-up-box|set-instant-alert-on';
138
168
  data._rel = {instant: 'false'};
139
169
  }
140
170
 
@@ -146,12 +176,12 @@ const toggleInstantAlertsPreference = async ({ event, conceptId, preferencesModa
146
176
  preferencesModal
147
177
  });
148
178
 
149
- instantAlertsToggle.checked = instantAlertsToggle.checked
179
+ instantAlertsCheckbox.checked = instantAlertsCheckbox.checked
150
180
  ? false
151
181
  : true;
152
182
  }
153
183
 
154
- instantAlertsToggle.removeAttribute('disabled');
184
+ instantAlertsCheckbox.removeAttribute('disabled');
155
185
  };
156
186
 
157
187
  export default () => {
@@ -162,16 +192,25 @@ export default () => {
162
192
  * If this was to be used in other locations it would need some additional work to avoid being singleton
163
193
  */
164
194
  const preferencesModal = document.querySelector('[data-component-id="myft-preferences-modal"]');
195
+
196
+ if (!preferencesModal) {
197
+ return;
198
+ }
165
199
  const conceptId = preferencesModal.dataset.conceptId;
166
200
 
167
- if (!preferencesModal || !conceptId) {
201
+ if (!conceptId) {
168
202
  return;
169
203
  }
170
204
 
171
205
  const removeTopicButton = preferencesModal.querySelector('[data-component-id="myft-preference-modal-remove"]');
172
206
  const instantAlertsCheckbox = preferencesModal.querySelector('[data-component-id="myft-preferences-modal-checkbox"]');
173
207
 
208
+ if (!removeTopicButton || !instantAlertsCheckbox) {
209
+ return;
210
+ }
211
+
174
212
  removeTopicButton.addEventListener('click', event => removeTopic({ event, conceptId, preferencesModal }));
213
+
175
214
  instantAlertsCheckbox.addEventListener('change', event => toggleInstantAlertsPreference({ event, conceptId, preferencesModal }));
176
215
 
177
216
  document.addEventListener('myft.preference-modal.show-hide.toggle', event => preferenceModalShowAndHide({ event, preferencesModal }));
@@ -26,6 +26,7 @@ export default function InstantAlertsPreferencesModal({ flags, conceptId, visibl
26
26
  className={`n-myft-ui__preferences-modal ${visible ? 'n-myft-ui__preferences-modal--show' : ''}`}
27
27
  data-component-id="myft-preferences-modal"
28
28
  data-concept-id={conceptId}
29
+ data-o-tracking-view="true"
29
30
  >
30
31
  <div className="n-myft-ui__preferences-modal__content">
31
32
  <span className="o-forms-input o-forms-input--checkbox">
@@ -44,9 +45,9 @@ export default function InstantAlertsPreferencesModal({ flags, conceptId, visibl
44
45
  </span>
45
46
 
46
47
  <p data-component-id="myft-preferences-modal-list" className="n-myft-ui__preferences-modal__text"></p>
47
- <a className="n-myft-ui__preferences-modal__text" href="/myft/alerts">Manage your preferences here</a>
48
+ <a className="n-myft-ui__preferences-modal__text" href="/myft/alerts" data-trackable="pop-up-box|contact-preference">Manage your preferences here</a>
48
49
  <span className="n-myft-ui__preferences-modal-error" data-component-id="myft-preference-modal-error"></span>
49
- <button className="n-myft-ui__preferences-modal__remove-button" data-component-id="myft-preference-modal-remove">Remove from myFT</button>
50
+ <button className="n-myft-ui__preferences-modal__remove-button" data-component-id="myft-preference-modal-remove" data-trackable="pop-up-box|remove-from-myFT">Remove from myFT</button>
50
51
  </div>
51
52
  </div>
52
53
  );
@@ -41,7 +41,8 @@ function InstantAlertsPreferencesModal(_ref) {
41
41
  {
42
42
  className: 'n-myft-ui__preferences-modal ' + (visible ? 'n-myft-ui__preferences-modal--show' : ''),
43
43
  'data-component-id': 'myft-preferences-modal',
44
- 'data-concept-id': conceptId
44
+ 'data-concept-id': conceptId,
45
+ 'data-o-tracking-view': 'true'
45
46
  },
46
47
  _react2.default.createElement(
47
48
  'div',
@@ -69,13 +70,13 @@ function InstantAlertsPreferencesModal(_ref) {
69
70
  _react2.default.createElement('p', { 'data-component-id': 'myft-preferences-modal-list', className: 'n-myft-ui__preferences-modal__text' }),
70
71
  _react2.default.createElement(
71
72
  'a',
72
- { className: 'n-myft-ui__preferences-modal__text', href: '/myft/alerts' },
73
+ { className: 'n-myft-ui__preferences-modal__text', href: '/myft/alerts', 'data-trackable': 'pop-up-box|contact-preference' },
73
74
  'Manage your preferences here'
74
75
  ),
75
76
  _react2.default.createElement('span', { className: 'n-myft-ui__preferences-modal-error', 'data-component-id': 'myft-preference-modal-error' }),
76
77
  _react2.default.createElement(
77
78
  'button',
78
- { className: 'n-myft-ui__preferences-modal__remove-button', 'data-component-id': 'myft-preference-modal-remove' },
79
+ { className: 'n-myft-ui__preferences-modal__remove-button', 'data-component-id': 'myft-preference-modal-remove', 'data-trackable': 'pop-up-box|remove-from-myFT' },
79
80
  'Remove from myFT'
80
81
  )
81
82
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-myft-ui",
3
- "version": "30.4.3",
3
+ "version": "30.4.4",
4
4
  "description": "Client side component for interaction with myft",
5
5
  "main": "server.js",
6
6
  "scripts": {
@@ -104,6 +104,7 @@
104
104
  "react": "^16.14.0"
105
105
  },
106
106
  "dependencies": {
107
+ "@financial-times/o-tracking": "^4.5.0",
107
108
  "date-fns": "2.16.1",
108
109
  "fetchres": "^1.7.2",
109
110
  "form-serialize": "^0.7.2",
package/secrets.js CHANGED
@@ -6,6 +6,7 @@ module.exports = {
6
6
  '190b4443-dc03-bd53-e79b-b4b6fbd04e64', // segment ID for subscribe URL
7
7
  'ce23dd51-4421-32fc-23df-30099f38f1a4', // segment ID for USG test https://financialtimes.atlassian.net/browse/UG-1191
8
8
  'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', // regex for uuid generator
9
- 'a5676e20-5c92-47f3-a76c-11f9761121f5' // test/navigationAlphaTest.spec.js
9
+ 'a5676e20-5c92-47f3-a76c-11f9761121f5', // test/navigationAlphaTest.spec.js
10
+ '72de123e-5082-11ee-be56-0242ac120002' // components/jsx/preferences-modal/index.js
10
11
  ]
11
12
  };