@financial-times/qanda-ui 0.0.1-beta.25 → 0.0.1-beta.26

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/README.md CHANGED
@@ -94,7 +94,7 @@ import QandaBlock from '@financial-times/qanda-ui';
94
94
  body={body}
95
95
  children={answers}
96
96
  byline={byeline}
97
- subtitle={lorem}
97
+ summary={lorem}
98
98
  />;
99
99
  ```
100
100
 
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("preact/jsx-runtime");
4
4
  const qanda_1 = require("../../config/qanda");
5
+ const tracking_1 = require("../../utils/tracking");
5
6
  function formatDateForIcs(date) {
6
7
  return date.replace(/-|:|\.\d+/g, '');
7
8
  }
@@ -11,7 +12,9 @@ function createIcsFile(title, startDateTime, endDateTime, url) {
11
12
  `.trim();
12
13
  return URL.createObjectURL(new Blob([icsContent], { type: 'title/calendar' }));
13
14
  }
14
- const CalendarLink = ({ href, children, }) => ((0, jsx_runtime_1.jsx)("a", { href: href, target: "_blank", rel: "noopener noreferrer", role: "menuitem", "data-trackable": "liveqa_calendar-link", className: "live-qa-calendar-list__item__link", children: children }));
15
+ const CalendarLink = ({ href, children, }) => {
16
+ return ((0, jsx_runtime_1.jsx)("a", { href: href, target: "_blank", rel: "noopener noreferrer", role: "menuitem", "data-trackable": (0, tracking_1.trackingNS)('calendar-link'), className: "live-qa-calendar-list__item__link", children: children }));
17
+ };
15
18
  function itemChildren(name, icon) {
16
19
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "live-qa-calendar-list__item__icon", children: icon }), (0, jsx_runtime_1.jsx)("span", { className: "live-qa-calendar-list__item__text", children: name })] }));
17
20
  }
@@ -44,6 +47,6 @@ exports.default = apps.map(({ name, icon, getLink, isDownload }) => ({
44
47
  icon,
45
48
  link: ({ title, startDateTime, endDateTime, url, }) => {
46
49
  const href = getLink({ title, startDateTime, endDateTime, url });
47
- return isDownload ? ((0, jsx_runtime_1.jsx)("a", { href: href, download: "event.ics", role: "menuitem", "data-trackable": "liveqa_calendar-link", className: "live-qa-calendar-list__item__link", children: itemChildren(name, icon) })) : ((0, jsx_runtime_1.jsx)(CalendarLink, { href: href, children: itemChildren(name, icon) }));
50
+ return isDownload ? ((0, jsx_runtime_1.jsx)("a", { href: href, download: "event.ics", role: "menuitem", "data-trackable": (0, tracking_1.trackingNS)('calendar-link-download'), className: "live-qa-calendar-list__item__link", children: itemChildren(name, icon) })) : ((0, jsx_runtime_1.jsx)(CalendarLink, { href: href, children: itemChildren(name, icon) }));
48
51
  },
49
52
  }));
@@ -9,6 +9,7 @@ const react_1 = require("react");
9
9
  const CalendarList_1 = __importDefault(require("./CalendarList"));
10
10
  const comments_api_1 = require("../../services/comments-api");
11
11
  const QandaProvider_1 = require("../QandaProvider");
12
+ const tracking_1 = require("../../utils/tracking");
12
13
  function Calendar() {
13
14
  const [dropDownVisible, setDropDownVisible] = (0, react_1.useState)(false);
14
15
  const containerRef = (0, react_1.useRef)(null);
@@ -41,7 +42,7 @@ function Calendar() {
41
42
  'aria-controls': 'menu',
42
43
  id: 'live-qa-calendar-button-menu',
43
44
  'data-testid': 'live-qa-calendar-button',
44
- 'data-trackable': 'liveqa_add-to-calendar-button',
45
+ 'data-trackable': (0, tracking_1.trackingNS)('add-to-calendar-button'),
45
46
  }, onClick: () => setDropDownVisible(!dropDownVisible) }), dropDownVisible && (0, jsx_runtime_1.jsx)(CalendarList_1.default, {})] })) }));
46
47
  }
47
48
  exports.default = Calendar;
@@ -42,10 +42,7 @@ function ErrorMessage({ error, storyId, errorMapping = {}, operation = 'not-spec
42
42
  // Critical operation are tracked by the reliability service using AWS RUM
43
43
  // We still log this to monitor untracked messages to the users.
44
44
  (0, tracking_1.trackEvent)({
45
- category: 'component',
46
- action: 'act',
47
45
  content: {
48
- asset_type: 'article',
49
46
  uuid: storyId,
50
47
  },
51
48
  trigger_action: operation,
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("preact/jsx-runtime");
4
4
  const react_1 = require("react");
5
5
  const o3_button_1 = require("@financial-times/o3-button");
6
+ const tracking_1 = require("../../utils/tracking");
6
7
  // Generic debounce function
7
8
  function debounce(func, delay) {
8
9
  let timerId;
@@ -59,7 +60,7 @@ function Expander({ className = '', children = [], expandLabel = 'Expand', colla
59
60
  const componentClassName = `${expandCollapseClass} ${className}`;
60
61
  return ((0, jsx_runtime_1.jsxs)("div", { className: `${componentClassName}`, children: [(0, jsx_runtime_1.jsx)("div", { className: `expander__text ${requiresExpander ? 'expander__text--multiline' : ''}`, id: expanderContentID, ref: textRef, children: (0, jsx_runtime_1.jsx)(EnsureParagraph, { children: children }) }), requiresExpander && ((0, jsx_runtime_1.jsx)(o3_button_1.Button, { label: label, type: "ghost", theme: "neutral", icon: state === 'expanded' ? 'chevron-up' : 'chevron-down', iconOnly: false, iconPosition: "end", attributes: {
61
62
  className: 'expander__link',
62
- 'data-trackable': `liveqa_expander`,
63
+ 'data-trackable': (0, tracking_1.trackingNS)('expander'),
63
64
  'data-trackable-context-action': label,
64
65
  'aria-expanded': state === 'expanded' ? true : false,
65
66
  'aria-controls': expanderContentID,
@@ -10,6 +10,7 @@ const comments_api_1 = require("../../services/comments-api");
10
10
  const updateComments_1 = require("../../store/updateComments");
11
11
  const react_1 = require("react");
12
12
  const QandaProvider_1 = require("../QandaProvider");
13
+ const tracking_1 = require("../../utils/tracking");
13
14
  function LiveIndicator() {
14
15
  return ((0, jsx_runtime_1.jsx)("div", { className: "o-labels-indicator--live o3-type-label floating-action-bar__live-container", children: (0, jsx_runtime_1.jsx)("span", { className: "o-labels-indicator__status floating-action-bar__live-label", children: "Live" }) }));
15
16
  }
@@ -44,14 +45,14 @@ function FloatingActionBar({ showLiveIndicator = true, }) {
44
45
  dataTrackable: 'open_expert_drawer',
45
46
  };
46
47
  const view = showExpertView ? expertConfig : userConfig;
47
- return ((0, jsx_runtime_1.jsxs)("div", { className: "floating-action-bar__container", "data-trackable": "floating-action-bar", children: [(0, jsx_runtime_1.jsx)("div", { className: "floating-action-bar__fade-overlay" }), (0, jsx_runtime_1.jsxs)("div", { className: "floating-action-bar", "data-testid": "floating-action-bar", children: [showLiveIndicator && (0, jsx_runtime_1.jsx)(LiveIndicator, {}), (0, jsx_runtime_1.jsxs)("div", { className: "floating-action-bar__buttons", children: [(0, jsx_runtime_1.jsx)(o3_button_1.Button, { attributes: {
48
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "floating-action-bar__container", "data-trackable": (0, tracking_1.trackingNS)('floating-action-bar'), children: [(0, jsx_runtime_1.jsx)("div", { className: "floating-action-bar__fade-overlay" }), (0, jsx_runtime_1.jsxs)("div", { className: "floating-action-bar", "data-testid": "floating-action-bar", children: [showLiveIndicator && (0, jsx_runtime_1.jsx)(LiveIndicator, {}), (0, jsx_runtime_1.jsxs)("div", { className: "floating-action-bar__buttons", children: [(0, jsx_runtime_1.jsx)(o3_button_1.Button, { attributes: {
48
49
  ariaLabel: view.descripton,
49
- 'data-trackable': view.dataTrackable,
50
+ 'data-trackable': (0, tracking_1.trackingNS)(view.dataTrackable),
50
51
  'data-trackable-context-action': view.descripton,
51
52
  'data-testid': `floating-action-bar__${view.testIdSuffix}`,
52
53
  }, label: view.descripton, type: "ghost", theme: "mono", icon: "edit", iconOnly: isMobile, onClick: view.onClick }), (0, jsx_runtime_1.jsx)(o3_button_1.Button, { attributes: {
53
54
  ariaLabel: 'Back to top',
54
- 'data-trackable': 'back_to_top',
55
+ 'data-trackable': (0, tracking_1.trackingNS)('back_to_top'),
55
56
  'data-trackable-context-action': 'Back to top',
56
57
  'data-testid': 'floating-action-bar__back-to-top-button',
57
58
  }, label: "Back to top", type: "ghost", theme: "mono", icon: "scroll-to", iconOnly: isMobile, onClick: handleShowUpdates })] }), updatedComments?.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "floating-action-bar__updates-counter o3-type-detail", children: updatedComments.length }))] })] }));
@@ -10,6 +10,7 @@ require("../Expander/index");
10
10
  const index_1 = __importDefault(require("../Expander/index"));
11
11
  const Author_1 = __importDefault(require("../Author"));
12
12
  const react_1 = require("react");
13
+ const tracking_1 = require("../../utils/tracking");
13
14
  function renderTime(publishedDate) {
14
15
  const date = new Date(publishedDate);
15
16
  return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
@@ -23,7 +24,7 @@ function interpolateColor(factor, colorStart = 'ccc1b7', colorEnd = '4d4845', al
23
24
  const alpha = alphaStart + factor * (alphaEnd - alphaStart);
24
25
  return `rgba(${rgb.join(', ')}, ${alpha})`;
25
26
  }
26
- function QandaBlock({ id, body, children, byline, subtitle, showAnswerTime = false, }) {
27
+ function QandaBlock({ id, body, children, byline, summary, showAnswerTime = false, }) {
27
28
  (0, react_1.useEffect)(() => {
28
29
  let currentBubble = null;
29
30
  const factorRef = { current: 0 };
@@ -73,6 +74,6 @@ function QandaBlock({ id, body, children, byline, subtitle, showAnswerTime = fal
73
74
  observer.disconnect();
74
75
  };
75
76
  }, []);
76
- return ((0, jsx_runtime_1.jsxs)("div", { className: "qanda-block", children: [(0, jsx_runtime_1.jsxs)("div", { className: "qanda-block__comment qanda-block__question", id: id, "data-testid": `qanda-block__question-${id}`, "data-trackable": "liveqa_question", children: [subtitle && ((0, jsx_runtime_1.jsx)("div", { className: "o3-type-headline-sm qanda-block__question-subtitle", children: subtitle })), (0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: (0, jsx_runtime_1.jsx)(Byline_1.default, { structuredContent: byline, showEditedBy: false }) }), (0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-base qanda-block__comment-text", children: (0, jsx_runtime_1.jsx)(index_1.default, { className: "qanda-block__text", expandLabel: "Expand question", collapseLabel: "Collapse question", id: id, children: (0, jsx_runtime_1.jsx)(RichText_1.default, { structuredContent: body.structured }) }) })] }, id), children?.map((child) => child.body && ((0, jsx_runtime_1.jsxs)("div", { className: "qanda-block__comment qanda-block__answer", "data-testid": `qanda-block__answer-${child.id}`, "data-trackable": "liveqa_answer", children: [(0, jsx_runtime_1.jsxs)("div", { className: "qanda-block__answer-header", children: [(0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: child.author ? ((0, jsx_runtime_1.jsx)(Author_1.default, { byline: child.byline, headshot: child.author.headshot, prefLabel: child.author.prefLabel, role: child.author.role, streamPage: child.author.streamPage })) : ((0, jsx_runtime_1.jsx)(Byline_1.default, { structuredContent: child.byline, showEditedBy: false })) }), showAnswerTime && ((0, jsx_runtime_1.jsx)("span", { className: "o3-type-detail", children: renderTime(child.publishedDate) }))] }), (0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-base qanda-block__comment-text", children: (0, jsx_runtime_1.jsx)(index_1.default, { className: "qanda-block__text", expandLabel: "Expand answer", collapseLabel: "Collapse answer", id: id, children: (0, jsx_runtime_1.jsx)(RichText_1.default, { structuredContent: child.body.structured }) }) })] }, child.id)))] }));
77
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "qanda-block", children: [(0, jsx_runtime_1.jsxs)("div", { className: "qanda-block__comment qanda-block__question", id: id, "data-testid": `qanda-block__question-${id}`, "data-trackable": (0, tracking_1.trackingNS)('question'), children: [summary && ((0, jsx_runtime_1.jsx)("div", { className: "o3-type-headline-sm qanda-block__question-summary", children: summary })), (0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: (0, jsx_runtime_1.jsx)(Byline_1.default, { structuredContent: byline, showEditedBy: false }) }), (0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-base qanda-block__comment-text", children: (0, jsx_runtime_1.jsx)(index_1.default, { className: "qanda-block__text", expandLabel: "Expand question", collapseLabel: "Collapse question", id: id, children: (0, jsx_runtime_1.jsx)(RichText_1.default, { structuredContent: body.structured }) }) })] }, id), children?.map((child) => child.body && ((0, jsx_runtime_1.jsxs)("div", { className: "qanda-block__comment qanda-block__answer", "data-testid": `qanda-block__answer-${child.id}`, "data-trackable": (0, tracking_1.trackingNS)('answer'), children: [(0, jsx_runtime_1.jsxs)("div", { className: "qanda-block__answer-header", children: [(0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: child.author ? ((0, jsx_runtime_1.jsx)(Author_1.default, { byline: child.byline, headshot: child.author.headshot, prefLabel: child.author.prefLabel, role: child.author.role, streamPage: child.author.streamPage })) : ((0, jsx_runtime_1.jsx)(Byline_1.default, { structuredContent: child.byline, showEditedBy: false })) }), showAnswerTime && ((0, jsx_runtime_1.jsx)("span", { className: "o3-type-detail", children: renderTime(child.publishedDate) }))] }), (0, jsx_runtime_1.jsx)("div", { className: "o3-type-body-base qanda-block__comment-text", children: (0, jsx_runtime_1.jsx)(index_1.default, { className: "qanda-block__text", expandLabel: "Expand answer", collapseLabel: "Collapse answer", id: id, children: (0, jsx_runtime_1.jsx)(RichText_1.default, { structuredContent: child.body.structured }) }) })] }, child.id)))] }));
77
78
  }
78
79
  exports.default = QandaBlock;
@@ -20,10 +20,10 @@ const QandaProvider_1 = require("./QandaProvider");
20
20
  const o_tracking_1 = __importDefault(require("@financial-times/o-tracking"));
21
21
  const comments_api_1 = require("../services/comments-api");
22
22
  const qanda_1 = require("../config/qanda");
23
+ const tracking_1 = require("../utils/tracking");
23
24
  function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
24
25
  const { storyId, useStaging, commentsAPIUrl } = (0, react_1.useContext)(QandaProvider_1.QandaContext);
25
26
  const dispatch = (0, react_redux_1.useDispatch)();
26
- const [liveMessage, setLiveMessage] = (0, react_1.useState)('');
27
27
  const { data, error, isLoading } = (0, comments_api_1.useGetQandAStreamQuery)({
28
28
  storyId,
29
29
  useStaging,
@@ -76,15 +76,7 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
76
76
  selector: '.qanda-container',
77
77
  getContextData: () => {
78
78
  return {
79
- component: {
80
- name: 'liveqa',
81
- type: 'container',
82
- id: '663ab2ca-77ca-4b50-873d-1fd2ff21ff08',
83
- },
84
- content: {
85
- asset_type: 'article',
86
- uuid: storyId,
87
- },
79
+ ...tracking_1.baseTrackingData,
88
80
  custom: [
89
81
  {
90
82
  name: 'status',
@@ -95,6 +87,6 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
95
87
  },
96
88
  });
97
89
  }, [data, status]);
98
- return ((0, jsx_runtime_1.jsxs)("div", { className: "qanda-container", "data-trackable": "liveqa", children: [error && ((0, jsx_runtime_1.jsxs)("p", { children: ["We are not able to load ", qanda_1.PRODUCT_NAME, " at the moment. Please try again later. Error:", error] })), !isLoading && !error && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [status !== 'close' && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showExpertView ? (0, jsx_runtime_1.jsx)(ExpertDrawer_1.default, {}) : (0, jsx_runtime_1.jsx)(QuestionForm_1.default, {}), (0, jsx_runtime_1.jsx)(CountdownTimer_1.default, { container: countdownTimerContainer })] })), status === 'pre-live' && (0, jsx_runtime_1.jsx)(Calendar_1.default, {}), (0, jsx_runtime_1.jsx)(Stream_1.default, { status: status }), (0, jsx_runtime_1.jsx)(Survey_1.default, { storyId: storyId, status: status }), (status === 'live' || (status === 'pre-live' && showExpertView)) && ((0, jsx_runtime_1.jsx)(FloatingActionBar_1.default, { showLiveIndicator: status === 'live' })), status !== 'close' && !showExpertView && ((0, jsx_runtime_1.jsx)(EmbedFormField_1.default, { container: embedFormFieldContainer }))] })), (0, jsx_runtime_1.jsx)("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
90
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "qanda-container", children: [error && ((0, jsx_runtime_1.jsxs)("p", { children: ["We are not able to load ", qanda_1.PRODUCT_NAME, " at the moment. Please try again later. Error:", error] })), !isLoading && !error && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [status !== 'close' && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showExpertView ? (0, jsx_runtime_1.jsx)(ExpertDrawer_1.default, {}) : (0, jsx_runtime_1.jsx)(QuestionForm_1.default, {}), (0, jsx_runtime_1.jsx)(CountdownTimer_1.default, { container: countdownTimerContainer })] })), status === 'pre-live' && (0, jsx_runtime_1.jsx)(Calendar_1.default, {}), (0, jsx_runtime_1.jsx)(Stream_1.default, { status: status }), (0, jsx_runtime_1.jsx)(Survey_1.default, { storyId: storyId, status: status }), (status === 'live' || (status === 'pre-live' && showExpertView)) && ((0, jsx_runtime_1.jsx)(FloatingActionBar_1.default, { showLiveIndicator: status === 'live' })), status !== 'close' && !showExpertView && ((0, jsx_runtime_1.jsx)(EmbedFormField_1.default, { container: embedFormFieldContainer }))] })), (0, jsx_runtime_1.jsx)("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
99
91
  }
100
92
  exports.default = QandaContainer;
@@ -78,8 +78,9 @@ function QuestionForm() {
78
78
  if (updatedProfile?.displayName) {
79
79
  // NB: we are using a component act event as analytics team can only support existing categories and actions at this time
80
80
  (0, tracking_1.trackEvent)({
81
- category: 'component',
82
- action: 'act',
81
+ content: {
82
+ uuid: storyId,
83
+ },
83
84
  trigger_action: 'success_set_displayname',
84
85
  });
85
86
  }
@@ -113,13 +114,13 @@ function QuestionForm() {
113
114
  (0, jsx_runtime_1.jsxs)(Overlay_1.default, { title: "Ask a question", closeCallback: () => {
114
115
  setNewDisplayName(null);
115
116
  dispatch((0, questionSlice_1.closeForm)());
116
- }, children: [profile.isSubscribed && ((0, jsx_runtime_1.jsx)("div", { className: "overlay__content-box overlay__form-box", "data-testid": "question-form-overlay", children: (0, jsx_runtime_1.jsxs)("form", { onSubmit: handleSubmit, "data-trackable": `liveqa_submit_question_form_${postAnonymously ? 'anonymous' : 'displayname'}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "overlay__user-container", children: [!postAnonymously && profile?.displayName && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)("span", { className: "overlay__user-container-display-name o3-type-body-highlight", children: [(0, jsx_runtime_1.jsx)("i", { className: "overlay__message-icon", style: { maskImage: 'var(--o3-icon-user)' } }), profile.displayName] }) })), !profile?.displayName && ((0, jsx_runtime_1.jsxs)("label", { for: "display-name", className: "question-form__displayname-input o-forms-field", children: [(0, jsx_runtime_1.jsx)("span", { className: "o-forms-title", children: (0, jsx_runtime_1.jsx)("span", { className: "o3-type-body-highlight", children: "Choose a display name" }) }), (0, jsx_runtime_1.jsxs)("span", { className: (0, classnames_1.default)([
117
+ }, children: [profile.isSubscribed && ((0, jsx_runtime_1.jsx)("div", { className: "overlay__content-box overlay__form-box", "data-testid": "question-form-overlay", children: (0, jsx_runtime_1.jsxs)("form", { onSubmit: handleSubmit, "data-trackable": (0, tracking_1.trackingNS)(`submit_question_form_${postAnonymously ? 'anonymous' : 'displayname'}`), children: [(0, jsx_runtime_1.jsxs)("div", { className: "overlay__user-container", children: [!postAnonymously && profile?.displayName && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)("span", { className: "overlay__user-container-display-name o3-type-body-highlight", children: [(0, jsx_runtime_1.jsx)("i", { className: "overlay__message-icon", style: { maskImage: 'var(--o3-icon-user)' } }), profile.displayName] }) })), !profile?.displayName && ((0, jsx_runtime_1.jsxs)("label", { for: "display-name", className: "question-form__displayname-input o-forms-field", children: [(0, jsx_runtime_1.jsx)("span", { className: "o-forms-title", children: (0, jsx_runtime_1.jsx)("span", { className: "o3-type-body-highlight", children: "Choose a display name" }) }), (0, jsx_runtime_1.jsxs)("span", { className: (0, classnames_1.default)([
117
118
  'question-form__displayname__input',
118
119
  'o-forms-input',
119
120
  'o-forms-input--text',
120
121
  { 'o-forms-input--invalid': !!displayNameError },
121
122
  ]), children: [(0, jsx_runtime_1.jsx)("input", { className: "question-form__displayname__input__field o3-type-body-lg", id: "display-name", value: newDisplayName || '', onChange: (e) => setNewDisplayName(e.currentTarget.value), type: postAnonymously ? 'password' : 'text', "aria-invalid": displayNameError ? 'true' : 'false', "aria-errormessage": displayNameError ??
122
- 'question_form__displayname-error-message' }), displayNameError && ((0, jsx_runtime_1.jsx)("span", { className: "question-form__displayname__input__error o3-type-detail", id: "question_form__displayname-error-message", children: (0, jsx_runtime_1.jsx)("span", { children: displayNameError }) }))] })] }))] }), (0, jsx_runtime_1.jsx)("div", { className: "o-forms-field", children: (0, jsx_runtime_1.jsxs)("label", { className: "o-forms-input o-forms-input--checkbox", htmlFor: "post-anonymously", children: [(0, jsx_runtime_1.jsx)("input", { type: "checkbox", name: "post-anonymously", id: "post-anonymously", value: "true", onChange: handleHideDisplayName, "data-trackable-context-action": `Post anonymously ${postAnonymously ? 'off' : 'on'}`, "data-trackable": `question-form__post_anonymously-${postAnonymously ? 'off' : 'on'}` }), (0, jsx_runtime_1.jsx)("span", { className: "o-forms-input__label", children: "Post anonymously (optional)" })] }) }), (0, jsx_runtime_1.jsxs)("label", { for: "question-text", class: "o-forms-field question-form__question__input", children: [(0, jsx_runtime_1.jsx)("span", { class: "o-forms-title", children: (0, jsx_runtime_1.jsx)("span", { class: "o3-type-body-highlight", children: "Enter your question" }) }), (0, jsx_runtime_1.jsx)("span", { class: "o-forms-input o-forms-input--textarea", children: (0, jsx_runtime_1.jsx)("textarea", { id: "question-text", name: "question", value: question, onChange: (e) => dispatch((0, questionSlice_1.updateQuestion)(e.currentTarget.value)), "aria-label": "Your question", placeholder: "Type your question", maxLength: maxQuestionLength, "aria-invalid": error ? 'true' : undefined, "aria-errormessage": "question-form-error-message" }) })] }), (0, jsx_runtime_1.jsx)("span", { className: "o3-type-detail", children: "Questions must be at least 20 characters long." }), (0, jsx_runtime_1.jsx)(o3_button_1.Button, { attributes: {
123
+ 'question_form__displayname-error-message' }), displayNameError && ((0, jsx_runtime_1.jsx)("span", { className: "question-form__displayname__input__error o3-type-detail", id: "question_form__displayname-error-message", children: (0, jsx_runtime_1.jsx)("span", { children: displayNameError }) }))] })] }))] }), (0, jsx_runtime_1.jsx)("div", { className: "o-forms-field", children: (0, jsx_runtime_1.jsxs)("label", { className: "o-forms-input o-forms-input--checkbox", htmlFor: "post-anonymously", children: [(0, jsx_runtime_1.jsx)("input", { type: "checkbox", name: "post-anonymously", id: "post-anonymously", value: "true", onChange: handleHideDisplayName, "data-trackable-context-action": `Post anonymously ${postAnonymously ? 'off' : 'on'}`, "data-trackable": (0, tracking_1.trackingNS)(`question-form__post_anonymously-${postAnonymously ? 'off' : 'on'}`) }), (0, jsx_runtime_1.jsx)("span", { className: "o-forms-input__label", children: "Post anonymously (optional)" })] }) }), (0, jsx_runtime_1.jsxs)("label", { for: "question-text", class: "o-forms-field question-form__question__input", children: [(0, jsx_runtime_1.jsx)("span", { class: "o-forms-title", children: (0, jsx_runtime_1.jsx)("span", { class: "o3-type-body-highlight", children: "Enter your question" }) }), (0, jsx_runtime_1.jsx)("span", { class: "o-forms-input o-forms-input--textarea", children: (0, jsx_runtime_1.jsx)("textarea", { id: "question-text", name: "question", value: question, onChange: (e) => dispatch((0, questionSlice_1.updateQuestion)(e.currentTarget.value)), "aria-label": "Your question", placeholder: "Type your question", maxLength: maxQuestionLength, "aria-invalid": error ? 'true' : undefined, "aria-errormessage": "question-form-error-message" }) })] }), (0, jsx_runtime_1.jsx)("span", { className: "o3-type-detail", children: "Questions must be at least 20 characters long." }), (0, jsx_runtime_1.jsx)(o3_button_1.Button, { attributes: {
123
124
  className: 'overlay__submit-button',
124
125
  type: 'submit',
125
126
  disabled: !submitEnabled,
@@ -5,6 +5,7 @@ exports.getTitleByUser = getTitleByUser;
5
5
  exports.getTextByUser = getTextByUser;
6
6
  const jsx_runtime_1 = require("preact/jsx-runtime");
7
7
  const qanda_1 = require("../../config/qanda");
8
+ const tracking_1 = require("../../utils/tracking");
8
9
  exports.SIGN_IN_URL = 'https://www.ft.com/login';
9
10
  exports.SUBSCRIBE_URL = 'https://subs.ft.com/products';
10
11
  exports.COMMUNITY_GUIDELINES_URL = 'https://help.ft.com/help/article-queries/commenting-on-an-article/commenting-guidelines';
@@ -21,14 +22,14 @@ function getTitleByUser(profile) {
21
22
  }
22
23
  function getTextByUser(profile) {
23
24
  if (profile.isSubscribed) {
24
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Keep your comments respectful and easy to understand for our global audience. By submitting, you agree to follow our", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": "question-form__community-guidelines", "data-trackable-context-action": "Community guidelines", href: exports.COMMUNITY_GUIDELINES_URL, target: "_parent", children: "community guidelines" }), ' ', "and", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": "question-form__terms-and-conditions", "data-trackable-context-action": "Terms and conditions", href: exports.TERMS_AND_CONDITIONS_URL, target: "_parent", children: "terms" }), "."] }));
25
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Keep your comments respectful and easy to understand for our global audience. By submitting, you agree to follow our", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": (0, tracking_1.trackingNS)('question-form__community-guidelines'), "data-trackable-context-action": "Community guidelines", href: exports.COMMUNITY_GUIDELINES_URL, target: "_parent", children: "community guidelines" }), ' ', "and", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": (0, tracking_1.trackingNS)('question-form__terms-and-conditions'), "data-trackable-context-action": "Terms and conditions", href: exports.TERMS_AND_CONDITIONS_URL, target: "_parent", children: "terms" }), "."] }));
25
26
  }
26
27
  if (profile.isTrialist) {
27
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["View our full", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": "question-form__subscribe-trialist", "data-trackable-context-action": "Subscribe", href: exports.SUBSCRIBE_URL, target: "_parent", children: "subscription packages" }), ' ', "to join the conversation."] }));
28
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["View our full", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": (0, tracking_1.trackingNS)('question-form__subscribe-trialist'), "data-trackable-context-action": "Subscribe", href: exports.SUBSCRIBE_URL, target: "_parent", children: "subscription packages" }), ' ', "to join the conversation."] }));
28
29
  }
29
30
  if (profile.isRegistered) {
30
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": "question-form__subscribe-registered", "data-trackable-context-action": "Subscribe", href: exports.SUBSCRIBE_URL, target: "_parent", children: "Subscribe" }), ' ', "to join the conversation."] }));
31
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": (0, tracking_1.trackingNS)('question-form__subscribe-registered'), "data-trackable-context-action": "Subscribe", href: exports.SUBSCRIBE_URL, target: "_parent", children: "Subscribe" }), ' ', "to join the conversation."] }));
31
32
  }
32
33
  // Anonymous users
33
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Please", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": "question-form__sign-in-anonymous", "data-trackable-context-action": "Sign in", href: exports.SIGN_IN_URL, target: "_parent", children: "sign in" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": "question-form__subscribe-anonymous", "data-trackable-context-action": "Subscribe", href: exports.SUBSCRIBE_URL, target: "_parent", children: "subscribe" }), ' ', "to join the conversation."] }));
34
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Please", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": (0, tracking_1.trackingNS)('question-form__sign-in-anonymous'), "data-trackable-context-action": "Sign in", href: exports.SIGN_IN_URL, target: "_parent", children: "sign in" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)("a", { className: "message-box__content-link", "data-trackable": (0, tracking_1.trackingNS)('question-form__subscribe-anonymous'), "data-trackable-context-action": "Subscribe", href: exports.SUBSCRIBE_URL, target: "_parent", children: "subscribe" }), ' ', "to join the conversation."] }));
34
35
  }
@@ -1,36 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("preact/jsx-runtime");
4
+ const tracking_1 = require("../../utils/tracking");
4
5
  function Survey({ storyId, status }) {
5
- const trackEvent = (trackingData) => {
6
- const event = new CustomEvent('oTracking.event', {
7
- detail: trackingData,
8
- bubbles: true,
9
- });
10
- document.body.dispatchEvent(event);
11
- };
12
- const handleClick = () => {
13
- trackEvent({
14
- category: 'component',
15
- component: {
16
- name: 'liveqa',
17
- type: 'container',
18
- id: '663ab2ca-77ca-4b50-873d-1fd2ff21ff08',
19
- },
20
- action: 'act',
21
- trigger_action: 'liveqa_survey_open',
22
- content: {
23
- asset_type: 'article',
24
- uuid: storyId,
25
- },
26
- custom: [
27
- {
28
- name: 'status',
29
- value: status,
30
- },
31
- ],
32
- });
33
- };
34
- return ((0, jsx_runtime_1.jsx)("div", { className: "o-message o-message--action o-message--inform o-message--survey", style: { marginBottom: 'var(--o3-spacing-l)' }, "data-o-message-close": "false", "data-o-component": "o-message", children: (0, jsx_runtime_1.jsx)("div", { className: "o-message__container", children: (0, jsx_runtime_1.jsxs)("div", { className: "o-message__content", children: [(0, jsx_runtime_1.jsx)("p", { className: "o-message__content-main", style: { fontSize: 'var(--o3-type-body-base-font-size)' }, children: "How was your experience?" }), (0, jsx_runtime_1.jsx)("div", { className: "o-message__actions", children: (0, jsx_runtime_1.jsx)("a", { href: `https://www.feedback.ft.com/c/a/6HTDVvrHSyaKLZ5281McAo?content_id=${storyId}&qa_status=${status}`, onClick: handleClick, className: "o-message__actions__primary", "data-trackable": "liveqa_survey_link", children: "Share your feedback" }) })] }) }) }));
6
+ return ((0, jsx_runtime_1.jsx)("div", { className: "o-message o-message--action o-message--inform o-message--survey", style: { marginBottom: 'var(--o3-spacing-l)' }, "data-o-message-close": "false", "data-o-component": "o-message", children: (0, jsx_runtime_1.jsx)("div", { className: "o-message__container", children: (0, jsx_runtime_1.jsxs)("div", { className: "o-message__content", children: [(0, jsx_runtime_1.jsx)("p", { className: "o-message__content-main", style: { fontSize: 'var(--o3-type-body-base-font-size)' }, children: "How was your experience?" }), (0, jsx_runtime_1.jsx)("div", { className: "o-message__actions", children: (0, jsx_runtime_1.jsx)("a", { href: `https://www.feedback.ft.com/c/a/6HTDVvrHSyaKLZ5281McAo?content_id=${storyId}&qa_status=${status}`, className: "o-message__actions__primary", "data-trackable": (0, tracking_1.trackingNS)('survey_link'), children: "Share your feedback" }) })] }) }) }));
35
7
  }
36
8
  exports.default = Survey;
@@ -1,7 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.trackEvent = void 0;
4
- const trackEvent = (trackingData) => {
3
+ exports.trackEvent = exports.baseTrackingData = void 0;
4
+ exports.trackingNS = trackingNS;
5
+ const trackingNamespace = 'askanexpert_';
6
+ function trackingNS(string) {
7
+ return trackingNamespace + string;
8
+ }
9
+ exports.baseTrackingData = {
10
+ category: 'component',
11
+ action: 'act',
12
+ component: {
13
+ name: 'askanexpert',
14
+ type: 'container',
15
+ id: '663ab2ca-77ca-4b50-873d-1fd2ff21ff08',
16
+ },
17
+ content: {
18
+ asset_type: 'article',
19
+ },
20
+ };
21
+ const trackEvent = (customTrackingData) => {
22
+ // Merge the base tracking data with the provided tracking data
23
+ const trackingData = {
24
+ ...exports.baseTrackingData,
25
+ ...customTrackingData,
26
+ trigger_action: trackingNamespace + customTrackingData.trigger_action,
27
+ };
5
28
  const event = new CustomEvent('oTracking.event', {
6
29
  detail: trackingData,
7
30
  bubbles: true,
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "preact/jsx-runtime";
2
2
  import { PRODUCT_NAME } from '../../config/qanda';
3
+ import { trackingNS } from '../../utils/tracking';
3
4
  function formatDateForIcs(date) {
4
5
  return date.replace(/-|:|\.\d+/g, '');
5
6
  }
@@ -9,7 +10,9 @@ function createIcsFile(title, startDateTime, endDateTime, url) {
9
10
  `.trim();
10
11
  return URL.createObjectURL(new Blob([icsContent], { type: 'title/calendar' }));
11
12
  }
12
- const CalendarLink = ({ href, children, }) => (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", role: "menuitem", "data-trackable": "liveqa_calendar-link", className: "live-qa-calendar-list__item__link", children: children }));
13
+ const CalendarLink = ({ href, children, }) => {
14
+ return (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", role: "menuitem", "data-trackable": trackingNS('calendar-link'), className: "live-qa-calendar-list__item__link", children: children }));
15
+ };
13
16
  function itemChildren(name, icon) {
14
17
  return (_jsxs(_Fragment, { children: [_jsx("span", { className: "live-qa-calendar-list__item__icon", children: icon }), _jsx("span", { className: "live-qa-calendar-list__item__text", children: name })] }));
15
18
  }
@@ -42,6 +45,6 @@ export default apps.map(({ name, icon, getLink, isDownload }) => ({
42
45
  icon,
43
46
  link: ({ title, startDateTime, endDateTime, url, }) => {
44
47
  const href = getLink({ title, startDateTime, endDateTime, url });
45
- return isDownload ? (_jsx("a", { href: href, download: "event.ics", role: "menuitem", "data-trackable": "liveqa_calendar-link", className: "live-qa-calendar-list__item__link", children: itemChildren(name, icon) })) : (_jsx(CalendarLink, { href: href, children: itemChildren(name, icon) }));
48
+ return isDownload ? (_jsx("a", { href: href, download: "event.ics", role: "menuitem", "data-trackable": trackingNS('calendar-link-download'), className: "live-qa-calendar-list__item__link", children: itemChildren(name, icon) })) : (_jsx(CalendarLink, { href: href, children: itemChildren(name, icon) }));
46
49
  },
47
50
  }));
@@ -4,6 +4,7 @@ import { useState, useRef, useEffect, useContext } from 'react';
4
4
  import CalendarList from './CalendarList';
5
5
  import { useGetQandAStreamQuery } from '../../services/comments-api';
6
6
  import { QandaContext } from '../QandaProvider';
7
+ import { trackingNS } from '../../utils/tracking';
7
8
  function Calendar() {
8
9
  const [dropDownVisible, setDropDownVisible] = useState(false);
9
10
  const containerRef = useRef(null);
@@ -36,7 +37,7 @@ function Calendar() {
36
37
  'aria-controls': 'menu',
37
38
  id: 'live-qa-calendar-button-menu',
38
39
  'data-testid': 'live-qa-calendar-button',
39
- 'data-trackable': 'liveqa_add-to-calendar-button',
40
+ 'data-trackable': trackingNS('add-to-calendar-button'),
40
41
  }, onClick: () => setDropDownVisible(!dropDownVisible) }), dropDownVisible && _jsx(CalendarList, {})] })) }));
41
42
  }
42
43
  export default Calendar;
@@ -36,10 +36,7 @@ export default function ErrorMessage({ error, storyId, errorMapping = {}, operat
36
36
  // Critical operation are tracked by the reliability service using AWS RUM
37
37
  // We still log this to monitor untracked messages to the users.
38
38
  trackEvent({
39
- category: 'component',
40
- action: 'act',
41
39
  content: {
42
- asset_type: 'article',
43
40
  uuid: storyId,
44
41
  },
45
42
  trigger_action: operation,
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
2
  import { useState, useRef, useEffect } from 'react';
3
3
  import { Button } from '@financial-times/o3-button';
4
+ import { trackingNS } from '../../utils/tracking';
4
5
  // Generic debounce function
5
6
  function debounce(func, delay) {
6
7
  let timerId;
@@ -57,7 +58,7 @@ function Expander({ className = '', children = [], expandLabel = 'Expand', colla
57
58
  const componentClassName = `${expandCollapseClass} ${className}`;
58
59
  return (_jsxs("div", { className: `${componentClassName}`, children: [_jsx("div", { className: `expander__text ${requiresExpander ? 'expander__text--multiline' : ''}`, id: expanderContentID, ref: textRef, children: _jsx(EnsureParagraph, { children: children }) }), requiresExpander && (_jsx(Button, { label: label, type: "ghost", theme: "neutral", icon: state === 'expanded' ? 'chevron-up' : 'chevron-down', iconOnly: false, iconPosition: "end", attributes: {
59
60
  className: 'expander__link',
60
- 'data-trackable': `liveqa_expander`,
61
+ 'data-trackable': trackingNS('expander'),
61
62
  'data-trackable-context-action': label,
62
63
  'aria-expanded': state === 'expanded' ? true : false,
63
64
  'aria-controls': expanderContentID,
@@ -8,6 +8,7 @@ import { useUpdatedComments } from '../../services/comments-api';
8
8
  import { updateComments } from '../../store/updateComments';
9
9
  import { useContext } from 'react';
10
10
  import { QandaContext } from '../QandaProvider';
11
+ import { trackingNS } from '../../utils/tracking';
11
12
  function LiveIndicator() {
12
13
  return (_jsx("div", { className: "o-labels-indicator--live o3-type-label floating-action-bar__live-container", children: _jsx("span", { className: "o-labels-indicator__status floating-action-bar__live-label", children: "Live" }) }));
13
14
  }
@@ -42,14 +43,14 @@ function FloatingActionBar({ showLiveIndicator = true, }) {
42
43
  dataTrackable: 'open_expert_drawer',
43
44
  };
44
45
  const view = showExpertView ? expertConfig : userConfig;
45
- return (_jsxs("div", { className: "floating-action-bar__container", "data-trackable": "floating-action-bar", children: [_jsx("div", { className: "floating-action-bar__fade-overlay" }), _jsxs("div", { className: "floating-action-bar", "data-testid": "floating-action-bar", children: [showLiveIndicator && _jsx(LiveIndicator, {}), _jsxs("div", { className: "floating-action-bar__buttons", children: [_jsx(Button, { attributes: {
46
+ return (_jsxs("div", { className: "floating-action-bar__container", "data-trackable": trackingNS('floating-action-bar'), children: [_jsx("div", { className: "floating-action-bar__fade-overlay" }), _jsxs("div", { className: "floating-action-bar", "data-testid": "floating-action-bar", children: [showLiveIndicator && _jsx(LiveIndicator, {}), _jsxs("div", { className: "floating-action-bar__buttons", children: [_jsx(Button, { attributes: {
46
47
  ariaLabel: view.descripton,
47
- 'data-trackable': view.dataTrackable,
48
+ 'data-trackable': trackingNS(view.dataTrackable),
48
49
  'data-trackable-context-action': view.descripton,
49
50
  'data-testid': `floating-action-bar__${view.testIdSuffix}`,
50
51
  }, label: view.descripton, type: "ghost", theme: "mono", icon: "edit", iconOnly: isMobile, onClick: view.onClick }), _jsx(Button, { attributes: {
51
52
  ariaLabel: 'Back to top',
52
- 'data-trackable': 'back_to_top',
53
+ 'data-trackable': trackingNS('back_to_top'),
53
54
  'data-trackable-context-action': 'Back to top',
54
55
  'data-testid': 'floating-action-bar__back-to-top-button',
55
56
  }, label: "Back to top", type: "ghost", theme: "mono", icon: "scroll-to", iconOnly: isMobile, onClick: handleShowUpdates })] }), updatedComments?.length > 0 && (_jsx("div", { className: "floating-action-bar__updates-counter o3-type-detail", children: updatedComments.length }))] })] }));
@@ -5,6 +5,7 @@ import '../Expander/index';
5
5
  import Expander from '../Expander/index';
6
6
  import Author from '../Author';
7
7
  import { useEffect } from 'react';
8
+ import { trackingNS } from '../../utils/tracking';
8
9
  function renderTime(publishedDate) {
9
10
  const date = new Date(publishedDate);
10
11
  return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
@@ -18,7 +19,7 @@ function interpolateColor(factor, colorStart = 'ccc1b7', colorEnd = '4d4845', al
18
19
  const alpha = alphaStart + factor * (alphaEnd - alphaStart);
19
20
  return `rgba(${rgb.join(', ')}, ${alpha})`;
20
21
  }
21
- function QandaBlock({ id, body, children, byline, subtitle, showAnswerTime = false, }) {
22
+ function QandaBlock({ id, body, children, byline, summary, showAnswerTime = false, }) {
22
23
  useEffect(() => {
23
24
  let currentBubble = null;
24
25
  const factorRef = { current: 0 };
@@ -68,6 +69,6 @@ function QandaBlock({ id, body, children, byline, subtitle, showAnswerTime = fal
68
69
  observer.disconnect();
69
70
  };
70
71
  }, []);
71
- return (_jsxs("div", { className: "qanda-block", children: [_jsxs("div", { className: "qanda-block__comment qanda-block__question", id: id, "data-testid": `qanda-block__question-${id}`, "data-trackable": "liveqa_question", children: [subtitle && (_jsx("div", { className: "o3-type-headline-sm qanda-block__question-subtitle", children: subtitle })), _jsx("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: _jsx(Byline, { structuredContent: byline, showEditedBy: false }) }), _jsx("div", { className: "o3-type-body-base qanda-block__comment-text", children: _jsx(Expander, { className: "qanda-block__text", expandLabel: "Expand question", collapseLabel: "Collapse question", id: id, children: _jsx(RichText, { structuredContent: body.structured }) }) })] }, id), children?.map((child) => child.body && (_jsxs("div", { className: "qanda-block__comment qanda-block__answer", "data-testid": `qanda-block__answer-${child.id}`, "data-trackable": "liveqa_answer", children: [_jsxs("div", { className: "qanda-block__answer-header", children: [_jsx("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: child.author ? (_jsx(Author, { byline: child.byline, headshot: child.author.headshot, prefLabel: child.author.prefLabel, role: child.author.role, streamPage: child.author.streamPage })) : (_jsx(Byline, { structuredContent: child.byline, showEditedBy: false })) }), showAnswerTime && (_jsx("span", { className: "o3-type-detail", children: renderTime(child.publishedDate) }))] }), _jsx("div", { className: "o3-type-body-base qanda-block__comment-text", children: _jsx(Expander, { className: "qanda-block__text", expandLabel: "Expand answer", collapseLabel: "Collapse answer", id: id, children: _jsx(RichText, { structuredContent: child.body.structured }) }) })] }, child.id)))] }));
72
+ return (_jsxs("div", { className: "qanda-block", children: [_jsxs("div", { className: "qanda-block__comment qanda-block__question", id: id, "data-testid": `qanda-block__question-${id}`, "data-trackable": trackingNS('question'), children: [summary && (_jsx("div", { className: "o3-type-headline-sm qanda-block__question-summary", children: summary })), _jsx("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: _jsx(Byline, { structuredContent: byline, showEditedBy: false }) }), _jsx("div", { className: "o3-type-body-base qanda-block__comment-text", children: _jsx(Expander, { className: "qanda-block__text", expandLabel: "Expand question", collapseLabel: "Collapse question", id: id, children: _jsx(RichText, { structuredContent: body.structured }) }) })] }, id), children?.map((child) => child.body && (_jsxs("div", { className: "qanda-block__comment qanda-block__answer", "data-testid": `qanda-block__answer-${child.id}`, "data-trackable": trackingNS('answer'), children: [_jsxs("div", { className: "qanda-block__answer-header", children: [_jsx("div", { className: "o3-type-body-highlight qanda-block__comment-byline", children: child.author ? (_jsx(Author, { byline: child.byline, headshot: child.author.headshot, prefLabel: child.author.prefLabel, role: child.author.role, streamPage: child.author.streamPage })) : (_jsx(Byline, { structuredContent: child.byline, showEditedBy: false })) }), showAnswerTime && (_jsx("span", { className: "o3-type-detail", children: renderTime(child.publishedDate) }))] }), _jsx("div", { className: "o3-type-body-base qanda-block__comment-text", children: _jsx(Expander, { className: "qanda-block__text", expandLabel: "Expand answer", collapseLabel: "Collapse answer", id: id, children: _jsx(RichText, { structuredContent: child.body.structured }) }) })] }, child.id)))] }));
72
73
  }
73
74
  export default QandaBlock;
@@ -15,10 +15,10 @@ import { QandaContext } from './QandaProvider';
15
15
  import oTracking from '@financial-times/o-tracking';
16
16
  import { useGetQandAStreamQuery, useUpdatedQA, useGetUserRolesQuery, nextCommentsApi, } from '../services/comments-api';
17
17
  import { PRODUCT_NAME } from '../config/qanda';
18
+ import { baseTrackingData } from '../utils/tracking';
18
19
  function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
19
20
  const { storyId, useStaging, commentsAPIUrl } = useContext(QandaContext);
20
21
  const dispatch = useDispatch();
21
- const [liveMessage, setLiveMessage] = useState('');
22
22
  const { data, error, isLoading } = useGetQandAStreamQuery({
23
23
  storyId,
24
24
  useStaging,
@@ -71,15 +71,7 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
71
71
  selector: '.qanda-container',
72
72
  getContextData: () => {
73
73
  return {
74
- component: {
75
- name: 'liveqa',
76
- type: 'container',
77
- id: '663ab2ca-77ca-4b50-873d-1fd2ff21ff08',
78
- },
79
- content: {
80
- asset_type: 'article',
81
- uuid: storyId,
82
- },
74
+ ...baseTrackingData,
83
75
  custom: [
84
76
  {
85
77
  name: 'status',
@@ -90,6 +82,6 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
90
82
  },
91
83
  });
92
84
  }, [data, status]);
93
- return (_jsxs("div", { className: "qanda-container", "data-trackable": "liveqa", children: [error && (_jsxs("p", { children: ["We are not able to load ", PRODUCT_NAME, " at the moment. Please try again later. Error:", error] })), !isLoading && !error && (_jsxs(_Fragment, { children: [status !== 'close' && (_jsxs(_Fragment, { children: [showExpertView ? _jsx(ExpertDrawer, {}) : _jsx(QuestionForm, {}), _jsx(CountdownTimer, { container: countdownTimerContainer })] })), status === 'pre-live' && _jsx(Calendar, {}), _jsx(Stream, { status: status }), _jsx(Survey, { storyId: storyId, status: status }), (status === 'live' || (status === 'pre-live' && showExpertView)) && (_jsx(FloatingActionBar, { showLiveIndicator: status === 'live' })), status !== 'close' && !showExpertView && (_jsx(EmbedFormField, { container: embedFormFieldContainer }))] })), _jsx("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
85
+ return (_jsxs("div", { className: "qanda-container", children: [error && (_jsxs("p", { children: ["We are not able to load ", PRODUCT_NAME, " at the moment. Please try again later. Error:", error] })), !isLoading && !error && (_jsxs(_Fragment, { children: [status !== 'close' && (_jsxs(_Fragment, { children: [showExpertView ? _jsx(ExpertDrawer, {}) : _jsx(QuestionForm, {}), _jsx(CountdownTimer, { container: countdownTimerContainer })] })), status === 'pre-live' && _jsx(Calendar, {}), _jsx(Stream, { status: status }), _jsx(Survey, { storyId: storyId, status: status }), (status === 'live' || (status === 'pre-live' && showExpertView)) && (_jsx(FloatingActionBar, { showLiveIndicator: status === 'live' })), status !== 'close' && !showExpertView && (_jsx(EmbedFormField, { container: embedFormFieldContainer }))] })), _jsx("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
94
86
  }
95
87
  export default QandaContainer;
@@ -13,7 +13,7 @@ import ErrorMessage from '../ErrorMessage';
13
13
  import { getUserProfile } from '../../store/user';
14
14
  import validateDisplayName from '../../utils/validate-display-name';
15
15
  import { getTitleByUser, getTextByUser } from './messagesByUserType';
16
- import { trackEvent } from '../../utils/tracking';
16
+ import { trackEvent, trackingNS } from '../../utils/tracking';
17
17
  export default function QuestionForm() {
18
18
  const dispatch = useDispatch();
19
19
  const { storyId, useStaging, commentsAPIUrl, maxQuestionLength } = useContext(QandaContext);
@@ -72,8 +72,9 @@ export default function QuestionForm() {
72
72
  if (updatedProfile?.displayName) {
73
73
  // NB: we are using a component act event as analytics team can only support existing categories and actions at this time
74
74
  trackEvent({
75
- category: 'component',
76
- action: 'act',
75
+ content: {
76
+ uuid: storyId,
77
+ },
77
78
  trigger_action: 'success_set_displayname',
78
79
  });
79
80
  }
@@ -107,13 +108,13 @@ export default function QuestionForm() {
107
108
  _jsxs(Overlay, { title: "Ask a question", closeCallback: () => {
108
109
  setNewDisplayName(null);
109
110
  dispatch(closeForm());
110
- }, children: [profile.isSubscribed && (_jsx("div", { className: "overlay__content-box overlay__form-box", "data-testid": "question-form-overlay", children: _jsxs("form", { onSubmit: handleSubmit, "data-trackable": `liveqa_submit_question_form_${postAnonymously ? 'anonymous' : 'displayname'}`, children: [_jsxs("div", { className: "overlay__user-container", children: [!postAnonymously && profile?.displayName && (_jsx(_Fragment, { children: _jsxs("span", { className: "overlay__user-container-display-name o3-type-body-highlight", children: [_jsx("i", { className: "overlay__message-icon", style: { maskImage: 'var(--o3-icon-user)' } }), profile.displayName] }) })), !profile?.displayName && (_jsxs("label", { for: "display-name", className: "question-form__displayname-input o-forms-field", children: [_jsx("span", { className: "o-forms-title", children: _jsx("span", { className: "o3-type-body-highlight", children: "Choose a display name" }) }), _jsxs("span", { className: classNames([
111
+ }, children: [profile.isSubscribed && (_jsx("div", { className: "overlay__content-box overlay__form-box", "data-testid": "question-form-overlay", children: _jsxs("form", { onSubmit: handleSubmit, "data-trackable": trackingNS(`submit_question_form_${postAnonymously ? 'anonymous' : 'displayname'}`), children: [_jsxs("div", { className: "overlay__user-container", children: [!postAnonymously && profile?.displayName && (_jsx(_Fragment, { children: _jsxs("span", { className: "overlay__user-container-display-name o3-type-body-highlight", children: [_jsx("i", { className: "overlay__message-icon", style: { maskImage: 'var(--o3-icon-user)' } }), profile.displayName] }) })), !profile?.displayName && (_jsxs("label", { for: "display-name", className: "question-form__displayname-input o-forms-field", children: [_jsx("span", { className: "o-forms-title", children: _jsx("span", { className: "o3-type-body-highlight", children: "Choose a display name" }) }), _jsxs("span", { className: classNames([
111
112
  'question-form__displayname__input',
112
113
  'o-forms-input',
113
114
  'o-forms-input--text',
114
115
  { 'o-forms-input--invalid': !!displayNameError },
115
116
  ]), children: [_jsx("input", { className: "question-form__displayname__input__field o3-type-body-lg", id: "display-name", value: newDisplayName || '', onChange: (e) => setNewDisplayName(e.currentTarget.value), type: postAnonymously ? 'password' : 'text', "aria-invalid": displayNameError ? 'true' : 'false', "aria-errormessage": displayNameError ??
116
- 'question_form__displayname-error-message' }), displayNameError && (_jsx("span", { className: "question-form__displayname__input__error o3-type-detail", id: "question_form__displayname-error-message", children: _jsx("span", { children: displayNameError }) }))] })] }))] }), _jsx("div", { className: "o-forms-field", children: _jsxs("label", { className: "o-forms-input o-forms-input--checkbox", htmlFor: "post-anonymously", children: [_jsx("input", { type: "checkbox", name: "post-anonymously", id: "post-anonymously", value: "true", onChange: handleHideDisplayName, "data-trackable-context-action": `Post anonymously ${postAnonymously ? 'off' : 'on'}`, "data-trackable": `question-form__post_anonymously-${postAnonymously ? 'off' : 'on'}` }), _jsx("span", { className: "o-forms-input__label", children: "Post anonymously (optional)" })] }) }), _jsxs("label", { for: "question-text", class: "o-forms-field question-form__question__input", children: [_jsx("span", { class: "o-forms-title", children: _jsx("span", { class: "o3-type-body-highlight", children: "Enter your question" }) }), _jsx("span", { class: "o-forms-input o-forms-input--textarea", children: _jsx("textarea", { id: "question-text", name: "question", value: question, onChange: (e) => dispatch(updateQuestion(e.currentTarget.value)), "aria-label": "Your question", placeholder: "Type your question", maxLength: maxQuestionLength, "aria-invalid": error ? 'true' : undefined, "aria-errormessage": "question-form-error-message" }) })] }), _jsx("span", { className: "o3-type-detail", children: "Questions must be at least 20 characters long." }), _jsx(Button, { attributes: {
117
+ 'question_form__displayname-error-message' }), displayNameError && (_jsx("span", { className: "question-form__displayname__input__error o3-type-detail", id: "question_form__displayname-error-message", children: _jsx("span", { children: displayNameError }) }))] })] }))] }), _jsx("div", { className: "o-forms-field", children: _jsxs("label", { className: "o-forms-input o-forms-input--checkbox", htmlFor: "post-anonymously", children: [_jsx("input", { type: "checkbox", name: "post-anonymously", id: "post-anonymously", value: "true", onChange: handleHideDisplayName, "data-trackable-context-action": `Post anonymously ${postAnonymously ? 'off' : 'on'}`, "data-trackable": trackingNS(`question-form__post_anonymously-${postAnonymously ? 'off' : 'on'}`) }), _jsx("span", { className: "o-forms-input__label", children: "Post anonymously (optional)" })] }) }), _jsxs("label", { for: "question-text", class: "o-forms-field question-form__question__input", children: [_jsx("span", { class: "o-forms-title", children: _jsx("span", { class: "o3-type-body-highlight", children: "Enter your question" }) }), _jsx("span", { class: "o-forms-input o-forms-input--textarea", children: _jsx("textarea", { id: "question-text", name: "question", value: question, onChange: (e) => dispatch(updateQuestion(e.currentTarget.value)), "aria-label": "Your question", placeholder: "Type your question", maxLength: maxQuestionLength, "aria-invalid": error ? 'true' : undefined, "aria-errormessage": "question-form-error-message" }) })] }), _jsx("span", { className: "o3-type-detail", children: "Questions must be at least 20 characters long." }), _jsx(Button, { attributes: {
117
118
  className: 'overlay__submit-button',
118
119
  type: 'submit',
119
120
  disabled: !submitEnabled,
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "preact/jsx-runtime";
2
2
  import { PRODUCT_NAME } from '../../config/qanda';
3
+ import { trackingNS } from '../../utils/tracking';
3
4
  export const SIGN_IN_URL = 'https://www.ft.com/login';
4
5
  export const SUBSCRIBE_URL = 'https://subs.ft.com/products';
5
6
  export const COMMUNITY_GUIDELINES_URL = 'https://help.ft.com/help/article-queries/commenting-on-an-article/commenting-guidelines';
@@ -16,14 +17,14 @@ export function getTitleByUser(profile) {
16
17
  }
17
18
  export function getTextByUser(profile) {
18
19
  if (profile.isSubscribed) {
19
- return (_jsxs(_Fragment, { children: ["Keep your comments respectful and easy to understand for our global audience. By submitting, you agree to follow our", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": "question-form__community-guidelines", "data-trackable-context-action": "Community guidelines", href: COMMUNITY_GUIDELINES_URL, target: "_parent", children: "community guidelines" }), ' ', "and", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": "question-form__terms-and-conditions", "data-trackable-context-action": "Terms and conditions", href: TERMS_AND_CONDITIONS_URL, target: "_parent", children: "terms" }), "."] }));
20
+ return (_jsxs(_Fragment, { children: ["Keep your comments respectful and easy to understand for our global audience. By submitting, you agree to follow our", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": trackingNS('question-form__community-guidelines'), "data-trackable-context-action": "Community guidelines", href: COMMUNITY_GUIDELINES_URL, target: "_parent", children: "community guidelines" }), ' ', "and", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": trackingNS('question-form__terms-and-conditions'), "data-trackable-context-action": "Terms and conditions", href: TERMS_AND_CONDITIONS_URL, target: "_parent", children: "terms" }), "."] }));
20
21
  }
21
22
  if (profile.isTrialist) {
22
- return (_jsxs(_Fragment, { children: ["View our full", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": "question-form__subscribe-trialist", "data-trackable-context-action": "Subscribe", href: SUBSCRIBE_URL, target: "_parent", children: "subscription packages" }), ' ', "to join the conversation."] }));
23
+ return (_jsxs(_Fragment, { children: ["View our full", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": trackingNS('question-form__subscribe-trialist'), "data-trackable-context-action": "Subscribe", href: SUBSCRIBE_URL, target: "_parent", children: "subscription packages" }), ' ', "to join the conversation."] }));
23
24
  }
24
25
  if (profile.isRegistered) {
25
- return (_jsxs(_Fragment, { children: [_jsx("a", { className: "message-box__content-link", "data-trackable": "question-form__subscribe-registered", "data-trackable-context-action": "Subscribe", href: SUBSCRIBE_URL, target: "_parent", children: "Subscribe" }), ' ', "to join the conversation."] }));
26
+ return (_jsxs(_Fragment, { children: [_jsx("a", { className: "message-box__content-link", "data-trackable": trackingNS('question-form__subscribe-registered'), "data-trackable-context-action": "Subscribe", href: SUBSCRIBE_URL, target: "_parent", children: "Subscribe" }), ' ', "to join the conversation."] }));
26
27
  }
27
28
  // Anonymous users
28
- return (_jsxs(_Fragment, { children: ["Please", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": "question-form__sign-in-anonymous", "data-trackable-context-action": "Sign in", href: SIGN_IN_URL, target: "_parent", children: "sign in" }), ' ', "or", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": "question-form__subscribe-anonymous", "data-trackable-context-action": "Subscribe", href: SUBSCRIBE_URL, target: "_parent", children: "subscribe" }), ' ', "to join the conversation."] }));
29
+ return (_jsxs(_Fragment, { children: ["Please", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": trackingNS('question-form__sign-in-anonymous'), "data-trackable-context-action": "Sign in", href: SIGN_IN_URL, target: "_parent", children: "sign in" }), ' ', "or", ' ', _jsx("a", { className: "message-box__content-link", "data-trackable": trackingNS('question-form__subscribe-anonymous'), "data-trackable-context-action": "Subscribe", href: SUBSCRIBE_URL, target: "_parent", children: "subscribe" }), ' ', "to join the conversation."] }));
29
30
  }
@@ -1,34 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { trackingNS } from '../../utils/tracking';
2
3
  function Survey({ storyId, status }) {
3
- const trackEvent = (trackingData) => {
4
- const event = new CustomEvent('oTracking.event', {
5
- detail: trackingData,
6
- bubbles: true,
7
- });
8
- document.body.dispatchEvent(event);
9
- };
10
- const handleClick = () => {
11
- trackEvent({
12
- category: 'component',
13
- component: {
14
- name: 'liveqa',
15
- type: 'container',
16
- id: '663ab2ca-77ca-4b50-873d-1fd2ff21ff08',
17
- },
18
- action: 'act',
19
- trigger_action: 'liveqa_survey_open',
20
- content: {
21
- asset_type: 'article',
22
- uuid: storyId,
23
- },
24
- custom: [
25
- {
26
- name: 'status',
27
- value: status,
28
- },
29
- ],
30
- });
31
- };
32
- return (_jsx("div", { className: "o-message o-message--action o-message--inform o-message--survey", style: { marginBottom: 'var(--o3-spacing-l)' }, "data-o-message-close": "false", "data-o-component": "o-message", children: _jsx("div", { className: "o-message__container", children: _jsxs("div", { className: "o-message__content", children: [_jsx("p", { className: "o-message__content-main", style: { fontSize: 'var(--o3-type-body-base-font-size)' }, children: "How was your experience?" }), _jsx("div", { className: "o-message__actions", children: _jsx("a", { href: `https://www.feedback.ft.com/c/a/6HTDVvrHSyaKLZ5281McAo?content_id=${storyId}&qa_status=${status}`, onClick: handleClick, className: "o-message__actions__primary", "data-trackable": "liveqa_survey_link", children: "Share your feedback" }) })] }) }) }));
4
+ return (_jsx("div", { className: "o-message o-message--action o-message--inform o-message--survey", style: { marginBottom: 'var(--o3-spacing-l)' }, "data-o-message-close": "false", "data-o-component": "o-message", children: _jsx("div", { className: "o-message__container", children: _jsxs("div", { className: "o-message__content", children: [_jsx("p", { className: "o-message__content-main", style: { fontSize: 'var(--o3-type-body-base-font-size)' }, children: "How was your experience?" }), _jsx("div", { className: "o-message__actions", children: _jsx("a", { href: `https://www.feedback.ft.com/c/a/6HTDVvrHSyaKLZ5281McAo?content_id=${storyId}&qa_status=${status}`, className: "o-message__actions__primary", "data-trackable": trackingNS('survey_link'), children: "Share your feedback" }) })] }) }) }));
33
5
  }
34
6
  export default Survey;
@@ -1,4 +1,26 @@
1
- export const trackEvent = (trackingData) => {
1
+ const trackingNamespace = 'askanexpert_';
2
+ export function trackingNS(string) {
3
+ return trackingNamespace + string;
4
+ }
5
+ export const baseTrackingData = {
6
+ category: 'component',
7
+ action: 'act',
8
+ component: {
9
+ name: 'askanexpert',
10
+ type: 'container',
11
+ id: '663ab2ca-77ca-4b50-873d-1fd2ff21ff08',
12
+ },
13
+ content: {
14
+ asset_type: 'article',
15
+ },
16
+ };
17
+ export const trackEvent = (customTrackingData) => {
18
+ // Merge the base tracking data with the provided tracking data
19
+ const trackingData = {
20
+ ...baseTrackingData,
21
+ ...customTrackingData,
22
+ trigger_action: trackingNamespace + customTrackingData.trigger_action,
23
+ };
2
24
  const event = new CustomEvent('oTracking.event', {
3
25
  detail: trackingData,
4
26
  bubbles: true,
package/dist/qanda.scss CHANGED
@@ -341,7 +341,7 @@ $app-header-color: #007acc;
341
341
  --overlay__header-icon-size: 48px;
342
342
  }
343
343
 
344
- @keyframes slideUp {
344
+ @keyframes QandaOverlaySlideUp {
345
345
  from {
346
346
  transform: translateY(100%);
347
347
  }
@@ -351,7 +351,7 @@ $app-header-color: #007acc;
351
351
  }
352
352
  }
353
353
 
354
- @keyframes slideIn {
354
+ @keyframes QandaOverlaySlideIn {
355
355
  from {
356
356
  transform: translateX(100%);
357
357
  }
@@ -361,7 +361,7 @@ $app-header-color: #007acc;
361
361
  }
362
362
  }
363
363
 
364
- @keyframes fadeIn {
364
+ @keyframes QandaOverlayFadeIn {
365
365
  from {
366
366
  opacity: 0;
367
367
  }
@@ -388,7 +388,7 @@ $app-header-color: #007acc;
388
388
  right: 0;
389
389
  bottom: 0;
390
390
  z-index: 19;
391
- animation: fadeIn 1s ease forwards;
391
+ animation: QandaOverlayFadeIn 1s ease forwards;
392
392
  background: var(--o3-color-palette-black-90);
393
393
  margin-top: calc(var(--safe-area-inset-top, 0px) / 2);
394
394
  }
@@ -400,14 +400,14 @@ $app-header-color: #007acc;
400
400
  height: 100%;
401
401
  width: 100%;
402
402
  z-index: 20;
403
- animation: slideUp 1s ease forwards;
403
+ animation: QandaOverlaySlideUp 1s ease forwards;
404
404
 
405
405
  @media (min-width: 740px) {
406
406
  width: 375px;
407
407
  right: 0;
408
408
  top: 0;
409
409
  border-radius: 0;
410
- animation: slideIn 1s ease forwards;
410
+ animation: QandaOverlaySlideIn 1s ease forwards;
411
411
  }
412
412
  }
413
413
 
@@ -557,7 +557,7 @@ $app-header-color: #007acc;
557
557
  var(--o3-color-palette-white-80);
558
558
  }
559
559
 
560
- .qanda-block__question-subtitle {
560
+ .qanda-block__question-summary {
561
561
  margin-bottom: var(--o3-spacing-4xs);
562
562
  }
563
563
 
@@ -3,5 +3,5 @@ import '../Expander/index';
3
3
  type QandaBlockProps = Comment & {
4
4
  showAnswerTime: boolean;
5
5
  };
6
- declare function QandaBlock({ id, body, children, byline, subtitle, showAnswerTime, }: QandaBlockProps): import("react").JSX.Element;
6
+ declare function QandaBlock({ id, body, children, byline, summary, showAnswerTime, }: QandaBlockProps): import("react").JSX.Element;
7
7
  export default QandaBlock;
@@ -1,6 +1,7 @@
1
+ import type { Status } from '../../types/qa';
1
2
  type SurveyProps = {
2
3
  storyId: string;
3
- status: string;
4
+ status: Status;
4
5
  };
5
6
  declare function Survey({ storyId, status }: SurveyProps): import("preact").JSX.Element;
6
7
  export default Survey;
@@ -1,2 +1,4 @@
1
- import type { TrackingData } from '../types/tracking';
2
- export declare const trackEvent: (trackingData: TrackingData) => void;
1
+ import type { BaseTrackingData, TrackingData } from '../types/tracking';
2
+ export declare function trackingNS(string: string): string;
3
+ export declare const baseTrackingData: BaseTrackingData;
4
+ export declare const trackEvent: (customTrackingData: TrackingData) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/qanda-ui",
3
- "version": "0.0.1-beta.25",
3
+ "version": "0.0.1-beta.26",
4
4
  "description": "Components for the Live Q&A (AKA Ask an Expert) UI",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",